比特币全节点Go语言实现BTCD之操作码解析

​ 操作码来源于比特币脚本语言,通过操作码可以在公钥脚本或签名脚本中实现压入数据或执行函数的操作。

比特币节点可以配置是否接受非标准交易,所以有个交易标准化验证方法。代码如下:

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,欢迎收藏,转载请保留原文地址并保留版权声明!谢谢~
还没完!往下看!!!



猜你喜欢

转载自blog.csdn.net/vohyeah/article/details/80704209