From a5f81fc5457eec41c1438f12b0d92a27a586039f Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Tue, 10 Sep 2013 11:39:29 -0400 Subject: [PATCH] Add PayToPubKeyHashScript and SignatureScript functions. PayToPubKeyHashScript generates a new pay to pubkey hash script to use as the pkScript when creating new transactions. If the passed pubkey hash is an invalid size, StackErrInvalidOpcode will be returned as an error. SignatureScript returns the signature script necessary to validate a single input of a transaction. This also adds sanity checking for serializing scripts into byte slices. If the length of a serialized opcode does not equal the expected length, StackErrInvalidOpcode will be returned when unparsing a []parsedOpcode. New internal tests were added to verify checks for valid and invalid parsed opcodes. --- internal_test.go | 3668 ++++++++++++++++++++++++++++++++++++++++++++- opcode.go | 30 +- script.go | 144 +- script_test.go | 395 +++++ stack.go | 2 +- test_coverage.txt | 126 +- 6 files changed, 4278 insertions(+), 87 deletions(-) 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)