func (tx *Transaction) BtcDecode(r io.Reader) error { var version [4]byte if _, err := r.Read(version[:]); err != nil { return err } tx.Version = binary.LittleEndian.Uint32(version[:]) inCount, err := varint.Deserialize(r) if err != nil { return err } tx.In = make([]*TxIn, inCount) for i := 0; i < int(inCount); i++ { tx.In[i] = &TxIn{} tx.In[i].BtcDecode(r) } outCount, err := varint.Deserialize(r) if err != nil { return err } tx.Out = make([]*TxOut, outCount) for i := 0; i < int(outCount); i++ { tx.Out[i] = &TxOut{} tx.Out[i].BtcDecode(r) } var lockTime [4]byte if _, err := r.Read(lockTime[:]); err != nil { return err } tx.LockTime = binary.LittleEndian.Uint32(lockTime[:]) return nil }
func (tx *TxOut) BtcDecode(r io.Reader) error { var value [8]byte if _, err := r.Read(value[:]); err != nil { return err } tx.Value = int64(binary.LittleEndian.Uint64(value[:])) pkscriptLen, err := varint.Deserialize(r) if err != nil { return err } pkscript := make([]byte, pkscriptLen) if _, err := r.Read(pkscript); err != nil { return err } tx.PKScript = pkscript return nil }
func (tx *TxIn) BtcDecode(r io.Reader) error { tx.PreviousTxOut.BtcDecode(r) scriptLen, err := varint.Deserialize(r) if err != nil { return err } sig := make([]byte, scriptLen) if _, err := r.Read(sig); err != nil { return err } tx.ScriptSignature = sig var seq [4]byte if _, err := r.Read(seq[:]); err != nil { return err } tx.Sequence = binary.LittleEndian.Uint32(seq[:]) return nil }
func TestVarintSerialize(t *testing.T) { tests := []struct { val uint64 // Value to get the serialized size for size int // Expected serialized size }{ // Single byte {0, 1}, // Max single byte {0xfc, 1}, // Min 2-byte {0xfd, 3}, // Max 2-byte {0xffff, 3}, // Min 4-byte {0x10000, 5}, // Max 4-byte {0xffffffff, 5}, // Min 8-byte {0x100000000, 9}, // Max 8-byte {0xffffffffffffffff, 9}, } for i, test := range tests { serialized := varint.Serialize(test.val) if len(serialized) != test.size { t.Errorf("Size #%d got: %d, want: %d", i, len(serialized), test.size) continue } value, err := varint.Deserialize(bytes.NewBuffer(serialized)) if err != nil { t.Fatal(err) } if value != test.val { t.Errorf("Value: Expected %v, got %v", i, test.val, value) continue } } }