操作码来源于比特币脚本语言,通过操作码可以在公钥脚本或签名脚本中实现压入数据或执行函数的操作。
比特币节点可以配置是否接受非标准交易,所以有个交易标准化验证方法。代码如下:
func checkTransactionStandard(tx *btcutil.Tx, height int32, medianTimePast time.Time, minRelayTxFee btcutil.Amount, maxTxVersion int32) error { msgTx := tx.MsgTx() if msgTx.Version > maxTxVersion || msgTx.Version < 1 { str := fmt.Sprintf("transaction version %d is not in the "+ "valid range of %d-%d", msgTx.Version, 1, maxTxVersion) return txRuleError(wire.RejectNonstandard, str) } if !blockchain.IsFinalizedTransaction(tx, height, medianTimePast) { return txRuleError(wire.RejectNonstandard, "transaction is not finalized") } txWeight := blockchain.GetTransactionWeight(tx) if txWeight > maxStandardTxWeight { str := fmt.Sprintf("weight of transaction %v is larger than max "+ "allowed weight of %v", txWeight, maxStandardTxWeight) return txRuleError(wire.RejectNonstandard, str) } for i, txIn := range msgTx.TxIn { sigScriptLen := len(txIn.SignatureScript) if sigScriptLen > maxStandardSigScriptSize { str := fmt.Sprintf("transaction input %d: signature "+ "script size of %d bytes is large than max "+ "allowed size of %d bytes", i, sigScriptLen, maxStandardSigScriptSize) return txRuleError(wire.RejectNonstandard, str) } if !txscript.IsPushOnlyScript(txIn.SignatureScript) { str := fmt.Sprintf("transaction input %d: signature "+ "script is not push only", i) return txRuleError(wire.RejectNonstandard, str) } } numNullDataOutputs := 0 for i, txOut := range msgTx.TxOut { scriptClass := txscript.GetScriptClass(txOut.PkScript) err := checkPkScriptStandard(txOut.PkScript, scriptClass) if err != nil { rejectCode := wire.RejectNonstandard if rejCode, found := extractRejectCode(err); found { rejectCode = rejCode } str := fmt.Sprintf("transaction output %d: %v", i, err) return txRuleError(rejectCode, str) } if scriptClass == txscript.NullDataTy { numNullDataOutputs++ } else if isDust(txOut, minRelayTxFee) { str := fmt.Sprintf("transaction output %d: payment "+ "of %d is dust", i, txOut.Value) return txRuleError(wire.RejectDust, str) } } if numNullDataOutputs > 1 { str := "more than one transaction output in a nulldata script" return txRuleError(wire.RejectNonstandard, str) } return nil }
有两个主要逻辑,分别是对input、output进行检查:
for i, txIn := range msgTx.TxIn {
for i, txOut := range msgTx.TxOut {
对于输入,输入脚本的指令需要全部为push指令,检查:
if !txscript.IsPushOnlyScript(txIn.SignatureScript) {
func IsPushOnlyScript(script []byte) bool { pops, err := parseScript(script) if err != nil { return false } return isPushOnly(pops) }
pops, err := parseScript(script)
是负责解析脚本。方法如下:
func parseScript(script []byte) ([]parsedOpcode, error) { return parseScriptTemplate(script, &opcodeArray) }
&opcodeArray
即包括所有的指令。OPCode一共256个,所有指令集如下:
var opcodeArray = [256]opcode{ // Data push opcodes. OP_FALSE: {OP_FALSE, "OP_0", 1, opcodeFalse}, OP_DATA_1: {OP_DATA_1, "OP_DATA_1", 2, opcodePushData}, 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}, // Control opcodes. 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}, OP_CHECKLOCKTIMEVERIFY: {OP_CHECKLOCKTIMEVERIFY, "OP_CHECKLOCKTIMEVERIFY", 1, opcodeCheckLockTimeVerify}, OP_CHECKSEQUENCEVERIFY: {OP_CHECKSEQUENCEVERIFY, "OP_CHECKSEQUENCEVERIFY", 1, opcodeCheckSequenceVerify}, // Stack opcodes. OP_TOALTSTACK: {OP_TOALTSTACK, "OP_TOALTSTACK", 1, opcodeToAltStack}, OP_FROMALTSTACK: {OP_FROMALTSTACK, "OP_FROMALTSTACK", 1, opcodeFromAltStack}, OP_2DROP: {OP_2DROP, "OP_2DROP", 1, opcode2Drop}, OP_2DUP: {OP_2DUP, "OP_2DUP", 1, opcode2Dup}, OP_3DUP: {OP_3DUP, "OP_3DUP", 1, opcode3Dup}, OP_2OVER: {OP_2OVER, "OP_2OVER", 1, opcode2Over}, OP_2ROT: {OP_2ROT, "OP_2ROT", 1, opcode2Rot}, OP_2SWAP: {OP_2SWAP, "OP_2SWAP", 1, opcode2Swap}, OP_IFDUP: {OP_IFDUP, "OP_IFDUP", 1, opcodeIfDup}, OP_DEPTH: {OP_DEPTH, "OP_DEPTH", 1, opcodeDepth}, OP_DROP: {OP_DROP, "OP_DROP", 1, opcodeDrop}, OP_DUP: {OP_DUP, "OP_DUP", 1, opcodeDup}, OP_NIP: {OP_NIP, "OP_NIP", 1, opcodeNip}, OP_OVER: {OP_OVER, "OP_OVER", 1, opcodeOver}, OP_PICK: {OP_PICK, "OP_PICK", 1, opcodePick}, OP_ROLL: {OP_ROLL, "OP_ROLL", 1, opcodeRoll}, OP_ROT: {OP_ROT, "OP_ROT", 1, opcodeRot}, OP_SWAP: {OP_SWAP, "OP_SWAP", 1, opcodeSwap}, OP_TUCK: {OP_TUCK, "OP_TUCK", 1, opcodeTuck}, // Splice opcodes. OP_CAT: {OP_CAT, "OP_CAT", 1, opcodeDisabled}, OP_SUBSTR: {OP_SUBSTR, "OP_SUBSTR", 1, opcodeDisabled}, OP_LEFT: {OP_LEFT, "OP_LEFT", 1, opcodeDisabled}, OP_RIGHT: {OP_RIGHT, "OP_RIGHT", 1, opcodeDisabled}, OP_SIZE: {OP_SIZE, "OP_SIZE", 1, opcodeSize}, // Bitwise logic opcodes. OP_INVERT: {OP_INVERT, "OP_INVERT", 1, opcodeDisabled}, OP_AND: {OP_AND, "OP_AND", 1, opcodeDisabled}, OP_OR: {OP_OR, "OP_OR", 1, opcodeDisabled}, OP_XOR: {OP_XOR, "OP_XOR", 1, opcodeDisabled}, OP_EQUAL: {OP_EQUAL, "OP_EQUAL", 1, opcodeEqual}, OP_EQUALVERIFY: {OP_EQUALVERIFY, "OP_EQUALVERIFY", 1, opcodeEqualVerify}, OP_RESERVED1: {OP_RESERVED1, "OP_RESERVED1", 1, opcodeReserved}, OP_RESERVED2: {OP_RESERVED2, "OP_RESERVED2", 1, opcodeReserved}, // Numeric related opcodes. OP_1ADD: {OP_1ADD, "OP_1ADD", 1, opcode1Add}, OP_1SUB: {OP_1SUB, "OP_1SUB", 1, opcode1Sub}, OP_2MUL: {OP_2MUL, "OP_2MUL", 1, opcodeDisabled}, OP_2DIV: {OP_2DIV, "OP_2DIV", 1, opcodeDisabled}, OP_NEGATE: {OP_NEGATE, "OP_NEGATE", 1, opcodeNegate}, OP_ABS: {OP_ABS, "OP_ABS", 1, opcodeAbs}, OP_NOT: {OP_NOT, "OP_NOT", 1, opcodeNot}, OP_0NOTEQUAL: {OP_0NOTEQUAL, "OP_0NOTEQUAL", 1, opcode0NotEqual}, OP_ADD: {OP_ADD, "OP_ADD", 1, opcodeAdd}, OP_SUB: {OP_SUB, "OP_SUB", 1, opcodeSub}, OP_MUL: {OP_MUL, "OP_MUL", 1, opcodeDisabled}, OP_DIV: {OP_DIV, "OP_DIV", 1, opcodeDisabled}, OP_MOD: {OP_MOD, "OP_MOD", 1, opcodeDisabled}, OP_LSHIFT: {OP_LSHIFT, "OP_LSHIFT", 1, opcodeDisabled}, OP_RSHIFT: {OP_RSHIFT, "OP_RSHIFT", 1, opcodeDisabled}, OP_BOOLAND: {OP_BOOLAND, "OP_BOOLAND", 1, opcodeBoolAnd}, OP_BOOLOR: {OP_BOOLOR, "OP_BOOLOR", 1, opcodeBoolOr}, OP_NUMEQUAL: {OP_NUMEQUAL, "OP_NUMEQUAL", 1, opcodeNumEqual}, OP_NUMEQUALVERIFY: {OP_NUMEQUALVERIFY, "OP_NUMEQUALVERIFY", 1, opcodeNumEqualVerify}, OP_NUMNOTEQUAL: {OP_NUMNOTEQUAL, "OP_NUMNOTEQUAL", 1, opcodeNumNotEqual}, OP_LESSTHAN: {OP_LESSTHAN, "OP_LESSTHAN", 1, opcodeLessThan}, OP_GREATERTHAN: {OP_GREATERTHAN, "OP_GREATERTHAN", 1, opcodeGreaterThan}, OP_LESSTHANOREQUAL: {OP_LESSTHANOREQUAL, "OP_LESSTHANOREQUAL", 1, opcodeLessThanOrEqual}, OP_GREATERTHANOREQUAL: {OP_GREATERTHANOREQUAL, "OP_GREATERTHANOREQUAL", 1, opcodeGreaterThanOrEqual}, OP_MIN: {OP_MIN, "OP_MIN", 1, opcodeMin}, OP_MAX: {OP_MAX, "OP_MAX", 1, opcodeMax}, OP_WITHIN: {OP_WITHIN, "OP_WITHIN", 1, opcodeWithin}, // Crypto opcodes. OP_RIPEMD160: {OP_RIPEMD160, "OP_RIPEMD160", 1, opcodeRipemd160}, OP_SHA1: {OP_SHA1, "OP_SHA1", 1, opcodeSha1}, OP_SHA256: {OP_SHA256, "OP_SHA256", 1, opcodeSha256}, OP_HASH160: {OP_HASH160, "OP_HASH160", 1, opcodeHash160}, OP_HASH256: {OP_HASH256, "OP_HASH256", 1, opcodeHash256}, OP_CODESEPARATOR: {OP_CODESEPARATOR, "OP_CODESEPARATOR", 1, opcodeCodeSeparator}, OP_CHECKSIG: {OP_CHECKSIG, "OP_CHECKSIG", 1, opcodeCheckSig}, OP_CHECKSIGVERIFY: {OP_CHECKSIGVERIFY, "OP_CHECKSIGVERIFY", 1, opcodeCheckSigVerify}, OP_CHECKMULTISIG: {OP_CHECKMULTISIG, "OP_CHECKMULTISIG", 1, opcodeCheckMultiSig}, OP_CHECKMULTISIGVERIFY: {OP_CHECKMULTISIGVERIFY, "OP_CHECKMULTISIGVERIFY", 1, opcodeCheckMultiSigVerify}, // Reserved opcodes. OP_NOP1: {OP_NOP1, "OP_NOP1", 1, opcodeNop}, OP_NOP4: {OP_NOP4, "OP_NOP4", 1, opcodeNop}, OP_NOP5: {OP_NOP5, "OP_NOP5", 1, opcodeNop}, OP_NOP6: {OP_NOP6, "OP_NOP6", 1, opcodeNop}, OP_NOP7: {OP_NOP7, "OP_NOP7", 1, opcodeNop}, OP_NOP8: {OP_NOP8, "OP_NOP8", 1, opcodeNop}, OP_NOP9: {OP_NOP9, "OP_NOP9", 1, opcodeNop}, OP_NOP10: {OP_NOP10, "OP_NOP10", 1, opcodeNop}, // Undefined opcodes. OP_UNKNOWN186: {OP_UNKNOWN186, "OP_UNKNOWN186", 1, opcodeInvalid}, OP_UNKNOWN187: {OP_UNKNOWN187, "OP_UNKNOWN187", 1, opcodeInvalid}, OP_UNKNOWN188: {OP_UNKNOWN188, "OP_UNKNOWN188", 1, opcodeInvalid}, OP_UNKNOWN189: {OP_UNKNOWN189, "OP_UNKNOWN189", 1, opcodeInvalid}, OP_UNKNOWN190: {OP_UNKNOWN190, "OP_UNKNOWN190", 1, opcodeInvalid}, OP_UNKNOWN191: {OP_UNKNOWN191, "OP_UNKNOWN191", 1, opcodeInvalid}, OP_UNKNOWN192: {OP_UNKNOWN192, "OP_UNKNOWN192", 1, opcodeInvalid}, OP_UNKNOWN193: {OP_UNKNOWN193, "OP_UNKNOWN193", 1, opcodeInvalid}, OP_UNKNOWN194: {OP_UNKNOWN194, "OP_UNKNOWN194", 1, opcodeInvalid}, OP_UNKNOWN195: {OP_UNKNOWN195, "OP_UNKNOWN195", 1, opcodeInvalid}, OP_UNKNOWN196: {OP_UNKNOWN196, "OP_UNKNOWN196", 1, opcodeInvalid}, OP_UNKNOWN197: {OP_UNKNOWN197, "OP_UNKNOWN197", 1, opcodeInvalid}, OP_UNKNOWN198: {OP_UNKNOWN198, "OP_UNKNOWN198", 1, opcodeInvalid}, OP_UNKNOWN199: {OP_UNKNOWN199, "OP_UNKNOWN199", 1, opcodeInvalid}, OP_UNKNOWN200: {OP_UNKNOWN200, "OP_UNKNOWN200", 1, opcodeInvalid}, OP_UNKNOWN201: {OP_UNKNOWN201, "OP_UNKNOWN201", 1, opcodeInvalid}, OP_UNKNOWN202: {OP_UNKNOWN202, "OP_UNKNOWN202", 1, opcodeInvalid}, OP_UNKNOWN203: {OP_UNKNOWN203, "OP_UNKNOWN203", 1, opcodeInvalid}, OP_UNKNOWN204: {OP_UNKNOWN204, "OP_UNKNOWN204", 1, opcodeInvalid}, OP_UNKNOWN205: {OP_UNKNOWN205, "OP_UNKNOWN205", 1, opcodeInvalid}, OP_UNKNOWN206: {OP_UNKNOWN206, "OP_UNKNOWN206", 1, opcodeInvalid}, OP_UNKNOWN207: {OP_UNKNOWN207, "OP_UNKNOWN207", 1, opcodeInvalid}, OP_UNKNOWN208: {OP_UNKNOWN208, "OP_UNKNOWN208", 1, opcodeInvalid}, OP_UNKNOWN209: {OP_UNKNOWN209, "OP_UNKNOWN209", 1, opcodeInvalid}, OP_UNKNOWN210: {OP_UNKNOWN210, "OP_UNKNOWN210", 1, opcodeInvalid}, OP_UNKNOWN211: {OP_UNKNOWN211, "OP_UNKNOWN211", 1, opcodeInvalid}, OP_UNKNOWN212: {OP_UNKNOWN212, "OP_UNKNOWN212", 1, opcodeInvalid}, OP_UNKNOWN213: {OP_UNKNOWN213, "OP_UNKNOWN213", 1, opcodeInvalid}, OP_UNKNOWN214: {OP_UNKNOWN214, "OP_UNKNOWN214", 1, opcodeInvalid}, OP_UNKNOWN215: {OP_UNKNOWN215, "OP_UNKNOWN215", 1, opcodeInvalid}, OP_UNKNOWN216: {OP_UNKNOWN216, "OP_UNKNOWN216", 1, opcodeInvalid}, OP_UNKNOWN217: {OP_UNKNOWN217, "OP_UNKNOWN217", 1, opcodeInvalid}, OP_UNKNOWN218: {OP_UNKNOWN218, "OP_UNKNOWN218", 1, opcodeInvalid}, OP_UNKNOWN219: {OP_UNKNOWN219, "OP_UNKNOWN219", 1, opcodeInvalid}, OP_UNKNOWN220: {OP_UNKNOWN220, "OP_UNKNOWN220", 1, opcodeInvalid}, OP_UNKNOWN221: {OP_UNKNOWN221, "OP_UNKNOWN221", 1, opcodeInvalid}, OP_UNKNOWN222: {OP_UNKNOWN222, "OP_UNKNOWN222", 1, opcodeInvalid}, OP_UNKNOWN223: {OP_UNKNOWN223, "OP_UNKNOWN223", 1, opcodeInvalid}, OP_UNKNOWN224: {OP_UNKNOWN224, "OP_UNKNOWN224", 1, opcodeInvalid}, OP_UNKNOWN225: {OP_UNKNOWN225, "OP_UNKNOWN225", 1, opcodeInvalid}, OP_UNKNOWN226: {OP_UNKNOWN226, "OP_UNKNOWN226", 1, opcodeInvalid}, OP_UNKNOWN227: {OP_UNKNOWN227, "OP_UNKNOWN227", 1, opcodeInvalid}, OP_UNKNOWN228: {OP_UNKNOWN228, "OP_UNKNOWN228", 1, opcodeInvalid}, OP_UNKNOWN229: {OP_UNKNOWN229, "OP_UNKNOWN229", 1, opcodeInvalid}, OP_UNKNOWN230: {OP_UNKNOWN230, "OP_UNKNOWN230", 1, opcodeInvalid}, OP_UNKNOWN231: {OP_UNKNOWN231, "OP_UNKNOWN231", 1, opcodeInvalid}, OP_UNKNOWN232: {OP_UNKNOWN232, "OP_UNKNOWN232", 1, opcodeInvalid}, OP_UNKNOWN233: {OP_UNKNOWN233, "OP_UNKNOWN233", 1, opcodeInvalid}, OP_UNKNOWN234: {OP_UNKNOWN234, "OP_UNKNOWN234", 1, opcodeInvalid}, OP_UNKNOWN235: {OP_UNKNOWN235, "OP_UNKNOWN235", 1, opcodeInvalid}, OP_UNKNOWN236: {OP_UNKNOWN236, "OP_UNKNOWN236", 1, opcodeInvalid}, OP_UNKNOWN237: {OP_UNKNOWN237, "OP_UNKNOWN237", 1, opcodeInvalid}, OP_UNKNOWN238: {OP_UNKNOWN238, "OP_UNKNOWN238", 1, opcodeInvalid}, OP_UNKNOWN239: {OP_UNKNOWN239, "OP_UNKNOWN239", 1, opcodeInvalid}, OP_UNKNOWN240: {OP_UNKNOWN240, "OP_UNKNOWN240", 1, opcodeInvalid}, OP_UNKNOWN241: {OP_UNKNOWN241, "OP_UNKNOWN241", 1, opcodeInvalid}, OP_UNKNOWN242: {OP_UNKNOWN242, "OP_UNKNOWN242", 1, opcodeInvalid}, OP_UNKNOWN243: {OP_UNKNOWN243, "OP_UNKNOWN243", 1, opcodeInvalid}, OP_UNKNOWN244: {OP_UNKNOWN244, "OP_UNKNOWN244", 1, opcodeInvalid}, OP_UNKNOWN245: {OP_UNKNOWN245, "OP_UNKNOWN245", 1, opcodeInvalid}, OP_UNKNOWN246: {OP_UNKNOWN246, "OP_UNKNOWN246", 1, opcodeInvalid}, OP_UNKNOWN247: {OP_UNKNOWN247, "OP_UNKNOWN247", 1, opcodeInvalid}, OP_UNKNOWN248: {OP_UNKNOWN248, "OP_UNKNOWN248", 1, opcodeInvalid}, OP_UNKNOWN249: {OP_UNKNOWN249, "OP_UNKNOWN249", 1, opcodeInvalid}, // Bitcoin Core internal use opcode. Defined here for completeness. OP_SMALLINTEGER: {OP_SMALLINTEGER, "OP_SMALLINTEGER", 1, opcodeInvalid}, OP_PUBKEYS: {OP_PUBKEYS, "OP_PUBKEYS", 1, opcodeInvalid}, OP_UNKNOWN252: {OP_UNKNOWN252, "OP_UNKNOWN252", 1, opcodeInvalid}, OP_PUBKEYHASH: {OP_PUBKEYHASH, "OP_PUBKEYHASH", 1, opcodeInvalid}, OP_PUBKEY: {OP_PUBKEY, "OP_PUBKEY", 1, opcodeInvalid}, OP_INVALIDOPCODE: {OP_INVALIDOPCODE, "OP_INVALIDOPCODE", 1, opcodeInvalid}, }
执行这些指令是基于栈执行的。如下:
type stack struct { stk [][]byte verifyMinimalData bool } // Depth returns the number of items on the stack. func (s *stack) Depth() int32 { return int32(len(s.stk)) } // PushByteArray adds the given back array to the top of the stack. // // Stack transformation: [... x1 x2] -> [... x1 x2 data] func (s *stack) PushByteArray(so []byte) { s.stk = append(s.stk, so) } // PushInt converts the provided scriptNum to a suitable byte array then pushes // it onto the top of the stack. // // Stack transformation: [... x1 x2] -> [... x1 x2 int] func (s *stack) PushInt(val scriptNum) { s.PushByteArray(val.Bytes()) } // PushBool converts the provided boolean to a suitable byte array then pushes // it onto the top of the stack. // // Stack transformation: [... x1 x2] -> [... x1 x2 bool] func (s *stack) PushBool(val bool) { s.PushByteArray(fromBool(val)) } .............略
本文作者:architect.bian,欢迎收藏,转载请保留原文地址并保留版权声明!谢谢~
还没完!往下看!!!