本文整理汇总了Golang中github.com/decred/dcrd/txscript.ExtractPkScriptAddrs函数的典型用法代码示例。如果您正苦于以下问题:Golang ExtractPkScriptAddrs函数的具体用法?Golang ExtractPkScriptAddrs怎么用?Golang ExtractPkScriptAddrs使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了ExtractPkScriptAddrs函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: TicketsWithAddress
// TicketsWithAddress returns a slice of ticket hashes that are currently live
// corresponding to the given address.
//
// This function is safe for concurrent access.
func (b *BlockChain) TicketsWithAddress(address dcrutil.Address) ([]chainhash.Hash, error) {
b.chainLock.RLock()
sn := b.bestNode.stakeNode
b.chainLock.RUnlock()
tickets := sn.LiveTickets()
var ticketsWithAddr []chainhash.Hash
err := b.db.View(func(dbTx database.Tx) error {
var err error
for _, hash := range tickets {
utxo, err := dbFetchUtxoEntry(dbTx, &hash)
if err != nil {
return err
}
_, addrs, _, err :=
txscript.ExtractPkScriptAddrs(txscript.DefaultScriptVersion,
utxo.PkScriptByIndex(0), b.chainParams)
if addrs[0].EncodeAddress() == address.EncodeAddress() {
ticketsWithAddr = append(ticketsWithAddr, hash)
}
}
return err
})
if err != nil {
return nil, err
}
return ticketsWithAddr, nil
}
开发者ID:decred,项目名称:dcrd,代码行数:35,代码来源:stakeext.go
示例2: GetLiveTicketsInBucketData
// GetLiveTicketsInBucketData creates a map indicating the ticket hash and the
// owner's address for each bucket. Used for an RPC call.
func (tmdb *TicketDB) GetLiveTicketsInBucketData(
bucket uint8) (map[chainhash.Hash]dcrutil.Address, error) {
tmdb.mtx.Lock()
defer tmdb.mtx.Unlock()
ltbd := make(map[chainhash.Hash]dcrutil.Address)
tickets := tmdb.maps.ticketMap[bucket]
for _, ticket := range tickets {
// Load the ticket from the database and find the address that it's
// going to.
txReply, err := tmdb.database.FetchTxBySha(&ticket.SStxHash)
if err != nil {
return nil, err
}
_, addr, _, err :=
txscript.ExtractPkScriptAddrs(txReply[0].Tx.TxOut[0].Version,
txReply[0].Tx.TxOut[0].PkScript, tmdb.chainParams)
if err != nil {
return nil, err
}
ltbd[ticket.SStxHash] = addr[0]
}
return ltbd, nil
}
开发者ID:zebbra2014,项目名称:dcrd,代码行数:28,代码来源:ticketdb.go
示例3: ExampleExtractPkScriptAddrs
// This example demonstrates extracting information from a standard public key
// script.
func ExampleExtractPkScriptAddrs() {
// Start with a standard pay-to-pubkey-hash script.
scriptHex := "76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac"
script, err := hex.DecodeString(scriptHex)
if err != nil {
fmt.Println(err)
return
}
// Extract and print details from the script.
scriptClass, addresses, reqSigs, err := txscript.ExtractPkScriptAddrs(
txscript.DefaultScriptVersion, script, &chaincfg.MainNetParams)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Script Class:", scriptClass)
fmt.Println("Addresses:", addresses)
fmt.Println("Required Signatures:", reqSigs)
// Output:
// Script Class: pubkeyhash
// Addresses: [DsSej1qR3Fyc8kV176DCh9n9cY9nqf9Quxk]
// Required Signatures: 1
}
开发者ID:ironbits,项目名称:dcrd,代码行数:27,代码来源:example_test.go
示例4: lookupInputAccount
func lookupInputAccount(dbtx walletdb.ReadTx, w *Wallet, details *wtxmgr.TxDetails, deb wtxmgr.DebitRecord) uint32 {
addrmgrNs := dbtx.ReadBucket(waddrmgrNamespaceKey)
txmgrNs := dbtx.ReadBucket(wtxmgrNamespaceKey)
// TODO: Debits should record which account(s?) they
// debit from so this doesn't need to be looked up.
prevOP := &details.MsgTx.TxIn[deb.Index].PreviousOutPoint
prev, err := w.TxStore.TxDetails(txmgrNs, &prevOP.Hash)
if err != nil {
log.Errorf("Cannot query previous transaction details for %v: %v", prevOP.Hash, err)
return 0
}
if prev == nil {
log.Errorf("Missing previous transaction %v", prevOP.Hash)
return 0
}
prevOut := prev.MsgTx.TxOut[prevOP.Index]
_, addrs, _, err := txscript.ExtractPkScriptAddrs(prevOut.Version, prevOut.PkScript, w.chainParams)
var inputAcct uint32
if err == nil && len(addrs) > 0 {
inputAcct, err = w.Manager.AddrAccount(addrmgrNs, addrs[0])
}
if err != nil {
log.Errorf("Cannot fetch account for previous output %v: %v", prevOP, err)
inputAcct = 0
}
return inputAcct
}
开发者ID:jcvernaleo,项目名称:btcwallet,代码行数:28,代码来源:notifications.go
示例5: GetLiveTicketsForAddress
// GetLiveTicketsForAddress gets all currently active tickets for a given
// address.
func (tmdb *TicketDB) GetLiveTicketsForAddress(
address dcrutil.Address) ([]chainhash.Hash, error) {
tmdb.mtx.Lock()
defer tmdb.mtx.Unlock()
var ltfa []chainhash.Hash
for i := 0; i < BucketsSize; i++ {
for _, ticket := range tmdb.maps.ticketMap[i] {
// Load the ticket from the database and find the address that it's
// going to.
txReply, err := tmdb.database.FetchTxBySha(&ticket.SStxHash)
if err != nil {
return nil, err
}
_, addr, _, err :=
txscript.ExtractPkScriptAddrs(txReply[0].Tx.TxOut[0].Version,
txReply[0].Tx.TxOut[0].PkScript, tmdb.chainParams)
if err != nil {
return nil, err
}
// Compare the HASH160 result and see if it's equal.
if bytes.Equal(addr[0].ScriptAddress(), address.ScriptAddress()) {
ltfa = append(ltfa, ticket.SStxHash)
}
}
}
return ltfa, nil
}
开发者ID:zebbra2014,项目名称:dcrd,代码行数:33,代码来源:ticketdb.go
示例6: signMultiSigUTXO
// signMultiSigUTXO signs the P2SH UTXO with the given index by constructing a
// script containing all given signatures plus the redeem (multi-sig) script. The
// redeem script is obtained by looking up the address of the given P2SH pkScript
// on the address manager.
// The order of the signatures must match that of the public keys in the multi-sig
// script as OP_CHECKMULTISIG expects that.
// This function must be called with the manager unlocked.
func signMultiSigUTXO(mgr *waddrmgr.Manager, tx *wire.MsgTx, idx int, pkScript []byte, sigs []RawSig) error {
class, addresses, _, err := txscript.ExtractPkScriptAddrs(txscript.DefaultScriptVersion, pkScript, mgr.ChainParams())
if err != nil {
return newError(ErrTxSigning, "unparseable pkScript", err)
}
if class != txscript.ScriptHashTy {
return newError(ErrTxSigning, fmt.Sprintf("pkScript is not P2SH: %s", class), nil)
}
redeemScript, err := getRedeemScript(mgr, addresses[0].(*dcrutil.AddressScriptHash))
if err != nil {
return newError(ErrTxSigning, "unable to retrieve redeem script", err)
}
class, _, nRequired, err := txscript.ExtractPkScriptAddrs(txscript.DefaultScriptVersion, redeemScript, mgr.ChainParams())
if err != nil {
return newError(ErrTxSigning, "unparseable redeem script", err)
}
if class != txscript.MultiSigTy {
return newError(ErrTxSigning, fmt.Sprintf("redeem script is not multi-sig: %v", class), nil)
}
if len(sigs) < nRequired {
errStr := fmt.Sprintf("not enough signatures; need %d but got only %d", nRequired,
len(sigs))
return newError(ErrTxSigning, errStr, nil)
}
// Construct the unlocking script.
// Start with an OP_0 because of the bug in bitcoind, then add nRequired signatures.
unlockingScript := txscript.NewScriptBuilder().AddOp(txscript.OP_FALSE)
for _, sig := range sigs[:nRequired] {
unlockingScript.AddData(sig)
}
// Combine the redeem script and the unlocking script to get the actual signature script.
sigScript := unlockingScript.AddData(redeemScript)
script, err := sigScript.Script()
if err != nil {
return newError(ErrTxSigning, "error building sigscript", err)
}
tx.TxIn[idx].SignatureScript = script
if err := validateSigScript(tx, idx, pkScript); err != nil {
return err
}
return nil
}
开发者ID:frankbraun,项目名称:dcrwallet,代码行数:53,代码来源:withdrawal.go
示例7: GetSSGenStakeOutputInfo
// GetSSGenStakeOutputInfo takes an SSGen tx as input and scans through its
// outputs, returning the amount of the output and the PKH or SH that it was
// sent to.
func GetSSGenStakeOutputInfo(tx *dcrutil.Tx, params *chaincfg.Params) ([]bool,
[][]byte, []int64, error) {
msgTx := tx.MsgTx()
numOutputsInSSGen := len(msgTx.TxOut)
isP2SH := make([]bool, numOutputsInSSGen-2)
addresses := make([][]byte, numOutputsInSSGen-2)
amounts := make([]int64, numOutputsInSSGen-2)
// Cycle through the inputs and generate
for idx, out := range msgTx.TxOut {
// We only care about the outputs where we get proportional
// amounts and the PKHs they were sent to.
if (idx > 1) && (idx < numOutputsInSSGen) {
// Get the PKH or SH it's going to, and what type of
// script it is.
class, addr, _, err :=
txscript.ExtractPkScriptAddrs(out.Version, out.PkScript, params)
if err != nil {
return nil, nil, nil, err
}
if class != txscript.StakeGenTy {
return nil, nil, nil, fmt.Errorf("ssgen output included non "+
"ssgen tagged output in idx %v", idx)
}
subClass, err := txscript.GetStakeOutSubclass(out.PkScript)
if !(subClass == txscript.PubKeyHashTy ||
subClass == txscript.ScriptHashTy) {
return nil, nil, nil, fmt.Errorf("bad script type")
}
isP2SH[idx-2] = false
if subClass == txscript.ScriptHashTy {
isP2SH[idx-2] = true
}
// Get the amount that was sent.
amt := out.Value
addresses[idx-2] = addr[0].ScriptAddress()
amounts[idx-2] = amt
}
}
return isP2SH, addresses, amounts, nil
}
开发者ID:ironbits,项目名称:dcrd,代码行数:47,代码来源:staketx.go
示例8: lookupOutputChain
func lookupOutputChain(dbtx walletdb.ReadTx, w *Wallet, details *wtxmgr.TxDetails,
cred wtxmgr.CreditRecord) (account uint32, internal bool) {
addrmgrNs := dbtx.ReadBucket(waddrmgrNamespaceKey)
output := details.MsgTx.TxOut[cred.Index]
_, addrs, _, err := txscript.ExtractPkScriptAddrs(output.Version, output.PkScript, w.chainParams)
var ma waddrmgr.ManagedAddress
if err == nil && len(addrs) > 0 {
ma, err = w.Manager.Address(addrmgrNs, addrs[0])
}
if err != nil {
log.Errorf("Cannot fetch account for wallet output: %v", err)
} else {
account = ma.Account()
internal = ma.Internal()
}
return
}
开发者ID:jcvernaleo,项目名称:btcwallet,代码行数:19,代码来源:notifications.go
示例9: AddTicket
// AddTicket adds a ticket transaction to the wallet.
func (w *Wallet) AddTicket(ticket *dcrutil.Tx) error {
return walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
stakemgrNs := tx.ReadWriteBucket(wstakemgrNamespaceKey)
// Insert the ticket to be tracked and voted.
err := w.StakeMgr.InsertSStx(stakemgrNs, ticket, w.VoteBits)
if err != nil {
return err
}
if w.stakePoolEnabled {
addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)
// Pluck the ticketaddress to indentify the stakepool user.
pkVersion := ticket.MsgTx().TxOut[0].Version
pkScript := ticket.MsgTx().TxOut[0].PkScript
_, addrs, _, err := txscript.ExtractPkScriptAddrs(pkVersion,
pkScript, w.ChainParams())
if err != nil {
return err
}
ticketHash := ticket.MsgTx().TxSha()
chainClient, err := w.requireChainClient()
if err != nil {
return err
}
rawTx, err := chainClient.GetRawTransactionVerbose(&ticketHash)
if err != nil {
return err
}
// Update the pool ticket stake. This will include removing it from the
// invalid slice and adding a ImmatureOrLive ticket to the valid ones.
err = w.updateStakePoolInvalidTicket(stakemgrNs, addrmgrNs, addrs[0], &ticketHash, rawTx.BlockHeight)
if err != nil {
return err
}
}
return nil
})
}
开发者ID:jcvernaleo,项目名称:btcwallet,代码行数:44,代码来源:tickets.go
示例10: indexUnconfirmedAddresses
// indexUnconfirmedAddresses modifies the unconfirmed (memory-only) address
// index to include mappings for the addresses encoded by the passed public key
// script to the transaction.
//
// This function is safe for concurrent access.
func (idx *AddrIndex) indexUnconfirmedAddresses(scriptVersion uint16, pkScript []byte, tx *dcrutil.Tx, isSStx bool) {
// The error is ignored here since the only reason it can fail is if the
// script fails to parse and it was already validated before being
// admitted to the mempool.
class, addresses, _, _ := txscript.ExtractPkScriptAddrs(scriptVersion,
pkScript, idx.chainParams)
if isSStx && class == txscript.NullDataTy {
addr, err := stake.AddrFromSStxPkScrCommitment(pkScript, idx.chainParams)
if err != nil {
// Fail if this fails to decode. It should.
return
}
addresses = append(addresses, addr)
}
for _, addr := range addresses {
// Ignore unsupported address types.
addrKey, err := addrToKey(addr, idx.chainParams)
if err != nil {
continue
}
// Add a mapping from the address to the transaction.
idx.unconfirmedLock.Lock()
addrIndexEntry := idx.txnsByAddr[addrKey]
if addrIndexEntry == nil {
addrIndexEntry = make(map[chainhash.Hash]*dcrutil.Tx)
idx.txnsByAddr[addrKey] = addrIndexEntry
}
addrIndexEntry[*tx.Sha()] = tx
// Add a mapping from the transaction to the address.
addrsByTxEntry := idx.addrsByTx[*tx.Sha()]
if addrsByTxEntry == nil {
addrsByTxEntry = make(map[[addrKeySize]byte]struct{})
idx.addrsByTx[*tx.Sha()] = addrsByTxEntry
}
addrsByTxEntry[addrKey] = struct{}{}
idx.unconfirmedLock.Unlock()
}
}
开发者ID:decred,项目名称:dcrd,代码行数:48,代码来源:addrindex.go
示例11: indexPkScript
// indexPkScript extracts all standard addresses from the passed public key
// script and maps each of them to the associated transaction using the passed
// map.
func (idx *AddrIndex) indexPkScript(data writeIndexData, scriptVersion uint16, pkScript []byte, txIdx int, isSStx bool) {
// Nothing to index if the script is non-standard or otherwise doesn't
// contain any addresses.
class, addrs, _, err := txscript.ExtractPkScriptAddrs(scriptVersion, pkScript,
idx.chainParams)
if err != nil {
return
}
if isSStx && class == txscript.NullDataTy {
addr, err := stake.AddrFromSStxPkScrCommitment(pkScript, idx.chainParams)
if err != nil {
return
}
addrs = append(addrs, addr)
}
if len(addrs) == 0 {
return
}
for _, addr := range addrs {
addrKey, err := addrToKey(addr, idx.chainParams)
if err != nil {
// Ignore unsupported address types.
continue
}
// Avoid inserting the transaction more than once. Since the
// transactions are indexed serially any duplicates will be
// indexed in a row, so checking the most recent entry for the
// address is enough to detect duplicates.
indexedTxns := data[addrKey]
numTxns := len(indexedTxns)
if numTxns > 0 && indexedTxns[numTxns-1] == txIdx {
continue
}
indexedTxns = append(indexedTxns, txIdx)
data[addrKey] = indexedTxns
}
}
开发者ID:decred,项目名称:dcrd,代码行数:45,代码来源:addrindex.go
示例12: TxSSRtxStakeOutputInfo
// TxSSRtxStakeOutputInfo takes an SSRtx tx as input and scans through its
// outputs, returning the amount of the output and the pkh that it was sent to.
func TxSSRtxStakeOutputInfo(tx *wire.MsgTx, params *chaincfg.Params) ([]bool,
[][]byte, []int64, error) {
numOutputsInSSRtx := len(tx.TxOut)
isP2SH := make([]bool, numOutputsInSSRtx)
addresses := make([][]byte, numOutputsInSSRtx)
amounts := make([]int64, numOutputsInSSRtx)
// Cycle through the inputs and generate
for idx, out := range tx.TxOut {
// Get the PKH or SH it's going to, and what type of
// script it is.
class, addr, _, err :=
txscript.ExtractPkScriptAddrs(out.Version, out.PkScript, params)
if err != nil {
return nil, nil, nil, err
}
if class != txscript.StakeRevocationTy {
return nil, nil, nil, fmt.Errorf("ssrtx output included non "+
"ssrtx tagged output in idx %v", idx)
}
subClass, err := txscript.GetStakeOutSubclass(out.PkScript)
if !(subClass == txscript.PubKeyHashTy ||
subClass == txscript.ScriptHashTy) {
return nil, nil, nil, fmt.Errorf("bad script type")
}
isP2SH[idx] = false
if subClass == txscript.ScriptHashTy {
isP2SH[idx] = true
}
// Get the amount that was sent.
amt := out.Value
addresses[idx] = addr[0].ScriptAddress()
amounts[idx] = amt
}
return isP2SH, addresses, amounts, nil
}
开发者ID:decred,项目名称:dcrd,代码行数:42,代码来源:staketx.go
示例13: totalBalances
func totalBalances(dbtx walletdb.ReadTx, w *Wallet, m map[uint32]dcrutil.Amount) error {
addrmgrNs := dbtx.ReadBucket(waddrmgrNamespaceKey)
unspent, err := w.TxStore.UnspentOutputs(dbtx.ReadBucket(wtxmgrNamespaceKey))
if err != nil {
return err
}
for i := range unspent {
output := unspent[i]
var outputAcct uint32
_, addrs, _, err := txscript.ExtractPkScriptAddrs(
txscript.DefaultScriptVersion, output.PkScript, w.chainParams)
if err == nil && len(addrs) > 0 {
outputAcct, err = w.Manager.AddrAccount(addrmgrNs, addrs[0])
}
if err == nil {
_, ok := m[outputAcct]
if ok {
m[outputAcct] += output.Amount
}
}
}
return nil
}
开发者ID:jcvernaleo,项目名称:btcwallet,代码行数:23,代码来源:notifications.go
示例14: groupCreditsByAddr
// groupCreditsByAddr converts a slice of credits to a map from the string
// representation of an encoded address to the unspent outputs associated with
// that address.
func groupCreditsByAddr(credits []*wtxmgr.Credit, chainParams *chaincfg.Params) (
map[string][]wtxmgr.Credit, error) {
addrMap := make(map[string][]wtxmgr.Credit)
for _, c := range credits {
_, addrs, _, err := txscript.ExtractPkScriptAddrs(txscript.DefaultScriptVersion, c.PkScript, chainParams)
if err != nil {
return nil, newError(ErrInputSelection, "failed to obtain input address", err)
}
// As our credits are all P2SH we should never have more than one
// address per credit, so let's error out if that assumption is
// violated.
if len(addrs) != 1 {
return nil, newError(ErrInputSelection, "input doesn't have exactly one address", nil)
}
encAddr := addrs[0].EncodeAddress()
if v, ok := addrMap[encAddr]; ok {
addrMap[encAddr] = append(v, *c)
} else {
addrMap[encAddr] = []wtxmgr.Credit{*c}
}
}
return addrMap, nil
}
开发者ID:frankbraun,项目名称:dcrwallet,代码行数:27,代码来源:input_selection.go
示例15: addRelevantTx
func (w *Wallet) addRelevantTx(dbtx walletdb.ReadWriteTx, rec *wtxmgr.TxRecord,
block *wtxmgr.BlockMeta) error {
addrmgrNs := dbtx.ReadWriteBucket(waddrmgrNamespaceKey)
stakemgrNs := dbtx.ReadWriteBucket(wstakemgrNamespaceKey)
txmgrNs := dbtx.ReadWriteBucket(wtxmgrNamespaceKey)
// At the moment all notified transactions are assumed to actually be
// relevant. This assumption will not hold true when SPV support is
// added, but until then, simply insert the transaction because there
// should either be one or more relevant inputs or outputs.
//
// TODO This function is pretty bad corruption wise, it's very easy
// to corrupt the wallet if you ctrl+c while in this function. This
// needs desperate refactoring.
tx := dcrutil.NewTx(&rec.MsgTx)
txHash := rec.Hash
// Handle incoming SStx; store them in the stake manager if we own
// the OP_SSTX tagged out, except if we're operating as a stake pool
// server. In that case, additionally consider the first commitment
// output as well.
if is, _ := stake.IsSStx(&rec.MsgTx); is {
// Errors don't matter here. If addrs is nil, the range below
// does nothing.
txOut := tx.MsgTx().TxOut[0]
_, addrs, _, _ := txscript.ExtractPkScriptAddrs(txOut.Version,
txOut.PkScript, w.chainParams)
insert := false
for _, addr := range addrs {
_, err := w.Manager.Address(addrmgrNs, addr)
if err == nil {
// We own the voting output pubkey or script and we're
// not operating as a stake pool, so simply insert this
// ticket now.
if !w.stakePoolEnabled {
insert = true
break
} else {
// We are operating as a stake pool. The below
// function will ONLY add the ticket into the
// stake pool if it has been found within a
// block.
if block == nil {
break
}
valid, errEval := w.evaluateStakePoolTicket(rec, block,
addr)
if valid {
// Be sure to insert this into the user's stake
// pool entry into the stake manager.
poolTicket := &wstakemgr.PoolTicket{
Ticket: txHash,
HeightTicket: uint32(block.Height),
Status: wstakemgr.TSImmatureOrLive,
}
errUpdate := w.StakeMgr.UpdateStakePoolUserTickets(
stakemgrNs, addrmgrNs, addr, poolTicket)
if errUpdate != nil {
log.Warnf("Failed to insert stake pool "+
"user ticket: %s", err.Error())
}
log.Debugf("Inserted stake pool ticket %v for user %v "+
"into the stake store database", txHash, addr)
insert = true
break
}
// Log errors if there were any. At this point the ticket
// must be invalid, so insert it into the list of invalid
// user tickets.
if errEval != nil {
log.Warnf("Ticket %v failed ticket evaluation for "+
"the stake pool: %s", rec.Hash, err.Error())
}
errUpdate := w.StakeMgr.UpdateStakePoolUserInvalTickets(
stakemgrNs, addr, &rec.Hash)
if errUpdate != nil {
log.Warnf("Failed to update pool user %v with "+
"invalid ticket %v", addr.EncodeAddress(),
rec.Hash)
}
}
}
}
if insert {
err := w.StakeMgr.InsertSStx(stakemgrNs, tx, w.VoteBits)
if err != nil {
log.Errorf("Failed to insert SStx %v"+
"into the stake store.", tx.Sha())
}
}
}
// Handle incoming SSGen; store them if we own
//.........这里部分代码省略.........
开发者ID:jcvernaleo,项目名称:btcwallet,代码行数:101,代码来源:chainntfns.go
示例16: convertToAddrIndex
// convertToAddrIndex indexes all data pushes greater than 8 bytes within the
// passed SPK and returns a TxAddrIndex with the given data. Our "address"
// index is actually a hash160 index, where in the ideal case the data push
// is either the hash160 of a publicKey (P2PKH) or a Script (P2SH).
func convertToAddrIndex(scrVersion uint16, scr []byte, height int64,
locInBlock *wire.TxLoc, txType stake.TxType) ([]*database.TxAddrIndex, error) {
var tais []*database.TxAddrIndex
if scr == nil || locInBlock == nil {
return nil, fmt.Errorf("passed nil pointer")
}
var indexKey [ripemd160.Size]byte
// Get the script classes and extract the PKH if applicable.
// If it's multisig, unknown, etc, just hash the script itself.
class, addrs, _, err := txscript.ExtractPkScriptAddrs(scrVersion, scr,
activeNetParams.Params)
if err != nil {
return nil, fmt.Errorf("script conversion error: %v", err.Error())
}
knownType := false
for _, addr := range addrs {
switch {
case class == txscript.PubKeyTy:
copy(indexKey[:], addr.Hash160()[:])
case class == txscript.PubkeyAltTy:
copy(indexKey[:], addr.Hash160()[:])
case class == txscript.PubKeyHashTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.PubkeyHashAltTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.StakeSubmissionTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.StakeGenTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.StakeRevocationTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.StakeSubChangeTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.MultiSigTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.ScriptHashTy:
copy(indexKey[:], addr.ScriptAddress()[:])
}
tai := &database.TxAddrIndex{
Hash160: indexKey,
Height: uint32(height),
TxOffset: uint32(locInBlock.TxStart),
TxLen: uint32(locInBlock.TxLen),
}
tais = append(tais, tai)
knownType = true
}
// This is a commitment for a future vote or
// revocation. Extract the address data from
// it and store it in the addrIndex.
if txType == stake.TxTypeSStx && class == txscript.NullDataTy {
addr, err := stake.AddrFromSStxPkScrCommitment(scr,
activeNetParams.Params)
if err != nil {
return nil, fmt.Errorf("ticket commit pkscr conversion error: %v",
err.Error())
}
copy(indexKey[:], addr.ScriptAddress()[:])
tai := &database.TxAddrIndex{
Hash160: indexKey,
Height: uint32(height),
TxOffset: uint32(locInBlock.TxStart),
TxLen: uint32(locInBlock.TxLen),
}
tais = append(tais, tai)
} else if !knownType {
copy(indexKey[:], dcrutil.Hash160(scr))
tai := &database.TxAddrIndex{
Hash160: indexKey,
Height: uint32(height),
TxOffset: uint32(locInBlock.TxStart),
TxLen: uint32(locInBlock.TxLen),
}
tais = append(tais, tai)
}
return tais, nil
}
开发者ID:alexlyp,项目名称:dcrd,代码行数:91,代码来源:chainindexer.go
示例17: TestExtractPkScriptAddrs
// TestExtractPkScriptAddrs ensures that extracting the type, addresses, and
// number of required signatures from PkScripts works as intended.
func TestExtractPkScriptAddrs(t *testing.T) {
t.Parallel()
tests := []struct {
name string
script []byte
addrs []dcrutil.Address
reqSigs int
class txscript.ScriptClass
}{
{
name: "standard p2pk with compressed pubkey (0x02)",
script: decodeHex("2102192d74d0cb94344c9569c2e7790157" +
"3d8d7903c3ebec3a957724895dca52c6b4ac"),
addrs: []dcrutil.Address{
newAddressPubKey(decodeHex("02192d74d0cb94344" +
"c9569c2e77901573d8d7903c3ebec3a95772" +
"4895dca52c6b4")),
},
reqSigs: 1,
class: txscript.PubKeyTy,
},
{
name: "standard p2pk with uncompressed pubkey (0x04)",
script: decodeHex("410411db93e1dcdb8a016b49840f8c53bc" +
"1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb" +
"84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643" +
"f656b412a3ac"),
addrs: []dcrutil.Address{
newAddressPubKey(decodeHex("0411db93e1dcdb8a0" +
"16b49840f8c53bc1eb68a382e97b1482ecad" +
"7b148a6909a5cb2e0eaddfb84ccf9744464f" +
"82e160bfa9b8b64f9d4c03f999b8643f656b" +
"412a3")),
},
reqSigs: 1,
class: txscript.PubKeyTy,
},
{
name: "standard p2pk with hybrid pubkey (0x06)",
script: decodeHex("4106192d74d0cb94344c9569c2e7790157" +
"3d8d7903c3ebec3a957724895dca52c6b40d45264838" +
"c0bd96852662ce6a847b197376830160c6d2eb5e6a4c" +
"44d33f453eac"),
addrs: []dcrutil.Address{
newAddressPubKey(decodeHex("06192d74d0cb94344" +
"c9569c2e77901573d8d7903c3ebec3a95772" +
"4895dca52c6b40d45264838c0bd96852662c" +
"e6a847b197376830160c6d2eb5e6a4c44d33" +
"f453e")),
},
reqSigs: 1,
class: txscript.PubKeyTy,
},
{
name: "standard p2pk with compressed pubkey (0x03)",
script: decodeHex("2103b0bd634234abbb1ba1e986e884185c" +
"61cf43e001f9137f23c2c409273eb16e65ac"),
addrs: []dcrutil.Address{
newAddressPubKey(decodeHex("03b0bd634234abbb1" +
"ba1e986e884185c61cf43e001f9137f23c2c" +
"409273eb16e65")),
},
reqSigs: 1,
class: txscript.PubKeyTy,
},
{
name: "2nd standard p2pk with uncompressed pubkey (0x04)",
script: decodeHex("4104b0bd634234abbb1ba1e986e884185c" +
"61cf43e001f9137f23c2c409273eb16e6537a576782e" +
"ba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c" +
"1e0908ef7bac"),
addrs: []dcrutil.Address{
newAddressPubKey(decodeHex("04b0bd634234abbb1" +
"ba1e986e884185c61cf43e001f9137f23c2c" +
"409273eb16e6537a576782eba668a7ef8bd3" +
"b3cfb1edb7117ab65129b8a2e681f3c1e090" +
"8ef7b")),
},
reqSigs: 1,
class: txscript.PubKeyTy,
},
{
name: "standard p2pk with hybrid pubkey (0x07)",
script: decodeHex("4107b0bd634234abbb1ba1e986e884185c" +
"61cf43e001f9137f23c2c409273eb16e6537a576782e" +
"ba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c" +
"1e0908ef7bac"),
addrs: []dcrutil.Address{
newAddressPubKey(decodeHex("07b0bd634234abbb1" +
"ba1e986e884185c61cf43e001f9137f23c2c" +
"409273eb16e6537a576782eba668a7ef8bd3" +
"b3cfb1edb7117ab65129b8a2e681f3c1e090" +
"8ef7b")),
},
reqSigs: 1,
class: txscript.PubKeyTy,
},
//.........这里部分代码省略.........
开发者ID:Kefkius,项目名称:dcrd,代码行数:101,代码来源:standard_test.go
示例18: addRelevantTx
func (w *Wallet) addRelevantTx(rec *wtxmgr.TxRecord,
block *wtxmgr.BlockMeta) error {
// TODO: The transaction store and address manager need to be updated
// together, but each operate under different namespaces and are changed
// under new transactions. This is not error safe as we lose
// transaction semantics.
//
// I'm unsure of the best way to solve this. Some possible solutions
// and drawbacks:
//
// 1. Open write transactions here and pass the handle to every
// waddrmr and wtxmgr method. This complicates the caller code
// everywhere, however.
//
// 2. Move the wtxmgr namespace into the waddrmgr namespace, likely
// under its own bucket. This entire function can then be moved
// into the waddrmgr package, which updates the nested wtxmgr.
// This removes some of separation between the components.
//
// 3. Use multiple wtxmgrs, one for each account, nested in the
// waddrmgr namespace. This still provides some sort of logical
// separation (transaction handling remains in another package, and
// is simply used by waddrmgr), but may result in duplicate
// transactions being saved if they are relevant to multiple
// accounts.
//
// 4. Store wtxmgr-related details under the waddrmgr namespace, but
// solve the drawback of #3 by splitting wtxmgr to save entire
// transaction records globally for all accounts, with
// credit/debit/balance tracking per account. Each account would
// also save the relevant transaction hashes and block incidence so
// the full transaction can be loaded from the waddrmgr
// transactions bucket. This currently seems like the best
// solution.
// At the moment all notified transactions are assumed to actually be
// relevant. This assumption will not hold true when SPV support is
// added, but until then, simply insert the transaction because there
// should either be one or more relevant inputs or outputs.
//
// TODO This function is pretty bad corruption wise, it's very easy
// to corrupt the wallet if you ctrl+c while in this function. This
// needs desperate refactoring.
tx := dcrutil.NewTx(&rec.MsgTx)
// Handle incoming SStx; store them in the stake manager if we own
// the OP_SSTX tagged out.
if is, _ := stake.IsSStx(tx); is {
// Errors don't matter here. If addrs is nil, the range below
// does nothing.
txOut := tx.MsgTx().TxOut[0]
_, addrs, _, _ := txscript.ExtractPkScriptAddrs(txOut.Version,
txOut.PkScript, w.chainParams)
insert := false
for _, addr := range addrs {
_, err := w.Manager.Address(addr)
if err == nil {
insert = true
break
}
}
if insert {
err := w.StakeMgr.InsertSStx(tx)
if err != nil {
log.Errorf("Failed to insert SStx %v"+
"into the stake store.", tx.Sha())
}
}
}
// Handle incoming SSGen; store them if we own
// the ticket used to purchase them.
if is, _ := stake.IsSSGen(tx); is {
if block != nil {
txInHash := tx.MsgTx().TxIn[1].PreviousOutPoint.Hash
if w.StakeMgr.CheckHashInStore(&txInHash) {
w.StakeMgr.InsertSSGen(&block.Hash,
int64(block.Height),
tx.Sha(),
w.VoteBits,
&txInHash)
}
} else {
// If there's no associated block, it's potentially a
// doublespent SSGen. Just ignore it and wait for it
// to later get into a block.
return nil
}
}
// Handle incoming SSRtx; store them if we own
// the ticket used to purchase them.
if is, _ := stake.IsSSRtx(tx); is {
if block != nil {
txInHash := tx.MsgTx().TxIn[0].PreviousOutPoint.Hash
if w.StakeMgr.CheckHashInStore(&txInHash) {
//.........这里部分代码省略.........
开发者ID:frankbraun,项目名称:dcrwallet,代码行数:101,代码来源:chainntfns.go
示例19: testAddrIndexOperations
// testAddrIndexOperations ensures that all normal operations concerning
// the optional address index function correctly.
func testAddrIndexOperations(t *testing.T, db database.Db, newestBlock *dcrutil.Block, newestSha *chainhash.Hash, newestBlockIdx int64) {
// Metadata about the current addr index state should be unset.
sha, height, err := db.FetchAddrIndexTip()
if err != database.ErrAddrIndexDoesNotExist {
t.Fatalf("Address index metadata shouldn't be in db, hasn't been built up yet.")
}
var zeroHash chainhash.Hash
if !sha.IsEqual(&zeroHash) {
t.Fatalf("AddrIndexTip wrong hash got: %s, want %s", sha, &zeroHash)
}
if height != -1 {
t.Fatalf("Addrindex not built up, yet a block index tip has been set to: %d.", height)
}
// Test enforcement of constraints for "limit" and "skip"
var fakeAddr dcrutil.Address
_, err = db.FetchTxsForAddr(fakeAddr, -1, 0)
if err == nil {
t.Fatalf("Negative value for skip passed, should return an error")
}
_, err = db.FetchTxsForAddr(fakeAddr, 0, -1)
if err == nil {
t.Fatalf("Negative value for limit passed, should return an error")
}
// Simple test to index outputs(s) of the first tx.
testIndex := make(database.BlockAddrIndex, database.AddrIndexKeySize)
testTx, err := newestBlock.Tx(0)
if err != nil {
t.Fatalf("Block has no transactions, unable to test addr "+
"indexing, err %v", err)
}
// Extract the dest addr from the tx.
_, testAddrs, _, err := txscript.ExtractPkScriptAddrs(testTx.MsgTx().TxOut[0].Version, testTx.MsgTx().TxOut[0].PkScript, &chaincfg.MainNetParams)
if err != nil {
t.Fatalf("Unable to decode tx output, err %v", err)
}
// Extract the hash160 from the output script.
var hash160Bytes [ripemd160.Size]byte
testHash160 := testAddrs[0].(*dcrutil.AddressScriptHash).Hash160()
copy(hash160Bytes[:], testHash160[:])
// Create a fake index.
blktxLoc, _, _ := newestBlock.TxLoc()
testIndex = []*database.TxAddrIndex{
&database.TxAddrIndex{
Hash160: hash160Bytes,
Height: uint32(newestBlockIdx),
TxOffset: uint32(blktxLoc[0].TxStart),
TxLen: uint32(blktxLoc[0].TxLen),
},
}
// Insert our test addr index into the DB.
err = db.UpdateAddrIndexForBlock(newestSha, newestBlockIdx, testIndex)
if err != nil {
t.Fatalf("UpdateAddrIndexForBlock: failed to index"+
" addrs for block #%d (%s) "+
"err %v", newestBlockIdx, newestSha, err)
}
// Chain Tip of address should've been updated.
assertAddrIndexTipIsUpdated(db, t, newestSha, newestBlockIdx)
// Check index retrieval.
txReplies, err := db.FetchTxsForAddr(testAddrs[0], 0, 1000)
if err != nil {
t.Fatalf("FetchTxsForAddr failed to correctly fetch txs for an "+
"address, err %v", err)
}
// Should have one reply.
if len(txReplies) != 1 {
t.Fatalf("Failed to properly index tx by address.")
}
// Our test tx and indexed tx should have the same sha.
indexedTx := txReplies[0]
if !bytes.Equal(indexedTx.Sha.Bytes(), testTx.Sha().Bytes()) {
t.Fatalf("Failed to fetch proper indexed tx. Expected sha %v, "+
"fetched %v", testTx.Sha(), indexedTx.Sha)
}
// Shut down DB.
db.Sync()
db.Close()
// Re-Open, tip still should be updated to current height and sha.
db, err = database.OpenDB("leveldb", "tstdbopmode")
if err != nil {
t.Fatalf("Unable to re-open created db, err %v", err)
}
assertAddrIndexTipIsUpdated(db, t, newestSha, newestBlockIdx)
//.........这里部分代码省略.........
开发者ID:zebbra2014,项目名称:dcrd,代码行数:101,代码来源:operational_test.go
示例20: convertToAddrIndex
// convertToAddrIndex indexes all data pushes greater than 8 bytes within the
// passed SPK and returns a TxAddrIndex with the given data. Our "address"
// index is actually a hash160 index, where in the ideal case the data push
// is either the hash160 of a publicKey (P2PKH) or a Script (P2SH).
func convertToAddrIndex(scrVersion uint16, scr []byte, height int64,
locInBlock *wire.TxLoc) ([]*database.TxAddrIndex, error) {
var tais []*database.TxAddrIndex
if scr == nil || locInBlock == nil {
return nil, fmt.Errorf("passed nil pointer")
}
var indexKey [ripemd160.Size]byte
// Get the script classes and extract the PKH if applicable.
// If it's multisig, unknown, etc, just hash the script itself.
class, addrs, _, err := txscript.ExtractPkScriptAddrs(scrVersion, scr,
activeNetParams.Params)
if err != nil {
return nil, fmt.Errorf("script conversion error: %v", err.Error())
}
knownType := false
for _, addr := range addrs {
switch {
case class == txscript.PubKeyTy:
copy(indexKey[:], addr.Hash160()[:])
case class == txscript.PubkeyAltTy:
copy(indexKey[:], addr.Hash160()[:])
case class == txscript.PubKeyHashTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.PubkeyHashAltTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.StakeSubmissionTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.StakeGenTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.StakeRevocationTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.StakeSubChangeTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.MultiSigTy:
copy(indexKey[:], addr.ScriptAddress()[:])
case class == txscript.ScriptHashTy:
copy(indexKey[:], addr.ScriptAddress()[:])
}
tai := &database.TxAddrIndex{
indexKey,
uint32(height),
uint32(locInBlock.TxStart),
uint32(locInBlock.TxLen),
}
tais = append(tais, tai)
knownType = true
}
if !knownType {
copy(indexKey[:], dcrutil.Hash160(scr))
tai := &database.TxAddrIndex{
indexKey,
uint32(height),
uint32(locInBlock.TxStart),
uint32(locInBlock.TxLen),
}
tais = append(tais, tai)
}
return tai
|
请发表评论