You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

736 lines
18 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package vm
  2. import (
  3. "errors"
  4. "fmt"
  5. "math"
  6. . "github.com/tendermint/tendermint/common"
  7. "github.com/tendermint/tendermint/vm/sha3"
  8. )
  9. var (
  10. ErrInsufficientBalance = errors.New("Insufficient balance")
  11. ErrInvalidJumpDest = errors.New("Invalid jump dest")
  12. ErrInsufficientGas = errors.New("Insuffient gas")
  13. ErrMemoryOutOfBounds = errors.New("Memory out of bounds")
  14. ErrCodeOutOfBounds = errors.New("Code out of bounds")
  15. ErrInputOutOfBounds = errors.New("Input out of bounds")
  16. ErrCallStackOverflow = errors.New("Call stack overflow")
  17. ErrCallStackUnderflow = errors.New("Call stack underflow")
  18. ErrDataStackOverflow = errors.New("Data stack overflow")
  19. ErrDataStackUnderflow = errors.New("Data stack underflow")
  20. ErrInvalidContract = errors.New("Invalid contract")
  21. )
  22. const (
  23. dataStackCapacity = 1024
  24. callStackCapacity = 100 // TODO ensure usage.
  25. memoryCapacity = 1024 * 1024 // 1 MB
  26. )
  27. type VM struct {
  28. appState AppState
  29. params VMParams
  30. callDepth int
  31. }
  32. type VMParams struct {
  33. BlockHeight uint64
  34. BlockHash Word
  35. BlockTime int64
  36. GasLimit uint64
  37. GasPrice uint64
  38. CallStackLimit uint64
  39. Origin Word
  40. }
  41. func NewVM(appState AppState, params VMParams) *VM {
  42. return &VM{
  43. appState: appState,
  44. params: params,
  45. callDepth: 0,
  46. }
  47. }
  48. /*
  49. // When running a transaction, the caller the pays for the fees.
  50. // Check caller's account balance vs feeLimit and value
  51. if caller.Balance < (feeLimit + value) {
  52. return nil, ErrInsufficientBalance
  53. }
  54. caller.Balance -= (feeLimit + value)
  55. */
  56. // gas: the maximum gas that will be run.
  57. // When the function returns, *gas will be the amount of remaining gas.
  58. func (vm *VM) Call(caller, callee *Account, code, input []byte, value uint64, gas *uint64) (output []byte, err error) {
  59. if len(callee.Code) == 0 {
  60. panic("Call() requires callee with code")
  61. }
  62. fmt.Printf("(%d) (%X) %X (code=%d) gas: %v (d) %X\n", vm.callDepth, caller.Address[:4], callee.Address, len(callee.Code), *gas, input)
  63. var (
  64. pc uint64 = 0
  65. stack = NewStack(dataStackCapacity, gas, &err)
  66. memory = make([]byte, memoryCapacity)
  67. ok = false // convenience
  68. )
  69. for {
  70. var op = codeGetOp(code, pc)
  71. fmt.Printf("(pc) %-3d (op) %-14s (st) %-4d ", pc, op.String(), stack.Len())
  72. switch op {
  73. case STOP: // 0x00
  74. return nil, nil
  75. case ADD: // 0x01
  76. x, y := stack.Pop64(), stack.Pop64()
  77. stack.Push64(x + y)
  78. fmt.Printf(" %v + %v = %v\n", x, y, x+y)
  79. case MUL: // 0x02
  80. x, y := stack.Pop64(), stack.Pop64()
  81. stack.Push64(x * y)
  82. fmt.Printf(" %v * %v = %v\n", x, y, x*y)
  83. case SUB: // 0x03
  84. x, y := stack.Pop64(), stack.Pop64()
  85. stack.Push64(x - y)
  86. fmt.Printf(" %v - %v = %v\n", x, y, x-y)
  87. case DIV: // 0x04
  88. x, y := stack.Pop64(), stack.Pop64()
  89. if y == 0 { // TODO
  90. stack.Push64(0)
  91. fmt.Printf(" %v / %v = %v (TODO)\n", x, y, 0)
  92. } else {
  93. stack.Push64(x / y)
  94. fmt.Printf(" %v / %v = %v\n", x, y, x/y)
  95. }
  96. case SDIV: // 0x05
  97. x, y := int64(stack.Pop64()), int64(stack.Pop64())
  98. if y == 0 { // TODO
  99. stack.Push64(0)
  100. fmt.Printf(" %v / %v = %v (TODO)\n", x, y, 0)
  101. } else {
  102. stack.Push64(uint64(x / y))
  103. fmt.Printf(" %v / %v = %v\n", x, y, x/y)
  104. }
  105. case MOD: // 0x06
  106. x, y := stack.Pop64(), stack.Pop64()
  107. if y == 0 { // TODO
  108. stack.Push64(0)
  109. fmt.Printf(" %v %% %v = %v (TODO)\n", x, y, 0)
  110. } else {
  111. stack.Push64(x % y)
  112. fmt.Printf(" %v %% %v = %v\n", x, y, x%y)
  113. }
  114. case SMOD: // 0x07
  115. x, y := int64(stack.Pop64()), int64(stack.Pop64())
  116. if y == 0 { // TODO
  117. stack.Push64(0)
  118. fmt.Printf(" %v %% %v = %v (TODO)\n", x, y, 0)
  119. } else {
  120. stack.Push64(uint64(x % y))
  121. fmt.Printf(" %v %% %v = %v\n", x, y, x%y)
  122. }
  123. case ADDMOD: // 0x08
  124. x, y, z := stack.Pop64(), stack.Pop64(), stack.Pop64()
  125. if z == 0 { // TODO
  126. stack.Push64(0)
  127. fmt.Printf(" (%v + %v) %% %v = %v (TODO)\n", x, y, z, 0)
  128. } else {
  129. stack.Push64(x % y)
  130. fmt.Printf(" (%v + %v) %% %v = %v\n", x, y, z, (x+y)%z)
  131. }
  132. case MULMOD: // 0x09
  133. x, y, z := stack.Pop64(), stack.Pop64(), stack.Pop64()
  134. if z == 0 { // TODO
  135. stack.Push64(0)
  136. fmt.Printf(" (%v + %v) %% %v = %v (TODO)\n", x, y, z, 0)
  137. } else {
  138. stack.Push64(x % y)
  139. fmt.Printf(" (%v + %v) %% %v = %v\n", x, y, z, (x*y)%z)
  140. }
  141. case EXP: // 0x0A
  142. x, y := stack.Pop64(), stack.Pop64()
  143. stack.Push64(ExpUint64(x, y))
  144. fmt.Printf(" %v ** %v = %v\n", x, y, uint64(math.Pow(float64(x), float64(y))))
  145. case SIGNEXTEND: // 0x0B
  146. x, y := stack.Pop64(), stack.Pop64()
  147. res := (y << uint(x)) >> x
  148. stack.Push64(res)
  149. fmt.Printf(" (%v << %v) >> %v = %v\n", y, x, x, res)
  150. case LT: // 0x10
  151. x, y := stack.Pop64(), stack.Pop64()
  152. if x < y {
  153. stack.Push64(1)
  154. } else {
  155. stack.Push64(0)
  156. }
  157. fmt.Printf(" %v < %v = %v\n", x, y, x < y)
  158. case GT: // 0x11
  159. x, y := stack.Pop64(), stack.Pop64()
  160. if x > y {
  161. stack.Push64(1)
  162. } else {
  163. stack.Push64(0)
  164. }
  165. fmt.Printf(" %v > %v = %v\n", x, y, x > y)
  166. case SLT: // 0x12
  167. x, y := int64(stack.Pop64()), int64(stack.Pop64())
  168. if x < y {
  169. stack.Push64(1)
  170. } else {
  171. stack.Push64(0)
  172. }
  173. fmt.Printf(" %v < %v = %v\n", x, y, x < y)
  174. case SGT: // 0x13
  175. x, y := int64(stack.Pop64()), int64(stack.Pop64())
  176. if x > y {
  177. stack.Push64(1)
  178. } else {
  179. stack.Push64(0)
  180. }
  181. fmt.Printf(" %v > %v = %v\n", x, y, x > y)
  182. case EQ: // 0x14
  183. x, y := stack.Pop64(), stack.Pop64()
  184. if x > y {
  185. stack.Push64(1)
  186. } else {
  187. stack.Push64(0)
  188. }
  189. fmt.Printf(" %v == %v = %v\n", x, y, x == y)
  190. case ISZERO: // 0x15
  191. x := stack.Pop64()
  192. if x == 0 {
  193. stack.Push64(1)
  194. } else {
  195. stack.Push64(0)
  196. }
  197. fmt.Printf(" %v == 0 = %v\n", x, x == 0)
  198. case AND: // 0x16
  199. x, y := stack.Pop64(), stack.Pop64()
  200. stack.Push64(x & y)
  201. fmt.Printf(" %v & %v = %v\n", x, y, x&y)
  202. case OR: // 0x17
  203. x, y := stack.Pop64(), stack.Pop64()
  204. stack.Push64(x | y)
  205. fmt.Printf(" %v | %v = %v\n", x, y, x|y)
  206. case XOR: // 0x18
  207. x, y := stack.Pop64(), stack.Pop64()
  208. stack.Push64(x ^ y)
  209. fmt.Printf(" %v ^ %v = %v\n", x, y, x^y)
  210. case NOT: // 0x19
  211. x := stack.Pop64()
  212. stack.Push64(^x)
  213. fmt.Printf(" !%v = %v\n", x, ^x)
  214. case BYTE: // 0x1A
  215. idx, val := stack.Pop64(), stack.Pop()
  216. res := byte(0)
  217. if idx < 32 {
  218. res = val[idx]
  219. }
  220. stack.Push64(uint64(res))
  221. fmt.Printf(" => 0x%X\n", res)
  222. case SHA3: // 0x20
  223. if ok = useGas(gas, GasSha3); !ok {
  224. return nil, firstErr(err, ErrInsufficientGas)
  225. }
  226. offset, size := stack.Pop64(), stack.Pop64()
  227. data, ok := subslice(memory, offset, size)
  228. if !ok {
  229. return nil, firstErr(err, ErrMemoryOutOfBounds)
  230. }
  231. data = sha3.Sha3(data)
  232. stack.PushBytes(data)
  233. fmt.Printf(" => (%v) %X\n", size, data)
  234. case ADDRESS: // 0x30
  235. stack.Push(callee.Address)
  236. fmt.Printf(" => %X\n", callee.Address)
  237. case BALANCE: // 0x31
  238. addr := stack.Pop()
  239. if ok = useGas(gas, GasGetAccount); !ok {
  240. return nil, firstErr(err, ErrInsufficientGas)
  241. }
  242. account, err_ := vm.appState.GetAccount(addr) // TODO ensure that 20byte lengths are supported.
  243. if err = firstErr(err, err_); err != nil {
  244. return nil, err
  245. }
  246. balance := account.Balance
  247. stack.Push64(balance)
  248. fmt.Printf(" => %v (%X)\n", balance, addr)
  249. case ORIGIN: // 0x32
  250. origin := vm.params.Origin
  251. stack.Push(origin)
  252. fmt.Printf(" => %X\n", origin)
  253. case CALLER: // 0x33
  254. stack.Push(caller.Address)
  255. fmt.Printf(" => %X\n", caller.Address)
  256. case CALLVALUE: // 0x34
  257. stack.Push64(value)
  258. fmt.Printf(" => %v\n", value)
  259. case CALLDATALOAD: // 0x35
  260. offset := stack.Pop64()
  261. data, ok := subslice(input, offset, 32)
  262. if !ok {
  263. return nil, firstErr(err, ErrInputOutOfBounds)
  264. }
  265. stack.Push(RightPadWord(data))
  266. fmt.Printf(" => 0x%X\n", data)
  267. case CALLDATASIZE: // 0x36
  268. stack.Push64(uint64(len(input)))
  269. fmt.Printf(" => %d\n", len(input))
  270. case CALLDATACOPY: // 0x37
  271. memOff := stack.Pop64()
  272. inputOff := stack.Pop64()
  273. length := stack.Pop64()
  274. data, ok := subslice(input, inputOff, length)
  275. if !ok {
  276. return nil, firstErr(err, ErrInputOutOfBounds)
  277. }
  278. dest, ok := subslice(memory, memOff, length)
  279. if !ok {
  280. return nil, firstErr(err, ErrMemoryOutOfBounds)
  281. }
  282. copy(dest, data)
  283. fmt.Printf(" => [%v, %v, %v] %X\n", memOff, inputOff, length, data)
  284. case CODESIZE: // 0x38
  285. l := uint64(len(code))
  286. stack.Push64(l)
  287. fmt.Printf(" => %d\n", l)
  288. case CODECOPY: // 0x39
  289. memOff := stack.Pop64()
  290. codeOff := stack.Pop64()
  291. length := stack.Pop64()
  292. data, ok := subslice(code, codeOff, length)
  293. if !ok {
  294. return nil, firstErr(err, ErrCodeOutOfBounds)
  295. }
  296. dest, ok := subslice(memory, memOff, length)
  297. if !ok {
  298. return nil, firstErr(err, ErrMemoryOutOfBounds)
  299. }
  300. copy(dest, data)
  301. fmt.Printf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data)
  302. case GASPRICE: // 0x3A
  303. stack.Push64(vm.params.GasPrice)
  304. fmt.Printf(" => %X\n", vm.params.GasPrice)
  305. case EXTCODESIZE: // 0x3B
  306. addr := stack.Pop()
  307. if ok = useGas(gas, GasGetAccount); !ok {
  308. return nil, firstErr(err, ErrInsufficientGas)
  309. }
  310. account, err_ := vm.appState.GetAccount(addr)
  311. if err = firstErr(err, err_); err != nil {
  312. return nil, err
  313. }
  314. code := account.Code
  315. l := uint64(len(code))
  316. stack.Push64(l)
  317. fmt.Printf(" => %d\n", l)
  318. case EXTCODECOPY: // 0x3C
  319. addr := stack.Pop()
  320. if ok = useGas(gas, GasGetAccount); !ok {
  321. return nil, firstErr(err, ErrInsufficientGas)
  322. }
  323. account, err_ := vm.appState.GetAccount(addr)
  324. if err = firstErr(err, err_); err != nil {
  325. return nil, err
  326. }
  327. code := account.Code
  328. memOff := stack.Pop64()
  329. codeOff := stack.Pop64()
  330. length := stack.Pop64()
  331. data, ok := subslice(code, codeOff, length)
  332. if !ok {
  333. return nil, ErrCodeOutOfBounds
  334. }
  335. dest, ok := subslice(memory, memOff, length)
  336. if !ok {
  337. return nil, ErrMemoryOutOfBounds
  338. }
  339. copy(dest, data)
  340. fmt.Printf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data)
  341. case BLOCKHASH: // 0x40
  342. stack.Push(Zero)
  343. fmt.Printf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes())
  344. case COINBASE: // 0x41
  345. stack.Push(Zero)
  346. fmt.Printf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes())
  347. case TIMESTAMP: // 0x42
  348. time := vm.params.BlockTime
  349. stack.Push64(uint64(time))
  350. fmt.Printf(" => 0x%X\n", time)
  351. case BLOCKHEIGHT: // 0x43
  352. number := uint64(vm.params.BlockHeight)
  353. stack.Push64(number)
  354. fmt.Printf(" => 0x%X\n", number)
  355. case GASLIMIT: // 0x45
  356. stack.Push64(vm.params.GasLimit)
  357. fmt.Printf(" => %v\n", vm.params.GasLimit)
  358. case POP: // 0x50
  359. stack.Pop()
  360. fmt.Printf(" => %v\n", vm.params.GasLimit)
  361. case MLOAD: // 0x51
  362. offset := stack.Pop64()
  363. data, ok := subslice(memory, offset, 32)
  364. if !ok {
  365. return nil, ErrMemoryOutOfBounds
  366. }
  367. stack.Push(RightPadWord(data))
  368. fmt.Printf(" => 0x%X\n", data)
  369. case MSTORE: // 0x52
  370. offset, data := stack.Pop64(), stack.Pop()
  371. dest, ok := subslice(memory, offset, 32)
  372. if !ok {
  373. return nil, ErrMemoryOutOfBounds
  374. }
  375. copy(dest, data[:])
  376. fmt.Printf(" => 0x%X\n", data)
  377. case MSTORE8: // 0x53
  378. offset, val := stack.Pop64(), byte(stack.Pop64()&0xFF)
  379. if len(memory) <= int(offset) {
  380. return nil, ErrMemoryOutOfBounds
  381. }
  382. memory[offset] = val
  383. fmt.Printf(" => [%v] 0x%X\n", offset, val)
  384. case SLOAD: // 0x54
  385. loc := stack.Pop()
  386. data, _ := vm.appState.GetStorage(callee.Address, loc)
  387. stack.Push(data)
  388. fmt.Printf(" {0x%X : 0x%X}\n", loc, data)
  389. case SSTORE: // 0x55
  390. loc, data := stack.Pop(), stack.Pop()
  391. updated, err_ := vm.appState.SetStorage(callee.Address, loc, data)
  392. if err = firstErr(err, err_); err != nil {
  393. return nil, err
  394. }
  395. if updated {
  396. useGas(gas, GasStorageUpdate)
  397. } else {
  398. useGas(gas, GasStorageCreate)
  399. }
  400. fmt.Printf(" {0x%X : 0x%X}\n", loc, data)
  401. case JUMP: // 0x56
  402. err = jump(code, stack.Pop64())
  403. continue
  404. case JUMPI: // 0x57
  405. pos, cond := stack.Pop64(), stack.Pop64()
  406. if cond >= 1 {
  407. err = jump(code, pos)
  408. continue
  409. }
  410. fmt.Printf(" ~> false\n")
  411. case PC: // 0x58
  412. stack.Push64(pc)
  413. case MSIZE: // 0x59
  414. stack.Push64(uint64(len(memory)))
  415. case GAS: // 0x5A
  416. stack.Push64(*gas)
  417. fmt.Printf(" => %X\n", *gas)
  418. case JUMPDEST: // 0x5B
  419. // Do nothing
  420. 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:
  421. a := uint64(op - PUSH1 + 1)
  422. codeSegment, ok := subslice(code, pc+1, a)
  423. if !ok {
  424. return nil, firstErr(err, ErrCodeOutOfBounds)
  425. }
  426. res := RightPadWord(codeSegment)
  427. stack.Push(res)
  428. pc += a
  429. fmt.Printf(" => 0x%X\n", res)
  430. case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
  431. n := int(op - DUP1 + 1)
  432. stack.Dup(n)
  433. fmt.Printf(" => [%d] 0x%X\n", n, stack.Peek().Bytes())
  434. case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
  435. n := int(op - SWAP1 + 2)
  436. stack.Swap(n)
  437. fmt.Printf(" => [%d]\n", n)
  438. case LOG0, LOG1, LOG2, LOG3, LOG4:
  439. n := int(op - LOG0)
  440. topics := make([]Word, n)
  441. offset, size := stack.Pop64(), stack.Pop64()
  442. for i := 0; i < n; i++ {
  443. topics[i] = stack.Pop()
  444. }
  445. data, ok := subslice(memory, offset, size)
  446. if !ok {
  447. return nil, firstErr(err, ErrMemoryOutOfBounds)
  448. }
  449. log := &Log{
  450. callee.Address,
  451. topics,
  452. data,
  453. vm.params.BlockHeight,
  454. }
  455. vm.appState.AddLog(log)
  456. fmt.Printf(" => %v\n", log)
  457. case CREATE: // 0xF0
  458. value := stack.Pop64()
  459. offset, size := stack.Pop64(), stack.Pop64()
  460. input, ok := subslice(memory, offset, size)
  461. if !ok {
  462. return nil, firstErr(err, ErrMemoryOutOfBounds)
  463. }
  464. // Check balance
  465. if caller.Balance < value {
  466. return nil, firstErr(err, ErrInsufficientBalance)
  467. } else {
  468. caller.Balance -= value
  469. }
  470. // Create a new address
  471. nonce := caller.Nonce
  472. addr := createAddress(caller.Address, nonce)
  473. caller.Nonce += 1
  474. // TODO charge for gas to create account _ the code length * GasCreateByte
  475. newAccount, err := vm.appState.CreateAccount(addr, value)
  476. if err != nil {
  477. stack.Push64(0)
  478. fmt.Printf(" (*) 0x0 %v\n", err)
  479. } else {
  480. // Run the input to get the contract code.
  481. // The code as well as the input to the code are the same.
  482. ret, err_ := vm.Call(callee, newAccount, input, input, value, gas)
  483. if err_ != nil {
  484. caller.Balance += value // Return the balance
  485. stack.Push64(0)
  486. } else {
  487. newAccount.Code = ret // Set the code
  488. stack.Push(newAccount.Address)
  489. }
  490. }
  491. case CALL, CALLCODE: // 0xF1, 0xF2
  492. gasLimit := stack.Pop64()
  493. addr, value := stack.Pop(), stack.Pop64()
  494. inOffset, inSize := stack.Pop64(), stack.Pop64() // inputs
  495. retOffset, retSize := stack.Pop64(), stack.Pop64() // outputs
  496. fmt.Printf(" => %X\n", addr)
  497. // Get the arguments from the memory
  498. args, ok := subslice(memory, inOffset, inSize)
  499. if !ok {
  500. return nil, firstErr(err, ErrMemoryOutOfBounds)
  501. }
  502. // Ensure that gasLimit is reasonable
  503. if *gas < gasLimit {
  504. return nil, firstErr(err, ErrInsufficientGas)
  505. } else {
  506. *gas -= gasLimit
  507. // NOTE: we will return any used gas later.
  508. }
  509. // Begin execution
  510. var ret []byte
  511. var err error
  512. // If addr is in nativeContracts
  513. if nativeContract := nativeContracts[addr]; nativeContract != nil {
  514. ret, err = nativeContract(args, &gasLimit)
  515. } else {
  516. if ok = useGas(gas, GasGetAccount); !ok {
  517. return nil, firstErr(err, ErrInsufficientGas)
  518. }
  519. account, err_ := vm.appState.GetAccount(addr)
  520. if err = firstErr(err, err_); err != nil {
  521. return nil, err
  522. }
  523. if op == CALLCODE {
  524. ret, err = vm.Call(callee, callee, account.Code, args, value, gas)
  525. } else {
  526. ret, err = vm.Call(callee, account, account.Code, args, value, gas)
  527. }
  528. }
  529. // Push result
  530. if err != nil {
  531. stack.Push(Zero)
  532. } else {
  533. stack.Push(One)
  534. dest, ok := subslice(memory, retOffset, retSize)
  535. if !ok {
  536. return nil, firstErr(err, ErrMemoryOutOfBounds)
  537. }
  538. copy(dest, ret)
  539. }
  540. // Handle remaining gas.
  541. *gas += gasLimit
  542. fmt.Printf("resume %X (%v)\n", callee.Address, gas)
  543. case RETURN: // 0xF3
  544. offset, size := stack.Pop64(), stack.Pop64()
  545. ret, ok := subslice(memory, offset, size)
  546. if !ok {
  547. return nil, firstErr(err, ErrMemoryOutOfBounds)
  548. }
  549. fmt.Printf(" => [%v, %v] (%d) 0x%X\n", offset, size, len(ret), ret)
  550. return ret, nil
  551. case SUICIDE: // 0xFF
  552. addr := stack.Pop()
  553. if ok = useGas(gas, GasGetAccount); !ok {
  554. return nil, firstErr(err, ErrInsufficientGas)
  555. }
  556. receiver, err_ := vm.appState.GetAccount(addr)
  557. if err = firstErr(err, err_); err != nil {
  558. return nil, err
  559. }
  560. balance := callee.Balance
  561. receiver.Balance += balance
  562. vm.appState.UpdateAccount(receiver)
  563. vm.appState.DeleteAccount(callee)
  564. fmt.Printf(" => (%X) %v\n", addr[:4], balance)
  565. fallthrough
  566. default:
  567. fmt.Printf("(pc) %-3v Invalid opcode %X\n", pc, op)
  568. panic(fmt.Errorf("Invalid opcode %X", op))
  569. }
  570. pc++
  571. }
  572. }
  573. /*
  574. func (vm *VM) CallPrecompiled(p *PrecompiledAccount, callData []byte, context *Context) (ret []byte, err error) {
  575. gas := p.Gas(len(callData))
  576. if context.UseGas(gas) {
  577. ret = p.Call(callData)
  578. fmt.Printf("NATIVE_FUNC => %X", ret)
  579. vm.Endl()
  580. return context.Return(ret), nil
  581. } else {
  582. fmt.Printf("NATIVE_FUNC => failed").Endl()
  583. tmp := new(big.Int).Set(context.Gas)
  584. panic(OOG(gas, tmp).Error())
  585. }
  586. }
  587. */
  588. func subslice(data []byte, offset, length uint64) ([]byte, bool) {
  589. size := uint64(len(data))
  590. if size < offset {
  591. return nil, false
  592. } else if size < offset+length {
  593. return data[offset:], false
  594. } else {
  595. return data[offset : offset+length], true
  596. }
  597. }
  598. func codeGetOp(code []byte, n uint64) OpCode {
  599. if uint64(len(code)) <= n {
  600. return OpCode(0) // stop
  601. } else {
  602. return OpCode(code[n])
  603. }
  604. }
  605. func jump(code []byte, to uint64) (err error) {
  606. dest := codeGetOp(code, to)
  607. if dest != JUMPDEST {
  608. return ErrInvalidJumpDest
  609. }
  610. fmt.Printf(" ~> %v\n", to)
  611. return nil
  612. }
  613. func firstErr(errA, errB error) error {
  614. if errA != nil {
  615. return errA
  616. } else {
  617. return errB
  618. }
  619. }
  620. func useGas(gas *uint64, gasToUse uint64) bool {
  621. if *gas > gasToUse {
  622. *gas -= gasToUse
  623. return true
  624. } else {
  625. return false
  626. }
  627. }
  628. // Creates a 20 byte address from the creatorAddr and nonce.
  629. func createAddress(creatorAddr Word, nonce uint64) Word {
  630. temp := make([]byte, 32+8)
  631. copy(temp, creatorAddr[:])
  632. PutUint64(temp[32:], nonce)
  633. return RightPadWord(sha3.Sha3(temp)[:20])
  634. }