txscript: Convert opcode map to an array.

This commit converts the opcode map to an array to improve performance.

Benchmark of executing a standard p2pk transaction:

New: BenchmarkExecute            2000            784349 ns/op
Old: BenchmarkExecute            2000            792600 ns/op

The time is dominated by the signature checking as expected, however there
is still an increase in speed.
This commit is contained in:
Dave Collins 2015-04-21 11:49:59 -05:00
parent d6f2b092c0
commit d251208f1f
4 changed files with 748 additions and 1014 deletions

File diff suppressed because it is too large Load diff

View file

@ -28,7 +28,6 @@ type opcode struct {
name string name string
length int length int
opfunc func(*parsedOpcode, *Engine) error opfunc func(*parsedOpcode, *Engine) error
parsefunc func(*opcode, *Engine, []byte) error
} }
// These constants are the values of the official opcodes used on the btc wiki, // These constants are the values of the official opcodes used on the btc wiki,
@ -302,533 +301,286 @@ const (
OpCondSkip = 2 OpCondSkip = 2
) )
// Some of the functions in opcodemap call things that themselves then will // opcodeArray holds details about all possible opcodes such as how many bytes
// reference the opcodemap to make decisions (things like op_checksig which // the opcode and any associated data should take, its human-readable name, and
// needs to parse scripts to remove opcodes, for example). // the handler function.
// The go compiler is very conservative in this matter and will think there var opcodeArray = [256]opcode{
// is an initialisation loop. In order to work around this we have the fake // Data push opcodes.
// ``prevariable'' opcodemapPreinit and then set the real variable to the OP_FALSE: {OP_FALSE, "OP_0", 1, opcodeFalse},
// preinit in init() OP_DATA_1: {OP_DATA_1, "OP_DATA_1", 2, opcodePushData},
var opcodemap map[byte]*opcode OP_DATA_2: {OP_DATA_2, "OP_DATA_2", 3, opcodePushData},
OP_DATA_3: {OP_DATA_3, "OP_DATA_3", 4, opcodePushData},
OP_DATA_4: {OP_DATA_4, "OP_DATA_4", 5, opcodePushData},
OP_DATA_5: {OP_DATA_5, "OP_DATA_5", 6, opcodePushData},
OP_DATA_6: {OP_DATA_6, "OP_DATA_6", 7, opcodePushData},
OP_DATA_7: {OP_DATA_7, "OP_DATA_7", 8, opcodePushData},
OP_DATA_8: {OP_DATA_8, "OP_DATA_8", 9, opcodePushData},
OP_DATA_9: {OP_DATA_9, "OP_DATA_9", 10, opcodePushData},
OP_DATA_10: {OP_DATA_10, "OP_DATA_10", 11, opcodePushData},
OP_DATA_11: {OP_DATA_11, "OP_DATA_11", 12, opcodePushData},
OP_DATA_12: {OP_DATA_12, "OP_DATA_12", 13, opcodePushData},
OP_DATA_13: {OP_DATA_13, "OP_DATA_13", 14, opcodePushData},
OP_DATA_14: {OP_DATA_14, "OP_DATA_14", 15, opcodePushData},
OP_DATA_15: {OP_DATA_15, "OP_DATA_15", 16, opcodePushData},
OP_DATA_16: {OP_DATA_16, "OP_DATA_16", 17, opcodePushData},
OP_DATA_17: {OP_DATA_17, "OP_DATA_17", 18, opcodePushData},
OP_DATA_18: {OP_DATA_18, "OP_DATA_18", 19, opcodePushData},
OP_DATA_19: {OP_DATA_19, "OP_DATA_19", 20, opcodePushData},
OP_DATA_20: {OP_DATA_20, "OP_DATA_20", 21, opcodePushData},
OP_DATA_21: {OP_DATA_21, "OP_DATA_21", 22, opcodePushData},
OP_DATA_22: {OP_DATA_22, "OP_DATA_22", 23, opcodePushData},
OP_DATA_23: {OP_DATA_23, "OP_DATA_23", 24, opcodePushData},
OP_DATA_24: {OP_DATA_24, "OP_DATA_24", 25, opcodePushData},
OP_DATA_25: {OP_DATA_25, "OP_DATA_25", 26, opcodePushData},
OP_DATA_26: {OP_DATA_26, "OP_DATA_26", 27, opcodePushData},
OP_DATA_27: {OP_DATA_27, "OP_DATA_27", 28, opcodePushData},
OP_DATA_28: {OP_DATA_28, "OP_DATA_28", 29, opcodePushData},
OP_DATA_29: {OP_DATA_29, "OP_DATA_29", 30, opcodePushData},
OP_DATA_30: {OP_DATA_30, "OP_DATA_30", 31, opcodePushData},
OP_DATA_31: {OP_DATA_31, "OP_DATA_31", 32, opcodePushData},
OP_DATA_32: {OP_DATA_32, "OP_DATA_32", 33, opcodePushData},
OP_DATA_33: {OP_DATA_33, "OP_DATA_33", 34, opcodePushData},
OP_DATA_34: {OP_DATA_34, "OP_DATA_34", 35, opcodePushData},
OP_DATA_35: {OP_DATA_35, "OP_DATA_35", 36, opcodePushData},
OP_DATA_36: {OP_DATA_36, "OP_DATA_36", 37, opcodePushData},
OP_DATA_37: {OP_DATA_37, "OP_DATA_37", 38, opcodePushData},
OP_DATA_38: {OP_DATA_38, "OP_DATA_38", 39, opcodePushData},
OP_DATA_39: {OP_DATA_39, "OP_DATA_39", 40, opcodePushData},
OP_DATA_40: {OP_DATA_40, "OP_DATA_40", 41, opcodePushData},
OP_DATA_41: {OP_DATA_41, "OP_DATA_41", 42, opcodePushData},
OP_DATA_42: {OP_DATA_42, "OP_DATA_42", 43, opcodePushData},
OP_DATA_43: {OP_DATA_43, "OP_DATA_43", 44, opcodePushData},
OP_DATA_44: {OP_DATA_44, "OP_DATA_44", 45, opcodePushData},
OP_DATA_45: {OP_DATA_45, "OP_DATA_45", 46, opcodePushData},
OP_DATA_46: {OP_DATA_46, "OP_DATA_46", 47, opcodePushData},
OP_DATA_47: {OP_DATA_47, "OP_DATA_47", 48, opcodePushData},
OP_DATA_48: {OP_DATA_48, "OP_DATA_48", 49, opcodePushData},
OP_DATA_49: {OP_DATA_49, "OP_DATA_49", 50, opcodePushData},
OP_DATA_50: {OP_DATA_50, "OP_DATA_50", 51, opcodePushData},
OP_DATA_51: {OP_DATA_51, "OP_DATA_51", 52, opcodePushData},
OP_DATA_52: {OP_DATA_52, "OP_DATA_52", 53, opcodePushData},
OP_DATA_53: {OP_DATA_53, "OP_DATA_53", 54, opcodePushData},
OP_DATA_54: {OP_DATA_54, "OP_DATA_54", 55, opcodePushData},
OP_DATA_55: {OP_DATA_55, "OP_DATA_55", 56, opcodePushData},
OP_DATA_56: {OP_DATA_56, "OP_DATA_56", 57, opcodePushData},
OP_DATA_57: {OP_DATA_57, "OP_DATA_57", 58, opcodePushData},
OP_DATA_58: {OP_DATA_58, "OP_DATA_58", 59, opcodePushData},
OP_DATA_59: {OP_DATA_59, "OP_DATA_59", 60, opcodePushData},
OP_DATA_60: {OP_DATA_60, "OP_DATA_60", 61, opcodePushData},
OP_DATA_61: {OP_DATA_61, "OP_DATA_61", 62, opcodePushData},
OP_DATA_62: {OP_DATA_62, "OP_DATA_62", 63, opcodePushData},
OP_DATA_63: {OP_DATA_63, "OP_DATA_63", 64, opcodePushData},
OP_DATA_64: {OP_DATA_64, "OP_DATA_64", 65, opcodePushData},
OP_DATA_65: {OP_DATA_65, "OP_DATA_65", 66, opcodePushData},
OP_DATA_66: {OP_DATA_66, "OP_DATA_66", 67, opcodePushData},
OP_DATA_67: {OP_DATA_67, "OP_DATA_67", 68, opcodePushData},
OP_DATA_68: {OP_DATA_68, "OP_DATA_68", 69, opcodePushData},
OP_DATA_69: {OP_DATA_69, "OP_DATA_69", 70, opcodePushData},
OP_DATA_70: {OP_DATA_70, "OP_DATA_70", 71, opcodePushData},
OP_DATA_71: {OP_DATA_71, "OP_DATA_71", 72, opcodePushData},
OP_DATA_72: {OP_DATA_72, "OP_DATA_72", 73, opcodePushData},
OP_DATA_73: {OP_DATA_73, "OP_DATA_73", 74, opcodePushData},
OP_DATA_74: {OP_DATA_74, "OP_DATA_74", 75, opcodePushData},
OP_DATA_75: {OP_DATA_75, "OP_DATA_75", 76, opcodePushData},
OP_PUSHDATA1: {OP_PUSHDATA1, "OP_PUSHDATA1", -1, opcodePushData},
OP_PUSHDATA2: {OP_PUSHDATA2, "OP_PUSHDATA2", -2, opcodePushData},
OP_PUSHDATA4: {OP_PUSHDATA4, "OP_PUSHDATA4", -4, opcodePushData},
OP_1NEGATE: {OP_1NEGATE, "OP_1NEGATE", 1, opcode1Negate},
OP_RESERVED: {OP_RESERVED, "OP_RESERVED", 1, opcodeReserved},
OP_TRUE: {OP_TRUE, "OP_1", 1, opcodeN},
OP_2: {OP_2, "OP_2", 1, opcodeN},
OP_3: {OP_3, "OP_3", 1, opcodeN},
OP_4: {OP_4, "OP_4", 1, opcodeN},
OP_5: {OP_5, "OP_5", 1, opcodeN},
OP_6: {OP_6, "OP_6", 1, opcodeN},
OP_7: {OP_7, "OP_7", 1, opcodeN},
OP_8: {OP_8, "OP_8", 1, opcodeN},
OP_9: {OP_9, "OP_9", 1, opcodeN},
OP_10: {OP_10, "OP_10", 1, opcodeN},
OP_11: {OP_11, "OP_11", 1, opcodeN},
OP_12: {OP_12, "OP_12", 1, opcodeN},
OP_13: {OP_13, "OP_13", 1, opcodeN},
OP_14: {OP_14, "OP_14", 1, opcodeN},
OP_15: {OP_15, "OP_15", 1, opcodeN},
OP_16: {OP_16, "OP_16", 1, opcodeN},
func init() { // Control opcodes.
opcodemap = opcodemapPreinit OP_NOP: {OP_NOP, "OP_NOP", 1, opcodeNop},
} OP_VER: {OP_VER, "OP_VER", 1, opcodeReserved},
OP_IF: {OP_IF, "OP_IF", 1, opcodeIf},
OP_NOTIF: {OP_NOTIF, "OP_NOTIF", 1, opcodeNotIf},
OP_VERIF: {OP_VERIF, "OP_VERIF", 1, opcodeReserved},
OP_VERNOTIF: {OP_VERNOTIF, "OP_VERNOTIF", 1, opcodeReserved},
OP_ELSE: {OP_ELSE, "OP_ELSE", 1, opcodeElse},
OP_ENDIF: {OP_ENDIF, "OP_ENDIF", 1, opcodeEndif},
OP_VERIFY: {OP_VERIFY, "OP_VERIFY", 1, opcodeVerify},
OP_RETURN: {OP_RETURN, "OP_RETURN", 1, opcodeReturn},
var opcodemapPreinit = map[byte]*opcode{ // Stack opcodes.
OP_FALSE: {value: OP_FALSE, name: "OP_0", length: 1, OP_TOALTSTACK: {OP_TOALTSTACK, "OP_TOALTSTACK", 1, opcodeToAltStack},
opfunc: opcodeFalse}, OP_FROMALTSTACK: {OP_FROMALTSTACK, "OP_FROMALTSTACK", 1, opcodeFromAltStack},
OP_DATA_1: {value: OP_DATA_1, name: "OP_DATA_1", length: 2, OP_2DROP: {OP_2DROP, "OP_2DROP", 1, opcode2Drop},
opfunc: opcodePushData}, OP_2DUP: {OP_2DUP, "OP_2DUP", 1, opcode2Dup},
OP_DATA_2: {value: OP_DATA_2, name: "OP_DATA_2", length: 3, OP_3DUP: {OP_3DUP, "OP_3DUP", 1, opcode3Dup},
opfunc: opcodePushData}, OP_2OVER: {OP_2OVER, "OP_2OVER", 1, opcode2Over},
OP_DATA_3: {value: OP_DATA_3, name: "OP_DATA_3", length: 4, OP_2ROT: {OP_2ROT, "OP_2ROT", 1, opcode2Rot},
opfunc: opcodePushData}, OP_2SWAP: {OP_2SWAP, "OP_2SWAP", 1, opcode2Swap},
OP_DATA_4: {value: OP_DATA_4, name: "OP_DATA_4", length: 5, OP_IFDUP: {OP_IFDUP, "OP_IFDUP", 1, opcodeIfDup},
opfunc: opcodePushData}, OP_DEPTH: {OP_DEPTH, "OP_DEPTH", 1, opcodeDepth},
OP_DATA_5: {value: OP_DATA_5, name: "OP_DATA_5", length: 6, OP_DROP: {OP_DROP, "OP_DROP", 1, opcodeDrop},
opfunc: opcodePushData}, OP_DUP: {OP_DUP, "OP_DUP", 1, opcodeDup},
OP_DATA_6: {value: OP_DATA_6, name: "OP_DATA_6", length: 7, OP_NIP: {OP_NIP, "OP_NIP", 1, opcodeNip},
opfunc: opcodePushData}, OP_OVER: {OP_OVER, "OP_OVER", 1, opcodeOver},
OP_DATA_7: {value: OP_DATA_7, name: "OP_DATA_7", length: 8, OP_PICK: {OP_PICK, "OP_PICK", 1, opcodePick},
opfunc: opcodePushData}, OP_ROLL: {OP_ROLL, "OP_ROLL", 1, opcodeRoll},
OP_DATA_8: {value: OP_DATA_8, name: "OP_DATA_8", length: 9, OP_ROT: {OP_ROT, "OP_ROT", 1, opcodeRot},
opfunc: opcodePushData}, OP_SWAP: {OP_SWAP, "OP_SWAP", 1, opcodeSwap},
OP_DATA_9: {value: OP_DATA_9, name: "OP_DATA_9", length: 10, OP_TUCK: {OP_TUCK, "OP_TUCK", 1, opcodeTuck},
opfunc: opcodePushData},
OP_DATA_10: {value: OP_DATA_10, name: "OP_DATA_10", length: 11,
opfunc: opcodePushData},
OP_DATA_11: {value: OP_DATA_11, name: "OP_DATA_11", length: 12,
opfunc: opcodePushData},
OP_DATA_12: {value: OP_DATA_12, name: "OP_DATA_12", length: 13,
opfunc: opcodePushData},
OP_DATA_13: {value: OP_DATA_13, name: "OP_DATA_13", length: 14,
opfunc: opcodePushData},
OP_DATA_14: {value: OP_DATA_14, name: "OP_DATA_14", length: 15,
opfunc: opcodePushData},
OP_DATA_15: {value: OP_DATA_15, name: "OP_DATA_15", length: 16,
opfunc: opcodePushData},
OP_DATA_16: {value: OP_DATA_16, name: "OP_DATA_16", length: 17,
opfunc: opcodePushData},
OP_DATA_17: {value: OP_DATA_17, name: "OP_DATA_17", length: 18,
opfunc: opcodePushData},
OP_DATA_18: {value: OP_DATA_18, name: "OP_DATA_18", length: 19,
opfunc: opcodePushData},
OP_DATA_19: {value: OP_DATA_19, name: "OP_DATA_19", length: 20,
opfunc: opcodePushData},
OP_DATA_20: {value: OP_DATA_20, name: "OP_DATA_20", length: 21,
opfunc: opcodePushData},
OP_DATA_21: {value: OP_DATA_21, name: "OP_DATA_21", length: 22,
opfunc: opcodePushData},
OP_DATA_22: {value: OP_DATA_22, name: "OP_DATA_22", length: 23,
opfunc: opcodePushData},
OP_DATA_23: {value: OP_DATA_23, name: "OP_DATA_23", length: 24,
opfunc: opcodePushData},
OP_DATA_24: {value: OP_DATA_24, name: "OP_DATA_24", length: 25,
opfunc: opcodePushData},
OP_DATA_25: {value: OP_DATA_25, name: "OP_DATA_25", length: 26,
opfunc: opcodePushData},
OP_DATA_26: {value: OP_DATA_26, name: "OP_DATA_26", length: 27,
opfunc: opcodePushData},
OP_DATA_27: {value: OP_DATA_27, name: "OP_DATA_27", length: 28,
opfunc: opcodePushData},
OP_DATA_28: {value: OP_DATA_28, name: "OP_DATA_28", length: 29,
opfunc: opcodePushData},
OP_DATA_29: {value: OP_DATA_29, name: "OP_DATA_29", length: 30,
opfunc: opcodePushData},
OP_DATA_30: {value: OP_DATA_30, name: "OP_DATA_30", length: 31,
opfunc: opcodePushData},
OP_DATA_31: {value: OP_DATA_31, name: "OP_DATA_31", length: 32,
opfunc: opcodePushData},
OP_DATA_32: {value: OP_DATA_32, name: "OP_DATA_32", length: 33,
opfunc: opcodePushData},
OP_DATA_33: {value: OP_DATA_33, name: "OP_DATA_33", length: 34,
opfunc: opcodePushData},
OP_DATA_34: {value: OP_DATA_34, name: "OP_DATA_34", length: 35,
opfunc: opcodePushData},
OP_DATA_35: {value: OP_DATA_35, name: "OP_DATA_35", length: 36,
opfunc: opcodePushData},
OP_DATA_36: {value: OP_DATA_36, name: "OP_DATA_36", length: 37,
opfunc: opcodePushData},
OP_DATA_37: {value: OP_DATA_37, name: "OP_DATA_37", length: 38,
opfunc: opcodePushData},
OP_DATA_38: {value: OP_DATA_38, name: "OP_DATA_38", length: 39,
opfunc: opcodePushData},
OP_DATA_39: {value: OP_DATA_39, name: "OP_DATA_39", length: 40,
opfunc: opcodePushData},
OP_DATA_40: {value: OP_DATA_40, name: "OP_DATA_40", length: 41,
opfunc: opcodePushData},
OP_DATA_41: {value: OP_DATA_41, name: "OP_DATA_41", length: 42,
opfunc: opcodePushData},
OP_DATA_42: {value: OP_DATA_42, name: "OP_DATA_42", length: 43,
opfunc: opcodePushData},
OP_DATA_43: {value: OP_DATA_43, name: "OP_DATA_43", length: 44,
opfunc: opcodePushData},
OP_DATA_44: {value: OP_DATA_44, name: "OP_DATA_44", length: 45,
opfunc: opcodePushData},
OP_DATA_45: {value: OP_DATA_45, name: "OP_DATA_45", length: 46,
opfunc: opcodePushData},
OP_DATA_46: {value: OP_DATA_46, name: "OP_DATA_46", length: 47,
opfunc: opcodePushData},
OP_DATA_47: {value: OP_DATA_47, name: "OP_DATA_47", length: 48,
opfunc: opcodePushData},
OP_DATA_48: {value: OP_DATA_48, name: "OP_DATA_48", length: 49,
opfunc: opcodePushData},
OP_DATA_49: {value: OP_DATA_49, name: "OP_DATA_49", length: 50,
opfunc: opcodePushData},
OP_DATA_50: {value: OP_DATA_50, name: "OP_DATA_50", length: 51,
opfunc: opcodePushData},
OP_DATA_51: {value: OP_DATA_51, name: "OP_DATA_51", length: 52,
opfunc: opcodePushData},
OP_DATA_52: {value: OP_DATA_52, name: "OP_DATA_52", length: 53,
opfunc: opcodePushData},
OP_DATA_53: {value: OP_DATA_53, name: "OP_DATA_53", length: 54,
opfunc: opcodePushData},
OP_DATA_54: {value: OP_DATA_54, name: "OP_DATA_54", length: 55,
opfunc: opcodePushData},
OP_DATA_55: {value: OP_DATA_55, name: "OP_DATA_55", length: 56,
opfunc: opcodePushData},
OP_DATA_56: {value: OP_DATA_56, name: "OP_DATA_56", length: 57,
opfunc: opcodePushData},
OP_DATA_57: {value: OP_DATA_57, name: "OP_DATA_57", length: 58,
opfunc: opcodePushData},
OP_DATA_58: {value: OP_DATA_58, name: "OP_DATA_58", length: 59,
opfunc: opcodePushData},
OP_DATA_59: {value: OP_DATA_59, name: "OP_DATA_59", length: 60,
opfunc: opcodePushData},
OP_DATA_60: {value: OP_DATA_60, name: "OP_DATA_60", length: 61,
opfunc: opcodePushData},
OP_DATA_61: {value: OP_DATA_61, name: "OP_DATA_61", length: 62,
opfunc: opcodePushData},
OP_DATA_62: {value: OP_DATA_62, name: "OP_DATA_62", length: 63,
opfunc: opcodePushData},
OP_DATA_63: {value: OP_DATA_63, name: "OP_DATA_63", length: 64,
opfunc: opcodePushData},
OP_DATA_64: {value: OP_DATA_64, name: "OP_DATA_64", length: 65,
opfunc: opcodePushData},
OP_DATA_65: {value: OP_DATA_65, name: "OP_DATA_65", length: 66,
opfunc: opcodePushData},
OP_DATA_66: {value: OP_DATA_66, name: "OP_DATA_66", length: 67,
opfunc: opcodePushData},
OP_DATA_67: {value: OP_DATA_67, name: "OP_DATA_67", length: 68,
opfunc: opcodePushData},
OP_DATA_68: {value: OP_DATA_68, name: "OP_DATA_68", length: 69,
opfunc: opcodePushData},
OP_DATA_69: {value: OP_DATA_69, name: "OP_DATA_69", length: 70,
opfunc: opcodePushData},
OP_DATA_70: {value: OP_DATA_70, name: "OP_DATA_70", length: 71,
opfunc: opcodePushData},
OP_DATA_71: {value: OP_DATA_71, name: "OP_DATA_71", length: 72,
opfunc: opcodePushData},
OP_DATA_72: {value: OP_DATA_72, name: "OP_DATA_72", length: 73,
opfunc: opcodePushData},
OP_DATA_73: {value: OP_DATA_73, name: "OP_DATA_73", length: 74,
opfunc: opcodePushData},
OP_DATA_74: {value: OP_DATA_74, name: "OP_DATA_74", length: 75,
opfunc: opcodePushData},
OP_DATA_75: {value: OP_DATA_75, name: "OP_DATA_75", length: 76,
opfunc: opcodePushData},
OP_PUSHDATA1: {value: OP_PUSHDATA1, name: "OP_PUSHDATA1", length: -1,
opfunc: opcodePushData},
OP_PUSHDATA2: {value: OP_PUSHDATA2, name: "OP_PUSHDATA2", length: -2,
opfunc: opcodePushData},
OP_PUSHDATA4: {value: OP_PUSHDATA4, name: "OP_PUSHDATA4", length: -4,
opfunc: opcodePushData},
OP_1NEGATE: {value: OP_1NEGATE, name: "OP_1NEGATE", length: 1,
opfunc: opcode1Negate},
OP_RESERVED: {value: OP_RESERVED, name: "OP_RESERVED", length: 1,
opfunc: opcodeReserved},
OP_TRUE: {value: OP_TRUE, name: "OP_1", length: 1,
opfunc: opcodeN},
OP_2: {value: OP_2, name: "OP_2", length: 1,
opfunc: opcodeN},
OP_3: {value: OP_3, name: "OP_3", length: 1,
opfunc: opcodeN},
OP_4: {value: OP_4, name: "OP_4", length: 1,
opfunc: opcodeN},
OP_5: {value: OP_5, name: "OP_5", length: 1,
opfunc: opcodeN},
OP_6: {value: OP_6, name: "OP_6", length: 1,
opfunc: opcodeN},
OP_7: {value: OP_7, name: "OP_7", length: 1,
opfunc: opcodeN},
OP_8: {value: OP_8, name: "OP_8", length: 1,
opfunc: opcodeN},
OP_9: {value: OP_9, name: "OP_9", length: 1,
opfunc: opcodeN},
OP_10: {value: OP_10, name: "OP_10", length: 1,
opfunc: opcodeN},
OP_11: {value: OP_11, name: "OP_11", length: 1,
opfunc: opcodeN},
OP_12: {value: OP_12, name: "OP_12", length: 1,
opfunc: opcodeN},
OP_13: {value: OP_13, name: "OP_13", length: 1,
opfunc: opcodeN},
OP_14: {value: OP_14, name: "OP_14", length: 1,
opfunc: opcodeN},
OP_15: {value: OP_15, name: "OP_15", length: 1,
opfunc: opcodeN},
OP_16: {value: OP_16, name: "OP_16", length: 1,
opfunc: opcodeN},
OP_NOP: {value: OP_NOP, name: "OP_NOP", length: 1,
opfunc: opcodeNop},
OP_VER: {value: OP_VER, name: "OP_VER", length: 1,
opfunc: opcodeReserved},
OP_IF: {value: OP_IF, name: "OP_IF", length: 1,
opfunc: opcodeIf},
OP_NOTIF: {value: OP_NOTIF, name: "OP_NOTIF", length: 1,
opfunc: opcodeNotIf},
OP_VERIF: {value: OP_VERIF, name: "OP_VERIF", length: 1,
opfunc: opcodeReserved},
OP_VERNOTIF: {value: OP_VERNOTIF, name: "OP_VERNOTIF", length: 1,
opfunc: opcodeReserved},
OP_ELSE: {value: OP_ELSE, name: "OP_ELSE", length: 1,
opfunc: opcodeElse},
OP_ENDIF: {value: OP_ENDIF, name: "OP_ENDIF", length: 1,
opfunc: opcodeEndif},
OP_VERIFY: {value: OP_VERIFY, name: "OP_VERIFY", length: 1,
opfunc: opcodeVerify},
OP_RETURN: {value: OP_RETURN, name: "OP_RETURN", length: 1,
opfunc: opcodeReturn},
OP_TOALTSTACK: {value: OP_TOALTSTACK, name: "OP_TOALTSTACK", length: 1,
opfunc: opcodeToAltStack},
OP_FROMALTSTACK: {value: OP_FROMALTSTACK, name: "OP_FROMALTSTACK", length: 1,
opfunc: opcodeFromAltStack},
OP_2DROP: {value: OP_2DROP, name: "OP_2DROP", length: 1,
opfunc: opcode2Drop},
OP_2DUP: {value: OP_2DUP, name: "OP_2DUP", length: 1,
opfunc: opcode2Dup},
OP_3DUP: {value: OP_3DUP, name: "OP_3DUP", length: 1,
opfunc: opcode3Dup},
OP_2OVER: {value: OP_2OVER, name: "OP_2OVER", length: 1,
opfunc: opcode2Over},
OP_2ROT: {value: OP_2ROT, name: "OP_2ROT", length: 1,
opfunc: opcode2Rot},
OP_2SWAP: {value: OP_2SWAP, name: "OP_2SWAP", length: 1,
opfunc: opcode2Swap},
OP_IFDUP: {value: OP_IFDUP, name: "OP_IFDUP", length: 1,
opfunc: opcodeIfDup},
OP_DEPTH: {value: OP_DEPTH, name: "OP_DEPTH", length: 1,
opfunc: opcodeDepth},
OP_DROP: {value: OP_DROP, name: "OP_DROP", length: 1,
opfunc: opcodeDrop},
OP_DUP: {value: OP_DUP, name: "OP_DUP", length: 1,
opfunc: opcodeDup},
OP_NIP: {value: OP_NIP, name: "OP_NIP", length: 1,
opfunc: opcodeNip},
OP_OVER: {value: OP_OVER, name: "OP_OVER", length: 1,
opfunc: opcodeOver},
OP_PICK: {value: OP_PICK, name: "OP_PICK", length: 1,
opfunc: opcodePick},
OP_ROLL: {value: OP_ROLL, name: "OP_ROLL", length: 1,
opfunc: opcodeRoll},
OP_ROT: {value: OP_ROT, name: "OP_ROT", length: 1,
opfunc: opcodeRot},
OP_SWAP: {value: OP_SWAP, name: "OP_SWAP", length: 1,
opfunc: opcodeSwap},
OP_TUCK: {value: OP_TUCK, name: "OP_TUCK", length: 1,
opfunc: opcodeTuck},
OP_CAT: {value: OP_CAT, name: "OP_CAT", length: 1,
opfunc: opcodeDisabled},
OP_SUBSTR: {value: OP_SUBSTR, name: "OP_SUBSTR", length: 1,
opfunc: opcodeDisabled},
OP_LEFT: {value: OP_LEFT, name: "OP_LEFT", length: 1,
opfunc: opcodeDisabled},
OP_RIGHT: {value: OP_RIGHT, name: "OP_RIGHT", length: 1,
opfunc: opcodeDisabled},
OP_SIZE: {value: OP_SIZE, name: "OP_SIZE", length: 1,
opfunc: opcodeSize},
OP_INVERT: {value: OP_INVERT, name: "OP_INVERT", length: 1,
opfunc: opcodeDisabled},
OP_AND: {value: OP_AND, name: "OP_AND", length: 1,
opfunc: opcodeDisabled},
OP_OR: {value: OP_OR, name: "OP_OR", length: 1,
opfunc: opcodeDisabled},
OP_XOR: {value: OP_XOR, name: "OP_XOR", length: 1,
opfunc: opcodeDisabled},
OP_EQUAL: {value: OP_EQUAL, name: "OP_EQUAL", length: 1,
opfunc: opcodeEqual},
OP_EQUALVERIFY: {value: OP_EQUALVERIFY, name: "OP_EQUALVERIFY", length: 1,
opfunc: opcodeEqualVerify},
OP_RESERVED1: {value: OP_RESERVED1, name: "OP_RESERVED1", length: 1,
opfunc: opcodeReserved},
OP_RESERVED2: {value: OP_RESERVED2, name: "OP_RESERVED2", length: 1,
opfunc: opcodeReserved},
OP_1ADD: {value: OP_1ADD, name: "OP_1ADD", length: 1,
opfunc: opcode1Add},
OP_1SUB: {value: OP_1SUB, name: "OP_1SUB", length: 1,
opfunc: opcode1Sub},
OP_2MUL: {value: OP_2MUL, name: "OP_2MUL", length: 1,
opfunc: opcodeDisabled},
OP_2DIV: {value: OP_2DIV, name: "OP_2DIV", length: 1,
opfunc: opcodeDisabled},
OP_NEGATE: {value: OP_NEGATE, name: "OP_NEGATE", length: 1,
opfunc: opcodeNegate},
OP_ABS: {value: OP_ABS, name: "OP_ABS", length: 1,
opfunc: opcodeAbs},
OP_NOT: {value: OP_NOT, name: "OP_NOT", length: 1,
opfunc: opcodeNot},
OP_0NOTEQUAL: {value: OP_0NOTEQUAL, name: "OP_0NOTEQUAL", length: 1,
opfunc: opcode0NotEqual},
OP_ADD: {value: OP_ADD, name: "OP_ADD", length: 1,
opfunc: opcodeAdd},
OP_SUB: {value: OP_SUB, name: "OP_SUB", length: 1,
opfunc: opcodeSub},
OP_MUL: {value: OP_MUL, name: "OP_MUL", length: 1,
opfunc: opcodeDisabled},
OP_DIV: {value: OP_DIV, name: "OP_DIV", length: 1,
opfunc: opcodeDisabled},
OP_MOD: {value: OP_MOD, name: "OP_MOD", length: 1,
opfunc: opcodeDisabled},
OP_LSHIFT: {value: OP_LSHIFT, name: "OP_LSHIFT", length: 1,
opfunc: opcodeDisabled},
OP_RSHIFT: {value: OP_RSHIFT, name: "OP_RSHIFT", length: 1,
opfunc: opcodeDisabled},
OP_BOOLAND: {value: OP_BOOLAND, name: "OP_BOOLAND", length: 1,
opfunc: opcodeBoolAnd},
OP_BOOLOR: {value: OP_BOOLOR, name: "OP_BOOLOR", length: 1,
opfunc: opcodeBoolOr},
OP_NUMEQUAL: {value: OP_NUMEQUAL, name: "OP_NUMEQUAL", length: 1,
opfunc: opcodeNumEqual},
OP_NUMEQUALVERIFY: {value: OP_NUMEQUALVERIFY, name: "OP_NUMEQUALVERIFY", length: 1,
opfunc: opcodeNumEqualVerify},
OP_NUMNOTEQUAL: {value: OP_NUMNOTEQUAL, name: "OP_NUMNOTEQUAL", length: 1,
opfunc: opcodeNumNotEqual},
OP_LESSTHAN: {value: OP_LESSTHAN, name: "OP_LESSTHAN", length: 1,
opfunc: opcodeLessThan},
OP_GREATERTHAN: {value: OP_GREATERTHAN, name: "OP_GREATERTHAN", length: 1,
opfunc: opcodeGreaterThan},
OP_LESSTHANOREQUAL: {value: OP_LESSTHANOREQUAL, name: "OP_LESSTHANOREQUAL", length: 1,
opfunc: opcodeLessThanOrEqual},
OP_GREATERTHANOREQUAL: {value: OP_GREATERTHANOREQUAL, name: "OP_GREATERTHANOREQUAL", length: 1,
opfunc: opcodeGreaterThanOrEqual},
OP_MIN: {value: OP_MIN, name: "OP_MIN", length: 1,
opfunc: opcodeMin},
OP_MAX: {value: OP_MAX, name: "OP_MAX", length: 1,
opfunc: opcodeMax},
OP_WITHIN: {value: OP_WITHIN, name: "OP_WITHIN", length: 1,
opfunc: opcodeWithin},
OP_RIPEMD160: {value: OP_RIPEMD160, name: "OP_RIPEMD160", length: 1,
opfunc: opcodeRipemd160},
OP_SHA1: {value: OP_SHA1, name: "OP_SHA1", length: 1,
opfunc: opcodeSha1},
OP_SHA256: {value: OP_SHA256, name: "OP_SHA256", length: 1,
opfunc: opcodeSha256},
OP_HASH160: {value: OP_HASH160, name: "OP_HASH160", length: 1,
opfunc: opcodeHash160},
OP_HASH256: {value: OP_HASH256, name: "OP_HASH256", length: 1,
opfunc: opcodeHash256},
OP_CODESEPARATOR: {value: OP_CODESEPARATOR, name: "OP_CODESEPARATOR", length: 1,
opfunc: opcodeCodeSeparator},
OP_CHECKSIG: {value: OP_CHECKSIG, name: "OP_CHECKSIG", length: 1,
opfunc: opcodeCheckSig},
OP_CHECKSIGVERIFY: {value: OP_CHECKSIGVERIFY, name: "OP_CHECKSIGVERIFY", length: 1,
opfunc: opcodeCheckSigVerify},
OP_CHECKMULTISIG: {value: OP_CHECKMULTISIG, name: "OP_CHECKMULTISIG", length: 1,
opfunc: opcodeCheckMultiSig},
OP_CHECKMULTISIGVERIFY: {value: OP_CHECKMULTISIGVERIFY, name: "OP_CHECKMULTISIGVERIFY", length: 1,
opfunc: opcodeCheckMultiSigVerify}, // Splice opcodes.
OP_NOP1: {value: OP_NOP1, name: "OP_NOP1", length: 1, OP_CAT: {OP_CAT, "OP_CAT", 1, opcodeDisabled},
opfunc: opcodeNop}, OP_SUBSTR: {OP_SUBSTR, "OP_SUBSTR", 1, opcodeDisabled},
OP_NOP2: {value: OP_NOP2, name: "OP_NOP2", length: 1, OP_LEFT: {OP_LEFT, "OP_LEFT", 1, opcodeDisabled},
opfunc: opcodeNop}, OP_RIGHT: {OP_RIGHT, "OP_RIGHT", 1, opcodeDisabled},
OP_NOP3: {value: OP_NOP3, name: "OP_NOP3", length: 1, OP_SIZE: {OP_SIZE, "OP_SIZE", 1, opcodeSize},
opfunc: opcodeNop},
OP_NOP4: {value: OP_NOP4, name: "OP_NOP4", length: 1, // Bitwise logic opcodes.
opfunc: opcodeNop}, OP_INVERT: {OP_INVERT, "OP_INVERT", 1, opcodeDisabled},
OP_NOP5: {value: OP_NOP5, name: "OP_NOP5", length: 1, OP_AND: {OP_AND, "OP_AND", 1, opcodeDisabled},
opfunc: opcodeNop}, OP_OR: {OP_OR, "OP_OR", 1, opcodeDisabled},
OP_NOP6: {value: OP_NOP6, name: "OP_NOP6", length: 1, OP_XOR: {OP_XOR, "OP_XOR", 1, opcodeDisabled},
opfunc: opcodeNop}, OP_EQUAL: {OP_EQUAL, "OP_EQUAL", 1, opcodeEqual},
OP_NOP7: {value: OP_NOP7, name: "OP_NOP7", length: 1, OP_EQUALVERIFY: {OP_EQUALVERIFY, "OP_EQUALVERIFY", 1, opcodeEqualVerify},
opfunc: opcodeNop}, OP_RESERVED1: {OP_RESERVED1, "OP_RESERVED1", 1, opcodeReserved},
OP_NOP8: {value: OP_NOP8, name: "OP_NOP8", length: 1, OP_RESERVED2: {OP_RESERVED2, "OP_RESERVED2", 1, opcodeReserved},
opfunc: opcodeNop},
OP_NOP9: {value: OP_NOP9, name: "OP_NOP9", length: 1, // Numeric related opcodes.
opfunc: opcodeNop}, OP_1ADD: {OP_1ADD, "OP_1ADD", 1, opcode1Add},
OP_NOP10: {value: OP_NOP10, name: "OP_NOP10", length: 1, OP_1SUB: {OP_1SUB, "OP_1SUB", 1, opcode1Sub},
opfunc: opcodeNop}, OP_2MUL: {OP_2MUL, "OP_2MUL", 1, opcodeDisabled},
OP_UNKNOWN186: {value: OP_UNKNOWN186, name: "OP_UNKNOWN186", length: 1, OP_2DIV: {OP_2DIV, "OP_2DIV", 1, opcodeDisabled},
opfunc: opcodeInvalid}, OP_NEGATE: {OP_NEGATE, "OP_NEGATE", 1, opcodeNegate},
OP_UNKNOWN187: {value: OP_UNKNOWN187, name: "OP_UNKNOWN187", length: 1, OP_ABS: {OP_ABS, "OP_ABS", 1, opcodeAbs},
opfunc: opcodeInvalid}, OP_NOT: {OP_NOT, "OP_NOT", 1, opcodeNot},
OP_UNKNOWN188: {value: OP_UNKNOWN188, name: "OP_UNKNOWN188", length: 1, OP_0NOTEQUAL: {OP_0NOTEQUAL, "OP_0NOTEQUAL", 1, opcode0NotEqual},
opfunc: opcodeInvalid}, OP_ADD: {OP_ADD, "OP_ADD", 1, opcodeAdd},
OP_UNKNOWN189: {value: OP_UNKNOWN189, name: "OP_UNKNOWN189", length: 1, OP_SUB: {OP_SUB, "OP_SUB", 1, opcodeSub},
opfunc: opcodeInvalid}, OP_MUL: {OP_MUL, "OP_MUL", 1, opcodeDisabled},
OP_UNKNOWN190: {value: OP_UNKNOWN190, name: "OP_UNKNOWN190", length: 1, OP_DIV: {OP_DIV, "OP_DIV", 1, opcodeDisabled},
opfunc: opcodeInvalid}, OP_MOD: {OP_MOD, "OP_MOD", 1, opcodeDisabled},
OP_UNKNOWN191: {value: OP_UNKNOWN191, name: "OP_UNKNOWN191", length: 1, OP_LSHIFT: {OP_LSHIFT, "OP_LSHIFT", 1, opcodeDisabled},
opfunc: opcodeInvalid}, OP_RSHIFT: {OP_RSHIFT, "OP_RSHIFT", 1, opcodeDisabled},
OP_UNKNOWN192: {value: OP_UNKNOWN192, name: "OP_UNKNOWN192", length: 1, OP_BOOLAND: {OP_BOOLAND, "OP_BOOLAND", 1, opcodeBoolAnd},
opfunc: opcodeInvalid}, OP_BOOLOR: {OP_BOOLOR, "OP_BOOLOR", 1, opcodeBoolOr},
OP_UNKNOWN193: {value: OP_UNKNOWN193, name: "OP_UNKNOWN193", length: 1, OP_NUMEQUAL: {OP_NUMEQUAL, "OP_NUMEQUAL", 1, opcodeNumEqual},
opfunc: opcodeInvalid}, OP_NUMEQUALVERIFY: {OP_NUMEQUALVERIFY, "OP_NUMEQUALVERIFY", 1, opcodeNumEqualVerify},
OP_UNKNOWN194: {value: OP_UNKNOWN194, name: "OP_UNKNOWN194", length: 1, OP_NUMNOTEQUAL: {OP_NUMNOTEQUAL, "OP_NUMNOTEQUAL", 1, opcodeNumNotEqual},
opfunc: opcodeInvalid}, OP_LESSTHAN: {OP_LESSTHAN, "OP_LESSTHAN", 1, opcodeLessThan},
OP_UNKNOWN195: {value: OP_UNKNOWN195, name: "OP_UNKNOWN195", length: 1, OP_GREATERTHAN: {OP_GREATERTHAN, "OP_GREATERTHAN", 1, opcodeGreaterThan},
opfunc: opcodeInvalid}, OP_LESSTHANOREQUAL: {OP_LESSTHANOREQUAL, "OP_LESSTHANOREQUAL", 1, opcodeLessThanOrEqual},
OP_UNKNOWN196: {value: OP_UNKNOWN196, name: "OP_UNKNOWN196", length: 1, OP_GREATERTHANOREQUAL: {OP_GREATERTHANOREQUAL, "OP_GREATERTHANOREQUAL", 1, opcodeGreaterThanOrEqual},
opfunc: opcodeInvalid}, OP_MIN: {OP_MIN, "OP_MIN", 1, opcodeMin},
OP_UNKNOWN197: {value: OP_UNKNOWN197, name: "OP_UNKNOWN197", length: 1, OP_MAX: {OP_MAX, "OP_MAX", 1, opcodeMax},
opfunc: opcodeInvalid}, OP_WITHIN: {OP_WITHIN, "OP_WITHIN", 1, opcodeWithin},
OP_UNKNOWN198: {value: OP_UNKNOWN198, name: "OP_UNKNOWN198", length: 1,
opfunc: opcodeInvalid}, // Crypto opcodes.
OP_UNKNOWN199: {value: OP_UNKNOWN199, name: "OP_UNKNOWN199", length: 1, OP_RIPEMD160: {OP_RIPEMD160, "OP_RIPEMD160", 1, opcodeRipemd160},
opfunc: opcodeInvalid}, OP_SHA1: {OP_SHA1, "OP_SHA1", 1, opcodeSha1},
OP_UNKNOWN200: {value: OP_UNKNOWN200, name: "OP_UNKNOWN200", length: 1, OP_SHA256: {OP_SHA256, "OP_SHA256", 1, opcodeSha256},
opfunc: opcodeInvalid}, OP_HASH160: {OP_HASH160, "OP_HASH160", 1, opcodeHash160},
OP_UNKNOWN201: {value: OP_UNKNOWN201, name: "OP_UNKNOWN201", length: 1, OP_HASH256: {OP_HASH256, "OP_HASH256", 1, opcodeHash256},
opfunc: opcodeInvalid}, OP_CODESEPARATOR: {OP_CODESEPARATOR, "OP_CODESEPARATOR", 1, opcodeCodeSeparator},
OP_UNKNOWN202: {value: OP_UNKNOWN202, name: "OP_UNKNOWN202", length: 1, OP_CHECKSIG: {OP_CHECKSIG, "OP_CHECKSIG", 1, opcodeCheckSig},
opfunc: opcodeInvalid}, OP_CHECKSIGVERIFY: {OP_CHECKSIGVERIFY, "OP_CHECKSIGVERIFY", 1, opcodeCheckSigVerify},
OP_UNKNOWN203: {value: OP_UNKNOWN203, name: "OP_UNKNOWN203", length: 1, OP_CHECKMULTISIG: {OP_CHECKMULTISIG, "OP_CHECKMULTISIG", 1, opcodeCheckMultiSig},
opfunc: opcodeInvalid}, OP_CHECKMULTISIGVERIFY: {OP_CHECKMULTISIGVERIFY, "OP_CHECKMULTISIGVERIFY", 1, opcodeCheckMultiSigVerify},
OP_UNKNOWN204: {value: OP_UNKNOWN204, name: "OP_UNKNOWN204", length: 1,
opfunc: opcodeInvalid}, // Reserved opcodes.
OP_UNKNOWN205: {value: OP_UNKNOWN205, name: "OP_UNKNOWN205", length: 1, OP_NOP1: {OP_NOP1, "OP_NOP1", 1, opcodeNop},
opfunc: opcodeInvalid}, OP_NOP2: {OP_NOP2, "OP_NOP2", 1, opcodeNop},
OP_UNKNOWN206: {value: OP_UNKNOWN206, name: "OP_UNKNOWN206", length: 1, OP_NOP3: {OP_NOP3, "OP_NOP3", 1, opcodeNop},
opfunc: opcodeInvalid}, OP_NOP4: {OP_NOP4, "OP_NOP4", 1, opcodeNop},
OP_UNKNOWN207: {value: OP_UNKNOWN207, name: "OP_UNKNOWN207", length: 1, OP_NOP5: {OP_NOP5, "OP_NOP5", 1, opcodeNop},
opfunc: opcodeInvalid}, OP_NOP6: {OP_NOP6, "OP_NOP6", 1, opcodeNop},
OP_UNKNOWN208: {value: OP_UNKNOWN208, name: "OP_UNKNOWN208", length: 1, OP_NOP7: {OP_NOP7, "OP_NOP7", 1, opcodeNop},
opfunc: opcodeInvalid}, OP_NOP8: {OP_NOP8, "OP_NOP8", 1, opcodeNop},
OP_UNKNOWN209: {value: OP_UNKNOWN209, name: "OP_UNKNOWN209", length: 1, OP_NOP9: {OP_NOP9, "OP_NOP9", 1, opcodeNop},
opfunc: opcodeInvalid}, OP_NOP10: {OP_NOP10, "OP_NOP10", 1, opcodeNop},
OP_UNKNOWN210: {value: OP_UNKNOWN210, name: "OP_UNKNOWN210", length: 1,
opfunc: opcodeInvalid}, // Undefined opcodes.
OP_UNKNOWN211: {value: OP_UNKNOWN211, name: "OP_UNKNOWN211", length: 1, OP_UNKNOWN186: {OP_UNKNOWN186, "OP_UNKNOWN186", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN187: {OP_UNKNOWN187, "OP_UNKNOWN187", 1, opcodeInvalid},
OP_UNKNOWN212: {value: OP_UNKNOWN212, name: "OP_UNKNOWN212", length: 1, OP_UNKNOWN188: {OP_UNKNOWN188, "OP_UNKNOWN188", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN189: {OP_UNKNOWN189, "OP_UNKNOWN189", 1, opcodeInvalid},
OP_UNKNOWN213: {value: OP_UNKNOWN213, name: "OP_UNKNOWN213", length: 1, OP_UNKNOWN190: {OP_UNKNOWN190, "OP_UNKNOWN190", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN191: {OP_UNKNOWN191, "OP_UNKNOWN191", 1, opcodeInvalid},
OP_UNKNOWN214: {value: OP_UNKNOWN214, name: "OP_UNKNOWN214", length: 1, OP_UNKNOWN192: {OP_UNKNOWN192, "OP_UNKNOWN192", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN193: {OP_UNKNOWN193, "OP_UNKNOWN193", 1, opcodeInvalid},
OP_UNKNOWN215: {value: OP_UNKNOWN215, name: "OP_UNKNOWN215", length: 1, OP_UNKNOWN194: {OP_UNKNOWN194, "OP_UNKNOWN194", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN195: {OP_UNKNOWN195, "OP_UNKNOWN195", 1, opcodeInvalid},
OP_UNKNOWN216: {value: OP_UNKNOWN216, name: "OP_UNKNOWN216", length: 1, OP_UNKNOWN196: {OP_UNKNOWN196, "OP_UNKNOWN196", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN197: {OP_UNKNOWN197, "OP_UNKNOWN197", 1, opcodeInvalid},
OP_UNKNOWN217: {value: OP_UNKNOWN217, name: "OP_UNKNOWN217", length: 1, OP_UNKNOWN198: {OP_UNKNOWN198, "OP_UNKNOWN198", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN199: {OP_UNKNOWN199, "OP_UNKNOWN199", 1, opcodeInvalid},
OP_UNKNOWN218: {value: OP_UNKNOWN218, name: "OP_UNKNOWN218", length: 1, OP_UNKNOWN200: {OP_UNKNOWN200, "OP_UNKNOWN200", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN201: {OP_UNKNOWN201, "OP_UNKNOWN201", 1, opcodeInvalid},
OP_UNKNOWN219: {value: OP_UNKNOWN219, name: "OP_UNKNOWN219", length: 1, OP_UNKNOWN202: {OP_UNKNOWN202, "OP_UNKNOWN202", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN203: {OP_UNKNOWN203, "OP_UNKNOWN203", 1, opcodeInvalid},
OP_UNKNOWN220: {value: OP_UNKNOWN220, name: "OP_UNKNOWN220", length: 1, OP_UNKNOWN204: {OP_UNKNOWN204, "OP_UNKNOWN204", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN205: {OP_UNKNOWN205, "OP_UNKNOWN205", 1, opcodeInvalid},
OP_UNKNOWN221: {value: OP_UNKNOWN221, name: "OP_UNKNOWN221", length: 1, OP_UNKNOWN206: {OP_UNKNOWN206, "OP_UNKNOWN206", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN207: {OP_UNKNOWN207, "OP_UNKNOWN207", 1, opcodeInvalid},
OP_UNKNOWN222: {value: OP_UNKNOWN222, name: "OP_UNKNOWN222", length: 1, OP_UNKNOWN208: {OP_UNKNOWN208, "OP_UNKNOWN208", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN209: {OP_UNKNOWN209, "OP_UNKNOWN209", 1, opcodeInvalid},
OP_UNKNOWN223: {value: OP_UNKNOWN223, name: "OP_UNKNOWN223", length: 1, OP_UNKNOWN210: {OP_UNKNOWN210, "OP_UNKNOWN210", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN211: {OP_UNKNOWN211, "OP_UNKNOWN211", 1, opcodeInvalid},
OP_UNKNOWN224: {value: OP_UNKNOWN224, name: "OP_UNKNOWN224", length: 1, OP_UNKNOWN212: {OP_UNKNOWN212, "OP_UNKNOWN212", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN213: {OP_UNKNOWN213, "OP_UNKNOWN213", 1, opcodeInvalid},
OP_UNKNOWN225: {value: OP_UNKNOWN225, name: "OP_UNKNOWN225", length: 1, OP_UNKNOWN214: {OP_UNKNOWN214, "OP_UNKNOWN214", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN215: {OP_UNKNOWN215, "OP_UNKNOWN215", 1, opcodeInvalid},
OP_UNKNOWN226: {value: OP_UNKNOWN226, name: "OP_UNKNOWN226", length: 1, OP_UNKNOWN216: {OP_UNKNOWN216, "OP_UNKNOWN216", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN217: {OP_UNKNOWN217, "OP_UNKNOWN217", 1, opcodeInvalid},
OP_UNKNOWN227: {value: OP_UNKNOWN227, name: "OP_UNKNOWN227", length: 1, OP_UNKNOWN218: {OP_UNKNOWN218, "OP_UNKNOWN218", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN219: {OP_UNKNOWN219, "OP_UNKNOWN219", 1, opcodeInvalid},
OP_UNKNOWN228: {value: OP_UNKNOWN228, name: "OP_UNKNOWN228", length: 1, OP_UNKNOWN220: {OP_UNKNOWN220, "OP_UNKNOWN220", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN221: {OP_UNKNOWN221, "OP_UNKNOWN221", 1, opcodeInvalid},
OP_UNKNOWN229: {value: OP_UNKNOWN229, name: "OP_UNKNOWN229", length: 1, OP_UNKNOWN222: {OP_UNKNOWN222, "OP_UNKNOWN222", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN223: {OP_UNKNOWN223, "OP_UNKNOWN223", 1, opcodeInvalid},
OP_UNKNOWN230: {value: OP_UNKNOWN230, name: "OP_UNKNOWN230", length: 1, OP_UNKNOWN224: {OP_UNKNOWN224, "OP_UNKNOWN224", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN225: {OP_UNKNOWN225, "OP_UNKNOWN225", 1, opcodeInvalid},
OP_UNKNOWN231: {value: OP_UNKNOWN231, name: "OP_UNKNOWN231", length: 1, OP_UNKNOWN226: {OP_UNKNOWN226, "OP_UNKNOWN226", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN227: {OP_UNKNOWN227, "OP_UNKNOWN227", 1, opcodeInvalid},
OP_UNKNOWN232: {value: OP_UNKNOWN232, name: "OP_UNKNOWN232", length: 1, OP_UNKNOWN228: {OP_UNKNOWN228, "OP_UNKNOWN228", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN229: {OP_UNKNOWN229, "OP_UNKNOWN229", 1, opcodeInvalid},
OP_UNKNOWN233: {value: OP_UNKNOWN233, name: "OP_UNKNOWN233", length: 1, OP_UNKNOWN230: {OP_UNKNOWN230, "OP_UNKNOWN230", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN231: {OP_UNKNOWN231, "OP_UNKNOWN231", 1, opcodeInvalid},
OP_UNKNOWN234: {value: OP_UNKNOWN234, name: "OP_UNKNOWN234", length: 1, OP_UNKNOWN232: {OP_UNKNOWN232, "OP_UNKNOWN232", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN233: {OP_UNKNOWN233, "OP_UNKNOWN233", 1, opcodeInvalid},
OP_UNKNOWN235: {value: OP_UNKNOWN235, name: "OP_UNKNOWN235", length: 1, OP_UNKNOWN234: {OP_UNKNOWN234, "OP_UNKNOWN234", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN235: {OP_UNKNOWN235, "OP_UNKNOWN235", 1, opcodeInvalid},
OP_UNKNOWN236: {value: OP_UNKNOWN236, name: "OP_UNKNOWN236", length: 1, OP_UNKNOWN236: {OP_UNKNOWN236, "OP_UNKNOWN236", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN237: {OP_UNKNOWN237, "OP_UNKNOWN237", 1, opcodeInvalid},
OP_UNKNOWN237: {value: OP_UNKNOWN237, name: "OP_UNKNOWN237", length: 1, OP_UNKNOWN238: {OP_UNKNOWN238, "OP_UNKNOWN238", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN239: {OP_UNKNOWN239, "OP_UNKNOWN239", 1, opcodeInvalid},
OP_UNKNOWN238: {value: OP_UNKNOWN238, name: "OP_UNKNOWN238", length: 1, OP_UNKNOWN240: {OP_UNKNOWN240, "OP_UNKNOWN240", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN241: {OP_UNKNOWN241, "OP_UNKNOWN241", 1, opcodeInvalid},
OP_UNKNOWN239: {value: OP_UNKNOWN239, name: "OP_UNKNOWN239", length: 1, OP_UNKNOWN242: {OP_UNKNOWN242, "OP_UNKNOWN242", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN243: {OP_UNKNOWN243, "OP_UNKNOWN243", 1, opcodeInvalid},
OP_UNKNOWN240: {value: OP_UNKNOWN240, name: "OP_UNKNOWN240", length: 1, OP_UNKNOWN244: {OP_UNKNOWN244, "OP_UNKNOWN244", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN245: {OP_UNKNOWN245, "OP_UNKNOWN245", 1, opcodeInvalid},
OP_UNKNOWN241: {value: OP_UNKNOWN241, name: "OP_UNKNOWN241", length: 1, OP_UNKNOWN246: {OP_UNKNOWN246, "OP_UNKNOWN246", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_UNKNOWN247: {OP_UNKNOWN247, "OP_UNKNOWN247", 1, opcodeInvalid},
OP_UNKNOWN242: {value: OP_UNKNOWN242, name: "OP_UNKNOWN242", length: 1, OP_UNKNOWN248: {OP_UNKNOWN248, "OP_UNKNOWN248", 1, opcodeInvalid},
opfunc: opcodeInvalid},
OP_UNKNOWN243: {value: OP_UNKNOWN243, name: "OP_UNKNOWN243", length: 1, // Bitcoin Core internal use opcode. Defined here for completeness.
opfunc: opcodeInvalid}, OP_SMALLDATA: {OP_SMALLDATA, "OP_SMALLDATA", 1, opcodeInvalid},
OP_UNKNOWN244: {value: OP_UNKNOWN244, name: "OP_UNKNOWN244", length: 1, OP_SMALLINTEGER: {OP_SMALLINTEGER, "OP_SMALLINTEGER", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_PUBKEYS: {OP_PUBKEYS, "OP_PUBKEYS", 1, opcodeInvalid},
OP_UNKNOWN245: {value: OP_UNKNOWN245, name: "OP_UNKNOWN245", length: 1, OP_UNKNOWN252: {OP_UNKNOWN252, "OP_UNKNOWN252", 1, opcodeInvalid},
opfunc: opcodeInvalid}, OP_PUBKEYHASH: {OP_PUBKEYHASH, "OP_PUBKEYHASH", 1, opcodeInvalid},
OP_UNKNOWN246: {value: OP_UNKNOWN246, name: "OP_UNKNOWN246", length: 1, OP_PUBKEY: {OP_PUBKEY, "OP_PUBKEY", 1, opcodeInvalid},
opfunc: opcodeInvalid},
OP_UNKNOWN247: {value: OP_UNKNOWN247, name: "OP_UNKNOWN247", length: 1, OP_INVALIDOPCODE: {OP_INVALIDOPCODE, "OP_INVALIDOPCODE", 1, opcodeInvalid},
opfunc: opcodeInvalid},
OP_UNKNOWN248: {value: OP_UNKNOWN248, name: "OP_UNKNOWN248", length: 1,
opfunc: opcodeInvalid},
OP_SMALLDATA: {value: OP_SMALLDATA, name: "OP_SMALLDATA", length: 1,
opfunc: opcodeInvalid},
OP_SMALLINTEGER: {value: OP_SMALLINTEGER, name: "OP_SMALLINTEGER",
length: 1, opfunc: opcodeInvalid},
OP_PUBKEYS: {value: OP_PUBKEYS, name: "OP_PUBKEYS", length: 1,
opfunc: opcodeInvalid},
OP_UNKNOWN252: {value: OP_UNKNOWN252, name: "OP_UNKNOWN252", length: 1,
opfunc: opcodeInvalid},
OP_PUBKEYHASH: {value: OP_PUBKEYHASH, name: "OP_PUBKEYHASH", length: 1,
opfunc: opcodeInvalid},
OP_PUBKEY: {value: OP_PUBKEY, name: "OP_PUBKEY", length: 1,
opfunc: opcodeInvalid},
OP_INVALIDOPCODE: {value: OP_INVALIDOPCODE, name: "OP_INVALIDOPCODE",
length: 1, opfunc: opcodeInvalid},
} }
// opcodeOnelineRepls defines opcode names which are replaced when doing a // opcodeOnelineRepls defines opcode names which are replaced when doing a
@ -1132,8 +884,8 @@ func opcodeNop(op *parsedOpcode, vm *Engine) error {
case OP_NOP1, OP_NOP2, OP_NOP3, OP_NOP4, OP_NOP5, case OP_NOP1, OP_NOP2, OP_NOP3, OP_NOP4, OP_NOP5,
OP_NOP6, OP_NOP7, OP_NOP8, OP_NOP9, OP_NOP10: OP_NOP6, OP_NOP7, OP_NOP8, OP_NOP9, OP_NOP10:
if vm.hasFlag(ScriptDiscourageUpgradableNops) { if vm.hasFlag(ScriptDiscourageUpgradableNops) {
return fmt.Errorf("%s reserved for soft-fork upgrades", return fmt.Errorf("OP_NOP%d reserved for soft-fork "+
opcodemap[op.opcode.value].name) "upgrades", op.opcode.value-OP_NOP1+1)
} }
} }
return nil return nil

View file

@ -56,7 +56,8 @@ func parseShortForm(script string) ([]byte, error) {
// 0x14 is OP_DATA_20) // 0x14 is OP_DATA_20)
// - single quoted strings are pushed as data. // - single quoted strings are pushed as data.
// - anything else is an error. // - anything else is an error.
for _, op := range opcodemap { for i := range opcodeArray {
op := &opcodeArray[i]
if op.value < OP_NOP && op.value != OP_RESERVED { if op.value < OP_NOP && op.value != OP_RESERVED {
continue continue
} }

View file

@ -264,21 +264,18 @@ func typeOfScript(pops []parsedOpcode) ScriptClass {
// parseScript preparses the script in bytes into a list of parsedOpcodes while // parseScript preparses the script in bytes into a list of parsedOpcodes while
// applying a number of sanity checks. // applying a number of sanity checks.
func parseScript(script []byte) ([]parsedOpcode, error) { func parseScript(script []byte) ([]parsedOpcode, error) {
return parseScriptTemplate(script, opcodemap) return parseScriptTemplate(script, &opcodeArray)
} }
// parseScriptTemplate is the same as parseScript but allows the passing of the // parseScriptTemplate is the same as parseScript but allows the passing of the
// template list for testing purposes. On error we return the list of parsed // template list for testing purposes. On error we return the list of parsed
// opcodes so far. // opcodes so far.
func parseScriptTemplate(script []byte, opcodemap map[byte]*opcode) ([]parsedOpcode, error) { func parseScriptTemplate(script []byte, opcodes *[256]opcode) ([]parsedOpcode, error) {
retScript := make([]parsedOpcode, 0, len(script)) retScript := make([]parsedOpcode, 0, len(script))
for i := 0; i < len(script); { for i := 0; i < len(script); {
instr := script[i] instr := script[i]
op, ok := opcodemap[instr] op := opcodes[instr]
if !ok { pop := parsedOpcode{opcode: &op}
return retScript, ErrStackInvalidOpcode
}
pop := parsedOpcode{opcode: op}
// parse data out of instruction. // parse data out of instruction.
switch { switch {
case op.length == 1: case op.length == 1: