func (tx *Transaction) BtcEncode(w io.Writer) error { var version [4]byte binary.LittleEndian.PutUint32(version[:], tx.Version) if _, err := w.Write(version[:]); err != nil { return err } w.Write(varint.Serialize(uint64(len(tx.In)))) for _, txin := range tx.In { txin.BtcEncode(w) } w.Write(varint.Serialize(uint64(len(tx.Out)))) for _, txout := range tx.Out { txout.BtcEncode(w) } var lockTime [4]byte binary.LittleEndian.PutUint32(lockTime[:], tx.LockTime) if _, err := w.Write(lockTime[:]); err != nil { return err } return nil }
func (tx *TxOut) BtcEncode(w io.Writer) error { var value [8]byte binary.LittleEndian.PutUint64(value[:], uint64(tx.Value)) if _, err := w.Write(value[:]); err != nil { return err } if _, err := w.Write(varint.Serialize(uint64(len(tx.PKScript)))); err != nil { return err } if _, err := w.Write(tx.PKScript); err != nil { return err } return nil }
func (tx *TxIn) BtcEncode(w io.Writer) error { tx.PreviousTxOut.BtcEncode(w) if _, err := w.Write(varint.Serialize(uint64(len(tx.ScriptSignature)))); err != nil { return err } if _, err := w.Write(tx.ScriptSignature); err != nil { return err } var seq [4]byte binary.LittleEndian.PutUint32(seq[:], tx.Sequence) if _, err := w.Write(seq[:]); err != nil { return err } 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 } } }