本文整理汇总了Golang中github.com/btcsuite/btcd/wire.MsgTx.TxSha方法的典型用法代码示例。如果您正苦于以下问题:Golang MsgTx.TxSha方法的具体用法?Golang MsgTx.TxSha怎么用?Golang MsgTx.TxSha使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/btcsuite/btcd/wire.MsgTx
的用法示例。
在下文中一共展示了MsgTx.TxSha方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: CheckDoubleSpends
// GetDoubleSpends takes a transaction and compares it with
// all transactions in the db. It returns a slice of all txids in the db
// which are double spent by the received tx.
func CheckDoubleSpends(
argTx *wire.MsgTx, txs []*wire.MsgTx) ([]*wire.ShaHash, error) {
var dubs []*wire.ShaHash // slice of all double-spent txs
argTxid := argTx.TxSha()
for _, compTx := range txs {
compTxid := compTx.TxSha()
// check if entire tx is dup
if argTxid.IsEqual(&compTxid) {
return nil, fmt.Errorf("tx %s is dup", argTxid.String())
}
// not dup, iterate through inputs of argTx
for _, argIn := range argTx.TxIn {
// iterate through inputs of compTx
for _, compIn := range compTx.TxIn {
if OutPointsEqual(
argIn.PreviousOutPoint, compIn.PreviousOutPoint) {
// found double spend
dubs = append(dubs, &compTxid)
break // back to argIn loop
}
}
}
}
return dubs, nil
}
示例2: AbsorbTx
// AbsorbTx absorbs money into wallet from a tx
func (t *TxStore) AbsorbTx(tx *wire.MsgTx) error {
if tx == nil {
return fmt.Errorf("Tried to add nil tx")
}
var hits uint32
var acq int64
// check if any of the tx's outputs match my adrs
for i, out := range tx.TxOut { // in each output of tx
for _, a := range t.Adrs { // compare to each adr we have
// more correct would be to check for full script
// contains could have false positive? (p2sh/p2pkh same hash ..?)
if bytes.Contains(out.PkScript, a.ScriptAddress()) { // hit
hits++
acq += out.Value
var newu Utxo
newu.KeyIdx = a.KeyIdx
newu.Txo = *out
var newop wire.OutPoint
newop.Hash = tx.TxSha()
newop.Index = uint32(i)
newu.Op = newop
t.Utxos = append(t.Utxos, newu)
break
}
}
}
log.Printf("%d hits, acquired %d", hits, acq)
t.Sum += acq
return nil
}
示例3: TxToString
// TxToString prints out some info about a transaction. for testing / debugging
func TxToString(tx *wire.MsgTx) string {
str := fmt.Sprintf("\t - Tx %s\n", tx.TxSha().String())
for i, in := range tx.TxIn {
str += fmt.Sprintf("Input %d: %s\n", i, in.PreviousOutPoint.String())
str += fmt.Sprintf("SigScript for input %d: %x\n", i, in.SignatureScript)
}
for i, out := range tx.TxOut {
if out != nil {
str += fmt.Sprintf("\toutput %d script: %x amt: %d\n",
i, out.PkScript, out.Value)
} else {
str += fmt.Sprintf("output %d nil (WARNING)\n", i)
}
}
return str
}
示例4: NewDetailsRecord
func NewDetailsRecord(msg *wire.MsgTx) *DetailsRecord {
record := &DetailsRecord{
hash: msg.TxSha(),
ins: make([]*InputRecord, len(msg.TxIn)),
outs: make([]*OutputRecord, len(msg.TxOut)),
}
for i, txin := range msg.TxIn {
record.ins[i] = NewInputRecord(txin)
}
for i, txout := range msg.TxOut {
record.outs[i] = NewOutputRecord(txout)
}
return record
}
示例5: NewOutgoingTx
func (s *SPVCon) NewOutgoingTx(tx *wire.MsgTx) error {
txid := tx.TxSha()
// assign height of zero for txs we create
err := s.TS.AddTxid(&txid, 0)
if err != nil {
return err
}
_, err = s.TS.Ingest(tx, 0) // our own tx; don't keep track of false positives
if err != nil {
return err
}
// make an inv message instead of a tx message to be polite
iv1 := wire.NewInvVect(wire.InvTypeTx, &txid)
invMsg := wire.NewMsgInv()
err = invMsg.AddInvVect(iv1)
if err != nil {
return err
}
s.outMsgQueue <- invMsg
return nil
}
示例6: IngestTx
// IngestTx ingests a tx into wallet, dealing with both gains and losses
func (t *TxStore) IngestTx(tx *wire.MsgTx) error {
var match bool
inTxid := tx.TxSha()
for _, ktxid := range t.KnownTxids {
if inTxid.IsEqual(ktxid) {
match = true
break // found tx match,
}
}
if !match {
return fmt.Errorf("we don't care about tx %s", inTxid.String())
}
err := t.AbsorbTx(tx)
if err != nil {
return err
}
err = t.ExpellTx(tx)
if err != nil {
return err
}
// fmt.Printf("ingested tx %s total amt %d\n", inTxid.String(), t.Sum)
return nil
}
示例7: TxHandler
// TxHandler takes in transaction messages that come in from either a request
// after an inv message or after a merkle block message.
func (s *SPVCon) TxHandler(m *wire.MsgTx) {
s.TS.OKMutex.Lock()
height, ok := s.TS.OKTxids[m.TxSha()]
s.TS.OKMutex.Unlock()
if !ok {
log.Printf("Tx %s unknown, will not ingest\n")
return
}
// check for double spends
allTxs, err := s.TS.GetAllTxs()
if err != nil {
log.Printf("Can't get txs from db: %s", err.Error())
return
}
dubs, err := CheckDoubleSpends(m, allTxs)
if err != nil {
log.Printf("CheckDoubleSpends error: %s", err.Error())
return
}
if len(dubs) > 0 {
for i, dub := range dubs {
fmt.Printf("dub %d known tx %s and new tx %s are exclusive!!!\n",
i, dub.String(), m.TxSha().String())
}
}
hits, err := s.TS.Ingest(m, height)
if err != nil {
log.Printf("Incoming Tx error: %s\n", err.Error())
return
}
if hits == 0 && !s.HardMode {
log.Printf("tx %s had no hits, filter false positive.",
m.TxSha().String())
s.fPositives <- 1 // add one false positive to chan
return
}
log.Printf("tx %s ingested and matches %d utxo/adrs.",
m.TxSha().String(), hits)
}
示例8: loadTxStore
// loadTxStore returns a transaction store loaded from a file.
func loadTxStore(filename string) (blockchain.TxStore, error) {
// The txstore file format is:
// <num tx data entries> <tx length> <serialized tx> <blk height>
// <num spent bits> <spent bits>
//
// All num and length fields are little-endian uint32s. The spent bits
// field is padded to a byte boundary.
filename = filepath.Join("testdata/", filename)
fi, err := os.Open(filename)
if err != nil {
return nil, err
}
// Choose read based on whether the file is compressed or not.
var r io.Reader
if strings.HasSuffix(filename, ".bz2") {
r = bzip2.NewReader(fi)
} else {
r = fi
}
defer fi.Close()
// Num of transaction store objects.
var numItems uint32
if err := binary.Read(r, binary.LittleEndian, &numItems); err != nil {
return nil, err
}
txStore := make(blockchain.TxStore)
var uintBuf uint32
for height := uint32(0); height < numItems; height++ {
txD := blockchain.TxData{}
// Serialized transaction length.
err = binary.Read(r, binary.LittleEndian, &uintBuf)
if err != nil {
return nil, err
}
serializedTxLen := uintBuf
if serializedTxLen > wire.MaxBlockPayload {
return nil, fmt.Errorf("Read serialized transaction "+
"length of %d is larger max allowed %d",
serializedTxLen, wire.MaxBlockPayload)
}
// Transaction.
var msgTx wire.MsgTx
err = msgTx.Deserialize(r)
if err != nil {
return nil, err
}
txD.Tx = btcutil.NewTx(&msgTx)
// Transaction hash.
txHash, err := msgTx.TxSha()
if err != nil {
return nil, err
}
txD.Hash = &txHash
// Block height the transaction came from.
err = binary.Read(r, binary.LittleEndian, &uintBuf)
if err != nil {
return nil, err
}
txD.BlockHeight = int64(uintBuf)
// Num spent bits.
err = binary.Read(r, binary.LittleEndian, &uintBuf)
if err != nil {
return nil, err
}
numSpentBits := uintBuf
numSpentBytes := numSpentBits / 8
if numSpentBits%8 != 0 {
numSpentBytes++
}
// Packed spent bytes.
spentBytes := make([]byte, numSpentBytes)
_, err = io.ReadFull(r, spentBytes)
if err != nil {
return nil, err
}
// Populate spent data based on spent bits.
txD.Spent = make([]bool, numSpentBits)
for byteNum, spentByte := range spentBytes {
for bit := 0; bit < 8; bit++ {
if uint32((byteNum*8)+bit) < numSpentBits {
if spentByte&(1<<uint(bit)) != 0 {
txD.Spent[(byteNum*8)+bit] = true
}
}
}
}
txStore[*txD.Hash] = &txD
//.........这里部分代码省略.........
示例9: TestSort
// TestSort ensures the transaction sorting works according to the BIP.
func TestSort(t *testing.T) {
tests := []struct {
name string
hexFile string
isSorted bool
unsortedHash string
sortedHash string
}{
{
name: "first test case from BIPLI01 - sorts inputs only, based on hash",
hexFile: "li01-1.hex",
isSorted: false,
unsortedHash: "0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3",
sortedHash: "839503cb611a3e3734bd521c608f881be2293ff77b7384057ab994c794fce623",
},
{
name: "second test case from BIPLI01 - already sorted",
hexFile: "li01-2.hex",
isSorted: true,
unsortedHash: "28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f",
sortedHash: "28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f",
},
{
name: "block 100001 tx[1] - sorts outputs only, based on amount",
hexFile: "li01-3.hex",
isSorted: false,
unsortedHash: "fbde5d03b027d2b9ba4cf5d4fecab9a99864df2637b25ea4cbcb1796ff6550ca",
sortedHash: "0a8c246c55f6b82f094d211f4f57167bf2ea4898741d218b09bdb2536fd8d13f",
},
{
name: "block 100001 tx[2] - sorts both inputs and outputs",
hexFile: "li01-4.hex",
isSorted: false,
unsortedHash: "8131ffb0a2c945ecaf9b9063e59558784f9c3a74741ce6ae2a18d0571dac15bb",
sortedHash: "a3196553b928b0b6154b002fa9a1ce875adabc486fedaaaf4c17430fd4486329",
},
{
name: "block 100998 tx[6] - sorts outputs only, based on output script",
hexFile: "li01-5.hex",
isSorted: false,
unsortedHash: "ff85e8fc92e71bbc217e3ea9a3bacb86b435e52b6df0b089d67302c293a2b81d",
sortedHash: "9a6c24746de024f77cac9b2138694f11101d1c66289261224ca52a25155a7c94",
},
}
for _, test := range tests {
// Load and deserialize the test transaction.
filePath := filepath.Join("testdata", test.hexFile)
txHexBytes, err := ioutil.ReadFile(filePath)
if err != nil {
t.Errorf("ReadFile (%s): failed to read test file: %v",
test.name, err)
continue
}
txBytes, err := hex.DecodeString(string(txHexBytes))
if err != nil {
t.Errorf("DecodeString (%s): failed to decode tx: %v",
test.name, err)
continue
}
var tx wire.MsgTx
err = tx.Deserialize(bytes.NewReader(txBytes))
if err != nil {
t.Errorf("Deserialize (%s): unexpected error %v",
test.name, err)
continue
}
// Ensure the sort order of the original transaction matches the
// expected value.
if got := txsort.IsSorted(&tx); got != test.isSorted {
t.Errorf("IsSorted (%s): sort does not match "+
"expected - got %v, want %v", test.name, got,
test.isSorted)
continue
}
// Sort the transaction and ensure the resulting hash is the
// expected value.
sortedTx := txsort.Sort(&tx)
if got := sortedTx.TxSha().String(); got != test.sortedHash {
t.Errorf("Sort (%s): sorted hash does not match "+
"expected - got %v, want %v", test.name, got,
test.sortedHash)
continue
}
// Ensure the original transaction is not modified.
if got := tx.TxSha().String(); got != test.unsortedHash {
t.Errorf("Sort (%s): unsorted hash does not match "+
"expected - got %v, want %v", test.name, got,
test.unsortedHash)
continue
}
// Now sort the transaction using the mutable version and ensure
// the resulting hash is the expected value.
txsort.InPlaceSort(&tx)
if got := tx.TxSha().String(); got != test.sortedHash {
//.........这里部分代码省略.........
示例10: Ingest
// Ingest puts a tx into the DB atomically. This can result in a
// gain, a loss, or no result. Gain or loss in satoshis is returned.
func (ts *TxStore) Ingest(tx *wire.MsgTx, height int32) (uint32, error) {
var hits uint32
var err error
var spentOPs [][]byte
var nUtxoBytes [][]byte
// tx has been OK'd by SPV; check tx sanity
utilTx := btcutil.NewTx(tx) // convert for validation
// checks basic stuff like there are inputs and ouputs
err = blockchain.CheckTransactionSanity(utilTx)
if err != nil {
return hits, err
}
// note that you can't check signatures; this is SPV.
// 0 conf SPV means pretty much nothing. Anyone can say anything.
// before entering into db, serialize all inputs of the ingested tx
for _, txin := range tx.TxIn {
nOP, err := outPointToBytes(&txin.PreviousOutPoint)
if err != nil {
return hits, err
}
spentOPs = append(spentOPs, nOP)
}
// also generate PKscripts for all addresses (maybe keep storing these?)
for _, adr := range ts.Adrs {
// iterate through all our addresses
aPKscript, err := txscript.PayToAddrScript(adr.PkhAdr)
if err != nil {
return hits, err
}
// iterate through all outputs of this tx
for i, out := range tx.TxOut {
if bytes.Equal(out.PkScript, aPKscript) { // new utxo for us
var newu Utxo
newu.AtHeight = height
newu.KeyIdx = adr.KeyIdx
newu.Value = out.Value
var newop wire.OutPoint
newop.Hash = tx.TxSha()
newop.Index = uint32(i)
newu.Op = newop
b, err := newu.ToBytes()
if err != nil {
return hits, err
}
nUtxoBytes = append(nUtxoBytes, b)
hits++
break // only one match
}
}
}
err = ts.StateDB.Update(func(btx *bolt.Tx) error {
// get all 4 buckets
duf := btx.Bucket(BKTUtxos)
// sta := btx.Bucket(BKTState)
old := btx.Bucket(BKTStxos)
txns := btx.Bucket(BKTTxns)
if duf == nil || old == nil || txns == nil {
return fmt.Errorf("error: db not initialized")
}
// first see if we lose utxos
// iterate through duffel bag and look for matches
// this makes us lose money, which is regrettable, but we need to know.
for _, nOP := range spentOPs {
duf.ForEach(func(k, v []byte) error {
if bytes.Equal(k, nOP) { // matched, we lost utxo
// do all this just to figure out value we lost
x := make([]byte, len(k)+len(v))
copy(x, k)
copy(x[len(k):], v)
lostTxo, err := UtxoFromBytes(x)
if err != nil {
return err
}
hits++
// then delete the utxo from duf, save to old
err = duf.Delete(k)
if err != nil {
return err
}
// after deletion, save stxo to old bucket
var st Stxo // generate spent txo
st.Utxo = lostTxo // assign outpoint
st.SpendHeight = height // spent at height
st.SpendTxid = tx.TxSha() // spent by txid
stxb, err := st.ToBytes() // serialize
if err != nil {
return err
}
err = old.Put(k, stxb) // write k:v outpoint:stxo bytes
if err != nil {
return err
}
// store this relevant tx
sha := tx.TxSha()
//.........这里部分代码省略.........