| 635 | } |
| 636 | |
| 637 | func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
| 638 | var ( |
| 639 | value = stack.pop() |
| 640 | offset, size = stack.pop(), stack.pop() |
| 641 | input = memory.Get(offset.Int64(), size.Int64()) |
| 642 | gas = contract.Gas |
| 643 | ) |
| 644 | gas -= gas / 64 |
| 645 | |
| 646 | contract.UseGas(gas) |
| 647 | res, addr, returnGas, suberr := evm.Create(contract, input, gas, value) |
| 648 | // Push item on the stack based on the returned error. If the ruleset is |
| 649 | // homestead we must check for CodeStoreOutOfGasError (homestead only |
| 650 | // rule) and treat as an error, if the ruleset is frontier we must |
| 651 | // ignore this error and pretend the operation was successful. |
| 652 | if suberr == ErrCodeStoreOutOfGas { |
| 653 | stack.push(evm.interpreter.intPool.getZero()) |
| 654 | } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { |
| 655 | stack.push(evm.interpreter.intPool.getZero()) |
| 656 | } else { |
| 657 | stack.push(addr.Big()) |
| 658 | } |
| 659 | contract.Gas += returnGas |
| 660 | evm.interpreter.intPool.put(value, offset, size) |
| 661 | |
| 662 | if suberr == errExecutionReverted { |
| 663 | return res, nil |
| 664 | } |
| 665 | return nil, nil |
| 666 | } |
| 667 | |
| 668 | func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { |
| 669 | // Pop gas. The actual gas in in evm.callGasTemp. |