github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/evm/contract.go (about) 1 package evm 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "io/ioutil" 8 "math/big" 9 "strings" 10 11 "github.com/hyperledger/burrow/acm" 12 . "github.com/hyperledger/burrow/binary" 13 "github.com/hyperledger/burrow/crypto" 14 "github.com/hyperledger/burrow/encoding" 15 "github.com/hyperledger/burrow/execution/engine" 16 "github.com/hyperledger/burrow/execution/errors" 17 "github.com/hyperledger/burrow/execution/evm/abi" 18 . "github.com/hyperledger/burrow/execution/evm/asm" 19 "github.com/hyperledger/burrow/execution/exec" 20 "github.com/hyperledger/burrow/permission" 21 "github.com/hyperledger/burrow/txs" 22 ) 23 24 type Contract struct { 25 *EVM 26 *Code 27 } 28 29 func (c *Contract) Call(state engine.State, params engine.CallParams) ([]byte, error) { 30 return engine.Call(state, params, c.execute) 31 } 32 33 // Executes the EVM code passed in the appropriate context 34 func (c *Contract) execute(st engine.State, params engine.CallParams) ([]byte, error) { 35 c.debugf("(%d) (%s) %s (code=%d) gas: %v (d) %X\n", 36 st.CallFrame.CallStackDepth(), params.Caller, params.Callee, c.Length(), *params.Gas, params.Input) 37 38 if c.Length() == 0 { 39 return nil, nil 40 } 41 42 if c.options.DumpTokens { 43 dumpTokens(c.options.Nonce, params.Caller, params.Callee, c.GetBytecode()) 44 } 45 46 // Program counter - the index into code that tracks current instruction 47 var pc uint64 48 // Return data from a call 49 var returnData []byte 50 51 // Maybe serves 3 purposes: 1. provides 'capture first error semantics', 2. reduces clutter of error handling 52 // particular for 1, 3. acts a shared error sink for stack, memory, and the main execute loop 53 maybe := new(errors.Maybe) 54 55 // Provide stack and memory storage - passing in the callState as an error provider 56 stack := NewStack(maybe, c.options.DataStackInitialCapacity, c.options.DataStackMaxDepth, params.Gas) 57 memory := c.options.MemoryProvider(maybe) 58 59 for { 60 // Check for any error in this frame. 61 if maybe.Error() != nil { 62 return nil, maybe.Error() 63 } 64 65 var op = c.GetSymbol(pc) 66 c.debugf("(pc) %-3d (op) %-14s (st) %-4d (gas) %d", pc, op.String(), stack.Len(), params.Gas) 67 // Use BaseOp gas. 68 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasBaseOp)) 69 70 switch op { 71 72 case ADD: // 0x01 73 x, y := stack.PopBigInt(), stack.PopBigInt() 74 sum := new(big.Int).Add(x, y) 75 res := stack.PushBigInt(sum) 76 c.debugf(" %v + %v = %v (%v)\n", x, y, sum, res) 77 78 case MUL: // 0x02 79 x, y := stack.PopBigInt(), stack.PopBigInt() 80 prod := new(big.Int).Mul(x, y) 81 res := stack.PushBigInt(prod) 82 c.debugf(" %v * %v = %v (%v)\n", x, y, prod, res) 83 84 case SUB: // 0x03 85 x, y := stack.PopBigInt(), stack.PopBigInt() 86 diff := new(big.Int).Sub(x, y) 87 res := stack.PushBigInt(diff) 88 c.debugf(" %v - %v = %v (%v)\n", x, y, diff, res) 89 90 case DIV: // 0x04 91 x, y := stack.PopBigInt(), stack.PopBigInt() 92 if y.Sign() == 0 { 93 stack.Push(Zero256) 94 c.debugf(" %v / %v = %v\n", x, y, 0) 95 } else { 96 div := new(big.Int).Div(x, y) 97 res := stack.PushBigInt(div) 98 c.debugf(" %v / %v = %v (%v)\n", x, y, div, res) 99 } 100 101 case SDIV: // 0x05 102 x, y := stack.PopBigIntSigned(), stack.PopBigIntSigned() 103 if y.Sign() == 0 { 104 stack.Push(Zero256) 105 c.debugf(" %v / %v = %v\n", x, y, 0) 106 } else { 107 div := new(big.Int).Quo(x, y) 108 res := stack.PushBigInt(div) 109 c.debugf(" %v / %v = %v (%v)\n", x, y, div, res) 110 } 111 112 case MOD: // 0x06 113 x, y := stack.PopBigInt(), stack.PopBigInt() 114 if y.Sign() == 0 { 115 stack.Push(Zero256) 116 c.debugf(" %v %% %v = %v\n", x, y, 0) 117 } else { 118 mod := new(big.Int).Mod(x, y) 119 res := stack.PushBigInt(mod) 120 c.debugf(" %v %% %v = %v (%v)\n", x, y, mod, res) 121 } 122 123 case SMOD: // 0x07 124 x, y := stack.PopBigIntSigned(), stack.PopBigIntSigned() 125 if y.Sign() == 0 { 126 stack.Push(Zero256) 127 c.debugf(" %v %% %v = %v\n", x, y, 0) 128 } else { 129 mod := new(big.Int).Rem(x, y) 130 res := stack.PushBigInt(mod) 131 c.debugf(" %v %% %v = %v (%v)\n", x, y, mod, res) 132 } 133 134 case ADDMOD: // 0x08 135 x, y, z := stack.PopBigInt(), stack.PopBigInt(), stack.PopBigInt() 136 if z.Sign() == 0 { 137 stack.Push(Zero256) 138 c.debugf(" %v %% %v = %v\n", x, y, 0) 139 } else { 140 add := new(big.Int).Add(x, y) 141 mod := add.Mod(add, z) 142 res := stack.PushBigInt(mod) 143 c.debugf(" %v + %v %% %v = %v (%v)\n", x, y, z, mod, res) 144 } 145 146 case MULMOD: // 0x09 147 x, y, z := stack.PopBigInt(), stack.PopBigInt(), stack.PopBigInt() 148 if z.Sign() == 0 { 149 stack.Push(Zero256) 150 c.debugf(" %v %% %v = %v\n", x, y, 0) 151 } else { 152 mul := new(big.Int).Mul(x, y) 153 mod := mul.Mod(mul, z) 154 res := stack.PushBigInt(mod) 155 c.debugf(" %v * %v %% %v = %v (%v)\n", x, y, z, mod, res) 156 } 157 158 case EXP: // 0x0A 159 x, y := stack.PopBigInt(), stack.PopBigInt() 160 pow := new(big.Int).Exp(x, y, nil) 161 res := stack.PushBigInt(pow) 162 c.debugf(" %v ** %v = %v (%v)\n", x, y, pow, res) 163 164 case SIGNEXTEND: // 0x0B 165 back := stack.PopBigInt().Uint64() 166 if back < Word256Bytes-1 { 167 bits := uint((back + 1) * 8) 168 stack.PushBigInt(SignExtend(stack.PopBigInt(), bits)) 169 } 170 // Continue leaving the sign extension argument on the stack. This makes sign-extending a no-op if embedded 171 // integer is already one word wide 172 173 case LT: // 0x10 174 x, y := stack.PopBigInt(), stack.PopBigInt() 175 if x.Cmp(y) < 0 { 176 stack.Push(One256) 177 c.debugf(" %v < %v = %v\n", x, y, 1) 178 } else { 179 stack.Push(Zero256) 180 c.debugf(" %v < %v = %v\n", x, y, 0) 181 } 182 183 case GT: // 0x11 184 x, y := stack.PopBigInt(), stack.PopBigInt() 185 if x.Cmp(y) > 0 { 186 stack.Push(One256) 187 c.debugf(" %v > %v = %v\n", x, y, 1) 188 } else { 189 stack.Push(Zero256) 190 c.debugf(" %v > %v = %v\n", x, y, 0) 191 } 192 193 case SLT: // 0x12 194 x, y := stack.PopBigIntSigned(), stack.PopBigIntSigned() 195 if x.Cmp(y) < 0 { 196 stack.Push(One256) 197 c.debugf(" %v < %v = %v\n", x, y, 1) 198 } else { 199 stack.Push(Zero256) 200 c.debugf(" %v < %v = %v\n", x, y, 0) 201 } 202 203 case SGT: // 0x13 204 x, y := stack.PopBigIntSigned(), stack.PopBigIntSigned() 205 if x.Cmp(y) > 0 { 206 stack.Push(One256) 207 c.debugf(" %v > %v = %v\n", x, y, 1) 208 } else { 209 stack.Push(Zero256) 210 c.debugf(" %v > %v = %v\n", x, y, 0) 211 } 212 213 case EQ: // 0x14 214 x, y := stack.Pop(), stack.Pop() 215 if bytes.Equal(x[:], y[:]) { 216 stack.Push(One256) 217 c.debugf(" %v == %v = %v\n", x, y, 1) 218 } else { 219 stack.Push(Zero256) 220 c.debugf(" %v == %v = %v\n", x, y, 0) 221 } 222 223 case ISZERO: // 0x15 224 x := stack.Pop() 225 if x.IsZero() { 226 stack.Push(One256) 227 c.debugf(" %v == 0 = %v\n", x, 1) 228 } else { 229 stack.Push(Zero256) 230 c.debugf(" %v == 0 = %v\n", x, 0) 231 } 232 233 case AND: // 0x16 234 x, y := stack.Pop(), stack.Pop() 235 z := [32]byte{} 236 for i := 0; i < 32; i++ { 237 z[i] = x[i] & y[i] 238 } 239 stack.Push(z) 240 c.debugf(" %v & %v = %v\n", x, y, z) 241 242 case OR: // 0x17 243 x, y := stack.Pop(), stack.Pop() 244 z := [32]byte{} 245 for i := 0; i < 32; i++ { 246 z[i] = x[i] | y[i] 247 } 248 stack.Push(z) 249 c.debugf(" %v | %v = %v\n", x, y, z) 250 251 case XOR: // 0x18 252 x, y := stack.Pop(), stack.Pop() 253 z := [32]byte{} 254 for i := 0; i < 32; i++ { 255 z[i] = x[i] ^ y[i] 256 } 257 stack.Push(z) 258 c.debugf(" %v ^ %v = %v\n", x, y, z) 259 260 case NOT: // 0x19 261 x := stack.Pop() 262 z := [32]byte{} 263 for i := 0; i < 32; i++ { 264 z[i] = ^x[i] 265 } 266 stack.Push(z) 267 c.debugf(" !%v = %v\n", x, z) 268 269 case BYTE: // 0x1A 270 idx := stack.Pop64() 271 val := stack.Pop() 272 res := byte(0) 273 if idx < 32 { 274 res = val[idx] 275 } 276 stack.Push64(uint64(res)) 277 c.debugf(" => 0x%X\n", res) 278 279 case SHL: //0x1B 280 shift, x := stack.PopBigInt(), stack.PopBigInt() 281 282 if shift.Cmp(Big256) >= 0 { 283 reset := big.NewInt(0) 284 stack.PushBigInt(reset) 285 c.debugf(" %v << %v = %v\n", x, shift, reset) 286 } else { 287 shiftedValue := x.Lsh(x, uint(shift.Uint64())) 288 stack.PushBigInt(shiftedValue) 289 c.debugf(" %v << %v = %v\n", x, shift, shiftedValue) 290 } 291 292 case SHR: //0x1C 293 shift, x := stack.PopBigInt(), stack.PopBigInt() 294 295 if shift.Cmp(Big256) >= 0 { 296 reset := big.NewInt(0) 297 stack.PushBigInt(reset) 298 c.debugf(" %v << %v = %v\n", x, shift, reset) 299 } else { 300 shiftedValue := x.Rsh(x, uint(shift.Uint64())) 301 stack.PushBigInt(shiftedValue) 302 c.debugf(" %v << %v = %v\n", x, shift, shiftedValue) 303 } 304 305 case SAR: //0x1D 306 shift, x := stack.PopBigInt(), stack.PopBigIntSigned() 307 308 if shift.Cmp(Big256) >= 0 { 309 reset := big.NewInt(0) 310 if x.Sign() < 0 { 311 reset.SetInt64(-1) 312 } 313 stack.PushBigInt(reset) 314 c.debugf(" %v << %v = %v\n", x, shift, reset) 315 } else { 316 shiftedValue := x.Rsh(x, uint(shift.Uint64())) 317 stack.PushBigInt(shiftedValue) 318 c.debugf(" %v << %v = %v\n", x, shift, shiftedValue) 319 } 320 321 case SHA3: // 0x20 322 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasSha3)) 323 offset, size := stack.PopBigInt(), stack.PopBigInt() 324 data := memory.Read(offset, size) 325 data = crypto.Keccak256(data) 326 stack.PushBytes(data) 327 c.debugf(" => (%v) %X\n", size, data) 328 329 case ADDRESS: // 0x30 330 stack.Push(params.Callee.Word256()) 331 c.debugf(" => %v\n", params.Callee) 332 333 case BALANCE: // 0x31 334 address := stack.PopAddress() 335 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasGetAccount)) 336 balance := engine.MustGetAccount(st.CallFrame, maybe, address).Balance 337 stack.Push64(balance) 338 c.debugf(" => %v (%v)\n", balance, address) 339 340 case ORIGIN: // 0x32 341 stack.Push(params.Origin.Word256()) 342 c.debugf(" => %v\n", params.Origin) 343 344 case CALLER: // 0x33 345 stack.Push(params.Caller.Word256()) 346 c.debugf(" => %v\n", params.Caller) 347 348 case CALLVALUE: // 0x34 349 stack.PushBigInt(¶ms.Value) 350 c.debugf(" => %v\n", params.Value) 351 352 case CALLDATALOAD: // 0x35 353 offset := stack.Pop64() 354 data := maybe.Bytes(subslice(params.Input, offset, 32)) 355 res := LeftPadWord256(data) 356 stack.Push(res) 357 c.debugf(" => 0x%v\n", res) 358 359 case CALLDATASIZE: // 0x36 360 stack.Push64(uint64(len(params.Input))) 361 c.debugf(" => %d\n", len(params.Input)) 362 363 case CALLDATACOPY: // 0x37 364 memOff := stack.PopBigInt() 365 inputOff := stack.Pop64() 366 length := stack.Pop64() 367 data := maybe.Bytes(subslice(params.Input, inputOff, length)) 368 memory.Write(memOff, data) 369 c.debugf(" => [%v, %v, %v] %X\n", memOff, inputOff, length, data) 370 371 case CODESIZE: // 0x38 372 l := uint64(c.Length()) 373 stack.Push64(l) 374 c.debugf(" => %d\n", l) 375 376 case CODECOPY: // 0x39 377 memOff := stack.PopBigInt() 378 codeOff := stack.Pop64() 379 length := stack.Pop64() 380 data := maybe.Bytes(subslice(c.GetBytecode(), codeOff, length)) 381 memory.Write(memOff, data) 382 c.debugf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data) 383 384 case GASPRICE_DEPRECATED: // 0x3A 385 stack.Push(Zero256) 386 c.debugf(" => %v (GASPRICE IS DEPRECATED)\n", Zero256) 387 388 case EXTCODESIZE: // 0x3B 389 address := stack.PopAddress() 390 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasGetAccount)) 391 acc := engine.MustGetAccount(st.CallFrame, maybe, address) 392 if acc == nil { 393 stack.Push(Zero256) 394 c.debugf(" => 0\n") 395 } else { 396 length := uint64(len(acc.Code())) 397 stack.Push64(length) 398 c.debugf(" => %d\n", length) 399 } 400 case EXTCODECOPY: // 0x3C 401 address := stack.PopAddress() 402 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasGetAccount)) 403 acc := engine.MustGetAccount(st.CallFrame, maybe, address) 404 if acc == nil { 405 maybe.PushError(errors.Codes.UnknownAddress) 406 } else { 407 code := acc.EVMCode 408 memOff := stack.PopBigInt() 409 codeOff := stack.Pop64() 410 length := stack.Pop64() 411 data := maybe.Bytes(subslice(code, codeOff, length)) 412 memory.Write(memOff, data) 413 c.debugf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data) 414 } 415 416 case RETURNDATASIZE: // 0x3D 417 stack.Push64(uint64(len(returnData))) 418 c.debugf(" => %d\n", len(returnData)) 419 420 case RETURNDATACOPY: // 0x3E 421 memOff, outputOff, length := stack.PopBigInt(), stack.PopBigInt(), stack.PopBigInt() 422 end := new(big.Int).Add(outputOff, length) 423 424 if end.BitLen() > 64 || uint64(len(returnData)) < end.Uint64() { 425 maybe.PushError(errors.Codes.ReturnDataOutOfBounds) 426 continue 427 } 428 429 memory.Write(memOff, returnData) 430 c.debugf(" => [%v, %v, %v] %X\n", memOff, outputOff, length, returnData) 431 432 case EXTCODEHASH: // 0x3F 433 address := stack.PopAddress() 434 435 acc := engine.GetAccount(st.CallFrame, maybe, address) 436 if acc == nil { 437 // In case the account does not exist 0 is pushed to the stack. 438 stack.Push64(0) 439 } else { 440 // keccak256 hash of a contract's code 441 var extcodehash Word256 442 if len(acc.CodeHash) > 0 { 443 copy(extcodehash[:], acc.CodeHash) 444 } else { 445 copy(extcodehash[:], crypto.Keccak256(acc.Code())) 446 } 447 stack.Push(extcodehash) 448 } 449 450 case BLOCKHASH: // 0x40 451 blockNumber := stack.Pop64() 452 453 lastBlockHeight := st.Blockchain.LastBlockHeight() 454 if blockNumber >= lastBlockHeight { 455 c.debugf(" => attempted to get block hash of a non-existent block: %v", blockNumber) 456 maybe.PushError(errors.Codes.InvalidBlockNumber) 457 } else if lastBlockHeight-blockNumber > MaximumAllowedBlockLookBack { 458 c.debugf(" => attempted to get block hash of a block %d outside of the allowed range "+ 459 "(must be within %d blocks)", blockNumber, MaximumAllowedBlockLookBack) 460 maybe.PushError(errors.Codes.BlockNumberOutOfRange) 461 } else { 462 hash := maybe.Bytes(st.Blockchain.BlockHash(blockNumber)) 463 blockHash := LeftPadWord256(hash) 464 stack.Push(blockHash) 465 c.debugf(" => 0x%v\n", blockHash) 466 } 467 468 case COINBASE: // 0x41 469 stack.Push(Zero256) 470 c.debugf(" => 0x%v (NOT SUPPORTED)\n", stack.Peek()) 471 472 case TIMESTAMP: // 0x42 473 blockTime := st.Blockchain.LastBlockTime().Unix() 474 stack.Push64(uint64(blockTime)) 475 c.debugf(" => %d\n", blockTime) 476 477 case BLOCKHEIGHT: // 0x43 478 number := st.Blockchain.LastBlockHeight() 479 stack.Push64(number) 480 c.debugf(" => %d\n", number) 481 482 case DIFFICULTY: // 0x44 483 // ~ hashes per solution - by convention we'll use unity since there are no misses if you are proposer 484 stack.Push(One256) 485 c.debugf(" => %v\n", One256) 486 487 case GASLIMIT: // 0x45 488 stack.PushBigInt(params.Gas) 489 c.debugf(" => %v\n", *params.Gas) 490 491 case CHAINID: // 0x46 492 id := encoding.GetEthChainID(st.Blockchain.ChainID()) 493 stack.PushBigInt(id) 494 c.debugf(" => %X\n", id) 495 496 case POP: // 0x50 497 popped := stack.Pop() 498 c.debugf(" => 0x%v\n", popped) 499 500 case MLOAD: // 0x51 501 offset := stack.PopBigInt() 502 data := memory.Read(offset, BigWord256Bytes) 503 stack.Push(LeftPadWord256(data)) 504 c.debugf(" => 0x%X @ 0x%v\n", data, offset) 505 506 case MSTORE: // 0x52 507 offset, data := stack.PopBigInt(), stack.Pop() 508 memory.Write(offset, data.Bytes()) 509 c.debugf(" => 0x%v @ 0x%v\n", data, offset) 510 511 case MSTORE8: // 0x53 512 offset := stack.PopBigInt() 513 val64 := stack.PopBigInt().Uint64() 514 val := byte(val64 & 0xFF) 515 memory.Write(offset, []byte{val}) 516 c.debugf(" => [%v] 0x%X\n", offset, val) 517 518 case SLOAD: // 0x54 519 loc := stack.Pop() 520 data := LeftPadWord256(maybe.Bytes(st.CallFrame.GetStorage(params.Callee, loc))) 521 stack.Push(data) 522 c.debugf("%v {0x%v = 0x%v}\n", params.Callee, loc, data) 523 524 case SSTORE: // 0x55 525 loc, data := stack.Pop(), stack.Pop() 526 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasStorageUpdate)) 527 maybe.PushError(st.CallFrame.SetStorage(params.Callee, loc, data.Bytes())) 528 c.debugf("%v {%v := %v}\n", params.Callee, loc, data) 529 530 case JUMP: // 0x56 531 to := stack.Pop64() 532 maybe.PushError(c.jump(to, &pc)) 533 continue 534 535 case JUMPI: // 0x57 536 pos := stack.Pop64() 537 cond := stack.Pop() 538 if !cond.IsZero() { 539 maybe.PushError(c.jump(pos, &pc)) 540 continue 541 } else { 542 c.debugf(" ~> false\n") 543 } 544 545 case PC: // 0x58 546 stack.Push64(pc) 547 548 case MSIZE: // 0x59 549 // Note: Solidity will write to this offset expecting to find guaranteed 550 // free memory to be allocated for it if a subsequent MSTORE is made to 551 // this offset. 552 capacity := memory.Capacity() 553 stack.PushBigInt(capacity) 554 c.debugf(" => 0x%X\n", capacity) 555 556 case GAS: // 0x5A 557 stack.PushBigInt(params.Gas) 558 c.debugf(" => %X\n", params.Gas) 559 560 case JUMPDEST: // 0x5B 561 c.debugf("\n") 562 // Do nothing 563 564 case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: 565 a := uint64(op - PUSH1 + 1) 566 codeSegment := maybe.Bytes(subslice(c.GetBytecode(), pc+1, a)) 567 res := LeftPadWord256(codeSegment) 568 stack.Push(res) 569 pc += a 570 c.debugf(" => 0x%v\n", res) 571 572 case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: 573 n := int(op - DUP1 + 1) 574 stack.Dup(n) 575 c.debugf(" => [%d] 0x%v\n", n, stack.Peek()) 576 577 case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16: 578 n := int(op - SWAP1 + 2) 579 stack.Swap(n) 580 c.debugf(" => [%d] %v\n", n, stack.Peek()) 581 582 case LOG0, LOG1, LOG2, LOG3, LOG4: 583 n := int(op - LOG0) 584 topics := make([]Word256, n) 585 offset, size := stack.PopBigInt(), stack.PopBigInt() 586 for i := 0; i < n; i++ { 587 topics[i] = stack.Pop() 588 } 589 data := memory.Read(offset, size) 590 maybe.PushError(st.EventSink.Log(&exec.LogEvent{ 591 Address: params.Callee, 592 Topics: topics, 593 Data: data, 594 })) 595 c.debugf(" => T:%v D:%X\n", topics, data) 596 597 case CREATE, CREATE2: // 0xF0, 0xFB 598 returnData = nil 599 contractValue := stack.PopBigInt() 600 offset, size := stack.PopBigInt(), stack.PopBigInt() 601 input := memory.Read(offset, size) 602 603 // TODO charge for gas to create account _ the code length * GasCreateByte 604 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasCreateAccount)) 605 606 var newAccountAddress crypto.Address 607 if op == CREATE { 608 c.sequence++ 609 nonce := make([]byte, txs.HashLength+uint64Length) 610 copy(nonce, c.options.Nonce) 611 binary.BigEndian.PutUint64(nonce[txs.HashLength:], c.sequence) 612 newAccountAddress = crypto.NewContractAddress(params.Callee, nonce) 613 } else if op == CREATE2 { 614 salt := stack.Pop() 615 code := engine.MustGetAccount(st.CallFrame, maybe, params.Callee).EVMCode 616 newAccountAddress = crypto.NewContractAddress2(params.Callee, salt, code) 617 } 618 619 // Check the CreateContract permission for this account 620 if maybe.PushError(engine.EnsurePermission(st.CallFrame, params.Callee, permission.CreateContract)) { 621 continue 622 } 623 624 // Establish a frame in which the putative account exists 625 childCallFrame, err := st.CallFrame.NewFrame() 626 maybe.PushError(err) 627 maybe.PushError(engine.CreateAccount(childCallFrame, newAccountAddress)) 628 629 // Run the input to get the contract code. 630 // NOTE: no need to copy 'input' as per Call contract. 631 ret, callErr := c.Contract(input).Call( 632 engine.State{ 633 CallFrame: childCallFrame, 634 Blockchain: st.Blockchain, 635 EventSink: st.EventSink, 636 }, 637 engine.CallParams{ 638 Origin: params.Origin, 639 Caller: params.Callee, 640 Callee: newAccountAddress, 641 Input: input, 642 Value: *contractValue, 643 Gas: params.Gas, 644 }) 645 if callErr != nil { 646 stack.Push(Zero256) 647 // Note we both set the return buffer and return the result normally in order to service the error to 648 // EVM caller 649 returnData = ret 650 } else { 651 // Update the account with its initialised contract code 652 maybe.PushError(engine.InitChildCode(childCallFrame, newAccountAddress, params.Callee, ret)) 653 maybe.PushError(childCallFrame.Sync()) 654 stack.PushAddress(newAccountAddress) 655 } 656 657 case CALL, CALLCODE, DELEGATECALL, STATICCALL: // 0xF1, 0xF2, 0xF4, 0xFA 658 returnData = nil 659 660 if maybe.PushError(engine.EnsurePermission(st.CallFrame, params.Callee, permission.Call)) { 661 continue 662 } 663 // Pull arguments off stack: 664 gasLimit := stack.PopBigInt() 665 target := stack.PopAddress() 666 value := params.Value 667 // NOTE: for DELEGATECALL value is preserved from the original 668 // caller, as such it is not stored on stack as an argument 669 // for DELEGATECALL and should not be popped. Instead previous 670 // caller value is used. for CALL and CALLCODE value is stored 671 // on stack and needs to be overwritten from the given value. 672 if op != DELEGATECALL && op != STATICCALL { 673 value = *stack.PopBigInt() 674 } 675 // inputs 676 inOffset, inSize := stack.PopBigInt(), stack.PopBigInt() 677 // outputs 678 retOffset := stack.PopBigInt() 679 retSize := stack.Pop64() 680 c.debugf(" => %v\n", target) 681 682 var err error 683 returnData, err = engine.CallFromSite(st, c.externalDispatcher, params, engine.CallParams{ 684 CallType: callTypeFromOpCode(op), 685 Callee: target, 686 Input: memory.Read(inOffset, inSize), 687 Value: value, 688 Gas: gasLimit, 689 }) 690 // Push result 691 if err != nil { 692 c.debugf("error from nested sub-call (depth: %v): %s\n", st.CallFrame.CallStackDepth(), err) 693 // So we can return nested errors.CodedError if the top level return is an errors.CodedError 694 stack.Push(Zero256) 695 696 } else { 697 stack.Push(One256) 698 } 699 700 code := errors.GetCode(err) 701 if code == errors.Codes.None || code == errors.Codes.ExecutionReverted { 702 memory.Write(retOffset, RightPadBytes(returnData, int(retSize))) 703 } else { 704 maybe.PushError(err) 705 } 706 707 // TODO: decide how to handle this 708 // Apply refund of any unused gas 709 params.Gas.Add(params.Gas, gasLimit) 710 711 c.debugf("resume %s (%v)\n", params.Callee, params.Gas) 712 713 case RETURN: // 0xF3 714 offset, size := stack.PopBigInt(), stack.PopBigInt() 715 output := memory.Read(offset, size) 716 c.debugf(" => [%v, %v] (%d) 0x%X\n", offset, size, len(output), output) 717 return output, maybe.Error() 718 719 case REVERT: // 0xFD 720 offset, size := stack.PopBigInt(), stack.PopBigInt() 721 output := memory.Read(offset, size) 722 c.debugf(" => [%v, %v] (%d) 0x%X\n", offset, size, len(output), output) 723 maybe.PushError(newRevertException(output)) 724 return output, maybe.Error() 725 726 case INVALID: // 0xFE 727 maybe.PushError(errors.Codes.ExecutionAborted) 728 return nil, maybe.Error() 729 730 case SELFDESTRUCT: // 0xFF 731 receiver := stack.PopAddress() 732 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasGetAccount)) 733 if engine.GetAccount(st.CallFrame, maybe, receiver) == nil { 734 // If receiver address doesn't exist, try to create it 735 maybe.PushError(engine.UseGasNegative(params.Gas, engine.GasCreateAccount)) 736 if maybe.PushError(st.CallFrame.CreateAccount(params.Callee, receiver)) { 737 continue 738 } 739 } 740 balance := engine.MustGetAccount(st.CallFrame, maybe, params.Callee).Balance 741 maybe.PushError(engine.UpdateAccount(st.CallFrame, receiver, func(account *acm.Account) error { 742 return account.AddToBalance(balance) 743 })) 744 maybe.PushError(engine.RemoveAccount(st.CallFrame, params.Callee)) 745 c.debugf(" => (%X) %v\n", receiver[:4], balance) 746 return nil, maybe.Error() 747 748 case STOP: // 0x00 749 c.debugf("\n") 750 return nil, maybe.Error() 751 752 default: 753 c.debugf("(pc) %-3v Unknown opcode %v\n", pc, op) 754 maybe.PushError(errors.Errorf(errors.Codes.Generic, "unknown opcode %v", op)) 755 return nil, maybe.Error() 756 } 757 pc++ 758 } 759 return nil, maybe.Error() 760 } 761 762 func (c *Contract) jump(to uint64, pc *uint64) error { 763 dest := c.GetSymbol(to) 764 if dest != JUMPDEST || c.IsPushData(to) { 765 c.debugf(" ~> %v invalid jump dest %v\n", to, dest) 766 return errors.Codes.InvalidJumpDest 767 } 768 c.debugf(" ~> %v\n", to) 769 *pc = to 770 return nil 771 } 772 773 // Returns a subslice from offset of length length and a bool 774 // (true iff slice was possible). If the subslice 775 // extends past the end of data it returns A COPY of the segment at the end of 776 // data padded with zeroes on the right. If offset == len(data) it returns all 777 // zeroes. if offset > len(data) it returns a false 778 func subslice(data []byte, offset, length uint64) ([]byte, error) { 779 size := uint64(len(data)) 780 if size < offset || offset < 0 || length < 0 { 781 return nil, errors.Errorf(errors.Codes.InputOutOfBounds, 782 "subslice could not slice data of size %d at offset %d for length %d", size, offset, length) 783 } 784 if size < offset+length { 785 // Extract slice from offset to end padding to requested length 786 ret := make([]byte, length) 787 copy(ret, data[offset:]) 788 return ret, nil 789 } 790 return data[offset : offset+length], nil 791 } 792 793 // Dump the bytecode being sent to the EVM in the current working directory 794 func dumpTokens(nonce []byte, caller, callee crypto.Address, code []byte) { 795 var tokensString string 796 tokens, err := acm.Bytecode(code).Tokens() 797 if err != nil { 798 tokensString = fmt.Sprintf("error generating tokens from bytecode: %v", err) 799 } else { 800 tokensString = strings.Join(tokens, "\n") 801 } 802 txHashString := "nil-nonce" 803 if len(nonce) >= 4 { 804 txHashString = fmt.Sprintf("nonce-%X", nonce[:4]) 805 } 806 callerString := "caller-none" 807 if caller != crypto.ZeroAddress { 808 callerString = fmt.Sprintf("caller-%v", caller) 809 } 810 calleeString := "callee-none" 811 if callee != crypto.ZeroAddress { 812 calleeString = fmt.Sprintf("callee-%v", caller) 813 } 814 _ = ioutil.WriteFile(fmt.Sprintf("tokens_%s_%s_%s.asm", txHashString, callerString, calleeString), 815 []byte(tokensString), 0777) 816 } 817 818 func newRevertException(ret []byte) errors.CodedError { 819 code := errors.Codes.ExecutionReverted 820 if len(ret) > 0 { 821 // Attempt decode 822 reason, err := abi.UnpackRevert(ret) 823 if err == nil { 824 return errors.Errorf(code, "with reason '%s'", *reason) 825 } 826 } 827 return code 828 } 829 830 func callTypeFromOpCode(o OpCode) exec.CallType { 831 switch o { 832 case CALL: 833 return exec.CallTypeCall 834 case CALLCODE: 835 return exec.CallTypeCode 836 case STATICCALL: 837 return exec.CallTypeStatic 838 case DELEGATECALL: 839 return exec.CallTypeDelegate 840 default: 841 return exec.CallTypeInvalid 842 } 843 }