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.

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