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.

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