diff --git a/internal_test.go b/internal_test.go index d957ebb8..fb0d47d3 100644 --- a/internal_test.go +++ b/internal_test.go @@ -5,6 +5,9 @@ package btcscript import ( + "crypto/ecdsa" + "github.com/conformal/btcwire" + "io" "testing" ) @@ -17,7 +20,7 @@ func TstRemoveOpcode(pkscript []byte, opcode byte) ([]byte, error) { return nil, err } pops = removeOpcode(pops, opcode) - return unparseScript(pops), nil + return unparseScript(pops) } func TstRemoveOpcodeByData(pkscript []byte, data []byte) ([]byte, error) { @@ -26,7 +29,7 @@ func TstRemoveOpcodeByData(pkscript []byte, data []byte) ([]byte, error) { return nil, err } pops = removeOpcodeByData(pops, data) - return unparseScript(pops), nil + return unparseScript(pops) } // TestSetPC allows the test modules to set the program counter to whatever they @@ -36,6 +39,16 @@ func (s *Script) TstSetPC(script, off int) { s.scriptoff = off } +// TstSignatureScriptCustomReader allows the test modules to test the internal +// function signatureScriptCustomReader. +func TstSignatureScriptCustomReader(reader io.Reader, tx *btcwire.MsgTx, idx int, + subscript []byte, hashType byte, privkey *ecdsa.PrivateKey, + compress bool) ([]byte, error) { + + return signatureScriptCustomReader(reader, tx, idx, subscript, + hashType, privkey, compress) +} + // Tests for internal error cases in ScriptToAddress. // We pass bad format definitions to ScriptToAddrss to make sure the internal // checks work correctly. This is located in internal_test.go and not address.go @@ -117,3 +130,3654 @@ func TestParseOpcode(t *testing.T) { t.Errorf("no error with dodgy opcode map!") } } + +type popTest struct { + name string + pop *parsedOpcode + expectedErr error +} + +var popTests = []popTest{ + popTest{ + name: "OP_FALSE", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_FALSE], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_FALSE long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_FALSE], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_1 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_1], + data: nil, + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_1", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_1], + data: make([]byte, 1), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_1 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_1], + data: make([]byte, 2), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_2 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_2], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_2", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_2], + data: make([]byte, 2), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_2 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_2], + data: make([]byte, 3), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_3 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_3], + data: make([]byte, 2), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_3", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_3], + data: make([]byte, 3), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_3 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_3], + data: make([]byte, 4), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_4 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_4], + data: make([]byte, 3), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_4", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_4], + data: make([]byte, 4), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_4 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_4], + data: make([]byte, 5), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_5 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_5], + data: make([]byte, 4), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_5", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_5], + data: make([]byte, 5), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_5 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_5], + data: make([]byte, 6), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_6 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_6], + data: make([]byte, 5), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_6", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_6], + data: make([]byte, 6), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_6 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_6], + data: make([]byte, 7), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_7 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_7], + data: make([]byte, 6), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_7", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_7], + data: make([]byte, 7), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_7 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_7], + data: make([]byte, 8), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_8 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_8], + data: make([]byte, 7), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_8", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_8], + data: make([]byte, 8), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_8 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_8], + data: make([]byte, 9), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_9 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_9], + data: make([]byte, 8), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_9", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_9], + data: make([]byte, 9), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_9 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_9], + data: make([]byte, 10), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_10 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_10], + data: make([]byte, 9), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_10", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_10], + data: make([]byte, 10), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_10 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_10], + data: make([]byte, 11), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_11 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_11], + data: make([]byte, 10), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_11", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_11], + data: make([]byte, 11), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_11 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_11], + data: make([]byte, 12), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_12 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_12], + data: make([]byte, 11), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_12", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_12], + data: make([]byte, 12), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_12 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_12], + data: make([]byte, 13), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_13 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_13], + data: make([]byte, 12), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_13", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_13], + data: make([]byte, 13), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_13 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_13], + data: make([]byte, 14), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_14 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_14], + data: make([]byte, 13), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_14", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_14], + data: make([]byte, 14), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_14 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_14], + data: make([]byte, 15), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_15 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_15], + data: make([]byte, 14), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_15", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_15], + data: make([]byte, 15), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_15 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_15], + data: make([]byte, 16), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_16 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_16], + data: make([]byte, 15), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_16", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_16], + data: make([]byte, 16), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_16 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_16], + data: make([]byte, 17), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_17 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_17], + data: make([]byte, 16), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_17", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_17], + data: make([]byte, 17), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_17 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_17], + data: make([]byte, 18), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_18 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_18], + data: make([]byte, 17), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_18", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_18], + data: make([]byte, 18), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_18 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_18], + data: make([]byte, 19), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_19 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_19], + data: make([]byte, 18), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_19", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_19], + data: make([]byte, 19), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_19 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_19], + data: make([]byte, 20), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_20 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_20], + data: make([]byte, 19), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_20", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_20], + data: make([]byte, 20), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_20 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_20], + data: make([]byte, 21), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_21 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_21], + data: make([]byte, 20), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_21", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_21], + data: make([]byte, 21), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_21 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_21], + data: make([]byte, 22), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_22 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_22], + data: make([]byte, 21), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_22", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_22], + data: make([]byte, 22), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_22 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_22], + data: make([]byte, 23), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_23 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_23], + data: make([]byte, 22), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_23", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_23], + data: make([]byte, 23), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_23 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_23], + data: make([]byte, 24), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_24 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_24], + data: make([]byte, 23), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_24", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_24], + data: make([]byte, 24), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_24 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_24], + data: make([]byte, 25), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_25 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_25], + data: make([]byte, 24), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_25", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_25], + data: make([]byte, 25), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_25 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_25], + data: make([]byte, 26), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_26 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_26], + data: make([]byte, 25), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_26", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_26], + data: make([]byte, 26), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_26 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_26], + data: make([]byte, 27), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_27 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_27], + data: make([]byte, 26), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_27", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_27], + data: make([]byte, 27), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_27 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_27], + data: make([]byte, 28), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_28 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_28], + data: make([]byte, 27), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_28", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_28], + data: make([]byte, 28), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_28 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_28], + data: make([]byte, 29), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_29 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_29], + data: make([]byte, 28), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_29", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_29], + data: make([]byte, 29), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_29 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_29], + data: make([]byte, 30), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_30 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_30], + data: make([]byte, 29), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_30", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_30], + data: make([]byte, 30), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_30 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_30], + data: make([]byte, 31), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_31 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_31], + data: make([]byte, 30), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_31", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_31], + data: make([]byte, 31), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_31 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_31], + data: make([]byte, 32), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_32 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_32], + data: make([]byte, 31), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_32", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_32], + data: make([]byte, 32), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_32 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_32], + data: make([]byte, 33), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_33 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_33], + data: make([]byte, 32), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_33", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_33], + data: make([]byte, 33), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_33 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_33], + data: make([]byte, 34), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_34 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_34], + data: make([]byte, 33), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_34", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_34], + data: make([]byte, 34), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_34 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_34], + data: make([]byte, 35), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_35 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_35], + data: make([]byte, 34), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_35", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_35], + data: make([]byte, 35), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_35 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_35], + data: make([]byte, 36), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_36 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_36], + data: make([]byte, 35), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_36", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_36], + data: make([]byte, 36), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_36 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_36], + data: make([]byte, 37), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_37 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_37], + data: make([]byte, 36), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_37", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_37], + data: make([]byte, 37), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_37 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_37], + data: make([]byte, 38), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_38 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_38], + data: make([]byte, 37), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_38", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_38], + data: make([]byte, 38), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_38 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_38], + data: make([]byte, 39), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_39 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_39], + data: make([]byte, 38), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_39", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_39], + data: make([]byte, 39), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_39 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_39], + data: make([]byte, 40), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_40 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_40], + data: make([]byte, 39), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_40", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_40], + data: make([]byte, 40), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_40 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_40], + data: make([]byte, 41), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_41 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_41], + data: make([]byte, 40), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_41", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_41], + data: make([]byte, 41), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_41 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_41], + data: make([]byte, 42), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_42 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_42], + data: make([]byte, 41), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_42", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_42], + data: make([]byte, 42), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_42 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_42], + data: make([]byte, 43), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_43 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_43], + data: make([]byte, 42), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_43", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_43], + data: make([]byte, 43), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_43 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_43], + data: make([]byte, 44), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_44 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_44], + data: make([]byte, 43), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_44", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_44], + data: make([]byte, 44), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_44 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_44], + data: make([]byte, 45), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_45 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_45], + data: make([]byte, 44), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_45", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_45], + data: make([]byte, 45), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_45 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_45], + data: make([]byte, 46), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_46 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_46], + data: make([]byte, 45), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_46", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_46], + data: make([]byte, 46), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_46 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_46], + data: make([]byte, 47), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_47 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_47], + data: make([]byte, 46), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_47", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_47], + data: make([]byte, 47), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_47 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_47], + data: make([]byte, 48), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_48 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_48], + data: make([]byte, 47), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_48", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_48], + data: make([]byte, 48), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_48 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_48], + data: make([]byte, 49), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_49 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_49], + data: make([]byte, 48), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_49", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_49], + data: make([]byte, 49), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_49 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_49], + data: make([]byte, 50), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_50 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_50], + data: make([]byte, 49), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_50", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_50], + data: make([]byte, 50), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_50 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_50], + data: make([]byte, 51), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_51 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_51], + data: make([]byte, 50), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_51", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_51], + data: make([]byte, 51), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_51 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_51], + data: make([]byte, 52), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_52 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_52], + data: make([]byte, 51), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_52", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_52], + data: make([]byte, 52), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_52 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_52], + data: make([]byte, 53), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_53 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_53], + data: make([]byte, 52), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_53", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_53], + data: make([]byte, 53), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_53 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_53], + data: make([]byte, 54), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_54 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_54], + data: make([]byte, 53), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_54", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_54], + data: make([]byte, 54), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_54 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_54], + data: make([]byte, 55), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_55 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_55], + data: make([]byte, 54), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_55", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_55], + data: make([]byte, 55), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_55 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_55], + data: make([]byte, 56), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_56 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_56], + data: make([]byte, 55), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_56", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_56], + data: make([]byte, 56), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_56 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_56], + data: make([]byte, 57), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_57 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_57], + data: make([]byte, 56), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_57", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_57], + data: make([]byte, 57), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_57 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_57], + data: make([]byte, 58), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_58 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_58], + data: make([]byte, 57), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_58", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_58], + data: make([]byte, 58), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_58 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_58], + data: make([]byte, 59), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_59 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_59], + data: make([]byte, 58), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_59", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_59], + data: make([]byte, 59), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_59 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_59], + data: make([]byte, 60), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_60 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_60], + data: make([]byte, 59), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_60", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_60], + data: make([]byte, 60), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_60 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_60], + data: make([]byte, 61), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_61 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_61], + data: make([]byte, 60), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_61", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_61], + data: make([]byte, 61), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_61 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_61], + data: make([]byte, 62), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_62 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_62], + data: make([]byte, 61), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_62", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_62], + data: make([]byte, 62), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_62 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_62], + data: make([]byte, 63), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_63 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_63], + data: make([]byte, 62), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_63", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_63], + data: make([]byte, 63), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_63 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_63], + data: make([]byte, 64), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_64 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_64], + data: make([]byte, 63), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_64", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_64], + data: make([]byte, 64), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_64 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_64], + data: make([]byte, 65), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_65 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_65], + data: make([]byte, 64), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_65", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_65], + data: make([]byte, 65), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_65 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_65], + data: make([]byte, 66), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_66 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_66], + data: make([]byte, 65), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_66", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_66], + data: make([]byte, 66), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_66 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_66], + data: make([]byte, 67), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_67 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_67], + data: make([]byte, 66), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_67", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_67], + data: make([]byte, 67), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_67 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_67], + data: make([]byte, 68), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_68 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_68], + data: make([]byte, 67), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_68", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_68], + data: make([]byte, 68), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_68 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_68], + data: make([]byte, 69), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_69 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_69], + data: make([]byte, 68), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_69", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_69], + data: make([]byte, 69), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_69 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_69], + data: make([]byte, 70), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_70 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_70], + data: make([]byte, 69), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_70", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_70], + data: make([]byte, 70), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_70 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_70], + data: make([]byte, 71), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_71 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_71], + data: make([]byte, 70), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_71", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_71], + data: make([]byte, 71), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_71 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_71], + data: make([]byte, 72), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_72 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_72], + data: make([]byte, 71), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_72", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_72], + data: make([]byte, 72), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_72 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_72], + data: make([]byte, 73), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_73 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_73], + data: make([]byte, 72), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_73", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_73], + data: make([]byte, 73), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_73 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_73], + data: make([]byte, 74), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_74 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_74], + data: make([]byte, 73), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_74", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_74], + data: make([]byte, 74), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_74 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_74], + data: make([]byte, 75), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_75 short", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_75], + data: make([]byte, 74), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DATA_75", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_75], + data: make([]byte, 75), + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DATA_75 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DATA_75], + data: make([]byte, 76), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_PUSHDATA1", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PUSHDATA1], + data: []byte{0, 1, 2, 3, 4}, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_PUSHDATA2", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PUSHDATA2], + data: []byte{0, 1, 2, 3, 4}, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_PUSHDATA4", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PUSHDATA1], + data: []byte{0, 1, 2, 3, 4}, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_1NEGATE", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_1NEGATE], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_1NEGATE long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_1NEGATE], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_RESERVED", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RESERVED], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_RESERVED long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RESERVED], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_TRUE", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_TRUE], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_TRUE long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_TRUE], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_3", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_3], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_3 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_3], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_4", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_4], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_4 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_4], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_5", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_5], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_5 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_5], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_6", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_6], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_6 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_6], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_7", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_7], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_7 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_7], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_8", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_8], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_8 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_8], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_9", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_9], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_9 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_9], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_10", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_10], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_10 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_10], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_11", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_11], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_11 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_11], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_12", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_12], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_12 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_12], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_13", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_13], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_13 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_13], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_14", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_14], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_14 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_14], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_15", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_15], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_15 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_15], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_16", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_16], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_16 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_16], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_VER", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_VER], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_VER long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_VER], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_IF", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_IF], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_IF long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_IF], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOTIF", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOTIF], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOTIF long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOTIF], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_VERIF", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_VERIF], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_VERIF long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_VERIF], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_VERNOTIF", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_VERNOTIF], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_VERNOTIF long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_VERNOTIF], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_ELSE", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ELSE], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_ELSE long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ELSE], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_ENDIF", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ENDIF], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_ENDIF long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ENDIF], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_VERIFY", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_VERIFY], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_VERIFY long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_VERIFY], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_RETURN", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RETURN], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_RETURN long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RETURN], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_TOALTSTACK", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_TOALTSTACK], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_TOALTSTACK long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_TOALTSTACK], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_FROMALTSTACK", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_FROMALTSTACK], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_FROMALTSTACK long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_FROMALTSTACK], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2DROP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2DROP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2DROP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2DROP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2DUP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2DUP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2DUP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2DUP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_3DUP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_3DUP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_3DUP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_3DUP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2OVER", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2OVER], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2OVER long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2OVER], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2ROT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2ROT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2ROT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2ROT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2SWAP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2SWAP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2SWAP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2SWAP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_IFDUP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_IFDUP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_IFDUP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_IFDUP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DEPTH", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DEPTH], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DEPTH long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DEPTH], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DROP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DROP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DROP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DROP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DUP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DUP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DUP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DUP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NIP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NIP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NIP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NIP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_OVER", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_OVER], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_OVER long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_OVER], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_PICK", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PICK], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_PICK long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PICK], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_ROLL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ROLL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_ROLL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ROLL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_ROT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ROT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_ROT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ROT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_SWAP", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SWAP], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_SWAP long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SWAP], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_TUCK", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_TUCK], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_TUCK long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_TUCK], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_CAT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CAT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_CAT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CAT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_SUBSTR", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SUBSTR], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_SUBSTR long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SUBSTR], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_LEFT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LEFT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_LEFT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LEFT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_LEFT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LEFT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_LEFT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LEFT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_RIGHT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RIGHT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_RIGHT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RIGHT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_SIZE", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SIZE], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_SIZE long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SIZE], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_INVERT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_INVERT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_INVERT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_INVERT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_AND", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_AND], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_AND long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_AND], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_OR", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_OR], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_OR long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_OR], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_XOR", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_XOR], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_XOR long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_XOR], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_EQUAL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_EQUAL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_EQUAL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_EQUAL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_EQUALVERIFY", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_EQUALVERIFY], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_EQUALVERIFY long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_EQUALVERIFY], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_RESERVED1", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RESERVED1], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_RESERVED1 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RESERVED1], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_RESERVED2", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RESERVED2], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_RESERVED2 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RESERVED2], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_1ADD", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_1ADD], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_1ADD long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_1ADD], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_1SUB", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_1SUB], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_1SUB long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_1SUB], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2MUL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2MUL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2MUL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2MUL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_2DIV", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2DIV], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_2DIV long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_2DIV], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NEGATE", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NEGATE], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NEGATE long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NEGATE], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_ABS", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ABS], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_ABS long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ABS], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_0NOTEQUAL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_0NOTEQUAL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_0NOTEQUAL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_0NOTEQUAL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_ADD", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ADD], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_ADD long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_ADD], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_SUB", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SUB], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_SUB long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SUB], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_MUL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_MUL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_MUL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_MUL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_DIV", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DIV], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_DIV long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_DIV], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_MOD", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_MOD], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_MOD long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_MOD], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_LSHIFT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LSHIFT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_LSHIFT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LSHIFT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_RSHIFT", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RSHIFT], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_RSHIFT long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RSHIFT], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_BOOLAND", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_BOOLAND], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_BOOLAND long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_BOOLAND], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_BOOLOR", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_BOOLOR], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_BOOLOR long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_BOOLOR], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NUMEQUAL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NUMEQUAL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NUMEQUAL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NUMEQUAL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NUMEQUALVERIFY", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NUMEQUALVERIFY], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NUMEQUALVERIFY long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NUMEQUALVERIFY], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NUMNOTEQUAL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NUMNOTEQUAL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NUMNOTEQUAL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NUMNOTEQUAL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_LESSTHAN", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LESSTHAN], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_LESSTHAN long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LESSTHAN], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_GREATERTHAN", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_GREATERTHAN], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_GREATERTHAN long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_GREATERTHAN], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_LESSTHANOREQUAL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LESSTHANOREQUAL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_LESSTHANOREQUAL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_LESSTHANOREQUAL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_GREATERTHANOREQUAL", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_GREATERTHANOREQUAL], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_GREATERTHANOREQUAL long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_GREATERTHANOREQUAL], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_MIN", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_MIN], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_MIN long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_MIN], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_MAX", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_MAX], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_MAX long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_MAX], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_WITHIN", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_WITHIN], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_WITHIN long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_WITHIN], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_RIPEMD160", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RIPEMD160], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_RIPEMD160 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_RIPEMD160], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_SHA1", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SHA1], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_SHA1 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SHA1], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_SHA256", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SHA256], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_SHA256 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_SHA256], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_HASH160", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_HASH160], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_HASH160 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_HASH160], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_HASH256", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_HASH256], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_HASH256 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_HASH256], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_CODESAPERATOR", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CODESEPARATOR], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_CODESEPARATOR long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CODESEPARATOR], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_CHECKSIG", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CHECKSIG], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_CHECKSIG long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CHECKSIG], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_CHECKSIGVERIFY", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CHECKSIGVERIFY], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_CHECKSIGVERIFY long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CHECKSIGVERIFY], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_CHECK_MULTISIG", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CHECK_MULTISIG], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_CHECK_MULTISIG long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CHECK_MULTISIG], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_CHECKMULTISIGVERIFY", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CHECKMULTISIGVERIFY], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_CHECKMULTISIGVERIFY long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_CHECKMULTISIGVERIFY], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP1", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP1], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP1 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP1], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP2", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP2], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP2 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP2], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP3", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP3], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP3 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP3], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP4", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP4], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP4 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP4], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP5", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP5], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP5 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP5], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP6", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP6], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP6 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP6], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP7", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP7], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP7 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP7], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP8", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP8], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP8 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP8], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP9", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP9], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP9 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP9], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_NOP10", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP10], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_NOP10 long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_NOP10], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_PUBKEYHASH", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PUBKEYHASH], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_PUBKEYHASH long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PUBKEYHASH], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_PUBKEY", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PUBKEY], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_PUBKEY long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_PUBKEY], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, + popTest{ + name: "OP_INVALIDOPCODE", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_INVALIDOPCODE], + data: nil, + }, + expectedErr: nil, + }, + popTest{ + name: "OP_INVALIDOPCODE long", + pop: &parsedOpcode{ + opcode: opcodemapPreinit[OP_INVALIDOPCODE], + data: make([]byte, 1), + }, + expectedErr: StackErrInvalidOpcode, + }, +} + +func TestUnparsingInvalidOpcodes(t *testing.T) { + for _, test := range popTests { + _, err := test.pop.bytes() + if err != test.expectedErr { + t.Errorf("Parsed Opcode test '%s' failed", test.name) + t.Error(err, test.expectedErr) + } + } +} diff --git a/opcode.go b/opcode.go index 2fcbd9fb..83c496f3 100644 --- a/opcode.go +++ b/opcode.go @@ -10,6 +10,7 @@ import ( "crypto/ecdsa" "crypto/sha1" "crypto/sha256" + "encoding/binary" "fmt" "github.com/conformal/btcec" "github.com/conformal/btcwire" @@ -687,36 +688,51 @@ func (pop *parsedOpcode) print(oneline bool) string { return retString } -func (pop *parsedOpcode) bytes() []byte { +func (pop *parsedOpcode) bytes() ([]byte, error) { var retbytes []byte if pop.opcode.length > 0 { retbytes = make([]byte, 1, pop.opcode.length) } else { - retbytes = make([]byte, 1, 1 + len(pop.data) - + retbytes = make([]byte, 1, 1+len(pop.data)- pop.opcode.length) } retbytes[0] = pop.opcode.value if pop.opcode.length == 1 { - return retbytes + if len(pop.data) != 0 { + return nil, StackErrInvalidOpcode + } + return retbytes, nil } + nbytes := pop.opcode.length if pop.opcode.length < 0 { l := len(pop.data) // tempting just to hardcode to avoid the complexity here. switch pop.opcode.length { case -1: retbytes = append(retbytes, byte(l)) + nbytes = int(retbytes[1]) + len(retbytes) case -2: retbytes = append(retbytes, byte(l&0xff), byte(l>>8&0xff)) + nbytes = int(binary.LittleEndian.Uint16(retbytes[1:])) + + len(retbytes) case -4: retbytes = append(retbytes, byte(l&0xff), byte((l>>8)&0xff), byte((l>>16)&0xff), byte((l>>24)&0xff)) + nbytes = int(binary.LittleEndian.Uint32(retbytes[1:])) + + len(retbytes) } } - return append(retbytes, pop.data...) + retbytes = append(retbytes, pop.data...) + + if len(retbytes) != nbytes { + return nil, StackErrInvalidOpcode + } + + return retbytes, nil } // opcode implementation functions from here @@ -840,7 +856,7 @@ func opcodeEndif(op *parsedOpcode, s *Script) error { return StackErrNoIf } - stk := make([]int, len(s.condStack) -1, len(s.condStack) -1) + stk := make([]int, len(s.condStack)-1, len(s.condStack)-1) copy(stk, s.condStack[1:]) s.condStack = stk return nil @@ -1457,7 +1473,7 @@ func opcodeCheckSig(op *parsedOpcode, s *Script) error { // the script if present. subScript = removeOpcodeByData(subScript, sigStr) - hash := s.calcScriptHash(subScript, hashType) + hash := calcScriptHash(subScript, hashType, &s.tx, s.txidx) pubKey, err := btcec.ParsePubKey(pkStr, btcec.S256()) if err != nil { @@ -1576,7 +1592,7 @@ func opcodeCheckMultiSig(op *parsedOpcode, s *Script) error { // get hashtype from original byte string hashType := sigStrings[i][len(sigStrings[i])-1] - hash := s.calcScriptHash(script, hashType) + hash := calcScriptHash(script, hashType, &s.tx, s.txidx) inner: // Find first pubkey that successfully validates signature. // we start off the search from the key that was successful diff --git a/script.go b/script.go index a4189637..86ae9198 100644 --- a/script.go +++ b/script.go @@ -6,11 +6,16 @@ package btcscript import ( "bytes" + "crypto/ecdsa" + "crypto/rand" "encoding/binary" "errors" "fmt" + "github.com/conformal/btcec" "github.com/conformal/btcwire" "github.com/davecgh/go-spew/spew" + "io" + "math/big" "time" ) @@ -338,12 +343,16 @@ func parseScriptTemplate(script []byte, opcodemap map[byte]*opcode) ([]parsedOpc // unparseScript reversed the action of parseScript and returns the // parsedOpcodes as a list of bytes -func unparseScript(pops []parsedOpcode) []byte { +func unparseScript(pops []parsedOpcode) ([]byte, error) { script := make([]byte, 0, len(pops)) for _, pop := range pops { - script = append(script, pop.bytes()...) + b, err := pop.bytes() + if err != nil { + return nil, err + } + script = append(script, b...) } - return script + return script, nil } // NewScript returns a new script engine for the provided tx and input idx with @@ -625,22 +634,23 @@ func DisasmString(buf []byte) (string, error) { // calcScriptHash will, given the a script and hashtype for the current // scriptmachine, calculate the doubleSha256 hash of the transaction and // script to be used for signature signing and verification. -func (s *Script) calcScriptHash(script []parsedOpcode, hashType byte) []byte { +func calcScriptHash(script []parsedOpcode, hashType byte, tx *btcwire.MsgTx, idx int) []byte { // remove all instances of OP_CODESEPARATOR still left in the script script = removeOpcode(script, OP_CODESEPARATOR) // Make a deep copy of the transaction, zeroing out the script // for all inputs that are not currently being processed. - txCopy := s.tx.Copy() - txidx := s.txidx + txCopy := tx.Copy() for i := range txCopy.TxIn { var txIn btcwire.TxIn txIn = *txCopy.TxIn[i] txCopy.TxIn[i] = &txIn - if i == txidx { - txCopy.TxIn[txidx].SignatureScript = - unparseScript(script) + if i == idx { + // unparseScript cannot fail here, because removeOpcode + // above only returns a valid script. + sigscript, _ := unparseScript(script) + txCopy.TxIn[idx].SignatureScript = sigscript } else { txCopy.TxIn[i].SignatureScript = []byte{} } @@ -656,12 +666,12 @@ func (s *Script) calcScriptHash(script []parsedOpcode, hashType byte) []byte { case SigHashNone: txCopy.TxOut = txCopy.TxOut[0:0] // empty slice for i := range txCopy.TxIn { - if i != txidx { + if i != idx { txCopy.TxIn[i].Sequence = 0 } } case SigHashSingle: - if txidx >= len(txCopy.TxOut) { + if idx >= len(txCopy.TxOut) { // This was created by a buggy implementation. // In this case we do the same as bitcoind and bitcoinj // and return 1 (as a uint256 little endian) as an @@ -673,15 +683,15 @@ func (s *Script) calcScriptHash(script []parsedOpcode, hashType byte) []byte { return hash } // Resize output array to up to and including requested index. - txCopy.TxOut = txCopy.TxOut[:txidx+1] + txCopy.TxOut = txCopy.TxOut[:idx+1] // all but current output get zeroed out - for i := 0; i < txidx; i++ { + for i := 0; i < idx; i++ { txCopy.TxOut[i].Value = -1 txCopy.TxOut[i].PkScript = []byte{} } // Sequence on all other inputs is 0, too. for i := range txCopy.TxIn { - if i != txidx { + if i != idx { txCopy.TxIn[i].Sequence = 0 } } @@ -695,8 +705,8 @@ func (s *Script) calcScriptHash(script []parsedOpcode, hashType byte) []byte { // nothing special here } if hashType&SigHashAnyOneCanPay != 0 { - txCopy.TxIn = txCopy.TxIn[s.txidx : s.txidx+1] - txidx = 0 + txCopy.TxIn = txCopy.TxIn[idx : idx+1] + idx = 0 } var wbuf bytes.Buffer @@ -861,3 +871,105 @@ func getSigOpCount(pops []parsedOpcode, precise bool) int { return nSigs } + +// PayToPubKeyHashScript creates a new script to pay a transaction +// output to a 20-byte pubkey hash. +func PayToPubKeyHashScript(pubKeyHash []byte) (pkScript []byte, err error) { + pops := []parsedOpcode{ + parsedOpcode{ + opcode: opcodemap[OP_DUP], + }, + parsedOpcode{ + opcode: opcodemap[OP_HASH160], + }, + parsedOpcode{ + opcode: opcodemap[OP_DATA_20], + data: pubKeyHash, + }, + parsedOpcode{ + opcode: opcodemap[OP_EQUALVERIFY], + }, + parsedOpcode{ + opcode: opcodemap[OP_CHECKSIG], + }, + } + return unparseScript(pops) +} + +// SignatureScript creates an input signature script for tx to spend +// BTC sent from a previous output to the owner of privkey. tx must +// include all transaction inputs and outputs, however txin scripts are +// allowed to be filled or empty. The returned script is calculated to +// be used as the idx'th txin sigscript for tx. subscript is the PkScript +// of the previous output being used as the idx'th input. privkey is +// serialized in either a compressed or uncompressed format based on +// compress. This format must match the same format used to generate +// the payment address, or the script validation will fail. +func SignatureScript(tx *btcwire.MsgTx, idx int, subscript []byte, hashType byte, privkey *ecdsa.PrivateKey, compress bool) ([]byte, error) { + + return signatureScriptCustomReader(rand.Reader, tx, idx, subscript, + hashType, privkey, compress) +} + +// This function exists so we can test ecdsa.Sign's error for an invalid +// reader. +func signatureScriptCustomReader(reader io.Reader, tx *btcwire.MsgTx, idx int, + subscript []byte, hashType byte, privkey *ecdsa.PrivateKey, + compress bool) ([]byte, error) { + + parsedScript, err := parseScript(subscript) + if err != nil { + return nil, fmt.Errorf("cannot parse output script: %v", err) + } + hash := calcScriptHash(parsedScript, hashType, tx, idx) + r, s, err := ecdsa.Sign(reader, privkey, hash) + if err != nil { + return nil, fmt.Errorf("cannot sign tx input: %s", err) + } + sig := append(sigDER(r, s), hashType) + + pk := (*btcec.PublicKey)(&privkey.PublicKey) + var pubkeyOpcode *parsedOpcode + if compress { + pubkeyOpcode = &parsedOpcode{ + opcode: opcodemap[OP_DATA_33], + data: pk.SerializeCompressed(), + } + } else { + pubkeyOpcode = &parsedOpcode{ + opcode: opcodemap[OP_DATA_65], + data: pk.SerializeUncompressed(), + } + } + pops := []parsedOpcode{ + parsedOpcode{ + opcode: opcodemap[byte(len(sig))], + data: sig, + }, + *pubkeyOpcode, + } + return unparseScript(pops) +} + +// sigDER returns the ECDSA signature r, s in the DER format used by +// signature scripts. The signature does not include the appended hashtype. +// +// encoding/asn1 is broken so we hand roll this output: +// +// 0x30 0x02 r 0x02 s +func sigDER(r, s *big.Int) []byte { + // total length of returned signature is 1 byte for each magic and + // length (6 total), plus lengths of r and s + length := 6 + len(r.Bytes()) + len(s.Bytes()) + b := make([]byte, length, length) + + b[0] = 0x30 + b[1] = byte(length - 2) + b[2] = 0x02 + b[3] = byte(len(r.Bytes())) + offset := copy(b[4:], r.Bytes()) + 4 + b[offset] = 0x02 + b[offset+1] = byte(len(s.Bytes())) + copy(b[offset+2:], s.Bytes()) + return b +} diff --git a/script_test.go b/script_test.go index 5f203792..951ef851 100644 --- a/script_test.go +++ b/script_test.go @@ -6,8 +6,11 @@ package btcscript_test import ( "bytes" + "crypto/ecdsa" + "github.com/conformal/btcec" "github.com/conformal/btcscript" "github.com/conformal/btcwire" + "math/big" "testing" ) @@ -1839,3 +1842,395 @@ func TestCheckErrorCondition(t *testing.T) { t.Errorf("unexpected error %v on final check", err) } } + +func TestPayToPubKeyHashScript(t *testing.T) { + validaddr := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20} + invalidaddr := validaddr[:len(validaddr)-2] + + expected := []byte{btcscript.OP_DUP, btcscript.OP_HASH160, + btcscript.OP_DATA_20, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, btcscript.OP_EQUALVERIFY, + btcscript.OP_CHECKSIG} + + script, err := btcscript.PayToPubKeyHashScript(validaddr) + if err != nil { + t.Error(err) + return + } + if !bytes.Equal(script, expected) { + t.Error("Unexpected script result.") + return + } + + _, err = btcscript.PayToPubKeyHashScript(invalidaddr) + if err == nil { + t.Error("Erroneously created script for invalid address.") + return + } +} + +type TstSigScript struct { + name string + inputs []TstInput + hashtype byte + compress bool + scriptAtWrongIndex bool +} + +type TstInput struct { + txout *btcwire.TxOut + sigscriptGenerates bool + inputValidates bool + indexOutOfRange bool + invalidReader bool +} + +var coinbaseOutPoint = &btcwire.OutPoint{ + Index: (1 << 32) - 1, +} + +// Pregenerated private key, with associated public key and pkScripts +// for the uncompressed and compressed hash160. +var ( + privkeyD = []byte{0x6b, 0x0f, 0xd8, 0xda, 0x54, 0x22, 0xd0, 0xb7, + 0xb4, 0xfc, 0x4e, 0x55, 0xd4, 0x88, 0x42, 0xb3, 0xa1, 0x65, + 0xac, 0x70, 0x7f, 0x3d, 0xa4, 0x39, 0x5e, 0xcb, 0x3b, 0xb0, + 0xd6, 0x0e, 0x06, 0x92} + pubkeyX = []byte{0xb2, 0x52, 0xf0, 0x49, 0x85, 0x78, 0x03, 0x03, 0xc8, + 0x7d, 0xce, 0x51, 0x7f, 0xa8, 0x69, 0x0b, 0x91, 0x95, 0xf4, + 0xf3, 0x5c, 0x26, 0x73, 0x05, 0x05, 0xa2, 0xee, 0xbc, 0x09, + 0x38, 0x34, 0x3a} + pubkeyY = []byte{0xb7, 0xc6, 0x7d, 0xb2, 0xe1, 0xff, 0xc8, 0x43, 0x1f, + 0x63, 0x32, 0x62, 0xaa, 0x60, 0xc6, 0x83, 0x30, 0xbd, 0x24, + 0x7e, 0xef, 0xdb, 0x6f, 0x2e, 0x8d, 0x56, 0xf0, 0x3c, 0x9f, + 0x6d, 0xb6, 0xf8} + uncompressedPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5, + 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32, + 0x53, 0x90, 0x0e, 0x0a, 0x86, 0xc9, 0xfa, 0x88, 0xac} + compressedPkScript = []byte{0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f, + 0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10, + 0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac} + shortPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5, + 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32, + 0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac} + uncompressedAddrStr = "1L6fd93zGmtzkK6CsZFVVoCwzZV3MUtJ4F" + compressedAddrStr = "14apLppt9zTq6cNw8SDfiJhk9PhkZrQtYZ" +) + +// Pretend output amounts. +const coinbaseVal = 2500000000 +const fee = 5000000 + +var SigScriptTests = []TstSigScript{ + TstSigScript{ + name: "one input uncompressed", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: false, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "two inputs uncompressed", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: false, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "one input compressed", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, compressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: true, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "two inputs compressed", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, compressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal+fee, compressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: true, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "hashtype SigHashNone", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashNone, + compress: false, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "hashtype SigHashSingle", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashSingle, + compress: false, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "hashtype SigHashAnyoneCanPay", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAnyOneCanPay, + compress: false, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "hashtype non-standard", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: 0x04, + compress: false, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "invalid compression", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: false, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: true, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "short PkScript", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, shortPkScript), + sigscriptGenerates: false, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: false, + scriptAtWrongIndex: false, + }, + TstSigScript{ + name: "valid script at wrong index", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: false, + scriptAtWrongIndex: true, + }, + TstSigScript{ + name: "index out of range", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), + sigscriptGenerates: true, + inputValidates: true, + indexOutOfRange: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: false, + scriptAtWrongIndex: true, + }, + TstSigScript{ + name: "invalid reader", + inputs: []TstInput{ + TstInput{ + txout: btcwire.NewTxOut(coinbaseVal, uncompressedPkScript), + invalidReader: true, + sigscriptGenerates: false, + }, + }, + hashtype: btcscript.SigHashAll, + compress: false, + scriptAtWrongIndex: true, + }, +} + +// Test the sigscript generation for valid and invalid inputs, all +// hashtypes, and with and without compression. This test creates +// sigscripts to spend fake coinbase inputs, as sigscripts cannot be +// created for the MsgTxs in txTests, since they come from the blockchain +// and we don't have the private keys. +func TestSignatureScript(t *testing.T) { + privkey := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: btcec.S256(), + X: new(big.Int), + Y: new(big.Int), + }, + D: new(big.Int), + } + privkey.D.SetBytes(privkeyD) + privkey.PublicKey.X.SetBytes(pubkeyX) + privkey.PublicKey.Y.SetBytes(pubkeyY) + +nexttest: + for i := range SigScriptTests { + tx := btcwire.NewMsgTx() + + output := btcwire.NewTxOut(500, []byte{btcscript.OP_RETURN}) + tx.AddTxOut(output) + + for _ = range SigScriptTests[i].inputs { + txin := btcwire.NewTxIn(coinbaseOutPoint, nil) + tx.AddTxIn(txin) + } + + var script []byte + var err error + for j := range tx.TxIn { + var idx int + if SigScriptTests[i].inputs[j].indexOutOfRange { + t.Errorf("at test %v", SigScriptTests[i].name) + idx = len(SigScriptTests[i].inputs) + } else { + idx = j + } + if SigScriptTests[i].inputs[j].invalidReader { + script, err = btcscript.TstSignatureScriptCustomReader( + new(bytes.Buffer), tx, idx, + SigScriptTests[i].inputs[j].txout.PkScript, + SigScriptTests[i].hashtype, + privkey, + SigScriptTests[i].compress) + } else { + script, err = btcscript.SignatureScript(tx, idx, + SigScriptTests[i].inputs[j].txout.PkScript, + SigScriptTests[i].hashtype, + privkey, + SigScriptTests[i].compress) + } + + if (err == nil) != SigScriptTests[i].inputs[j].sigscriptGenerates { + if err == nil { + t.Errorf("passed test '%v' incorrectly", + SigScriptTests[i].name) + } else { + t.Errorf("failed test '%v': %v", + SigScriptTests[i].name, err) + } + continue nexttest + } + if !SigScriptTests[i].inputs[j].sigscriptGenerates { + // done with this test + continue nexttest + } + + tx.TxIn[j].SignatureScript = script + } + + // If testing using a correct sigscript but for an incorrect + // index, use last input script for first input. Requires > 0 + // inputs for test. + if SigScriptTests[i].scriptAtWrongIndex { + tx.TxIn[0].SignatureScript = script + SigScriptTests[i].inputs[0].inputValidates = false + } + + // Validate tx input scripts + for j, txin := range tx.TxIn { + engine, err := btcscript.NewScript(txin.SignatureScript, + SigScriptTests[i].inputs[j].txout.PkScript, + j, tx, true) + if err != nil { + t.Errorf("cannot create script vm for test %v: %v", + SigScriptTests[i].name, err) + continue nexttest + } + err = engine.Execute() + if (err == nil) != SigScriptTests[i].inputs[j].inputValidates { + if err == nil { + t.Errorf("passed test '%v' validation incorrectly: %v", + SigScriptTests[i].name, err) + } else { + t.Errorf("failed test '%v' validation: %v", + SigScriptTests[i].name, err) + } + continue nexttest + } + } + } +} diff --git a/stack.go b/stack.go index 656c16a9..ae00f647 100644 --- a/stack.go +++ b/stack.go @@ -173,7 +173,7 @@ func (s *Stack) nipN(idx int) (so []byte, err error) { if idx == 0 { s.stk = s.stk[:sz-1] } else if idx == sz-1 { - s1 := make([][]byte, sz - 1, sz - 1) + s1 := make([][]byte, sz-1, sz-1) copy(s1, s.stk[1:]) s.stk = s1 } else { diff --git a/test_coverage.txt b/test_coverage.txt index 20a56830..8515d055 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -2,67 +2,70 @@ github.com/conformal/btcscript/address.go scriptToAddressTemplate 100.00% (58/58) github.com/conformal/btcscript/script.go Script.Step 100.00% (37/37) github.com/conformal/btcscript/script.go parseScriptTemplate 100.00% (30/30) +github.com/conformal/btcscript/opcode.go parsedOpcode.bytes 100.00% (23/23) github.com/conformal/btcscript/script.go NewScript 100.00% (18/18) github.com/conformal/btcscript/stack.go asInt 100.00% (18/18) +github.com/conformal/btcscript/script.go signatureScriptCustomReader 100.00% (15/15) github.com/conformal/btcscript/stack.go Stack.nipN 100.00% (14/14) github.com/conformal/btcscript/stack.go fromInt 100.00% (14/14) -github.com/conformal/btcscript/opcode.go parsedOpcode.bytes 100.00% (14/14) github.com/conformal/btcscript/script.go isMultiSig 100.00% (13/13) github.com/conformal/btcscript/script.go GetPreciseSigOpCount 100.00% (13/13) github.com/conformal/btcscript/opcode.go opcodeWithin 100.00% (13/13) github.com/conformal/btcscript/opcode.go parsedOpcode.print 100.00% (12/12) -github.com/conformal/btcscript/opcode.go opcodeIf 100.00% (11/11) +github.com/conformal/btcscript/script.go sigDER 100.00% (11/11) github.com/conformal/btcscript/opcode.go opcodeNotIf 100.00% (11/11) +github.com/conformal/btcscript/opcode.go opcodeIf 100.00% (11/11) +github.com/conformal/btcscript/opcode.go opcodeMax 100.00% (10/10) github.com/conformal/btcscript/opcode.go opcodeLessThanOrEqual 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeGreaterThanOrEqual 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeMin 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeGreaterThan 100.00% (10/10) github.com/conformal/btcscript/opcode.go opcodeNumNotEqual 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeLessThan 100.00% (10/10) +github.com/conformal/btcscript/script.go getSigOpCount 100.00% (10/10) +github.com/conformal/btcscript/stack.go Stack.Tuck 100.00% (10/10) github.com/conformal/btcscript/opcode.go opcodeNumEqual 100.00% (10/10) github.com/conformal/btcscript/opcode.go opcodeBoolOr 100.00% (10/10) github.com/conformal/btcscript/opcode.go opcodeBoolAnd 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeLessThan 100.00% (10/10) -github.com/conformal/btcscript/stack.go Stack.Tuck 100.00% (10/10) -github.com/conformal/btcscript/script.go getSigOpCount 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeMin 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeMax 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeGreaterThan 100.00% (10/10) -github.com/conformal/btcscript/stack.go Stack.RotN 100.00% (9/9) -github.com/conformal/btcscript/script.go DisasmString 100.00% (9/9) +github.com/conformal/btcscript/opcode.go opcodeGreaterThanOrEqual 100.00% (10/10) github.com/conformal/btcscript/stack.go Stack.SwapN 100.00% (9/9) +github.com/conformal/btcscript/script.go DisasmString 100.00% (9/9) +github.com/conformal/btcscript/stack.go Stack.RotN 100.00% (9/9) github.com/conformal/btcscript/stack.go Stack.OverN 100.00% (9/9) +github.com/conformal/btcscript/opcode.go opcodeAdd 100.00% (8/8) github.com/conformal/btcscript/opcode.go opcodeEqual 100.00% (8/8) github.com/conformal/btcscript/opcode.go opcodeSub 100.00% (8/8) -github.com/conformal/btcscript/opcode.go opcodeAdd 100.00% (8/8) github.com/conformal/btcscript/stack.go Stack.DupN 100.00% (8/8) +github.com/conformal/btcscript/script.go unparseScript 100.00% (7/7) +github.com/conformal/btcscript/opcode.go opcodePick 100.00% (7/7) github.com/conformal/btcscript/opcode.go opcode0NotEqual 100.00% (7/7) +github.com/conformal/btcscript/opcode.go opcodeRoll 100.00% (7/7) github.com/conformal/btcscript/stack.go Stack.DropN 100.00% (7/7) github.com/conformal/btcscript/opcode.go opcodeNot 100.00% (7/7) -github.com/conformal/btcscript/opcode.go opcodePick 100.00% (7/7) -github.com/conformal/btcscript/opcode.go opcodeRoll 100.00% (7/7) -github.com/conformal/btcscript/script.go typeOfScript 100.00% (6/6) github.com/conformal/btcscript/opcode.go opcodeEndif 100.00% (6/6) github.com/conformal/btcscript/opcode.go parsedOpcode.conditional 100.00% (6/6) github.com/conformal/btcscript/opcode.go opcodeIfDup 100.00% (6/6) -github.com/conformal/btcscript/opcode.go opcodeVerify 100.00% (6/6) github.com/conformal/btcscript/opcode.go opcodeElse 100.00% (6/6) -github.com/conformal/btcscript/opcode.go opcodeSize 100.00% (5/5) -github.com/conformal/btcscript/stack.go Stack.PickN 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcodeVerify 100.00% (6/6) +github.com/conformal/btcscript/script.go typeOfScript 100.00% (6/6) +github.com/conformal/btcscript/opcode.go opcodeRipemd160 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcodeSha1 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcode1Add 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcode1Sub 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeNegate 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeAbs 100.00% (5/5) -github.com/conformal/btcscript/stack.go Stack.RollN 100.00% (5/5) -github.com/conformal/btcscript/script.go removeOpcodeByData 100.00% (5/5) -github.com/conformal/btcscript/script.go removeOpcode 100.00% (5/5) -github.com/conformal/btcscript/opcode.go parsedOpcode.exec 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcodeRipemd160 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcodeHash256 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeHash160 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcodeHash256 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeSha256 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcodeSha1 100.00% (5/5) -github.com/conformal/btcscript/script.go Script.validPC 100.00% (5/5) -github.com/conformal/btcscript/script.go Script.DisasmScript 100.00% (5/5) +github.com/conformal/btcscript/stack.go Stack.PickN 100.00% (5/5) +github.com/conformal/btcscript/stack.go Stack.RollN 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeFromAltStack 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeToAltStack 100.00% (5/5) +github.com/conformal/btcscript/script.go removeOpcodeByData 100.00% (5/5) +github.com/conformal/btcscript/script.go removeOpcode 100.00% (5/5) +github.com/conformal/btcscript/script.go Script.validPC 100.00% (5/5) +github.com/conformal/btcscript/opcode.go parsedOpcode.exec 100.00% (5/5) +github.com/conformal/btcscript/script.go Script.DisasmScript 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcodeSize 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodePushData 100.00% (4/4) github.com/conformal/btcscript/opcode.go opcodeEqualVerify 100.00% (4/4) github.com/conformal/btcscript/opcode.go opcodeNumEqualVerify 100.00% (4/4) @@ -72,76 +75,77 @@ github.com/conformal/btcscript/stack.go asBool 100.00% (4/4) github.com/conformal/btcscript/stack.go Stack.PeekByteArray 100.00% (4/4) github.com/conformal/btcscript/stack.go Stack.PeekInt 100.00% (4/4) github.com/conformal/btcscript/stack.go Stack.PopInt 100.00% (4/4) -github.com/conformal/btcscript/script.go unparseScript 100.00% (4/4) github.com/conformal/btcscript/script.go IsPayToScriptHash 100.00% (4/4) github.com/conformal/btcscript/script.go isPushOnly 100.00% (4/4) github.com/conformal/btcscript/script.go GetScriptClass 100.00% (4/4) github.com/conformal/btcscript/script.go Script.curPC 100.00% (4/4) github.com/conformal/btcscript/script.go Script.DisasmPC 100.00% (4/4) -github.com/conformal/btcscript/script.go getStack 100.00% (4/4) github.com/conformal/btcscript/stack.go Stack.PeekBool 100.00% (4/4) +github.com/conformal/btcscript/script.go getStack 100.00% (4/4) +github.com/conformal/btcscript/script.go scriptUInt16 100.00% (3/3) +github.com/conformal/btcscript/address.go ScriptType.String 100.00% (3/3) +github.com/conformal/btcscript/script.go scriptUInt8 100.00% (3/3) +github.com/conformal/btcscript/script.go setStack 100.00% (3/3) github.com/conformal/btcscript/stack.go fromBool 100.00% (3/3) github.com/conformal/btcscript/script.go scriptUInt32 100.00% (3/3) -github.com/conformal/btcscript/script.go setStack 100.00% (3/3) -github.com/conformal/btcscript/address.go ScriptType.String 100.00% (3/3) -github.com/conformal/btcscript/script.go scriptUInt16 100.00% (3/3) -github.com/conformal/btcscript/script.go scriptUInt8 100.00% (3/3) -github.com/conformal/btcscript/opcode.go opcodeFalse 100.00% (2/2) github.com/conformal/btcscript/opcode.go opcodeCodeSeparator 100.00% (2/2) -github.com/conformal/btcscript/opcode.go calcHash 100.00% (2/2) -github.com/conformal/btcscript/script.go GetSigOpCount 100.00% (2/2) -github.com/conformal/btcscript/opcode.go opcodeDepth 100.00% (2/2) -github.com/conformal/btcscript/stack.go Stack.Depth 100.00% (2/2) -github.com/conformal/btcscript/stack.go Stack.NipN 100.00% (2/2) github.com/conformal/btcscript/address.go ScriptToAddress 100.00% (2/2) +github.com/conformal/btcscript/stack.go Stack.NipN 100.00% (2/2) +github.com/conformal/btcscript/opcode.go opcodeDepth 100.00% (2/2) +github.com/conformal/btcscript/script.go GetSigOpCount 100.00% (2/2) +github.com/conformal/btcscript/opcode.go calcHash 100.00% (2/2) +github.com/conformal/btcscript/script.go PayToPubKeyHashScript 100.00% (2/2) +github.com/conformal/btcscript/opcode.go opcodeFalse 100.00% (2/2) github.com/conformal/btcscript/opcode.go opcodeN 100.00% (2/2) github.com/conformal/btcscript/opcode.go opcode1Negate 100.00% (2/2) -github.com/conformal/btcscript/script.go Script.GetStack 100.00% (1/1) +github.com/conformal/btcscript/stack.go Stack.Depth 100.00% (2/2) +github.com/conformal/btcscript/opcode.go opcodeNop 100.00% (1/1) +github.com/conformal/btcscript/log.go DisableLog 100.00% (1/1) github.com/conformal/btcscript/script.go isPubkey 100.00% (1/1) github.com/conformal/btcscript/script.go isPubkeyHash 100.00% (1/1) -github.com/conformal/btcscript/script.go Script.SetStack 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeReserved 100.00% (1/1) -github.com/conformal/btcscript/script.go Script.GetAltStack 100.00% (1/1) -github.com/conformal/btcscript/script.go Script.SetAltStack 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeDisabled 100.00% (1/1) -github.com/conformal/btcscript/script.go parseScript 100.00% (1/1) -github.com/conformal/btcscript/opcode.go init 100.00% (1/1) -github.com/conformal/btcscript/log.go newLogClosure 100.00% (1/1) github.com/conformal/btcscript/script.go isScriptHash 100.00% (1/1) +github.com/conformal/btcscript/log.go UseLogger 100.00% (1/1) +github.com/conformal/btcscript/script.go Script.GetAltStack 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeInvalid 100.00% (1/1) +github.com/conformal/btcscript/script.go parseScript 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeReserved 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeDisabled 100.00% (1/1) +github.com/conformal/btcscript/opcode.go init 100.00% (1/1) +github.com/conformal/btcscript/script.go SignatureScript 100.00% (1/1) +github.com/conformal/btcscript/log.go newLogClosure 100.00% (1/1) +github.com/conformal/btcscript/log.go init 100.00% (1/1) github.com/conformal/btcscript/stack.go Stack.PushByteArray 100.00% (1/1) -github.com/conformal/btcscript/stack.go Stack.PushInt 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeRot 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeDup 100.00% (1/1) +github.com/conformal/btcscript/script.go Script.GetStack 100.00% (1/1) github.com/conformal/btcscript/stack.go Stack.PopByteArray 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeDrop 100.00% (1/1) +github.com/conformal/btcscript/script.go Script.SetStack 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcode2Swap 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcode2Rot 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcode2Over 100.00% (1/1) +github.com/conformal/btcscript/script.go Script.SetAltStack 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcode3Dup 100.00% (1/1) +github.com/conformal/btcscript/stack.go Stack.PushInt 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcode2Dup 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcode2Drop 100.00% (1/1) -github.com/conformal/btcscript/log.go DisableLog 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcodeReturn 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeNop 100.00% (1/1) github.com/conformal/btcscript/stack.go Stack.PushBool 100.00% (1/1) github.com/conformal/btcscript/script.go Script.subScript 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeInvalid 100.00% (1/1) +github.com/conformal/btcscript/script.go Script.disasm 100.00% (1/1) +github.com/conformal/btcscript/opcode.go calcHash160 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcodeTuck 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcodeSwap 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeRot 100.00% (1/1) -github.com/conformal/btcscript/opcode.go calcHash160 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcodeOver 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcodeNip 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeDup 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeDrop 100.00% (1/1) -github.com/conformal/btcscript/script.go Script.disasm 100.00% (1/1) -github.com/conformal/btcscript/log.go UseLogger 100.00% (1/1) -github.com/conformal/btcscript/log.go init 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcodeCheckMultiSig 98.21% (55/56) github.com/conformal/btcscript/opcode.go opcodeCheckSig 96.15% (25/26) +github.com/conformal/btcscript/script.go calcScriptHash 82.05% (32/39) github.com/conformal/btcscript/script.go Script.CheckErrorCondition 78.57% (11/14) github.com/conformal/btcscript/opcode.go opcodeCheckSigVerify 75.00% (3/4) -github.com/conformal/btcscript/script.go Script.calcScriptHash 64.10% (25/39) github.com/conformal/btcscript/script.go Script.Execute 44.44% (8/18) github.com/conformal/btcscript/log.go SetLogWriter 0.00% (0/7) github.com/conformal/btcscript/script.go IsPushOnlyScript 0.00% (0/4) github.com/conformal/btcscript/log.go logClosure.String 0.00% (0/1) -github.com/conformal/btcscript -------------------------- 95.55% (901/943) +github.com/conformal/btcscript --------------------------- 96.44% (949/984)