github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/vm/ops.go (about)

     1  package vm
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"math"
     7  	"reflect"
     8  
     9  	"github.com/bytom/bytom/errors"
    10  	"github.com/bytom/bytom/math/checked"
    11  )
    12  
    13  type Op uint8
    14  
    15  func (op Op) String() string {
    16  	return ops[op].name
    17  }
    18  
    19  type Instruction struct {
    20  	Op   Op
    21  	Len  uint32
    22  	Data []byte
    23  }
    24  
    25  const (
    26  	OP_FALSE Op = 0x00
    27  	OP_0     Op = 0x00 // synonym
    28  
    29  	OP_1    Op = 0x51
    30  	OP_TRUE Op = 0x51 // synonym
    31  
    32  	OP_2  Op = 0x52
    33  	OP_3  Op = 0x53
    34  	OP_4  Op = 0x54
    35  	OP_5  Op = 0x55
    36  	OP_6  Op = 0x56
    37  	OP_7  Op = 0x57
    38  	OP_8  Op = 0x58
    39  	OP_9  Op = 0x59
    40  	OP_10 Op = 0x5a
    41  	OP_11 Op = 0x5b
    42  	OP_12 Op = 0x5c
    43  	OP_13 Op = 0x5d
    44  	OP_14 Op = 0x5e
    45  	OP_15 Op = 0x5f
    46  	OP_16 Op = 0x60
    47  
    48  	OP_DATA_1  Op = 0x01
    49  	OP_DATA_2  Op = 0x02
    50  	OP_DATA_3  Op = 0x03
    51  	OP_DATA_4  Op = 0x04
    52  	OP_DATA_5  Op = 0x05
    53  	OP_DATA_6  Op = 0x06
    54  	OP_DATA_7  Op = 0x07
    55  	OP_DATA_8  Op = 0x08
    56  	OP_DATA_9  Op = 0x09
    57  	OP_DATA_10 Op = 0x0a
    58  	OP_DATA_11 Op = 0x0b
    59  	OP_DATA_12 Op = 0x0c
    60  	OP_DATA_13 Op = 0x0d
    61  	OP_DATA_14 Op = 0x0e
    62  	OP_DATA_15 Op = 0x0f
    63  	OP_DATA_16 Op = 0x10
    64  	OP_DATA_17 Op = 0x11
    65  	OP_DATA_18 Op = 0x12
    66  	OP_DATA_19 Op = 0x13
    67  	OP_DATA_20 Op = 0x14
    68  	OP_DATA_21 Op = 0x15
    69  	OP_DATA_22 Op = 0x16
    70  	OP_DATA_23 Op = 0x17
    71  	OP_DATA_24 Op = 0x18
    72  	OP_DATA_25 Op = 0x19
    73  	OP_DATA_26 Op = 0x1a
    74  	OP_DATA_27 Op = 0x1b
    75  	OP_DATA_28 Op = 0x1c
    76  	OP_DATA_29 Op = 0x1d
    77  	OP_DATA_30 Op = 0x1e
    78  	OP_DATA_31 Op = 0x1f
    79  	OP_DATA_32 Op = 0x20
    80  	OP_DATA_33 Op = 0x21
    81  	OP_DATA_34 Op = 0x22
    82  	OP_DATA_35 Op = 0x23
    83  	OP_DATA_36 Op = 0x24
    84  	OP_DATA_37 Op = 0x25
    85  	OP_DATA_38 Op = 0x26
    86  	OP_DATA_39 Op = 0x27
    87  	OP_DATA_40 Op = 0x28
    88  	OP_DATA_41 Op = 0x29
    89  	OP_DATA_42 Op = 0x2a
    90  	OP_DATA_43 Op = 0x2b
    91  	OP_DATA_44 Op = 0x2c
    92  	OP_DATA_45 Op = 0x2d
    93  	OP_DATA_46 Op = 0x2e
    94  	OP_DATA_47 Op = 0x2f
    95  	OP_DATA_48 Op = 0x30
    96  	OP_DATA_49 Op = 0x31
    97  	OP_DATA_50 Op = 0x32
    98  	OP_DATA_51 Op = 0x33
    99  	OP_DATA_52 Op = 0x34
   100  	OP_DATA_53 Op = 0x35
   101  	OP_DATA_54 Op = 0x36
   102  	OP_DATA_55 Op = 0x37
   103  	OP_DATA_56 Op = 0x38
   104  	OP_DATA_57 Op = 0x39
   105  	OP_DATA_58 Op = 0x3a
   106  	OP_DATA_59 Op = 0x3b
   107  	OP_DATA_60 Op = 0x3c
   108  	OP_DATA_61 Op = 0x3d
   109  	OP_DATA_62 Op = 0x3e
   110  	OP_DATA_63 Op = 0x3f
   111  	OP_DATA_64 Op = 0x40
   112  	OP_DATA_65 Op = 0x41
   113  	OP_DATA_66 Op = 0x42
   114  	OP_DATA_67 Op = 0x43
   115  	OP_DATA_68 Op = 0x44
   116  	OP_DATA_69 Op = 0x45
   117  	OP_DATA_70 Op = 0x46
   118  	OP_DATA_71 Op = 0x47
   119  	OP_DATA_72 Op = 0x48
   120  	OP_DATA_73 Op = 0x49
   121  	OP_DATA_74 Op = 0x4a
   122  	OP_DATA_75 Op = 0x4b
   123  
   124  	OP_PUSHDATA1 Op = 0x4c
   125  	OP_PUSHDATA2 Op = 0x4d
   126  	OP_PUSHDATA4 Op = 0x4e
   127  	OP_1NEGATE   Op = 0x4f
   128  	OP_NOP       Op = 0x61
   129  
   130  	OP_JUMP           Op = 0x63
   131  	OP_JUMPIF         Op = 0x64
   132  	OP_VERIFY         Op = 0x69
   133  	OP_FAIL           Op = 0x6a
   134  	OP_CHECKPREDICATE Op = 0xc0
   135  
   136  	OP_TOALTSTACK   Op = 0x6b
   137  	OP_FROMALTSTACK Op = 0x6c
   138  	OP_2DROP        Op = 0x6d
   139  	OP_2DUP         Op = 0x6e
   140  	OP_3DUP         Op = 0x6f
   141  	OP_2OVER        Op = 0x70
   142  	OP_2ROT         Op = 0x71
   143  	OP_2SWAP        Op = 0x72
   144  	OP_IFDUP        Op = 0x73
   145  	OP_DEPTH        Op = 0x74
   146  	OP_DROP         Op = 0x75
   147  	OP_DUP          Op = 0x76
   148  	OP_NIP          Op = 0x77
   149  	OP_OVER         Op = 0x78
   150  	OP_PICK         Op = 0x79
   151  	OP_ROLL         Op = 0x7a
   152  	OP_ROT          Op = 0x7b
   153  	OP_SWAP         Op = 0x7c
   154  	OP_TUCK         Op = 0x7d
   155  
   156  	OP_CAT         Op = 0x7e
   157  	OP_SUBSTR      Op = 0x7f
   158  	OP_LEFT        Op = 0x80
   159  	OP_RIGHT       Op = 0x81
   160  	OP_SIZE        Op = 0x82
   161  	OP_CATPUSHDATA Op = 0x89
   162  
   163  	OP_INVERT      Op = 0x83
   164  	OP_AND         Op = 0x84
   165  	OP_OR          Op = 0x85
   166  	OP_XOR         Op = 0x86
   167  	OP_EQUAL       Op = 0x87
   168  	OP_EQUALVERIFY Op = 0x88
   169  
   170  	OP_1ADD               Op = 0x8b
   171  	OP_1SUB               Op = 0x8c
   172  	OP_2MUL               Op = 0x8d
   173  	OP_2DIV               Op = 0x8e
   174  	OP_NEGATE             Op = 0x8f
   175  	OP_ABS                Op = 0x90
   176  	OP_NOT                Op = 0x91
   177  	OP_0NOTEQUAL          Op = 0x92
   178  	OP_ADD                Op = 0x93
   179  	OP_SUB                Op = 0x94
   180  	OP_MUL                Op = 0x95
   181  	OP_DIV                Op = 0x96
   182  	OP_MOD                Op = 0x97
   183  	OP_LSHIFT             Op = 0x98
   184  	OP_RSHIFT             Op = 0x99
   185  	OP_BOOLAND            Op = 0x9a
   186  	OP_BOOLOR             Op = 0x9b
   187  	OP_NUMEQUAL           Op = 0x9c
   188  	OP_NUMEQUALVERIFY     Op = 0x9d
   189  	OP_NUMNOTEQUAL        Op = 0x9e
   190  	OP_LESSTHAN           Op = 0x9f
   191  	OP_GREATERTHAN        Op = 0xa0
   192  	OP_LESSTHANOREQUAL    Op = 0xa1
   193  	OP_GREATERTHANOREQUAL Op = 0xa2
   194  	OP_MIN                Op = 0xa3
   195  	OP_MAX                Op = 0xa4
   196  	OP_WITHIN             Op = 0xa5
   197  
   198  	OP_SHA256        Op = 0xa8
   199  	OP_SHA3          Op = 0xaa
   200  	OP_HASH160       Op = 0xab
   201  	OP_CHECKSIG      Op = 0xac
   202  	OP_CHECKMULTISIG Op = 0xad
   203  	OP_TXSIGHASH     Op = 0xae
   204  
   205  	OP_CHECKOUTPUT Op = 0xc1
   206  	OP_ASSET       Op = 0xc2
   207  	OP_AMOUNT      Op = 0xc3
   208  	OP_PROGRAM     Op = 0xc4
   209  	OP_INDEX       Op = 0xc9
   210  	OP_ENTRYID     Op = 0xca
   211  	OP_OUTPUTID    Op = 0xcb
   212  	OP_BLOCKHEIGHT Op = 0xcd
   213  )
   214  
   215  type opInfo struct {
   216  	op   Op
   217  	name string
   218  	fn   func(*virtualMachine) error
   219  }
   220  
   221  var (
   222  	ops = [256]opInfo{
   223  		// data pushing
   224  		OP_FALSE: {OP_FALSE, "FALSE", opFalse},
   225  
   226  		// sic: the PUSHDATA ops all share an implementation
   227  		OP_PUSHDATA1: {OP_PUSHDATA1, "PUSHDATA1", opPushdata},
   228  		OP_PUSHDATA2: {OP_PUSHDATA2, "PUSHDATA2", opPushdata},
   229  		OP_PUSHDATA4: {OP_PUSHDATA4, "PUSHDATA4", opPushdata},
   230  
   231  		OP_1NEGATE: {OP_1NEGATE, "1NEGATE", op1Negate},
   232  
   233  		OP_NOP: {OP_NOP, "NOP", opNop},
   234  
   235  		// control flow
   236  		OP_JUMP:   {OP_JUMP, "JUMP", opJump},
   237  		OP_JUMPIF: {OP_JUMPIF, "JUMPIF", opJumpIf},
   238  
   239  		OP_VERIFY: {OP_VERIFY, "VERIFY", opVerify},
   240  		OP_FAIL:   {OP_FAIL, "FAIL", opFail},
   241  
   242  		OP_TOALTSTACK:   {OP_TOALTSTACK, "TOALTSTACK", opToAltStack},
   243  		OP_FROMALTSTACK: {OP_FROMALTSTACK, "FROMALTSTACK", opFromAltStack},
   244  		OP_2DROP:        {OP_2DROP, "2DROP", op2Drop},
   245  		OP_2DUP:         {OP_2DUP, "2DUP", op2Dup},
   246  		OP_3DUP:         {OP_3DUP, "3DUP", op3Dup},
   247  		OP_2OVER:        {OP_2OVER, "2OVER", op2Over},
   248  		OP_2ROT:         {OP_2ROT, "2ROT", op2Rot},
   249  		OP_2SWAP:        {OP_2SWAP, "2SWAP", op2Swap},
   250  		OP_IFDUP:        {OP_IFDUP, "IFDUP", opIfDup},
   251  		OP_DEPTH:        {OP_DEPTH, "DEPTH", opDepth},
   252  		OP_DROP:         {OP_DROP, "DROP", opDrop},
   253  		OP_DUP:          {OP_DUP, "DUP", opDup},
   254  		OP_NIP:          {OP_NIP, "NIP", opNip},
   255  		OP_OVER:         {OP_OVER, "OVER", opOver},
   256  		OP_PICK:         {OP_PICK, "PICK", opPick},
   257  		OP_ROLL:         {OP_ROLL, "ROLL", opRoll},
   258  		OP_ROT:          {OP_ROT, "ROT", opRot},
   259  		OP_SWAP:         {OP_SWAP, "SWAP", opSwap},
   260  		OP_TUCK:         {OP_TUCK, "TUCK", opTuck},
   261  
   262  		OP_CAT:         {OP_CAT, "CAT", opCat},
   263  		OP_SUBSTR:      {OP_SUBSTR, "SUBSTR", opSubstr},
   264  		OP_LEFT:        {OP_LEFT, "LEFT", opLeft},
   265  		OP_RIGHT:       {OP_RIGHT, "RIGHT", opRight},
   266  		OP_SIZE:        {OP_SIZE, "SIZE", opSize},
   267  		OP_CATPUSHDATA: {OP_CATPUSHDATA, "CATPUSHDATA", opCatpushdata},
   268  
   269  		OP_INVERT:      {OP_INVERT, "INVERT", opInvert},
   270  		OP_AND:         {OP_AND, "AND", opAnd},
   271  		OP_OR:          {OP_OR, "OR", opOr},
   272  		OP_XOR:         {OP_XOR, "XOR", opXor},
   273  		OP_EQUAL:       {OP_EQUAL, "EQUAL", opEqual},
   274  		OP_EQUALVERIFY: {OP_EQUALVERIFY, "EQUALVERIFY", opEqualVerify},
   275  
   276  		OP_1ADD:               {OP_1ADD, "1ADD", op1Add},
   277  		OP_1SUB:               {OP_1SUB, "1SUB", op1Sub},
   278  		OP_2MUL:               {OP_2MUL, "2MUL", op2Mul},
   279  		OP_2DIV:               {OP_2DIV, "2DIV", op2Div},
   280  		OP_NEGATE:             {OP_NEGATE, "NEGATE", opNegate},
   281  		OP_ABS:                {OP_ABS, "ABS", opAbs},
   282  		OP_NOT:                {OP_NOT, "NOT", opNot},
   283  		OP_0NOTEQUAL:          {OP_0NOTEQUAL, "0NOTEQUAL", op0NotEqual},
   284  		OP_ADD:                {OP_ADD, "ADD", opAdd},
   285  		OP_SUB:                {OP_SUB, "SUB", opSub},
   286  		OP_MUL:                {OP_MUL, "MUL", opMul},
   287  		OP_DIV:                {OP_DIV, "DIV", opDiv},
   288  		OP_MOD:                {OP_MOD, "MOD", opMod},
   289  		OP_LSHIFT:             {OP_LSHIFT, "LSHIFT", opLshift},
   290  		OP_RSHIFT:             {OP_RSHIFT, "RSHIFT", opRshift},
   291  		OP_BOOLAND:            {OP_BOOLAND, "BOOLAND", opBoolAnd},
   292  		OP_BOOLOR:             {OP_BOOLOR, "BOOLOR", opBoolOr},
   293  		OP_NUMEQUAL:           {OP_NUMEQUAL, "NUMEQUAL", opNumEqual},
   294  		OP_NUMEQUALVERIFY:     {OP_NUMEQUALVERIFY, "NUMEQUALVERIFY", opNumEqualVerify},
   295  		OP_NUMNOTEQUAL:        {OP_NUMNOTEQUAL, "NUMNOTEQUAL", opNumNotEqual},
   296  		OP_LESSTHAN:           {OP_LESSTHAN, "LESSTHAN", opLessThan},
   297  		OP_GREATERTHAN:        {OP_GREATERTHAN, "GREATERTHAN", opGreaterThan},
   298  		OP_LESSTHANOREQUAL:    {OP_LESSTHANOREQUAL, "LESSTHANOREQUAL", opLessThanOrEqual},
   299  		OP_GREATERTHANOREQUAL: {OP_GREATERTHANOREQUAL, "GREATERTHANOREQUAL", opGreaterThanOrEqual},
   300  		OP_MIN:                {OP_MIN, "MIN", opMin},
   301  		OP_MAX:                {OP_MAX, "MAX", opMax},
   302  		OP_WITHIN:             {OP_WITHIN, "WITHIN", opWithin},
   303  
   304  		OP_SHA256:        {OP_SHA256, "SHA256", opSha256},
   305  		OP_SHA3:          {OP_SHA3, "SHA3", opSha3},
   306  		OP_HASH160:       {OP_HASH160, "HASH160", opHash160},
   307  		OP_CHECKSIG:      {OP_CHECKSIG, "CHECKSIG", opCheckSig},
   308  		OP_CHECKMULTISIG: {OP_CHECKMULTISIG, "CHECKMULTISIG", opCheckMultiSig},
   309  		OP_TXSIGHASH:     {OP_TXSIGHASH, "TXSIGHASH", opTxSigHash},
   310  
   311  		OP_CHECKOUTPUT: {OP_CHECKOUTPUT, "CHECKOUTPUT", opCheckOutput},
   312  		OP_ASSET:       {OP_ASSET, "ASSET", opAsset},
   313  		OP_AMOUNT:      {OP_AMOUNT, "AMOUNT", opAmount},
   314  		OP_PROGRAM:     {OP_PROGRAM, "PROGRAM", opProgram},
   315  		OP_INDEX:       {OP_INDEX, "INDEX", opIndex},
   316  		OP_ENTRYID:     {OP_ENTRYID, "ENTRYID", opEntryID},
   317  		OP_OUTPUTID:    {OP_OUTPUTID, "OUTPUTID", opOutputID},
   318  		OP_BLOCKHEIGHT: {OP_BLOCKHEIGHT, "BLOCKHEIGHT", opBlockHeight},
   319  	}
   320  
   321  	opsByName map[string]opInfo
   322  )
   323  
   324  // ParseOp parses the op at position pc in prog, returning the parsed
   325  // instruction (opcode plus any associated data).
   326  func ParseOp(prog []byte, pc uint32) (inst Instruction, err error) {
   327  	if len(prog) > math.MaxInt32 {
   328  		err = ErrLongProgram
   329  	}
   330  	l := uint32(len(prog))
   331  	if pc >= l {
   332  		err = ErrShortProgram
   333  		return
   334  	}
   335  	opcode := Op(prog[pc])
   336  	inst.Op = opcode
   337  	inst.Len = 1
   338  	if opcode >= OP_1 && opcode <= OP_16 {
   339  		inst.Data = []byte{uint8(opcode-OP_1) + 1}
   340  		return
   341  	}
   342  	if opcode >= OP_DATA_1 && opcode <= OP_DATA_75 {
   343  		inst.Len += uint32(opcode - OP_DATA_1 + 1)
   344  		end, ok := checked.AddUint32(pc, inst.Len)
   345  		if !ok {
   346  			err = errors.WithDetail(checked.ErrOverflow, "data length exceeds max program size")
   347  			return
   348  		}
   349  		if end > l {
   350  			err = ErrShortProgram
   351  			return
   352  		}
   353  		inst.Data = prog[pc+1 : end]
   354  		return
   355  	}
   356  	if opcode == OP_PUSHDATA1 {
   357  		if pc == l-1 {
   358  			err = ErrShortProgram
   359  			return
   360  		}
   361  		n := prog[pc+1]
   362  		inst.Len += uint32(n) + 1
   363  		end, ok := checked.AddUint32(pc, inst.Len)
   364  		if !ok {
   365  			err = errors.WithDetail(checked.ErrOverflow, "data length exceeds max program size")
   366  		}
   367  		if end > l {
   368  			err = ErrShortProgram
   369  			return
   370  		}
   371  		inst.Data = prog[pc+2 : end]
   372  		return
   373  	}
   374  	if opcode == OP_PUSHDATA2 {
   375  		if len(prog) < 3 || pc > l-3 {
   376  			err = ErrShortProgram
   377  			return
   378  		}
   379  		n := binary.LittleEndian.Uint16(prog[pc+1 : pc+3])
   380  		inst.Len += uint32(n) + 2
   381  		end, ok := checked.AddUint32(pc, inst.Len)
   382  		if !ok {
   383  			err = errors.WithDetail(checked.ErrOverflow, "data length exceeds max program size")
   384  			return
   385  		}
   386  		if end > l {
   387  			err = ErrShortProgram
   388  			return
   389  		}
   390  		inst.Data = prog[pc+3 : end]
   391  		return
   392  	}
   393  	if opcode == OP_PUSHDATA4 {
   394  		if len(prog) < 5 || pc > l-5 {
   395  			err = ErrShortProgram
   396  			return
   397  		}
   398  		inst.Len += 4
   399  
   400  		n := binary.LittleEndian.Uint32(prog[pc+1 : pc+5])
   401  		var ok bool
   402  		inst.Len, ok = checked.AddUint32(inst.Len, n)
   403  		if !ok {
   404  			err = errors.WithDetail(checked.ErrOverflow, "data length exceeds max program size")
   405  			return
   406  		}
   407  		end, ok := checked.AddUint32(pc, inst.Len)
   408  		if !ok {
   409  			err = errors.WithDetail(checked.ErrOverflow, "data length exceeds max program size")
   410  			return
   411  		}
   412  		if end > l {
   413  			err = ErrShortProgram
   414  			return
   415  		}
   416  		inst.Data = prog[pc+5 : end]
   417  		return
   418  	}
   419  	if opcode == OP_JUMP || opcode == OP_JUMPIF {
   420  		inst.Len += 4
   421  		end, ok := checked.AddUint32(pc, inst.Len)
   422  		if !ok {
   423  			err = errors.WithDetail(checked.ErrOverflow, "jump target exceeds max program size")
   424  			return
   425  		}
   426  		if end > l {
   427  			err = ErrShortProgram
   428  			return
   429  		}
   430  		inst.Data = prog[pc+1 : end]
   431  		return
   432  	}
   433  	return
   434  }
   435  
   436  func ParseProgram(prog []byte) ([]Instruction, error) {
   437  	var result []Instruction
   438  	for pc := uint32(0); pc < uint32(len(prog)); { // update pc inside the loop
   439  		inst, err := ParseOp(prog, pc)
   440  		if err != nil {
   441  			return nil, err
   442  		}
   443  		result = append(result, inst)
   444  		var ok bool
   445  		pc, ok = checked.AddUint32(pc, inst.Len)
   446  		if !ok {
   447  			return nil, errors.WithDetail(checked.ErrOverflow, "program counter exceeds max program size")
   448  		}
   449  	}
   450  	return result, nil
   451  }
   452  
   453  var isExpansion [256]bool
   454  
   455  func init() {
   456  	for i := 1; i <= 75; i++ {
   457  		ops[i] = opInfo{Op(i), fmt.Sprintf("DATA_%d", i), opPushdata}
   458  	}
   459  	for i := uint8(0); i <= 15; i++ {
   460  		op := uint8(OP_1) + i
   461  		ops[op] = opInfo{Op(op), fmt.Sprintf("%d", i+1), opPushdata}
   462  	}
   463  
   464  	// This is here to break a dependency cycle
   465  	ops[OP_CHECKPREDICATE] = opInfo{OP_CHECKPREDICATE, "CHECKPREDICATE", opCheckPredicate}
   466  
   467  	opsByName = make(map[string]opInfo)
   468  	for _, info := range ops {
   469  		opsByName[info.name] = info
   470  	}
   471  	opsByName["0"] = ops[OP_FALSE]
   472  	opsByName["TRUE"] = ops[OP_1]
   473  
   474  	for i := 0; i <= 255; i++ {
   475  		if ops[i].name == "" {
   476  			ops[i] = opInfo{Op(i), fmt.Sprintf("NOPx%02x", i), opNop}
   477  			isExpansion[i] = true
   478  		}
   479  	}
   480  }
   481  
   482  // IsPushdata judge instruction whether is a pushdata operation(include opFalse operation)
   483  func (inst *Instruction) IsPushdata() bool {
   484  	if reflect.ValueOf(ops[inst.Op].fn) == reflect.ValueOf(ops[OP_1].fn) ||
   485  		reflect.ValueOf(ops[inst.Op].fn) == reflect.ValueOf(ops[OP_0].fn) {
   486  		return true
   487  	}
   488  
   489  	return false
   490  }