BIP0144+wire: implement witness encoding/decoding for transactions

This commit implements the new witness encoding/decoding for
transactions as specified by BIP0144. After segwit activation, a
special transaction encoding is used to signal to upgraded nodes that
the transaction being deserialized bares witness data. The prior
BtcEncode and BtcDecode methods have been extended to be aware of the
new signaling bytes and the encoding of witness data within
transactions.

Additionally, a new method has been added to calculate the “stripped
size” of a transaction/block which is defined as the size of a
transaction/block *excluding* any witness data.
This commit is contained in:
Olaoluwa Osuntokun 2016-10-18 16:32:35 -07:00 committed by Dave Collins
parent 28c5ce8e5c
commit 192bfbf123
4 changed files with 472 additions and 26 deletions

View File

@ -53,7 +53,7 @@ const (
CmdFeeFilter = "feefilter"
)
// WireEncoding represents the wire message encoding format to be used.
// MessageEncoding represents the wire message encoding format to be used.
type MessageEncoding uint32
const (

View File

@ -23,7 +23,8 @@ const defaultTransactionAlloc = 2048
const MaxBlocksPerMsg = 500
// MaxBlockPayload is the maximum bytes a block message can be in bytes.
const MaxBlockPayload = 1000000 // Not actually 1MB which would be 1024 * 1024
// After Segregated Witness, the max block payload has been raised to 4MB.
const MaxBlockPayload = 4000000
// maxTxPerBlock is the maximum number of transactions that could
// possibly fit into a block.
@ -114,7 +115,7 @@ func (msg *MsgBlock) Deserialize(r io.Reader) error {
return msg.BtcDecode(r, 0, WitnessEncoding)
}
// DeserializeWitness decodes a block from r into the receiver similar to
// DeserializeNoWitness decodes a block from r into the receiver similar to
// Deserialize, however DeserializeWitness strips all (if any) witness data
// from the transactions within the block before encoding them.
func (msg *MsgBlock) DeserializeNoWitness(r io.Reader) error {
@ -213,8 +214,8 @@ func (msg *MsgBlock) Serialize(w io.Writer) error {
return msg.BtcEncode(w, 0, WitnessEncoding)
}
// SerializeWitness encodes a block to w using an identical format to Serialize,
// with all (if any) witness data stripped from all transactions.
// SerializeNoWitness encodes a block to w using an identical format to
// Serialize, with all (if any) witness data stripped from all transactions.
// This method is provided in additon to the regular Serialize, in order to
// allow one to selectively encode transaction witness data to non-upgraded
// peers which are unaware of the new encoding.
@ -223,7 +224,7 @@ func (msg *MsgBlock) SerializeNoWitness(w io.Writer) error {
}
// SerializeSize returns the number of bytes it would take to serialize the
// the block.
// block, factoring in any witness data within transaction.
func (msg *MsgBlock) SerializeSize() int {
// Block header bytes + Serialized varint size for the number of
// transactions.
@ -236,6 +237,20 @@ func (msg *MsgBlock) SerializeSize() int {
return n
}
// SerializeSizeStripped returns the number of bytes it would take to serialize
// the block, excluding any witness data (if any).
func (msg *MsgBlock) SerializeSizeStripped() int {
// Block header bytes + Serialized varint size for the number of
// transactions.
n := blockHeaderLen + VarIntSerializeSize(uint64(len(msg.Transactions)))
for _, tx := range msg.Transactions {
n += tx.SerializeSizeStripped()
}
return n
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgBlock) Command() string {

View File

@ -93,8 +93,31 @@ const (
// peers. Thus, the peak usage of the free list is 12,500 * 512 =
// 6,400,000 bytes.
freeListMaxItems = 12500
// maxWitnessItemsPerInput is the maximum number of witness items to
// be read for the witness data for a single TxIn. This number is
// derived using a possble lower bound for the encoding of a witness
// item: 1 byte for length + 1 byte for the witness item itself, or two
// bytes. This value is then divided by the currently allowed maximum
// "cost" for a transaction.
maxWitnessItemsPerInput = 500000
// maxWitnessItemSize is the maximum allowed size for an item within
// an input's witness data. This number is derived from the fact that
// for script validation, each pushed item onto the stack must be less
// than 10k bytes.
maxWitnessItemSize = 11000
)
// witnessMarkerBytes are a pair of bytes specific to the witness encoding. If
// this sequence is encoutered, then it indicates a transaction has iwtness
// data. The first byte is an always 0x00 marker byte, which allows decoders to
// distinguish a serialized transaction with witnesses from a regular (legacy)
// one. The second byte is the Flag field, which at the moment is always 0x01,
// but may be extended in the future to accommodate auxiliary non-committed
// fields.
var witessMarkerBytes = []byte{0x00, 0x01}
// scriptFreeList defines a free list of byte slices (up to the maximum number
// defined by the freeListMaxItems constant) that have a cap according to the
// freeListMaxScriptSize constant. It is used to provide temporary buffers for
@ -187,6 +210,7 @@ func (o OutPoint) String() string {
type TxIn struct {
PreviousOutPoint OutPoint
SignatureScript []byte
Witness TxWitness
Sequence uint32
}
@ -203,14 +227,36 @@ func (t *TxIn) SerializeSize() int {
// NewTxIn returns a new bitcoin transaction input with the provided
// previous outpoint point and signature script with a default sequence of
// MaxTxInSequenceNum.
func NewTxIn(prevOut *OutPoint, signatureScript []byte) *TxIn {
func NewTxIn(prevOut *OutPoint, signatureScript []byte, witness [][]byte) *TxIn {
return &TxIn{
PreviousOutPoint: *prevOut,
SignatureScript: signatureScript,
Witness: witness,
Sequence: MaxTxInSequenceNum,
}
}
// TxWitness defines the witness for a TxIn. A witness is to be interpreted as
// a slice of byte slices, or a stack with one or many elements.
type TxWitness [][]byte
// SerializeSize returns the number of bytes it would take to serialize the the
// transaction input's witness.
func (t TxWitness) SerializeSize() int {
// A varint to signal the number of elements the witness has.
n := VarIntSerializeSize(uint64(len(t)))
// For each element in the witness, we'll need a varint to signal the
// size of the element, then finally the number of bytes the element
// itself comprises.
for _, witItem := range t {
n += VarIntSerializeSize(uint64(len(witItem)))
n += len(witItem)
}
return n
}
// TxOut defines a bitcoin transaction output.
type TxOut struct {
Value int64
@ -263,8 +309,8 @@ func (msg *MsgTx) TxHash() chainhash.Hash {
// Ignore the error returns since the only way the encode could fail
// is being out of memory or due to nil pointers, both of which would
// cause a run-time panic.
buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSize()))
_ = msg.Serialize(buf)
buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSizeStripped()))
_ = msg.SerializeNoWitness(buf)
return chainhash.DoubleHashH(buf.Bytes())
}
@ -297,13 +343,26 @@ func (msg *MsgTx) Copy() *MsgTx {
copy(newScript, oldScript[:oldScriptLen])
}
// Create new txIn with the deep copied data and append it to
// new Tx.
// Create new txIn with the deep copied data.
newTxIn := TxIn{
PreviousOutPoint: newOutPoint,
SignatureScript: newScript,
Sequence: oldTxIn.Sequence,
}
// If the transaction is witnessy, then also copy the
// witnesses.
if len(oldTxIn.Witness) != 0 {
// Deep copy the old witness data.
newTxIn.Witness = make([][]byte, len(oldTxIn.Witness))
for i, oldItem := range oldTxIn.Witness {
newItem := make([]byte, len(oldItem))
copy(newItem, oldItem)
newTxIn.Witness[i] = newItem
}
}
// Finally, append this fully copied txin.
newTx.TxIn = append(newTx.TxIn, &newTxIn)
}
@ -346,6 +405,30 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error
return err
}
// A count of zero (meaning no TxIn's to the uninitiated) indicates
// this is a transaction with witness data.
var flag [1]byte
if count == 0 && enc == WitnessEncoding {
// Next, we need to read the flag, which is a single byte.
if _, err = io.ReadFull(r, flag[:]); err != nil {
return err
}
// At the moment, the flag MUST be 0x01. In the future other
// flag types may be supported.
if flag[0] != 0x01 {
str := fmt.Sprintf("witness tx but flag byte is %x", flag)
return messageError("MsgTx.BtcDecode", str)
}
// With the Segregated Witness specific fields decoded, we can
// now read in the actual txin count.
count, err = ReadVarInt(r, pver)
if err != nil {
return err
}
}
// Prevent more input transactions than could possibly fit into a
// message. It would be possible to cause memory exhaustion and panics
// without a sane upper bound on this count.
@ -363,10 +446,19 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error
// returns them.
returnScriptBuffers := func() {
for _, txIn := range msg.TxIn {
if txIn == nil || txIn.SignatureScript == nil {
if txIn == nil {
continue
}
scriptPool.Return(txIn.SignatureScript)
if txIn.SignatureScript != nil {
scriptPool.Return(txIn.SignatureScript)
}
for _, witnessElem := range txIn.Witness {
if witnessElem != nil {
scriptPool.Return(witnessElem)
}
}
}
for _, txOut := range msg.TxOut {
if txOut == nil || txOut.PkScript == nil {
@ -426,6 +518,45 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error
totalScriptSize += uint64(len(to.PkScript))
}
// If the transaction's flag byte isn't 0x00 at this point, then one or
// more of its inputs has accompanying witness data.
if flag[0] != 0 && enc == WitnessEncoding {
for _, txin := range msg.TxIn {
// For each input, the witness is encoded as a stack
// with one or more items. Therefore, we first read a
// varint which encodes the number of stack items.
witCount, err := ReadVarInt(r, pver)
if err != nil {
returnScriptBuffers()
return err
}
// Prevent a possible memory exhaustion attack by
// limiting the witCount value to a sane upper bound.
if witCount > maxWitnessItemsPerInput {
returnScriptBuffers()
str := fmt.Sprintf("too many witness items to fit "+
"into max message size [count %d, max %d]",
witCount, maxWitnessItemsPerInput)
return messageError("MsgTx.BtcDecode", str)
}
// Then for witCount number of stack items, each item
// has a varint length prefix, followed by the witness
// item itself.
txin.Witness = make([][]byte, witCount)
for j := uint64(0); j < witCount; j++ {
txin.Witness[j], err = readScript(r, pver,
maxWitnessItemSize, "script witness item")
if err != nil {
returnScriptBuffers()
return err
}
totalScriptSize += uint64(len(txin.Witness[j]))
}
}
}
msg.LockTime, err = binarySerializer.Uint32(r, littleEndian)
if err != nil {
returnScriptBuffers()
@ -463,6 +594,25 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error
// Return the temporary script buffer to the pool.
scriptPool.Return(signatureScript)
for j := 0; j < len(msg.TxIn[i].Witness); j++ {
// Copy each item within the witness stack for this
// input into the contiguous buffer at the appropriate
// offset.
witnessElem := msg.TxIn[i].Witness[j]
copy(scripts[offset:], witnessElem)
// Reset the witness item within the stack to the slice
// of the contiguous buffer where the witness lives.
witnessElemSize := uint64(len(witnessElem))
end := offset + witnessElemSize
msg.TxIn[i].Witness[j] = scripts[offset:end:end]
offset += witnessElemSize
// Return the temporary buffer used for the witness stack
// item to the pool.
scriptPool.Return(witnessElem)
}
}
for i := 0; i < len(msg.TxOut); i++ {
// Copy the public key script into the contiguous buffer at the
@ -519,6 +669,24 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error
return err
}
// If the encoding version is set to WitnessEncoding, and the Flags
// field for the MsgTx aren't 0x00, then this indicates the transaction
// is to be encoded using the new witness inclusionary structure
// defined in BIP0144.
doWitness := enc == WitnessEncoding && msg.HasWitness()
if doWitness {
// After the txn's Version field, we include two additional
// bytes specific to the witness encoding. The first byte is an
// always 0x00 marker byte, which allows decoders to
// distinguish a serialized transaction with witnesses from a
// regular (legacy) one. The second byte is the Flag field,
// which at the moment is always 0x01, but may be extended in
// the future to accommodate auxiliary non-committed fields.
if _, err := w.Write(witessMarkerBytes); err != nil {
return err
}
}
count := uint64(len(msg.TxIn))
err = WriteVarInt(w, pver, count)
if err != nil {
@ -545,9 +713,33 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error
}
}
// If this transaction is a witness transaction, and the witness
// encoded is desired, then encode the witness for each of the inputs
// within the transaction.
if doWitness {
for _, ti := range msg.TxIn {
err = writeTxWitness(w, pver, msg.Version, ti.Witness)
if err != nil {
return err
}
}
}
return binarySerializer.PutUint32(w, littleEndian, msg.LockTime)
}
// HasWitness returns false if none of the inputs within the transaction
// contain witness data, true false otherwise.
func (msg *MsgTx) HasWitness() bool {
for _, txIn := range msg.TxIn {
if len(txIn.Witness) != 0 {
return true
}
}
return false
}
// Serialize encodes the transaction to w using a format that suitable for
// long-term storage such as a database while respecting the Version field in
// the transaction. This function differs from BtcEncode in that BtcEncode
@ -570,16 +762,16 @@ func (msg *MsgTx) Serialize(w io.Writer) error {
return msg.BtcEncode(w, 0, WitnessEncoding)
}
// SerializeWitness encodes the transaction to w in an identical manner to
// SerializeNoWitness encodes the transaction to w in an identical manner to
// Serialize, however even if the source transaction has inputs with witness
// data, the old serialization format will still be used.
func (msg *MsgTx) SerializeNoWitness(w io.Writer) error {
return msg.BtcEncode(w, 0, BaseEncoding)
}
// SerializeSize returns the number of bytes it would take to serialize the
// the transaction.
func (msg *MsgTx) SerializeSize() int {
// baseSize returns the serialized size of the transaction without accounting
// for any witness data.
func (msg *MsgTx) baseSize() int {
// Version 4 bytes + LockTime 4 bytes + Serialized varint size for the
// number of transaction inputs and outputs.
n := 8 + VarIntSerializeSize(uint64(len(msg.TxIn))) +
@ -596,6 +788,31 @@ func (msg *MsgTx) SerializeSize() int {
return n
}
// SerializeSize returns the number of bytes it would take to serialize the
// the transaction.
func (msg *MsgTx) SerializeSize() int {
n := msg.baseSize()
if msg.HasWitness() {
// The marker, and flag fields take up two additional bytes.
n += 2
// Additionally, factor in the serialized size of each of the
// witnesses for each txin.
for _, txin := range msg.TxIn {
n += txin.Witness.SerializeSize()
}
}
return n
}
// SerializeSizeStripped returns the number of bytes it would take to serialize
// the transaction, excluding any included witness data.
func (msg *MsgTx) SerializeSizeStripped() int {
return msg.baseSize()
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgTx) Command() string {
@ -626,6 +843,13 @@ func (msg *MsgTx) PkScriptLocs() []int {
// input.
n := 4 + VarIntSerializeSize(uint64(len(msg.TxIn))) +
VarIntSerializeSize(uint64(numTxOut))
// If this transaction has a witness input, the an additional two bytes
// for the marker, and flag byte need to be taken into account.
if len(msg.TxIn) > 0 && msg.TxIn[0].Witness != nil {
n += 2
}
for _, txIn := range msg.TxIn {
n += txIn.SerializeSize()
}
@ -767,3 +991,19 @@ func writeTxOut(w io.Writer, pver uint32, version int32, to *TxOut) error {
return WriteVarBytes(w, pver, to.PkScript)
}
// writeTxWitness encodes the bitcoin protocol encoding for a transaction
// input's witness into to w.
func writeTxWitness(w io.Writer, pver uint32, version int32, wit [][]byte) error {
err := WriteVarInt(w, pver, uint64(len(wit)))
if err != nil {
return err
}
for _, item := range wit {
err = WriteVarBytes(w, pver, item)
if err != nil {
return err
}
}
return nil
}

View File

@ -35,8 +35,7 @@ func TestTx(t *testing.T) {
}
// Ensure max payload is expected value for latest protocol version.
// Num addresses (varInt) + max allowed addresses.
wantPayload := uint32(1000 * 1000)
wantPayload := uint32(1000 * 4000)
maxPayload := msg.MaxPayloadLength(pver)
if maxPayload != wantPayload {
t.Errorf("MaxPayloadLength: wrong max payload length for "+
@ -65,7 +64,11 @@ func TestTx(t *testing.T) {
// Ensure we get the same transaction input back out.
sigScript := []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62}
txIn := NewTxIn(prevOut, sigScript)
witnessData := [][]byte{
{0x04, 0x31},
{0x01, 0x43},
}
txIn := NewTxIn(prevOut, sigScript, witnessData)
if !reflect.DeepEqual(&txIn.PreviousOutPoint, prevOut) {
t.Errorf("NewTxIn: wrong prev outpoint - got %v, want %v",
spew.Sprint(&txIn.PreviousOutPoint),
@ -76,6 +79,11 @@ func TestTx(t *testing.T) {
spew.Sdump(txIn.SignatureScript),
spew.Sdump(sigScript))
}
if !reflect.DeepEqual(txIn.Witness, TxWitness(witnessData)) {
t.Errorf("NewTxIn: wrong witness data - got %v, want %v",
spew.Sdump(txIn.Witness),
spew.Sdump(witnessData))
}
// Ensure we get the same transaction output back out.
txValue := int64(5000000000)
@ -203,7 +211,7 @@ func TestWTxSha(t *testing.T) {
Index: 19,
},
Witness: [][]byte{
[]byte{ // 70-byte signature
{ // 70-byte signature
0x30, 0x43, 0x02, 0x1f, 0x4d, 0x23, 0x81, 0xdc,
0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51,
0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd,
@ -214,7 +222,7 @@ func TestWTxSha(t *testing.T) {
0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7,
0x56, 0x9a, 0x18, 0x19, 0x70, 0x01,
},
[]byte{ // 33-byte serialize pub key
{ // 33-byte serialize pub key
0x03, 0x07, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7,
0x63, 0x46, 0xdf, 0x69, 0x77, 0x00, 0x0c, 0x89,
0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61,
@ -493,6 +501,14 @@ func TestTxSerialize(t *testing.T) {
multiTxPkScriptLocs,
false,
},
// Multiple outputs witness transaction.
{
multiWitnessTx,
multiWitnessTx,
multiWitnessTxEncoded,
multiWitnessTxPkScriptLocs,
true,
},
}
t.Logf("Running %d tests", len(tests))
@ -513,7 +529,11 @@ func TestTxSerialize(t *testing.T) {
// Deserialize the transaction.
var tx MsgTx
rbuf := bytes.NewReader(test.buf)
err = tx.Deserialize(rbuf)
if test.witness {
err = tx.Deserialize(rbuf)
} else {
err = tx.DeserializeNoWitness(rbuf)
}
if err != nil {
t.Errorf("Deserialize #%d error %v", i, err)
continue
@ -701,9 +721,9 @@ func TestTxOverflowErrors(t *testing.T) {
}
}
// TestTxSerializeSize performs tests to ensure the serialize size for various
// transactions is accurate.
func TestTxSerializeSize(t *testing.T) {
// TestTxSerializeSizeStripped performs tests to ensure the serialize size for
// various transactions is accurate.
func TestTxSerializeSizeStripped(t *testing.T) {
// Empty tx message.
noTx := NewMsgTx(1)
noTx.Version = 1
@ -717,6 +737,34 @@ func TestTxSerializeSize(t *testing.T) {
// Transcaction with an input and an output.
{multiTx, 210},
// Transaction with an input which includes witness data, and
// one output. Note that this uses SerializeSizeStripped which
// excludes the additional bytes due to witness data encoding.
{multiWitnessTx, 82},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
serializedSize := test.in.SerializeSizeStripped()
if serializedSize != test.size {
t.Errorf("MsgTx.SerializeSizeStripped: #%d got: %d, want: %d", i,
serializedSize, test.size)
continue
}
}
}
// TestTxWitnessSize performs tests to ensure that the serialized size for
// various types of transactions that include witness data is accurate.
func TestTxWitnessSize(t *testing.T) {
tests := []struct {
in *MsgTx // Tx to encode
size int // Expected serialized size w/ witnesses
}{
// Transaction with an input which includes witness data, and
// one output.
{multiWitnessTx, 190},
}
t.Logf("Running %d tests", len(tests))
@ -828,3 +876,146 @@ var multiTxEncoded = []byte{
// multiTxPkScriptLocs is the location information for the public key scripts
// located in multiTx.
var multiTxPkScriptLocs = []int{63, 139}
// multiWitnessTx is a MsgTx with an input with witness data, and an
// output used in various tests.
var multiWitnessTx = &MsgTx{
Version: 1,
TxIn: []*TxIn{
{
PreviousOutPoint: OutPoint{
Hash: chainhash.Hash{
0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0,
0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2,
0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8,
0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd,
},
Index: 19,
},
SignatureScript: []byte{},
Witness: [][]byte{
{ // 70-byte signature
0x30, 0x43, 0x02, 0x1f, 0x4d, 0x23, 0x81, 0xdc,
0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51,
0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd,
0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36,
0x58, 0xda, 0x19, 0x02, 0x20, 0x60, 0x8b, 0x5c,
0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e,
0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b,
0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7,
0x56, 0x9a, 0x18, 0x19, 0x70, 0x01,
},
{ // 33-byte serialize pub key
0x03, 0x07, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7,
0x63, 0x46, 0xdf, 0x69, 0x77, 0x00, 0x0c, 0x89,
0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61,
0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x06, 0x6a,
0x8f,
},
},
Sequence: 0xffffffff,
},
},
TxOut: []*TxOut{
{
Value: 395019,
PkScript: []byte{ // p2wkh output
0x00, // Version 0 witness program
0x14, // OP_DATA_20
0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39,
0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89,
0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash
},
},
},
}
// multiWitnessTxEncoded is the wire encoded bytes for multiWitnessTx including inputs
// with witness data using protocol version 70012 and is used in the various
// tests.
var multiWitnessTxEncoded = []byte{
0x1, 0x0, 0x0, 0x0, // Version
0x0, // Marker byte indicating 0 inputs, or a segwit encoded tx
0x1, // Flag byte
0x1, // Varint for number of inputs
0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0,
0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2,
0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8,
0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, // Previous output hash
0x13, 0x0, 0x0, 0x0, // Little endian previous output index
0x0, // No sig script (this is a witness input)
0xff, 0xff, 0xff, 0xff, // Sequence
0x1, // Varint for number of outputs
0xb, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, // Output amount
0x16, // Varint for length of pk script
0x0, // Version 0 witness program
0x14, // OP_DATA_20
0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39,
0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89,
0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash
0x2, // Two items on the witness stack
0x46, // 70 byte stack item
0x30, 0x43, 0x2, 0x1f, 0x4d, 0x23, 0x81, 0xdc,
0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51,
0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd,
0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36,
0x58, 0xda, 0x19, 0x2, 0x20, 0x60, 0x8b, 0x5c,
0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e,
0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b,
0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7,
0x56, 0x9a, 0x18, 0x19, 0x70, 0x1,
0x21, // 33 byte stack item
0x3, 0x7, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7,
0x63, 0x46, 0xdf, 0x69, 0x77, 0x0, 0xc, 0x89,
0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61,
0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x6, 0x6a,
0x8f,
0x0, 0x0, 0x0, 0x0, // Lock time
}
// multiWitnessTxEncodedNonZeroFlag is an incorrect wire encoded bytes for
// multiWitnessTx including inputs with witness data. Instead of the flag byte
// being set to 0x01, the flag is 0x00, which should trigger a decoding error.
var multiWitnessTxEncodedNonZeroFlag = []byte{
0x1, 0x0, 0x0, 0x0, // Version
0x0, // Marker byte indicating 0 inputs, or a segwit encoded tx
0x0, // Incorrect flag byte (should be 0x01)
0x1, // Varint for number of inputs
0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0,
0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2,
0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8,
0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, // Previous output hash
0x13, 0x0, 0x0, 0x0, // Little endian previous output index
0x0, // No sig script (this is a witness input)
0xff, 0xff, 0xff, 0xff, // Sequence
0x1, // Varint for number of outputs
0xb, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, // Output amount
0x16, // Varint for length of pk script
0x0, // Version 0 witness program
0x14, // OP_DATA_20
0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39,
0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89,
0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash
0x2, // Two items on the witness stack
0x46, // 70 byte stack item
0x30, 0x43, 0x2, 0x1f, 0x4d, 0x23, 0x81, 0xdc,
0x97, 0xf1, 0x82, 0xab, 0xd8, 0x18, 0x5f, 0x51,
0x75, 0x30, 0x18, 0x52, 0x32, 0x12, 0xf5, 0xdd,
0xc0, 0x7c, 0xc4, 0xe6, 0x3a, 0x8d, 0xc0, 0x36,
0x58, 0xda, 0x19, 0x2, 0x20, 0x60, 0x8b, 0x5c,
0x4d, 0x92, 0xb8, 0x6b, 0x6d, 0xe7, 0xd7, 0x8e,
0xf2, 0x3a, 0x2f, 0xa7, 0x35, 0xbc, 0xb5, 0x9b,
0x91, 0x4a, 0x48, 0xb0, 0xe1, 0x87, 0xc5, 0xe7,
0x56, 0x9a, 0x18, 0x19, 0x70, 0x1,
0x21, // 33 byte stack item
0x3, 0x7, 0xea, 0xd0, 0x84, 0x80, 0x7e, 0xb7,
0x63, 0x46, 0xdf, 0x69, 0x77, 0x0, 0xc, 0x89,
0x39, 0x2f, 0x45, 0xc7, 0x64, 0x25, 0xb2, 0x61,
0x81, 0xf5, 0x21, 0xd7, 0xf3, 0x70, 0x6, 0x6a,
0x8f,
0x0, 0x0, 0x0, 0x0, // Lock time
}
// multiTxPkScriptLocs is the location information for the public key scripts
// located in multiWitnessTx.
var multiWitnessTxPkScriptLocs = []int{58}