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.

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