lbcd/script_test.go
Owain G. Ainsworth 7ae307abfd Fix case where we have an empty script that isn't the first.
Silly check needed to confirm it was the first script. Add test for this case.
2013-06-26 14:16:00 +01:00

1779 lines
48 KiB
Go

// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcscript_test
import (
"bytes"
"github.com/conformal/btcscript"
"github.com/conformal/btcwire"
"testing"
)
type txTest struct {
name string
tx *btcwire.MsgTx
pkScript []byte // output script of previous tx
idx int // tx idx to be run.
bip16 bool // is bip16 active?
parseErr error // failure of NewScript
err error // Failure of Executre
shouldFail bool // Execute should fail with nonspecified error.
nSigOps int // result of GetPreciseSigOpsCount
sigOpsErr error // failure of GetPreciseSigOpsCount()
}
var txTests = []txTest{
// tx 0437cd7f8525ceed2324359c2d0ba26006d92d85. the first tx in the
// blockchain that verifies signatures.
txTest{
name: "CheckSig",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0xc9, 0x97, 0xa5, 0xe5,
0x6e, 0x10, 0x41, 0x02,
0xfa, 0x20, 0x9c, 0x6a,
0x85, 0x2d, 0xd9, 0x06,
0x60, 0xa2, 0x0b, 0x2d,
0x9c, 0x35, 0x24, 0x23,
0xed, 0xce, 0x25, 0x85,
0x7f, 0xcd, 0x37, 0x04,
}),
Index: 0,
},
SignatureScript: []uint8{
btcscript.OP_DATA_71,
0x30, 0x44, 0x02, 0x20, 0x4e,
0x45, 0xe1, 0x69, 0x32, 0xb8,
0xaf, 0x51, 0x49, 0x61, 0xa1,
0xd3, 0xa1, 0xa2, 0x5f, 0xdf,
0x3f, 0x4f, 0x77, 0x32, 0xe9,
0xd6, 0x24, 0xc6, 0xc6, 0x15,
0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15,
0x22, 0xec, 0x8e, 0xca, 0x07,
0xde, 0x48, 0x60, 0xa4, 0xac,
0xdd, 0x12, 0x90, 0x9d, 0x83,
0x1c, 0xc5, 0x6c, 0xbb, 0xac,
0x46, 0x22, 0x08, 0x22, 0x21,
0xa8, 0x76, 0x8d, 0x1d, 0x09,
0x01,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000000,
PkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0xae, 0x1a, 0x62, 0xfe,
0x09, 0xc5, 0xf5, 0x1b, 0x13,
0x90, 0x5f, 0x07, 0xf0, 0x6b,
0x99, 0xa2, 0xf7, 0x15, 0x9b,
0x22, 0x25, 0xf3, 0x74, 0xcd,
0x37, 0x8d, 0x71, 0x30, 0x2f,
0xa2, 0x84, 0x14, 0xe7, 0xaa,
0xb3, 0x73, 0x97, 0xf5, 0x54,
0xa7, 0xdf, 0x5f, 0x14, 0x2c,
0x21, 0xc1, 0xb7, 0x30, 0x3b,
0x8a, 0x06, 0x26, 0xf1, 0xba,
0xde, 0xd5, 0xc7, 0x2a, 0x70,
0x4f, 0x7e, 0x6c, 0xd8, 0x4c,
btcscript.OP_CHECKSIG,
},
},
&btcwire.TxOut{
Value: 4000000000,
PkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0x11, 0xdb, 0x93, 0xe1,
0xdc, 0xdb, 0x8a, 0x01, 0x6b,
0x49, 0x84, 0x0f, 0x8c, 0x53,
0xbc, 0x1e, 0xb6, 0x8a, 0x38,
0x2e, 0x97, 0xb1, 0x48, 0x2e,
0xca, 0xd7, 0xb1, 0x48, 0xa6,
0x90, 0x9a, 0x5c, 0xb2, 0xe0,
0xea, 0xdd, 0xfb, 0x84, 0xcc,
0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b,
0x8b, 0x64, 0xf9, 0xd4, 0xc0,
0x3f, 0x99, 0x9b, 0x86, 0x43,
0xf6, 0x56, 0xb4, 0x12, 0xa3,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01,
0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6,
0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7,
0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea,
0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9, 0xd4,
0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56, 0xb4,
0x12, 0xa3, btcscript.OP_CHECKSIG,
},
idx: 0,
nSigOps: 1,
},
// Previous test with the value of one output changed.
txTest{
name: "CheckSig Failure",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0xc9, 0x97, 0xa5, 0xe5,
0x6e, 0x10, 0x41, 0x02,
0xfa, 0x20, 0x9c, 0x6a,
0x85, 0x2d, 0xd9, 0x06,
0x60, 0xa2, 0x0b, 0x2d,
0x9c, 0x35, 0x24, 0x23,
0xed, 0xce, 0x25, 0x85,
0x7f, 0xcd, 0x37, 0x04,
}),
Index: 0,
},
SignatureScript: []uint8{
btcscript.OP_DATA_71,
0x30, 0x44, 0x02, 0x20, 0x4e,
0x45, 0xe1, 0x69, 0x32, 0xb8,
0xaf, 0x51, 0x49, 0x61, 0xa1,
0xd3, 0xa1, 0xa2, 0x5f, 0xdf,
0x3f, 0x4f, 0x77, 0x32, 0xe9,
0xd6, 0x24, 0xc6, 0xc6, 0x15,
0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15,
0x22, 0xec, 0x8e, 0xca, 0x07,
0xde, 0x48, 0x60, 0xa4, 0xac,
0xdd, 0x12, 0x90, 0x9d, 0x83,
0x1c, 0xc5, 0x6c, 0xbb, 0xac,
0x46, 0x22, 0x08, 0x22, 0x21,
0xa8, 0x76, 0x8d, 0x1d, 0x09,
0x01,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000000,
PkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0xae, 0x1a, 0x62, 0xfe,
0x09, 0xc5, 0xf5, 0x1b, 0x13,
0x90, 0x5f, 0x07, 0xf0, 0x6b,
0x99, 0xa2, 0xf7, 0x15, 0x9b,
0x22, 0x25, 0xf3, 0x74, 0xcd,
0x37, 0x8d, 0x71, 0x30, 0x2f,
0xa2, 0x84, 0x14, 0xe7, 0xaa,
0xb3, 0x73, 0x97, 0xf5, 0x54,
0xa7, 0xdf, 0x5f, 0x14, 0x2c,
0x21, 0xc1, 0xb7, 0x30, 0x3b,
0x8a, 0x06, 0x26, 0xf1, 0xba,
0xde, 0xd5, 0xc7, 0x2a, 0x70,
0x4f, 0x7e, 0x6c, 0xd8, 0x4c,
btcscript.OP_CHECKSIG,
},
},
&btcwire.TxOut{
Value: 5000000000,
PkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0x11, 0xdb, 0x93, 0xe1,
0xdc, 0xdb, 0x8a, 0x01, 0x6b,
0x49, 0x84, 0x0f, 0x8c, 0x53,
0xbc, 0x1e, 0xb6, 0x8a, 0x38,
0x2e, 0x97, 0xb1, 0x48, 0x2e,
0xca, 0xd7, 0xb1, 0x48, 0xa6,
0x90, 0x9a, 0x5c, 0xb2, 0xe0,
0xea, 0xdd, 0xfb, 0x84, 0xcc,
0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b,
0x8b, 0x64, 0xf9, 0xd4, 0xc0,
0x3f, 0x99, 0x9b, 0x86, 0x43,
0xf6, 0x56, 0xb4, 0x12, 0xa3,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01,
0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6,
0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7,
0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea,
0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9, 0xd4,
0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56, 0xb4,
0x12, 0xa3, btcscript.OP_CHECKSIG,
},
idx: 0,
err: btcscript.StackErrScriptFailed,
nSigOps: 1,
},
txTest{
name: "CheckSig invalid signature",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0xc9, 0x97, 0xa5, 0xe5,
0x6e, 0x10, 0x41, 0x02,
0xfa, 0x20, 0x9c, 0x6a,
0x85, 0x2d, 0xd9, 0x06,
0x60, 0xa2, 0x0b, 0x2d,
0x9c, 0x35, 0x24, 0x23,
0xed, 0xce, 0x25, 0x85,
0x7f, 0xcd, 0x37, 0x04,
}),
Index: 0,
},
// Signature has length fiddled to
// fail parsing.
SignatureScript: []uint8{
btcscript.OP_DATA_71,
0x30, 0x45, 0x02, 0x20, 0x4e,
0x45, 0xe1, 0x69, 0x32, 0xb8,
0xaf, 0x51, 0x49, 0x61, 0xa1,
0xd3, 0xa1, 0xa2, 0x5f, 0xdf,
0x3f, 0x4f, 0x77, 0x32, 0xe9,
0xd6, 0x24, 0xc6, 0xc6, 0x15,
0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15,
0x22, 0xec, 0x8e, 0xca, 0x07,
0xde, 0x48, 0x60, 0xa4, 0xac,
0xdd, 0x12, 0x90, 0x9d, 0x83,
0x1c, 0xc5, 0x6c, 0xbb, 0xac,
0x46, 0x22, 0x08, 0x22, 0x21,
0xa8, 0x76, 0x8d, 0x1d, 0x09,
0x01,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000000,
PkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0xae, 0x1a, 0x62, 0xfe,
0x09, 0xc5, 0xf5, 0x1b, 0x13,
0x90, 0x5f, 0x07, 0xf0, 0x6b,
0x99, 0xa2, 0xf7, 0x15, 0x9b,
0x22, 0x25, 0xf3, 0x74, 0xcd,
0x37, 0x8d, 0x71, 0x30, 0x2f,
0xa2, 0x84, 0x14, 0xe7, 0xaa,
0xb3, 0x73, 0x97, 0xf5, 0x54,
0xa7, 0xdf, 0x5f, 0x14, 0x2c,
0x21, 0xc1, 0xb7, 0x30, 0x3b,
0x8a, 0x06, 0x26, 0xf1, 0xba,
0xde, 0xd5, 0xc7, 0x2a, 0x70,
0x4f, 0x7e, 0x6c, 0xd8, 0x4c,
btcscript.OP_CHECKSIG,
},
},
&btcwire.TxOut{
Value: 4000000000,
PkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0x11, 0xdb, 0x93, 0xe1,
0xdc, 0xdb, 0x8a, 0x01, 0x6b,
0x49, 0x84, 0x0f, 0x8c, 0x53,
0xbc, 0x1e, 0xb6, 0x8a, 0x38,
0x2e, 0x97, 0xb1, 0x48, 0x2e,
0xca, 0xd7, 0xb1, 0x48, 0xa6,
0x90, 0x9a, 0x5c, 0xb2, 0xe0,
0xea, 0xdd, 0xfb, 0x84, 0xcc,
0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b,
0x8b, 0x64, 0xf9, 0xd4, 0xc0,
0x3f, 0x99, 0x9b, 0x86, 0x43,
0xf6, 0x56, 0xb4, 0x12, 0xa3,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01,
0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6,
0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7,
0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea,
0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9, 0xd4,
0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56, 0xb4,
0x12, 0xa3, btcscript.OP_CHECKSIG,
},
idx: 0,
shouldFail: true,
nSigOps: 1,
},
txTest{
name: "CheckSig invalid pubkey",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0xc9, 0x97, 0xa5, 0xe5,
0x6e, 0x10, 0x41, 0x02,
0xfa, 0x20, 0x9c, 0x6a,
0x85, 0x2d, 0xd9, 0x06,
0x60, 0xa2, 0x0b, 0x2d,
0x9c, 0x35, 0x24, 0x23,
0xed, 0xce, 0x25, 0x85,
0x7f, 0xcd, 0x37, 0x04,
}),
Index: 0,
},
SignatureScript: []uint8{
btcscript.OP_DATA_71,
0x30, 0x44, 0x02, 0x20, 0x4e,
0x45, 0xe1, 0x69, 0x32, 0xb8,
0xaf, 0x51, 0x49, 0x61, 0xa1,
0xd3, 0xa1, 0xa2, 0x5f, 0xdf,
0x3f, 0x4f, 0x77, 0x32, 0xe9,
0xd6, 0x24, 0xc6, 0xc6, 0x15,
0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15,
0x22, 0xec, 0x8e, 0xca, 0x07,
0xde, 0x48, 0x60, 0xa4, 0xac,
0xdd, 0x12, 0x90, 0x9d, 0x83,
0x1c, 0xc5, 0x6c, 0xbb, 0xac,
0x46, 0x22, 0x08, 0x22, 0x21,
0xa8, 0x76, 0x8d, 0x1d, 0x09,
0x01,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000000,
PkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0xae, 0x1a, 0x62, 0xfe,
0x09, 0xc5, 0xf5, 0x1b, 0x13,
0x90, 0x5f, 0x07, 0xf0, 0x6b,
0x99, 0xa2, 0xf7, 0x15, 0x9b,
0x22, 0x25, 0xf3, 0x74, 0xcd,
0x37, 0x8d, 0x71, 0x30, 0x2f,
0xa2, 0x84, 0x14, 0xe7, 0xaa,
0xb3, 0x73, 0x97, 0xf5, 0x54,
0xa7, 0xdf, 0x5f, 0x14, 0x2c,
0x21, 0xc1, 0xb7, 0x30, 0x3b,
0x8a, 0x06, 0x26, 0xf1, 0xba,
0xde, 0xd5, 0xc7, 0x2a, 0x70,
0x4f, 0x7e, 0x6c, 0xd8, 0x4c,
btcscript.OP_CHECKSIG,
},
},
&btcwire.TxOut{
Value: 4000000000,
PkScript: []byte{
btcscript.OP_DATA_65,
0x04, 0x11, 0xdb, 0x93, 0xe1,
0xdc, 0xdb, 0x8a, 0x01, 0x6b,
0x49, 0x84, 0x0f, 0x8c, 0x53,
0xbc, 0x1e, 0xb6, 0x8a, 0x38,
0x2e, 0x97, 0xb1, 0x48, 0x2e,
0xca, 0xd7, 0xb1, 0x48, 0xa6,
0x90, 0x9a, 0x5c, 0xb2, 0xe0,
0xea, 0xdd, 0xfb, 0x84, 0xcc,
0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b,
0x8b, 0x64, 0xf9, 0xd4, 0xc0,
0x3f, 0x99, 0x9b, 0x86, 0x43,
0xf6, 0x56, 0xb4, 0x12, 0xa3,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
// pubkey header magic byte has been changed to parse wrong.
pkScript: []byte{
btcscript.OP_DATA_65,
0x02, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01,
0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6,
0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7,
0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea,
0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9, 0xd4,
0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56, 0xb4,
0x12, 0xa3, btcscript.OP_CHECKSIG,
},
idx: 0,
shouldFail: true,
nSigOps: 1,
},
// tx 599e47a8114fe098103663029548811d2651991b62397e057f0c863c2bc9f9ea
// uses checksig with SigHashNone.
txTest{
name: "CheckSigHashNone",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x5f, 0x38, 0x6c, 0x8a,
0x38, 0x42, 0xc9, 0xa9,
0xdc, 0xfa, 0x9b, 0x78,
0xbe, 0x78, 0x5a, 0x40,
0xa7, 0xbd, 0xa0, 0x8b,
0x64, 0x64, 0x6b, 0xe3,
0x65, 0x43, 0x01, 0xea,
0xcc, 0xfc, 0x8d, 0x5e,
}),
Index: 1,
},
SignatureScript: []byte{
btcscript.OP_DATA_71,
0x30, 0x44, 0x02, 0x20, 0xbb,
0x4f, 0xbc, 0x49, 0x5a, 0xa2,
0x3b, 0xab, 0xb2, 0xc2, 0xbe,
0x4e, 0x3f, 0xb4, 0xa5, 0xdf,
0xfe, 0xfe, 0x20, 0xc8, 0xef,
0xf5, 0x94, 0x0f, 0x13, 0x56,
0x49, 0xc3, 0xea, 0x96, 0x44,
0x4a, 0x02, 0x20, 0x04, 0xaf,
0xcd, 0xa9, 0x66, 0xc8, 0x07,
0xbb, 0x97, 0x62, 0x2d, 0x3e,
0xef, 0xea, 0x82, 0x8f, 0x62,
0x3a, 0xf3, 0x06, 0xef, 0x2b,
0x75, 0x67, 0x82, 0xee, 0x6f,
0x8a, 0x22, 0xa9, 0x59, 0xa2,
0x02,
btcscript.OP_DATA_65,
0x04, 0xf1, 0x93, 0x9a, 0xe6,
0xb0, 0x1e, 0x84, 0x9b, 0xf0,
0x5d, 0x0e, 0xd5, 0x1f, 0xd5,
0xb9, 0x2b, 0x79, 0xa0, 0xe3,
0x13, 0xe3, 0xf3, 0x89, 0xc7,
0x26, 0xf1, 0x1f, 0xa3, 0xe1,
0x44, 0xd9, 0x22, 0x7b, 0x07,
0xe8, 0xa8, 0x7c, 0x0e, 0xe3,
0x63, 0x72, 0xe9, 0x67, 0xe0,
0x90, 0xd1, 0x1b, 0x77, 0x77,
0x07, 0xaa, 0x73, 0xef, 0xac,
0xab, 0xff, 0xff, 0xa2, 0x85,
0xc0, 0x0b, 0x36, 0x22, 0xd6,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x66, 0x0d, 0x4e, 0xf3, 0xa7,
0x43, 0xe3, 0xe6, 0x96, 0xad,
0x99, 0x03, 0x64, 0xe5, 0x55,
0xc2, 0x71, 0xad, 0x50, 0x4b,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
&btcwire.TxOut{
Value: 29913632,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x21, 0xc4, 0x3c, 0xe4, 0x00,
0x90, 0x13, 0x12, 0xa6, 0x03,
0xe4, 0x20, 0x7a, 0xad, 0xfd,
0x74, 0x2b, 0xe8, 0xe7, 0xda,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x21, 0xc4, 0x3c, 0xe4, 0x00, 0x90, 0x13, 0x12, 0xa6,
0x03, 0xe4, 0x20, 0x7a, 0xad, 0xfd, 0x74, 0x2b, 0xe8,
0xe7, 0xda,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
idx: 0,
bip16: true, // after threshold
nSigOps: 1,
},
// tx 51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e
// first instance of an AnyoneCanPay signature in the blockchain
txTest{
name: "CheckSigHashAnyoneCanPay",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0xf6, 0x04, 0x4c, 0x0a,
0xd4, 0x85, 0xf6, 0x33,
0xb4, 0x1f, 0x97, 0xd0,
0xd7, 0x93, 0xeb, 0x28,
0x37, 0xae, 0x40, 0xf7,
0x38, 0xff, 0x6d, 0x5f,
0x50, 0xfd, 0xfd, 0x10,
0x52, 0x8c, 0x1d, 0x76,
}),
Index: 1,
},
SignatureScript: []byte{
btcscript.OP_DATA_72,
0x30, 0x45, 0x02, 0x20, 0x58,
0x53, 0xc7, 0xf1, 0x39, 0x57,
0x85, 0xbf, 0xab, 0xb0, 0x3c,
0x57, 0xe9, 0x62, 0xeb, 0x07,
0x6f, 0xf2, 0x4d, 0x8e, 0x4e,
0x57, 0x3b, 0x04, 0xdb, 0x13,
0xb4, 0x5e, 0xd3, 0xed, 0x6e,
0xe2, 0x02, 0x21, 0x00, 0x9d,
0xc8, 0x2a, 0xe4, 0x3b, 0xe9,
0xd4, 0xb1, 0xfe, 0x28, 0x47,
0x75, 0x4e, 0x1d, 0x36, 0xda,
0xd4, 0x8b, 0xa8, 0x01, 0x81,
0x7d, 0x48, 0x5d, 0xc5, 0x29,
0xaf, 0xc5, 0x16, 0xc2, 0xdd,
0xb4, 0x81,
btcscript.OP_DATA_33,
0x03, 0x05, 0x58, 0x49, 0x80,
0x36, 0x7b, 0x32, 0x1f, 0xad,
0x7f, 0x1c, 0x1f, 0x4d, 0x5d,
0x72, 0x3d, 0x0a, 0xc8, 0x0c,
0x1d, 0x80, 0xc8, 0xba, 0x12,
0x34, 0x39, 0x65, 0xb4, 0x83,
0x64, 0x53, 0x7a,
},
Sequence: 4294967295,
},
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x9c, 0x6a, 0xf0, 0xdf,
0x66, 0x69, 0xbc, 0xde,
0xd1, 0x9e, 0x31, 0x7e,
0x25, 0xbe, 0xbc, 0x8c,
0x78, 0xe4, 0x8d, 0xf8,
0xae, 0x1f, 0xe0, 0x2a,
0x7f, 0x03, 0x08, 0x18,
0xe7, 0x1e, 0xcd, 0x40,
}),
Index: 1,
},
SignatureScript: []byte{
btcscript.OP_DATA_73,
0x30, 0x46, 0x02, 0x21, 0x00,
0x82, 0x69, 0xc9, 0xd7, 0xba,
0x0a, 0x7e, 0x73, 0x0d, 0xd1,
0x6f, 0x40, 0x82, 0xd2, 0x9e,
0x36, 0x84, 0xfb, 0x74, 0x63,
0xba, 0x06, 0x4f, 0xd0, 0x93,
0xaf, 0xc1, 0x70, 0xad, 0x6e,
0x03, 0x88, 0x02, 0x21, 0x00,
0xbc, 0x6d, 0x76, 0x37, 0x39,
0x16, 0xa3, 0xff, 0x6e, 0xe4,
0x1b, 0x2c, 0x75, 0x20, 0x01,
0xfd, 0xa3, 0xc9, 0xe0, 0x48,
0xbc, 0xff, 0x0d, 0x81, 0xd0,
0x5b, 0x39, 0xff, 0x0f, 0x42,
0x17, 0xb2, 0x81,
btcscript.OP_DATA_33,
0x03, 0xaa, 0xe3, 0x03, 0xd8,
0x25, 0x42, 0x15, 0x45, 0xc5,
0xbc, 0x7c, 0xcd, 0x5a, 0xc8,
0x7d, 0xd5, 0xad, 0xd3, 0xbc,
0xc3, 0xa4, 0x32, 0xba, 0x7a,
0xa2, 0xf2, 0x66, 0x16, 0x99,
0xf9, 0xf6, 0x59,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 300000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x5c, 0x11, 0xf9, 0x17, 0x88,
0x3b, 0x92, 0x7e, 0xef, 0x77,
0xdc, 0x57, 0x70, 0x7a, 0xeb,
0x85, 0x3f, 0x6d, 0x38, 0x94,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x85, 0x51, 0xe4, 0x8a, 0x53, 0xde, 0xcd, 0x1c, 0xfc,
0x63, 0x07, 0x9a, 0x45, 0x81, 0xbc, 0xcc, 0xfa, 0xd1,
0xa9, 0x3c,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
idx: 0,
bip16: true, // after threshold
nSigOps: 1,
},
// tx 6d36bc17e947ce00bb6f12f8e7a56a1585c5a36188ffa2b05e10b4743273a74b
// Uses OP_CODESEPARATOR and OP_CHECKMULTISIG
txTest{
name: "CheckMultiSig",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x37, 0xb1, 0x7d, 0x76,
0x38, 0x51, 0xcd, 0x1a,
0xb0, 0x4a, 0x42, 0x44,
0x63, 0xd4, 0x13, 0xc4,
0xee, 0x5c, 0xf6, 0x13,
0x04, 0xc7, 0xfd, 0x76,
0x97, 0x7b, 0xea, 0x7f,
0xce, 0x07, 0x57, 0x05,
}),
Index: 0,
},
SignatureScript: []byte{
btcscript.OP_DATA_71,
0x30, 0x44, 0x02, 0x20, 0x02,
0xdb, 0xe4, 0xb5, 0xa2, 0xfb,
0xb5, 0x21, 0xe4, 0xdc, 0x5f,
0xbe, 0xc7, 0x5f, 0xd9, 0x60,
0x65, 0x1a, 0x27, 0x54, 0xb0,
0x3d, 0x08, 0x71, 0xb8, 0xc9,
0x65, 0x46, 0x9b, 0xe5, 0x0f,
0xa7, 0x02, 0x20, 0x6d, 0x97,
0x42, 0x1f, 0xb7, 0xea, 0x93,
0x59, 0xb6, 0x3e, 0x48, 0xc2,
0x10, 0x82, 0x23, 0x28, 0x4b,
0x9a, 0x71, 0x56, 0x0b, 0xd8,
0x18, 0x24, 0x69, 0xb9, 0x03,
0x92, 0x28, 0xd7, 0xb3, 0xd7,
0x01, 0x21, 0x02, 0x95, 0xbf,
0x72, 0x71, 0x11, 0xac, 0xde,
0xab, 0x87, 0x78, 0x28, 0x4f,
0x02, 0xb7, 0x68, 0xd1, 0xe2,
0x1a, 0xcb, 0xcb, 0xae, 0x42,
},
Sequence: 4294967295,
},
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x37, 0xb1, 0x7d, 0x76,
0x38, 0x51, 0xcd, 0x1a,
0xb0, 0x4a, 0x42, 0x44,
0x63, 0xd4, 0x13, 0xc4,
0xee, 0x5c, 0xf6, 0x13,
0x04, 0xc7, 0xfd, 0x76,
0x97, 0x7b, 0xea, 0x7f,
0xce, 0x07, 0x57, 0x05,
}),
Index: 1,
},
SignatureScript: []uint8{
btcscript.OP_FALSE,
btcscript.OP_DATA_72,
0x30, 0x45, 0x02, 0x20, 0x10,
0x6a, 0x3e, 0x4e, 0xf0, 0xb5,
0x1b, 0x76, 0x4a, 0x28, 0x87,
0x22, 0x62, 0xff, 0xef, 0x55,
0x84, 0x65, 0x14, 0xda, 0xcb,
0xdc, 0xbb, 0xdd, 0x65, 0x2c,
0x84, 0x9d, 0x39, 0x5b, 0x43,
0x84, 0x02, 0x21, 0x00, 0xe0,
0x3a, 0xe5, 0x54, 0xc3, 0xcb,
0xb4, 0x06, 0x00, 0xd3, 0x1d,
0xd4, 0x6f, 0xc3, 0x3f, 0x25,
0xe4, 0x7b, 0xf8, 0x52, 0x5b,
0x1f, 0xe0, 0x72, 0x82, 0xe3,
0xb6, 0xec, 0xb5, 0xf3, 0xbb,
0x28, 0x01,
btcscript.OP_CODESEPARATOR,
btcscript.OP_TRUE,
btcscript.OP_DATA_33,
0x02, 0x32, 0xab, 0xdc, 0x89,
0x3e, 0x7f, 0x06, 0x31, 0x36,
0x4d, 0x7f, 0xd0, 0x1c, 0xb3,
0x3d, 0x24, 0xda, 0x45, 0x32,
0x9a, 0x00, 0x35, 0x7b, 0x3a,
0x78, 0x86, 0x21, 0x1a, 0xb4,
0x14, 0xd5, 0x5a,
btcscript.OP_TRUE,
btcscript.OP_CHECK_MULTISIG,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 4800000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x0d, 0x77, 0x13, 0x64, 0x9f,
0x9a, 0x06, 0x78, 0xf4, 0xe8,
0x80, 0xb4, 0x0f, 0x86, 0xb9,
0x32, 0x89, 0xd1, 0xbb, 0x27,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
// This is a very weird script...
pkScript: []byte{
btcscript.OP_DATA_20,
0x2a, 0x9b, 0xc5, 0x44, 0x7d, 0x66, 0x4c, 0x1d, 0x01,
0x41, 0x39, 0x2a, 0x84, 0x2d, 0x23, 0xdb, 0xa4, 0x5c,
0x4f, 0x13,
btcscript.OP_NOP2, btcscript.OP_DROP,
},
idx: 1,
bip16: false,
nSigOps: 0, // multisig is in the pkScript!
},
// same as previous but with one byte changed to make signature fail
txTest{
name: "CheckMultiSig fail",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x37, 0xb1, 0x7d, 0x76,
0x38, 0x51, 0xcd, 0x1a,
0xb0, 0x4a, 0x42, 0x44,
0x63, 0xd4, 0x13, 0xc4,
0xee, 0x5c, 0xf6, 0x13,
0x04, 0xc7, 0xfd, 0x76,
0x97, 0x7b, 0xea, 0x7f,
0xce, 0x07, 0x57, 0x05,
}),
Index: 0,
},
SignatureScript: []byte{
btcscript.OP_DATA_71,
0x30, 0x44, 0x02, 0x20, 0x02,
0xdb, 0xe4, 0xb5, 0xa2, 0xfb,
0xb5, 0x21, 0xe4, 0xdc, 0x5f,
0xbe, 0xc7, 0x5f, 0xd9, 0x60,
0x65, 0x1a, 0x27, 0x54, 0xb0,
0x3d, 0x08, 0x71, 0xb8, 0xc9,
0x65, 0x46, 0x9b, 0xe5, 0x0f,
0xa7, 0x02, 0x20, 0x6d, 0x97,
0x42, 0x1f, 0xb7, 0xea, 0x93,
0x59, 0xb6, 0x3e, 0x48, 0xc2,
0x10, 0x82, 0x23, 0x28, 0x4b,
0x9a, 0x71, 0x56, 0x0b, 0xd8,
0x18, 0x24, 0x69, 0xb9, 0x03,
0x92, 0x28, 0xd7, 0xb3, 0xd7,
0x01, 0x21, 0x02, 0x95, 0xbf,
0x72, 0x71, 0x11, 0xac, 0xde,
0xab, 0x87, 0x78, 0x28, 0x4f,
0x02, 0xb7, 0x68, 0xd1, 0xe2,
0x1a, 0xcb, 0xcb, 0xae, 0x42,
},
Sequence: 4294967295,
},
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x37, 0xb1, 0x7d, 0x76,
0x38, 0x51, 0xcd, 0x1a,
0xb0, 0x4a, 0x42, 0x44,
0x63, 0xd4, 0x13, 0xc4,
0xee, 0x5c, 0xf6, 0x13,
0x04, 0xc7, 0xfd, 0x76,
0x97, 0x7b, 0xea, 0x7f,
0xce, 0x07, 0x57, 0x05,
}),
Index: 1,
},
SignatureScript: []uint8{
btcscript.OP_FALSE,
btcscript.OP_DATA_72,
0x30, 0x45, 0x02, 0x20, 0x10,
0x6a, 0x3e, 0x4e, 0xf0, 0xb5,
0x1b, 0x76, 0x4a, 0x28, 0x87,
0x22, 0x62, 0xff, 0xef, 0x55,
0x84, 0x65, 0x14, 0xda, 0xcb,
0xdc, 0xbb, 0xdd, 0x65, 0x2c,
0x84, 0x9d, 0x39, 0x5b, 0x43,
0x84, 0x02, 0x21, 0x00, 0xe0,
0x3a, 0xe5, 0x54, 0xc3, 0xcb,
0xb4, 0x06, 0x00, 0xd3, 0x1d,
0xd4, 0x6f, 0xc3, 0x3f, 0x25,
0xe4, 0x7b, 0xf8, 0x52, 0x5b,
0x1f, 0xe0, 0x72, 0x82, 0xe3,
0xb6, 0xec, 0xb5, 0xf3, 0xbb,
0x28, 0x01,
btcscript.OP_CODESEPARATOR,
btcscript.OP_TRUE,
btcscript.OP_DATA_33,
0x02, 0x32, 0xab, 0xdc, 0x89,
0x3e, 0x7f, 0x06, 0x31, 0x36,
0x4d, 0x7f, 0xd0, 0x1c, 0xb3,
0x3d, 0x24, 0xda, 0x45, 0x32,
0x9a, 0x00, 0x35, 0x7b, 0x3a,
0x78, 0x86, 0x21, 0x1a, 0xb4,
0x14, 0xd5, 0x5a,
btcscript.OP_TRUE,
btcscript.OP_CHECK_MULTISIG,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 5800000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x0d, 0x77, 0x13, 0x64, 0x9f,
0x9a, 0x06, 0x78, 0xf4, 0xe8,
0x80, 0xb4, 0x0f, 0x86, 0xb9,
0x32, 0x89, 0xd1, 0xbb, 0x27,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
// This is a very weird script...
pkScript: []byte{
btcscript.OP_DATA_20,
0x2a, 0x9b, 0xc5, 0x44, 0x7d, 0x66, 0x4c, 0x1d, 0x01,
0x41, 0x39, 0x2a, 0x84, 0x2d, 0x23, 0xdb, 0xa4, 0x5c,
0x4f, 0x13,
btcscript.OP_NOP2, btcscript.OP_DROP,
},
idx: 1,
bip16: false,
err: btcscript.StackErrScriptFailed,
nSigOps: 0, // multisig is in the pkScript!
},
// tx e5779b9e78f9650debc2893fd9636d827b26b4ddfa6a8172fe8708c924f5c39d
// First P2SH transaction in the blockchain
txTest{
name: "P2SH",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x6d, 0x58, 0xf8, 0xa3,
0xaa, 0x43, 0x0b, 0x84,
0x78, 0x52, 0x3a, 0x65,
0xc2, 0x03, 0xa2, 0x7b,
0xb8, 0x81, 0x17, 0x8c,
0xb1, 0x23, 0x13, 0xaf,
0xde, 0x29, 0xf9, 0x2e,
0xd7, 0x56, 0xaa, 0x7e,
}),
Index: 0,
},
SignatureScript: []byte{
btcscript.OP_DATA_2,
// OP_3 OP_7
0x53, 0x57,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x5b, 0x69, 0xd8, 0xb9, 0xdf,
0xa6, 0xe4, 0x12, 0x26, 0x47,
0xe1, 0x79, 0x4e, 0xaa, 0x3b,
0xfc, 0x11, 0x1f, 0x70, 0xef,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x43, 0x3e, 0xc2, 0xac, 0x1f, 0xfa, 0x1b, 0x7b, 0x7d,
0x02, 0x7f, 0x56, 0x45, 0x29, 0xc5, 0x71, 0x97, 0xf9,
0xae, 0x88,
btcscript.OP_EQUAL,
},
idx: 0,
bip16: true,
nSigOps: 0, // no signature ops in the pushed script.
},
// next few tests are modified versions of previous to hit p2sh error
// cases.
txTest{
// sigscript changed so that pkscript hash will not match.
name: "P2SH - bad hash",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x6d, 0x58, 0xf8, 0xa3,
0xaa, 0x43, 0x0b, 0x84,
0x78, 0x52, 0x3a, 0x65,
0xc2, 0x03, 0xa2, 0x7b,
0xb8, 0x81, 0x17, 0x8c,
0xb1, 0x23, 0x13, 0xaf,
0xde, 0x29, 0xf9, 0x2e,
0xd7, 0x56, 0xaa, 0x7e,
}),
Index: 0,
},
SignatureScript: []byte{
btcscript.OP_DATA_2,
// OP_3 OP_8
0x53, 0x58,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x5b, 0x69, 0xd8, 0xb9, 0xdf,
0xa6, 0xe4, 0x12, 0x26, 0x47,
0xe1, 0x79, 0x4e, 0xaa, 0x3b,
0xfc, 0x11, 0x1f, 0x70, 0xef,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x43, 0x3e, 0xc2, 0xac, 0x1f, 0xfa, 0x1b, 0x7b, 0x7d,
0x02, 0x7f, 0x56, 0x45, 0x29, 0xc5, 0x71, 0x97, 0xf9,
0xae, 0x88,
btcscript.OP_EQUAL,
},
idx: 0,
err: btcscript.StackErrScriptFailed,
bip16: true,
nSigOps: 0, // no signature ops in the pushed script.
},
txTest{
// sigscript changed so that pkscript hash will not match.
name: "P2SH - doesn't parse",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x6d, 0x58, 0xf8, 0xa3,
0xaa, 0x43, 0x0b, 0x84,
0x78, 0x52, 0x3a, 0x65,
0xc2, 0x03, 0xa2, 0x7b,
0xb8, 0x81, 0x17, 0x8c,
0xb1, 0x23, 0x13, 0xaf,
0xde, 0x29, 0xf9, 0x2e,
0xd7, 0x56, 0xaa, 0x7e,
}),
Index: 0,
},
SignatureScript: []byte{
btcscript.OP_DATA_2,
// pushed script.
btcscript.OP_DATA_2, 0x1,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x5b, 0x69, 0xd8, 0xb9, 0xdf,
0xa6, 0xe4, 0x12, 0x26, 0x47,
0xe1, 0x79, 0x4e, 0xaa, 0x3b,
0xfc, 0x11, 0x1f, 0x70, 0xef,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0xd4, 0x8c, 0xe8, 0x6c, 0x69, 0x8f, 0x24, 0x68, 0x29,
0x92, 0x1b, 0xa9, 0xfb, 0x2a, 0x84, 0x4a, 0xe2, 0xad,
0xba, 0x67,
btcscript.OP_EQUAL,
},
idx: 0,
err: btcscript.StackErrShortScript,
bip16: true,
sigOpsErr: btcscript.StackErrShortScript,
},
txTest{
// sigscript changed so to be non pushonly.
name: "P2SH - non pushonly",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x6d, 0x58, 0xf8, 0xa3,
0xaa, 0x43, 0x0b, 0x84,
0x78, 0x52, 0x3a, 0x65,
0xc2, 0x03, 0xa2, 0x7b,
0xb8, 0x81, 0x17, 0x8c,
0xb1, 0x23, 0x13, 0xaf,
0xde, 0x29, 0xf9, 0x2e,
0xd7, 0x56, 0xaa, 0x7e,
}),
Index: 0,
},
// doesn't have to match signature.
// will never run.
SignatureScript: []byte{
btcscript.OP_DATA_2,
// pushed script.
btcscript.OP_DATA_1, 0x1,
btcscript.OP_DUP,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x5b, 0x69, 0xd8, 0xb9, 0xdf,
0xa6, 0xe4, 0x12, 0x26, 0x47,
0xe1, 0x79, 0x4e, 0xaa, 0x3b,
0xfc, 0x11, 0x1f, 0x70, 0xef,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x43, 0x3e, 0xc2, 0xac, 0x1f, 0xfa, 0x1b, 0x7b, 0x7d,
0x02, 0x7f, 0x56, 0x45, 0x29, 0xc5, 0x71, 0x97, 0xf9,
0xae, 0x88,
btcscript.OP_EQUAL,
},
idx: 0,
parseErr: btcscript.StackErrP2SHNonPushOnly,
bip16: true,
nSigOps: 0, // no signature ops in the pushed script.
},
txTest{
// sigscript changed so to be non pushonly.
name: "empty pkScript",
tx: &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0x6d, 0x58, 0xf8, 0xa3,
0xaa, 0x43, 0x0b, 0x84,
0x78, 0x52, 0x3a, 0x65,
0xc2, 0x03, 0xa2, 0x7b,
0xb8, 0x81, 0x17, 0x8c,
0xb1, 0x23, 0x13, 0xaf,
0xde, 0x29, 0xf9, 0x2e,
0xd7, 0x56, 0xaa, 0x7e,
}),
Index: 0,
},
// doesn't have to match signature.
// will never run.
SignatureScript: []byte{
btcscript.OP_TRUE,
},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000,
PkScript: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x5b, 0x69, 0xd8, 0xb9, 0xdf,
0xa6, 0xe4, 0x12, 0x26, 0x47,
0xe1, 0x79, 0x4e, 0xaa, 0x3b,
0xfc, 0x11, 0x1f, 0x70, 0xef,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
},
},
LockTime: 0,
},
pkScript: []byte{},
idx: 0,
bip16: true,
nSigOps: 0, // no signature ops in the pushed script.
},
}
// Test a number of tx from the blockchain to test otherwise difficult to test
// opcodes (i.e. those that involve signatures). Being from the blockchain,
// these transactions are known good.
// TODO(oga) For signatures we currently do not test SigHashSingle because
// nothing in the blockchain that we have yet seen uses them, making it hard
// to confirm we implemented the spec correctly.
func testTx(t *testing.T, test txTest) {
engine, err := btcscript.NewScript(
test.tx.TxIn[test.idx].SignatureScript, test.pkScript,
test.idx, test.tx, 70001, test.bip16)
if err != nil {
if err != test.parseErr {
t.Errorf("Failed to parse %s: got \"%v\" expected "+
"\"%v\"", test.name, err, test.parseErr)
}
return
}
if test.parseErr != nil {
t.Errorf("%s: parse succeeded when expecting \"%v\"", test.name,
test.parseErr)
}
err = engine.Execute()
if err != nil {
// failed means no specified error
if test.shouldFail == true {
return
}
if err != test.err {
t.Errorf("Failed to validate %s tx: %v expected %v",
test.name, err, test.err)
}
return
}
if test.err != nil || test.shouldFail == true {
t.Errorf("%s: expected failure: %v, succeeded", test.name,
test.err)
}
}
func TestTX(t *testing.T) {
for i := range txTests {
testTx(t, txTests[i])
}
}
func TestGetPreciseSignOps(t *testing.T) {
// First we go over the range of tests in testTx and count the sigops in
// them.
for _, test := range txTests {
count, err := btcscript.GetPreciseSigOpCount(
test.tx.TxIn[test.idx].SignatureScript, test.pkScript,
test.bip16)
// all tx currently parse
if err != nil {
if err != test.sigOpsErr {
t.Errorf("%s: unexpected error. got \"%v\"",
test.name, err)
}
continue
}
if test.sigOpsErr != nil {
t.Errorf("%s: expected error \"%v\" but got success",
test.name, err)
continue
}
if count != test.nSigOps {
t.Errorf("%s: expected count of %d, got %d", test.name,
test.nSigOps, count)
}
}
// Now we go over a number of tests to hit the more awkward error
// conditions in the P2SH cases..
type psocTest struct {
name string
scriptSig []byte
nSigOps int
err error
}
psocTests := []psocTest{
psocTest{
name: "scriptSig doesn't parse",
scriptSig: []byte{btcscript.OP_PUSHDATA1, 2},
err: btcscript.StackErrShortScript,
},
psocTest{
name: "scriptSig isn't push only",
scriptSig: []byte{btcscript.OP_1, btcscript.OP_DUP},
nSigOps: 0,
},
psocTest{
name: "scriptSig length 0",
scriptSig: []byte{},
nSigOps: 0,
},
psocTest{
name: "No script at the end",
// No script at end but still push only.
scriptSig: []byte{btcscript.OP_1, btcscript.OP_1},
nSigOps: 0,
},
// pushed script doesn't parse.
psocTest{
name: "pushed script doesn't parse",
scriptSig: []byte{btcscript.OP_DATA_2,
btcscript.OP_PUSHDATA1, 2},
err: btcscript.StackErrShortScript,
},
}
// The signature in the p2sh script is nonsensical for the tests since
// this script will never be executed. What matters is that it matches
// the right pattern.
pkScript := []byte{
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x43, 0x3e, 0xc2, 0xac, 0x1f, 0xfa, 0x1b, 0x7b, 0x7d,
0x02, 0x7f, 0x56, 0x45, 0x29, 0xc5, 0x71, 0x97, 0xf9,
0xae, 0x88,
btcscript.OP_EQUAL,
}
for _, test := range psocTests {
count, err := btcscript.GetPreciseSigOpCount(
test.scriptSig, pkScript, true)
// all tx currently parse
if err != nil {
if err != test.err {
t.Errorf("%s: unexpected error. got \"%v\" exp: \"%v\"",
test.name, err, test.err)
}
continue
}
if test.err != nil {
t.Errorf("%s: expected error \"%v\" got none",
test.name, test.err)
continue
}
if count != test.nSigOps {
t.Errorf("%s: expected count of %d, got %d", test.name,
test.nSigOps, count)
}
}
}
type removeOpcodeTest struct {
name string
before []byte
remove byte
err error
after []byte
}
var removeOpcodeTests = []removeOpcodeTest{
// Nothing to remove.
removeOpcodeTest{
name: "nothing to remove",
before: []byte{btcscript.OP_NOP},
remove: btcscript.OP_CODESEPARATOR,
after: []byte{btcscript.OP_NOP},
},
// Test basic opcode removal
removeOpcodeTest{
name: "codeseparator 1",
before: []byte{btcscript.OP_NOP, btcscript.OP_CODESEPARATOR,
btcscript.OP_TRUE},
remove: btcscript.OP_CODESEPARATOR,
after: []byte{btcscript.OP_NOP, btcscript.OP_TRUE},
},
// The opcode in question is actually part of the data in a previous
// opcode
removeOpcodeTest{
name: "codeseparator by coincidence",
before: []byte{btcscript.OP_NOP, btcscript.OP_DATA_1, btcscript.OP_CODESEPARATOR,
btcscript.OP_TRUE},
remove: btcscript.OP_CODESEPARATOR,
after: []byte{btcscript.OP_NOP, btcscript.OP_DATA_1, btcscript.OP_CODESEPARATOR,
btcscript.OP_TRUE},
},
removeOpcodeTest{
name: "invalid opcode",
before: []byte{186},
remove: btcscript.OP_CODESEPARATOR,
err: btcscript.StackErrInvalidOpcode,
},
removeOpcodeTest{
name: "invalid length (insruction)",
before: []byte{btcscript.OP_PUSHDATA1},
remove: btcscript.OP_CODESEPARATOR,
err: btcscript.StackErrShortScript,
},
removeOpcodeTest{
name: "invalid length (data)",
before: []byte{btcscript.OP_PUSHDATA1, 255, 254},
remove: btcscript.OP_CODESEPARATOR,
err: btcscript.StackErrShortScript,
},
}
func testRemoveOpcode(t *testing.T, test *removeOpcodeTest) {
result, err := btcscript.TstRemoveOpcode(test.before, test.remove)
if test.err != nil {
if err != test.err {
t.Errorf("%s: got unexpected error. exp: \"%v\" "+
"got: \"%v\"", test.name, test.err, err)
}
return
}
if err != nil {
t.Errorf("%s: unexpected failure: \"%v\"", test.name, err)
return
}
if !bytes.Equal(test.after, result) {
t.Errorf("%s: value does not equal expected: exp: \"%v\""+
" got: \"%v\"", test.name, test.after, result)
}
}
func TestRemoveOpcodes(t *testing.T) {
for i := range removeOpcodeTests {
testRemoveOpcode(t, &removeOpcodeTests[i])
}
}
type removeOpcodeByDataTest struct {
name string
before []byte
remove []byte
err error
after []byte
}
var removeOpcodeByDataTests = []removeOpcodeByDataTest{
removeOpcodeByDataTest{
name: "nothing to do",
before: []byte{btcscript.OP_NOP},
remove: []byte{1, 2, 3, 4},
after: []byte{btcscript.OP_NOP},
},
removeOpcodeByDataTest{
name: "simple case",
before: []byte{btcscript.OP_DATA_4, 1, 2, 3, 4},
remove: []byte{1, 2, 3, 4},
after: []byte{},
},
removeOpcodeByDataTest{
name: "simple case (miss)",
before: []byte{btcscript.OP_DATA_4, 1, 2, 3, 4},
remove: []byte{1, 2, 3, 5},
after: []byte{btcscript.OP_DATA_4, 1, 2, 3, 4},
},
removeOpcodeByDataTest{
name: "simple case (pushdata1)",
before: []byte{btcscript.OP_PUSHDATA1, 4, 1, 2, 3, 4},
remove: []byte{1, 2, 3, 4},
after: []byte{},
},
removeOpcodeByDataTest{
name: "simple case (pushdata1 miss)",
before: []byte{btcscript.OP_PUSHDATA1, 4, 1, 2, 3, 4},
remove: []byte{1, 2, 3, 5},
after: []byte{btcscript.OP_PUSHDATA1, 4, 1, 2, 3, 4},
},
removeOpcodeByDataTest{
name: "simple case (pushdata2)",
before: []byte{btcscript.OP_PUSHDATA2, 4, 0, 1, 2, 3, 4},
remove: []byte{1, 2, 3, 4},
after: []byte{},
},
removeOpcodeByDataTest{
name: "simple case (pushdata2 miss)",
before: []byte{btcscript.OP_PUSHDATA2, 4, 0, 1, 2, 3, 4},
remove: []byte{1, 2, 3, 5},
after: []byte{btcscript.OP_PUSHDATA2, 4, 0, 1, 2, 3, 4},
},
removeOpcodeByDataTest{
name: "simple case (pushdata4)",
before: []byte{btcscript.OP_PUSHDATA4, 4, 0, 0, 0, 1, 2, 3, 4},
remove: []byte{1, 2, 3, 4},
after: []byte{},
},
removeOpcodeByDataTest{
name: "simple case (pushdata4 miss)",
before: []byte{btcscript.OP_PUSHDATA4, 4, 0, 0, 0, 1, 2, 3, 4},
remove: []byte{1, 2, 3, 4, 5},
after: []byte{btcscript.OP_PUSHDATA4, 4, 0, 0, 0, 1, 2, 3, 4},
},
removeOpcodeByDataTest{
name: "invalid opcode ",
before: []byte{187},
remove: []byte{1, 2, 3, 4},
err: btcscript.StackErrInvalidOpcode,
},
removeOpcodeByDataTest{
name: "invalid length (instruction)",
before: []byte{btcscript.OP_PUSHDATA1},
remove: []byte{1, 2, 3, 4},
err: btcscript.StackErrShortScript,
},
removeOpcodeByDataTest{
name: "invalid length (data)",
before: []byte{btcscript.OP_PUSHDATA1, 255, 254},
remove: []byte{1, 2, 3, 4},
err: btcscript.StackErrShortScript,
},
}
func testRemoveOpcodeByData(t *testing.T, test *removeOpcodeByDataTest) {
result, err := btcscript.TstRemoveOpcodeByData(test.before,
test.remove)
if test.err != nil {
if err != test.err {
t.Errorf("%s: got unexpected error. exp: \"%v\" "+
"got: \"%v\"", test.name, test.err, err)
}
return
}
if err != nil {
t.Errorf("%s: unexpected failure: \"%v\"", test.name, err)
return
}
if !bytes.Equal(test.after, result) {
t.Errorf("%s: value does not equal expected: exp: \"%v\""+
" got: \"%v\"", test.name, test.after, result)
}
}
func TestRemoveOpcodeByDatas(t *testing.T) {
for i := range removeOpcodeByDataTests {
testRemoveOpcodeByData(t, &removeOpcodeByDataTests[i])
}
}
// Tests for the script type logic
type scriptTypeTest struct {
name string
script []byte
scripttype btcscript.TstScriptType
}
var scriptTypeTests = []scriptTypeTest{
// tx 0437cd7f8525ceed2324359c2d0ba26006d92d85.
scriptTypeTest{
name: "Pay Pubkey",
script: []byte{
btcscript.OP_DATA_65,
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01,
0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6,
0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7,
0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea,
0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64, 0xf8,
0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9, 0xd4,
0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56, 0xb4,
0x12, 0xa3,
btcscript.OP_CHECKSIG,
},
scripttype: btcscript.TstPubKeyTy,
},
// tx 599e47a8114fe098103663029548811d2651991b62397e057f0c863c2bc9f9ea
scriptTypeTest{
name: "Pay PubkeyHash",
script: []byte{
btcscript.OP_DUP,
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x66, 0x0d, 0x4e, 0xf3, 0xa7, 0x43, 0xe3, 0xe6, 0x96,
0xad, 0x99, 0x03, 0x64, 0xe5, 0x55, 0xc2, 0x71, 0xad,
0x50, 0x4b,
btcscript.OP_EQUALVERIFY,
btcscript.OP_CHECKSIG,
},
scripttype: btcscript.TstPubKeyHashTy,
},
// part of tx 6d36bc17e947ce00bb6f12f8e7a56a1585c5a36188ffa2b05e10b4743273a74b
// codeseparator parts have been elided. (bitcoind's checks for multisig
// type doesn't have codesep etc either.
scriptTypeTest{
name: "multisig",
script: []byte{
btcscript.OP_TRUE,
btcscript.OP_DATA_33,
0x02, 0x32, 0xab, 0xdc, 0x89, 0x3e, 0x7f, 0x06, 0x31,
0x36, 0x4d, 0x7f, 0xd0, 0x1c, 0xb3, 0x3d, 0x24, 0xda,
0x45, 0x32, 0x9a, 0x00, 0x35, 0x7b, 0x3a, 0x78, 0x86,
0x21, 0x1a, 0xb4, 0x14, 0xd5, 0x5a,
btcscript.OP_TRUE,
btcscript.OP_CHECK_MULTISIG,
},
scripttype: btcscript.TstMultiSigTy,
},
// tx e5779b9e78f9650debc2893fd9636d827b26b4ddfa6a8172fe8708c924f5c39d
// P2SH
scriptTypeTest{
name: "P2SH",
script: []byte{
btcscript.OP_HASH160,
btcscript.OP_DATA_20,
0x43, 0x3e, 0xc2, 0xac, 0x1f, 0xfa, 0x1b, 0x7b, 0x7d,
0x02, 0x7f, 0x56, 0x45, 0x29, 0xc5, 0x71, 0x97, 0xf9,
0xae, 0x88,
btcscript.OP_EQUAL,
},
scripttype: btcscript.TstScriptHashTy,
},
}
func testScriptType(t *testing.T, test *scriptTypeTest) {
scripttype := btcscript.TstTypeOfScript(test.script)
if scripttype != test.scripttype {
t.Errorf("%s: expected %s got %s", test.name, test.scripttype,
scripttype)
}
}
func TestScriptTypes(t *testing.T) {
for i := range scriptTypeTests {
testScriptType(t, &scriptTypeTests[i])
}
}
// This test sets the pc to a deliberately bad result then confirms that Step()
// and Disasm fail correctly.
func TestBadPC(t *testing.T) {
type pcTest struct {
script, off int
}
pcTests := []pcTest{
pcTest{
script: 2,
off: 0,
},
pcTest{
script: 0,
off: 2,
},
}
// tx with almost empty scripts.
tx := &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0xc9, 0x97, 0xa5, 0xe5,
0x6e, 0x10, 0x41, 0x02,
0xfa, 0x20, 0x9c, 0x6a,
0x85, 0x2d, 0xd9, 0x06,
0x60, 0xa2, 0x0b, 0x2d,
0x9c, 0x35, 0x24, 0x23,
0xed, 0xce, 0x25, 0x85,
0x7f, 0xcd, 0x37, 0x04,
}),
Index: 0,
},
SignatureScript: []uint8{btcscript.OP_NOP},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000000,
PkScript: []byte{},
},
},
LockTime: 0,
}
pkScript := []byte{btcscript.OP_NOP}
for _, test := range pcTests {
engine, err := btcscript.NewScript(tx.TxIn[0].SignatureScript,
pkScript, 0, tx, 70001, false)
if err != nil {
t.Errorf("Failed to create script: %v", err)
}
// set to after all scripts
engine.TstSetPC(test.script, test.off)
_, err = engine.Step()
if err == nil {
t.Errorf("Step with invalid pc (%v) succeeds!", test)
continue
}
_, err = engine.DisasmPC()
if err == nil {
t.Errorf("DisasmPC with invalid pc (%v) succeeds!",
test)
}
}
}
// Most codepaths in CheckErrorCondition() are testd elsewhere, this tests
// the execute early test.
func TestCheckErrorCondition(t *testing.T) {
// tx with almost empty scripts.
tx := &btcwire.MsgTx{
Version: 1,
TxIn: []*btcwire.TxIn{
&btcwire.TxIn{
PreviousOutpoint: btcwire.OutPoint{
Hash: btcwire.ShaHash([32]byte{
0xc9, 0x97, 0xa5, 0xe5,
0x6e, 0x10, 0x41, 0x02,
0xfa, 0x20, 0x9c, 0x6a,
0x85, 0x2d, 0xd9, 0x06,
0x60, 0xa2, 0x0b, 0x2d,
0x9c, 0x35, 0x24, 0x23,
0xed, 0xce, 0x25, 0x85,
0x7f, 0xcd, 0x37, 0x04,
}),
Index: 0,
},
SignatureScript: []uint8{},
Sequence: 4294967295,
},
},
TxOut: []*btcwire.TxOut{
&btcwire.TxOut{
Value: 1000000000,
PkScript: []byte{},
},
},
LockTime: 0,
}
pkScript := []byte{
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_NOP,
btcscript.OP_TRUE,
}
engine, err := btcscript.NewScript(tx.TxIn[0].SignatureScript, pkScript,
0, tx, 70001, false)
if err != nil {
t.Errorf("failed to create script: %v", err)
}
for i := 0; i < len(pkScript)-1; i++ {
done, err := engine.Step()
if err != nil {
t.Errorf("failed to step %dth time: %v", i, err)
return
}
if done {
t.Errorf("finshed early on %dth time", i)
return
}
err = engine.CheckErrorCondition()
if err != btcscript.StackErrScriptUnfinished {
t.Errorf("got unexepected error %v on %dth iteration",
err, i)
return
}
}
done, err := engine.Step()
if err != nil {
t.Errorf("final step failed %v", err)
return
}
if !done {
t.Errorf("final step isn't done!")
return
}
err = engine.CheckErrorCondition()
if err != nil {
t.Errorf("unexpected error %v on final check", err)
}
}