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 }