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.

918 lines
24 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
  1. package vm
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "math/big"
  7. . "github.com/tendermint/tendermint/common"
  8. "github.com/tendermint/tendermint/events"
  9. ptypes "github.com/tendermint/tendermint/permission/types"
  10. "github.com/tendermint/tendermint/types"
  11. "github.com/tendermint/tendermint/vm/sha3"
  12. )
  13. var (
  14. ErrUnknownAddress = errors.New("Unknown address")
  15. ErrInsufficientBalance = errors.New("Insufficient balance")
  16. ErrInvalidJumpDest = errors.New("Invalid jump dest")
  17. ErrInsufficientGas = errors.New("Insuffient gas")
  18. ErrMemoryOutOfBounds = errors.New("Memory out of bounds")
  19. ErrCodeOutOfBounds = errors.New("Code out of bounds")
  20. ErrInputOutOfBounds = errors.New("Input out of bounds")
  21. ErrCallStackOverflow = errors.New("Call stack overflow")
  22. ErrCallStackUnderflow = errors.New("Call stack underflow")
  23. ErrDataStackOverflow = errors.New("Data stack overflow")
  24. ErrDataStackUnderflow = errors.New("Data stack underflow")
  25. ErrInvalidContract = errors.New("Invalid contract")
  26. )
  27. type ErrPermission struct {
  28. typ string
  29. }
  30. func (err ErrPermission) Error() string {
  31. return fmt.Sprintf("Contract does not have permission to %s", err.typ)
  32. }
  33. type Debug bool
  34. const (
  35. dataStackCapacity = 1024
  36. callStackCapacity = 100 // TODO ensure usage.
  37. memoryCapacity = 1024 * 1024 // 1 MB
  38. dbg Debug = true
  39. )
  40. func (d Debug) Printf(s string, a ...interface{}) {
  41. if d {
  42. fmt.Printf(s, a...)
  43. }
  44. }
  45. type VM struct {
  46. appState AppState
  47. params Params
  48. origin Word256
  49. txid []byte
  50. callDepth int
  51. evc events.Fireable
  52. }
  53. func NewVM(appState AppState, params Params, origin Word256, txid []byte) *VM {
  54. return &VM{
  55. appState: appState,
  56. params: params,
  57. origin: origin,
  58. callDepth: 0,
  59. txid: txid,
  60. }
  61. }
  62. // satisfies events.Eventable
  63. func (vm *VM) SetFireable(evc events.Fireable) {
  64. vm.evc = evc
  65. }
  66. // CONTRACT: it is the duty of the contract writer to call known permissions
  67. // we do not convey if a permission is not set
  68. // (unlike in state/execution, where we guarantee HasPermission is called
  69. // on known permissions and panics else)
  70. // If the perm is not defined in the acc nor set by default in GlobalPermissions,
  71. // prints a log warning and returns false.
  72. func HasPermission(appState AppState, acc *Account, perm ptypes.PermFlag) bool {
  73. v, err := acc.Permissions.Base.Get(perm)
  74. if _, ok := err.(ptypes.ErrValueNotSet); ok {
  75. if appState == nil {
  76. log.Warn(Fmt("\n\n***** Unknown permission %b! ********\n\n", perm))
  77. return false
  78. }
  79. return HasPermission(nil, appState.GetAccount(ptypes.GlobalPermissionsAddress256), perm)
  80. }
  81. return v
  82. }
  83. func (vm *VM) fireCallEvent(exception *string, output *[]byte, caller, callee *Account, input []byte, value int64, gas *int64) {
  84. // fire the post call event (including exception if applicable)
  85. if vm.evc != nil {
  86. vm.evc.FireEvent(types.EventStringAccCall(callee.Address.Postfix(20)), types.EventMsgCall{
  87. &types.CallData{caller.Address.Postfix(20), callee.Address.Postfix(20), input, value, *gas},
  88. vm.origin.Postfix(20),
  89. vm.txid,
  90. *output,
  91. *exception,
  92. })
  93. }
  94. }
  95. // CONTRACT appState is aware of caller and callee, so we can just mutate them.
  96. // value: To be transferred from caller to callee. Refunded upon error.
  97. // gas: Available gas. No refunds for gas.
  98. // code: May be nil, since the CALL opcode may be used to send value from contracts to accounts
  99. func (vm *VM) Call(caller, callee *Account, code, input []byte, value int64, gas *int64) (output []byte, err error) {
  100. exception := new(string)
  101. // fire the post call event (including exception if applicable)
  102. defer vm.fireCallEvent(exception, &output, caller, callee, input, value, gas)
  103. if err = transfer(caller, callee, value); err != nil {
  104. *exception = err.Error()
  105. return
  106. }
  107. if len(code) > 0 {
  108. vm.callDepth += 1
  109. output, err = vm.call(caller, callee, code, input, value, gas)
  110. vm.callDepth -= 1
  111. if err != nil {
  112. *exception = err.Error()
  113. err := transfer(callee, caller, value)
  114. if err != nil {
  115. // data has been corrupted in ram
  116. PanicCrisis("Could not return value to caller")
  117. }
  118. }
  119. }
  120. return
  121. }
  122. // Try to deduct gasToUse from gasLeft. If ok return false, otherwise
  123. // set err and return true.
  124. func useGasNegative(gasLeft *int64, gasToUse int64, err *error) bool {
  125. if *gasLeft >= gasToUse {
  126. *gasLeft -= gasToUse
  127. return false
  128. } else if *err == nil {
  129. *err = ErrInsufficientGas
  130. }
  131. return true
  132. }
  133. // Just like Call() but does not transfer 'value' or modify the callDepth.
  134. func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas *int64) (output []byte, err error) {
  135. dbg.Printf("(%d) (%X) %X (code=%d) gas: %v (d) %X\n", vm.callDepth, caller.Address[:4], callee.Address, len(callee.Code), *gas, input)
  136. var (
  137. pc int64 = 0
  138. stack = NewStack(dataStackCapacity, gas, &err)
  139. memory = make([]byte, memoryCapacity)
  140. )
  141. for {
  142. // Use BaseOp gas.
  143. if useGasNegative(gas, GasBaseOp, &err) {
  144. return nil, err
  145. }
  146. var op = codeGetOp(code, pc)
  147. dbg.Printf("(pc) %-3d (op) %-14s (st) %-4d ", pc, op.String(), stack.Len())
  148. switch op {
  149. case STOP: // 0x00
  150. return nil, nil
  151. case ADD: // 0x01
  152. x, y := stack.Pop(), stack.Pop()
  153. xb := new(big.Int).SetBytes(x[:])
  154. yb := new(big.Int).SetBytes(y[:])
  155. sum := new(big.Int).Add(xb, yb)
  156. res := LeftPadWord256(U256(sum).Bytes())
  157. stack.Push(res)
  158. dbg.Printf(" %v + %v = %v (%X)\n", xb, yb, sum, res)
  159. case MUL: // 0x02
  160. x, y := stack.Pop(), stack.Pop()
  161. xb := new(big.Int).SetBytes(x[:])
  162. yb := new(big.Int).SetBytes(y[:])
  163. prod := new(big.Int).Mul(xb, yb)
  164. res := LeftPadWord256(U256(prod).Bytes())
  165. stack.Push(res)
  166. dbg.Printf(" %v * %v = %v (%X)\n", xb, yb, prod, res)
  167. case SUB: // 0x03
  168. x, y := stack.Pop(), stack.Pop()
  169. xb := new(big.Int).SetBytes(x[:])
  170. yb := new(big.Int).SetBytes(y[:])
  171. diff := new(big.Int).Sub(xb, yb)
  172. res := LeftPadWord256(U256(diff).Bytes())
  173. stack.Push(res)
  174. dbg.Printf(" %v - %v = %v (%X)\n", xb, yb, diff, res)
  175. case DIV: // 0x04
  176. x, y := stack.Pop(), stack.Pop()
  177. if y.IsZero() {
  178. stack.Push(Zero256)
  179. dbg.Printf(" %x / %x = %v\n", x, y, 0)
  180. } else {
  181. xb := new(big.Int).SetBytes(x[:])
  182. yb := new(big.Int).SetBytes(y[:])
  183. div := new(big.Int).Div(xb, yb)
  184. res := LeftPadWord256(U256(div).Bytes())
  185. stack.Push(res)
  186. dbg.Printf(" %v / %v = %v (%X)\n", xb, yb, div, res)
  187. }
  188. case SDIV: // 0x05
  189. x, y := stack.Pop(), stack.Pop()
  190. if y.IsZero() {
  191. stack.Push(Zero256)
  192. dbg.Printf(" %x / %x = %v\n", x, y, 0)
  193. } else {
  194. xb := S256(new(big.Int).SetBytes(x[:]))
  195. yb := S256(new(big.Int).SetBytes(y[:]))
  196. div := new(big.Int).Div(xb, yb)
  197. res := LeftPadWord256(U256(div).Bytes())
  198. stack.Push(res)
  199. dbg.Printf(" %v / %v = %v (%X)\n", xb, yb, div, res)
  200. }
  201. case MOD: // 0x06
  202. x, y := stack.Pop(), stack.Pop()
  203. if y.IsZero() {
  204. stack.Push(Zero256)
  205. dbg.Printf(" %v %% %v = %v\n", x, y, 0)
  206. } else {
  207. xb := new(big.Int).SetBytes(x[:])
  208. yb := new(big.Int).SetBytes(y[:])
  209. mod := new(big.Int).Mod(xb, yb)
  210. res := LeftPadWord256(U256(mod).Bytes())
  211. stack.Push(res)
  212. dbg.Printf(" %v %% %v = %v (%X)\n", xb, yb, mod, res)
  213. }
  214. case SMOD: // 0x07
  215. x, y := stack.Pop(), stack.Pop()
  216. if y.IsZero() {
  217. stack.Push(Zero256)
  218. dbg.Printf(" %v %% %v = %v\n", x, y, 0)
  219. } else {
  220. xb := S256(new(big.Int).SetBytes(x[:]))
  221. yb := S256(new(big.Int).SetBytes(y[:]))
  222. mod := new(big.Int).Mod(xb, yb)
  223. res := LeftPadWord256(U256(mod).Bytes())
  224. stack.Push(res)
  225. dbg.Printf(" %v %% %v = %v (%X)\n", xb, yb, mod, res)
  226. }
  227. case ADDMOD: // 0x08
  228. x, y, z := stack.Pop(), stack.Pop(), stack.Pop()
  229. if z.IsZero() {
  230. stack.Push(Zero256)
  231. dbg.Printf(" %v %% %v = %v\n", x, y, 0)
  232. } else {
  233. xb := new(big.Int).SetBytes(x[:])
  234. yb := new(big.Int).SetBytes(y[:])
  235. zb := new(big.Int).SetBytes(z[:])
  236. add := new(big.Int).Add(xb, yb)
  237. mod := new(big.Int).Mod(add, zb)
  238. res := LeftPadWord256(U256(mod).Bytes())
  239. stack.Push(res)
  240. dbg.Printf(" %v + %v %% %v = %v (%X)\n",
  241. xb, yb, zb, mod, res)
  242. }
  243. case MULMOD: // 0x09
  244. x, y, z := stack.Pop(), stack.Pop(), stack.Pop()
  245. if z.IsZero() {
  246. stack.Push(Zero256)
  247. dbg.Printf(" %v %% %v = %v\n", x, y, 0)
  248. } else {
  249. xb := new(big.Int).SetBytes(x[:])
  250. yb := new(big.Int).SetBytes(y[:])
  251. zb := new(big.Int).SetBytes(z[:])
  252. mul := new(big.Int).Mul(xb, yb)
  253. mod := new(big.Int).Mod(mul, zb)
  254. res := LeftPadWord256(U256(mod).Bytes())
  255. stack.Push(res)
  256. dbg.Printf(" %v * %v %% %v = %v (%X)\n",
  257. xb, yb, zb, mod, res)
  258. }
  259. case EXP: // 0x0A
  260. x, y := stack.Pop(), stack.Pop()
  261. xb := new(big.Int).SetBytes(x[:])
  262. yb := new(big.Int).SetBytes(y[:])
  263. pow := new(big.Int).Exp(xb, yb, big.NewInt(0))
  264. res := LeftPadWord256(U256(pow).Bytes())
  265. stack.Push(res)
  266. dbg.Printf(" %v ** %v = %v (%X)\n", xb, yb, pow, res)
  267. case SIGNEXTEND: // 0x0B
  268. back := stack.Pop()
  269. backb := new(big.Int).SetBytes(back[:])
  270. if backb.Cmp(big.NewInt(31)) < 0 {
  271. bit := uint(backb.Uint64()*8 + 7)
  272. num := stack.Pop()
  273. numb := new(big.Int).SetBytes(num[:])
  274. mask := new(big.Int).Lsh(big.NewInt(1), bit)
  275. mask.Sub(mask, big.NewInt(1))
  276. if numb.Bit(int(bit)) == 1 {
  277. numb.Or(numb, mask.Not(mask))
  278. } else {
  279. numb.Add(numb, mask)
  280. }
  281. res := LeftPadWord256(U256(numb).Bytes())
  282. dbg.Printf(" = %v (%X)", numb, res)
  283. stack.Push(res)
  284. }
  285. case LT: // 0x10
  286. x, y := stack.Pop(), stack.Pop()
  287. xb := new(big.Int).SetBytes(x[:])
  288. yb := new(big.Int).SetBytes(y[:])
  289. if xb.Cmp(yb) < 0 {
  290. stack.Push64(1)
  291. dbg.Printf(" %v < %v = %v\n", xb, yb, 1)
  292. } else {
  293. stack.Push(Zero256)
  294. dbg.Printf(" %v < %v = %v\n", xb, yb, 0)
  295. }
  296. case GT: // 0x11
  297. x, y := stack.Pop(), stack.Pop()
  298. xb := new(big.Int).SetBytes(x[:])
  299. yb := new(big.Int).SetBytes(y[:])
  300. if xb.Cmp(yb) > 0 {
  301. stack.Push64(1)
  302. dbg.Printf(" %v > %v = %v\n", xb, yb, 1)
  303. } else {
  304. stack.Push(Zero256)
  305. dbg.Printf(" %v > %v = %v\n", xb, yb, 0)
  306. }
  307. case SLT: // 0x12
  308. x, y := stack.Pop(), stack.Pop()
  309. xb := S256(new(big.Int).SetBytes(x[:]))
  310. yb := S256(new(big.Int).SetBytes(y[:]))
  311. if xb.Cmp(yb) < 0 {
  312. stack.Push64(1)
  313. dbg.Printf(" %v < %v = %v\n", xb, yb, 1)
  314. } else {
  315. stack.Push(Zero256)
  316. dbg.Printf(" %v < %v = %v\n", xb, yb, 0)
  317. }
  318. case SGT: // 0x13
  319. x, y := stack.Pop(), stack.Pop()
  320. xb := S256(new(big.Int).SetBytes(x[:]))
  321. yb := S256(new(big.Int).SetBytes(y[:]))
  322. if xb.Cmp(yb) > 0 {
  323. stack.Push64(1)
  324. dbg.Printf(" %v > %v = %v\n", xb, yb, 1)
  325. } else {
  326. stack.Push(Zero256)
  327. dbg.Printf(" %v > %v = %v\n", xb, yb, 0)
  328. }
  329. case EQ: // 0x14
  330. x, y := stack.Pop(), stack.Pop()
  331. if bytes.Equal(x[:], y[:]) {
  332. stack.Push64(1)
  333. dbg.Printf(" %X == %X = %v\n", x, y, 1)
  334. } else {
  335. stack.Push(Zero256)
  336. dbg.Printf(" %X == %X = %v\n", x, y, 0)
  337. }
  338. case ISZERO: // 0x15
  339. x := stack.Pop()
  340. if x.IsZero() {
  341. stack.Push64(1)
  342. dbg.Printf(" %v == 0 = %v\n", x, 1)
  343. } else {
  344. stack.Push(Zero256)
  345. dbg.Printf(" %v == 0 = %v\n", x, 0)
  346. }
  347. case AND: // 0x16
  348. x, y := stack.Pop(), stack.Pop()
  349. z := [32]byte{}
  350. for i := 0; i < 32; i++ {
  351. z[i] = x[i] & y[i]
  352. }
  353. stack.Push(z)
  354. dbg.Printf(" %X & %X = %X\n", x, y, z)
  355. case OR: // 0x17
  356. x, y := stack.Pop(), stack.Pop()
  357. z := [32]byte{}
  358. for i := 0; i < 32; i++ {
  359. z[i] = x[i] | y[i]
  360. }
  361. stack.Push(z)
  362. dbg.Printf(" %X | %X = %X\n", x, y, z)
  363. case XOR: // 0x18
  364. x, y := stack.Pop(), stack.Pop()
  365. z := [32]byte{}
  366. for i := 0; i < 32; i++ {
  367. z[i] = x[i] ^ y[i]
  368. }
  369. stack.Push(z)
  370. dbg.Printf(" %X ^ %X = %X\n", x, y, z)
  371. case NOT: // 0x19
  372. x := stack.Pop()
  373. z := [32]byte{}
  374. for i := 0; i < 32; i++ {
  375. z[i] = ^x[i]
  376. }
  377. stack.Push(z)
  378. dbg.Printf(" !%X = %X\n", x, z)
  379. case BYTE: // 0x1A
  380. idx, val := stack.Pop64(), stack.Pop()
  381. res := byte(0)
  382. if idx < 32 {
  383. res = val[idx]
  384. }
  385. stack.Push64(int64(res))
  386. dbg.Printf(" => 0x%X\n", res)
  387. case SHA3: // 0x20
  388. if useGasNegative(gas, GasSha3, &err) {
  389. return nil, err
  390. }
  391. offset, size := stack.Pop64(), stack.Pop64()
  392. data, ok := subslice(memory, offset, size)
  393. if !ok {
  394. return nil, firstErr(err, ErrMemoryOutOfBounds)
  395. }
  396. data = sha3.Sha3(data)
  397. stack.PushBytes(data)
  398. dbg.Printf(" => (%v) %X\n", size, data)
  399. case ADDRESS: // 0x30
  400. stack.Push(callee.Address)
  401. dbg.Printf(" => %X\n", callee.Address)
  402. case BALANCE: // 0x31
  403. addr := stack.Pop()
  404. if useGasNegative(gas, GasGetAccount, &err) {
  405. return nil, err
  406. }
  407. acc := vm.appState.GetAccount(addr)
  408. if acc == nil {
  409. return nil, firstErr(err, ErrUnknownAddress)
  410. }
  411. balance := acc.Balance
  412. stack.Push64(balance)
  413. dbg.Printf(" => %v (%X)\n", balance, addr)
  414. case ORIGIN: // 0x32
  415. stack.Push(vm.origin)
  416. dbg.Printf(" => %X\n", vm.origin)
  417. case CALLER: // 0x33
  418. stack.Push(caller.Address)
  419. dbg.Printf(" => %X\n", caller.Address)
  420. case CALLVALUE: // 0x34
  421. stack.Push64(value)
  422. dbg.Printf(" => %v\n", value)
  423. case CALLDATALOAD: // 0x35
  424. offset := stack.Pop64()
  425. data, ok := subslice(input, offset, 32)
  426. if !ok {
  427. return nil, firstErr(err, ErrInputOutOfBounds)
  428. }
  429. res := LeftPadWord256(data)
  430. stack.Push(res)
  431. dbg.Printf(" => 0x%X\n", res)
  432. case CALLDATASIZE: // 0x36
  433. stack.Push64(int64(len(input)))
  434. dbg.Printf(" => %d\n", len(input))
  435. case CALLDATACOPY: // 0x37
  436. memOff := stack.Pop64()
  437. inputOff := stack.Pop64()
  438. length := stack.Pop64()
  439. data, ok := subslice(input, inputOff, length)
  440. if !ok {
  441. return nil, firstErr(err, ErrInputOutOfBounds)
  442. }
  443. dest, ok := subslice(memory, memOff, length)
  444. if !ok {
  445. return nil, firstErr(err, ErrMemoryOutOfBounds)
  446. }
  447. copy(dest, data)
  448. dbg.Printf(" => [%v, %v, %v] %X\n", memOff, inputOff, length, data)
  449. case CODESIZE: // 0x38
  450. l := int64(len(code))
  451. stack.Push64(l)
  452. dbg.Printf(" => %d\n", l)
  453. case CODECOPY: // 0x39
  454. memOff := stack.Pop64()
  455. codeOff := stack.Pop64()
  456. length := stack.Pop64()
  457. data, ok := subslice(code, codeOff, length)
  458. if !ok {
  459. return nil, firstErr(err, ErrCodeOutOfBounds)
  460. }
  461. dest, ok := subslice(memory, memOff, length)
  462. if !ok {
  463. return nil, firstErr(err, ErrMemoryOutOfBounds)
  464. }
  465. copy(dest, data)
  466. dbg.Printf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data)
  467. case GASPRICE_DEPRECATED: // 0x3A
  468. stack.Push(Zero256)
  469. dbg.Printf(" => %X (GASPRICE IS DEPRECATED)\n")
  470. case EXTCODESIZE: // 0x3B
  471. addr := stack.Pop()
  472. if useGasNegative(gas, GasGetAccount, &err) {
  473. return nil, err
  474. }
  475. acc := vm.appState.GetAccount(addr)
  476. if acc == nil {
  477. return nil, firstErr(err, ErrUnknownAddress)
  478. }
  479. code := acc.Code
  480. l := int64(len(code))
  481. stack.Push64(l)
  482. dbg.Printf(" => %d\n", l)
  483. case EXTCODECOPY: // 0x3C
  484. addr := stack.Pop()
  485. if useGasNegative(gas, GasGetAccount, &err) {
  486. return nil, err
  487. }
  488. acc := vm.appState.GetAccount(addr)
  489. if acc == nil {
  490. return nil, firstErr(err, ErrUnknownAddress)
  491. }
  492. code := acc.Code
  493. memOff := stack.Pop64()
  494. codeOff := stack.Pop64()
  495. length := stack.Pop64()
  496. data, ok := subslice(code, codeOff, length)
  497. if !ok {
  498. return nil, firstErr(err, ErrCodeOutOfBounds)
  499. }
  500. dest, ok := subslice(memory, memOff, length)
  501. if !ok {
  502. return nil, firstErr(err, ErrMemoryOutOfBounds)
  503. }
  504. copy(dest, data)
  505. dbg.Printf(" => [%v, %v, %v] %X\n", memOff, codeOff, length, data)
  506. case BLOCKHASH: // 0x40
  507. stack.Push(Zero256)
  508. dbg.Printf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes())
  509. case COINBASE: // 0x41
  510. stack.Push(Zero256)
  511. dbg.Printf(" => 0x%X (NOT SUPPORTED)\n", stack.Peek().Bytes())
  512. case TIMESTAMP: // 0x42
  513. time := vm.params.BlockTime
  514. stack.Push64(int64(time))
  515. dbg.Printf(" => 0x%X\n", time)
  516. case BLOCKHEIGHT: // 0x43
  517. number := int64(vm.params.BlockHeight)
  518. stack.Push64(number)
  519. dbg.Printf(" => 0x%X\n", number)
  520. case GASLIMIT: // 0x45
  521. stack.Push64(vm.params.GasLimit)
  522. dbg.Printf(" => %v\n", vm.params.GasLimit)
  523. case POP: // 0x50
  524. popped := stack.Pop()
  525. dbg.Printf(" => 0x%X\n", popped)
  526. case MLOAD: // 0x51
  527. offset := stack.Pop64()
  528. data, ok := subslice(memory, offset, 32)
  529. if !ok {
  530. return nil, firstErr(err, ErrMemoryOutOfBounds)
  531. }
  532. stack.Push(LeftPadWord256(data))
  533. dbg.Printf(" => 0x%X\n", data)
  534. case MSTORE: // 0x52
  535. offset, data := stack.Pop64(), stack.Pop()
  536. dest, ok := subslice(memory, offset, 32)
  537. if !ok {
  538. return nil, firstErr(err, ErrMemoryOutOfBounds)
  539. }
  540. copy(dest, data[:])
  541. dbg.Printf(" => 0x%X\n", data)
  542. case MSTORE8: // 0x53
  543. offset, val := stack.Pop64(), byte(stack.Pop64()&0xFF)
  544. if len(memory) <= int(offset) {
  545. return nil, firstErr(err, ErrMemoryOutOfBounds)
  546. }
  547. memory[offset] = val
  548. dbg.Printf(" => [%v] 0x%X\n", offset, val)
  549. case SLOAD: // 0x54
  550. loc := stack.Pop()
  551. data := vm.appState.GetStorage(callee.Address, loc)
  552. stack.Push(data)
  553. dbg.Printf(" {0x%X : 0x%X}\n", loc, data)
  554. case SSTORE: // 0x55
  555. loc, data := stack.Pop(), stack.Pop()
  556. if useGasNegative(gas, GasStorageUpdate, &err) {
  557. return nil, err
  558. }
  559. vm.appState.SetStorage(callee.Address, loc, data)
  560. dbg.Printf(" {0x%X : 0x%X}\n", loc, data)
  561. case JUMP: // 0x56
  562. err = jump(code, stack.Pop64(), &pc)
  563. continue
  564. case JUMPI: // 0x57
  565. pos, cond := stack.Pop64(), stack.Pop()
  566. if !cond.IsZero() {
  567. err = jump(code, pos, &pc)
  568. continue
  569. }
  570. dbg.Printf(" ~> false\n")
  571. case PC: // 0x58
  572. stack.Push64(pc)
  573. case MSIZE: // 0x59
  574. stack.Push64(int64(len(memory)))
  575. case GAS: // 0x5A
  576. stack.Push64(*gas)
  577. dbg.Printf(" => %X\n", *gas)
  578. case JUMPDEST: // 0x5B
  579. dbg.Printf("\n")
  580. // Do nothing
  581. 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:
  582. a := int64(op - PUSH1 + 1)
  583. codeSegment, ok := subslice(code, pc+1, a)
  584. if !ok {
  585. return nil, firstErr(err, ErrCodeOutOfBounds)
  586. }
  587. res := LeftPadWord256(codeSegment)
  588. stack.Push(res)
  589. pc += a
  590. dbg.Printf(" => 0x%X\n", res)
  591. //stack.Print(10)
  592. case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
  593. n := int(op - DUP1 + 1)
  594. stack.Dup(n)
  595. dbg.Printf(" => [%d] 0x%X\n", n, stack.Peek().Bytes())
  596. case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
  597. n := int(op - SWAP1 + 2)
  598. stack.Swap(n)
  599. dbg.Printf(" => [%d] %X\n", n, stack.Peek())
  600. //stack.Print(10)
  601. case LOG0, LOG1, LOG2, LOG3, LOG4:
  602. n := int(op - LOG0)
  603. topics := make([]Word256, n)
  604. offset, size := stack.Pop64(), stack.Pop64()
  605. for i := 0; i < n; i++ {
  606. topics[i] = stack.Pop()
  607. }
  608. data, ok := subslice(memory, offset, size)
  609. if !ok {
  610. return nil, firstErr(err, ErrMemoryOutOfBounds)
  611. }
  612. log := &Log{
  613. callee.Address,
  614. topics,
  615. data,
  616. vm.params.BlockHeight,
  617. }
  618. vm.appState.AddLog(log)
  619. if vm.evc != nil {
  620. eventId := types.EventStringLogEvent(callee.Address.Postfix(20))
  621. fmt.Printf("eventId: %s\n", eventId)
  622. vm.evc.FireEvent(eventId, log)
  623. }
  624. // Using sol-log for this as well since 'log' will print garbage.
  625. dbg.Printf(" => T:%X D:%X\n", log.Topics, log.Data)
  626. case CREATE: // 0xF0
  627. if !HasPermission(vm.appState, callee, ptypes.CreateContract) {
  628. return nil, ErrPermission{"create_contract"}
  629. }
  630. contractValue := stack.Pop64()
  631. offset, size := stack.Pop64(), stack.Pop64()
  632. input, ok := subslice(memory, offset, size)
  633. if !ok {
  634. return nil, firstErr(err, ErrMemoryOutOfBounds)
  635. }
  636. // Check balance
  637. if callee.Balance < contractValue {
  638. return nil, firstErr(err, ErrInsufficientBalance)
  639. }
  640. // TODO charge for gas to create account _ the code length * GasCreateByte
  641. newAccount := vm.appState.CreateAccount(callee)
  642. // Run the input to get the contract code.
  643. ret, err_ := vm.Call(callee, newAccount, input, input, contractValue, gas)
  644. if err_ != nil {
  645. stack.Push(Zero256)
  646. } else {
  647. newAccount.Code = ret // Set the code
  648. stack.Push(newAccount.Address)
  649. }
  650. case CALL, CALLCODE: // 0xF1, 0xF2
  651. if !HasPermission(vm.appState, callee, ptypes.Call) {
  652. return nil, ErrPermission{"call"}
  653. }
  654. gasLimit := stack.Pop64()
  655. addr, value := stack.Pop(), stack.Pop64()
  656. inOffset, inSize := stack.Pop64(), stack.Pop64() // inputs
  657. retOffset, retSize := stack.Pop64(), stack.Pop64() // outputs
  658. dbg.Printf(" => %X\n", addr)
  659. // Get the arguments from the memory
  660. args, ok := subslice(memory, inOffset, inSize)
  661. if !ok {
  662. return nil, firstErr(err, ErrMemoryOutOfBounds)
  663. }
  664. // Ensure that gasLimit is reasonable
  665. if *gas < gasLimit {
  666. return nil, firstErr(err, ErrInsufficientGas)
  667. } else {
  668. *gas -= gasLimit
  669. // NOTE: we will return any used gas later.
  670. }
  671. // Begin execution
  672. var ret []byte
  673. var err error
  674. if nativeContract := registeredNativeContracts[addr]; nativeContract != nil {
  675. // Native contract
  676. ret, err = nativeContract(vm.appState, callee, args, &gasLimit)
  677. // for now we fire the Call event. maybe later we'll fire more particulars
  678. var exception string
  679. if err != nil {
  680. exception = err.Error()
  681. }
  682. vm.fireCallEvent(&exception, &ret, callee, &Account{Address: addr}, args, value, gas)
  683. } else {
  684. // EVM contract
  685. if useGasNegative(gas, GasGetAccount, &err) {
  686. return nil, err
  687. }
  688. acc := vm.appState.GetAccount(addr)
  689. // since CALL is used also for sending funds,
  690. // acc may not exist yet. This is an error for
  691. // CALLCODE, but not for CALL, though I don't think
  692. // ethereum actually cares
  693. if op == CALLCODE {
  694. if acc == nil {
  695. return nil, firstErr(err, ErrUnknownAddress)
  696. }
  697. ret, err = vm.Call(callee, callee, acc.Code, args, value, gas)
  698. } else {
  699. if acc == nil {
  700. // nil account means we're sending funds to a new account
  701. if !HasPermission(vm.appState, caller, ptypes.CreateAccount) {
  702. return nil, ErrPermission{"create_account"}
  703. }
  704. acc = &Account{Address: addr}
  705. vm.appState.UpdateAccount(acc)
  706. // send funds to new account
  707. ret, err = vm.Call(callee, acc, acc.Code, args, value, gas)
  708. } else {
  709. // call standard contract
  710. ret, err = vm.Call(callee, acc, acc.Code, args, value, gas)
  711. }
  712. }
  713. }
  714. // Push result
  715. if err != nil {
  716. dbg.Printf("error on call: %s\n", err.Error())
  717. stack.Push(Zero256)
  718. } else {
  719. stack.Push(One256)
  720. dest, ok := subslice(memory, retOffset, retSize)
  721. if !ok {
  722. return nil, firstErr(err, ErrMemoryOutOfBounds)
  723. }
  724. copy(dest, ret)
  725. }
  726. // Handle remaining gas.
  727. *gas += gasLimit
  728. dbg.Printf("resume %X (%v)\n", callee.Address, gas)
  729. case RETURN: // 0xF3
  730. offset, size := stack.Pop64(), stack.Pop64()
  731. ret, ok := subslice(memory, offset, size)
  732. if !ok {
  733. return nil, firstErr(err, ErrMemoryOutOfBounds)
  734. }
  735. dbg.Printf(" => [%v, %v] (%d) 0x%X\n", offset, size, len(ret), ret)
  736. return ret, nil
  737. case SUICIDE: // 0xFF
  738. addr := stack.Pop()
  739. if useGasNegative(gas, GasGetAccount, &err) {
  740. return nil, err
  741. }
  742. // TODO if the receiver is , then make it the fee.
  743. receiver := vm.appState.GetAccount(addr)
  744. if receiver == nil {
  745. return nil, firstErr(err, ErrUnknownAddress)
  746. }
  747. balance := callee.Balance
  748. receiver.Balance += balance
  749. vm.appState.UpdateAccount(receiver)
  750. vm.appState.RemoveAccount(callee)
  751. dbg.Printf(" => (%X) %v\n", addr[:4], balance)
  752. fallthrough
  753. default:
  754. dbg.Printf("(pc) %-3v Invalid opcode %X\n", pc, op)
  755. return nil, fmt.Errorf("Invalid opcode %X", op)
  756. }
  757. pc++
  758. }
  759. }
  760. func subslice(data []byte, offset, length int64) (ret []byte, ok bool) {
  761. size := int64(len(data))
  762. if size < offset {
  763. return nil, false
  764. } else if size < offset+length {
  765. ret, ok = data[offset:], true
  766. ret = RightPadBytes(ret, 32)
  767. } else {
  768. ret, ok = data[offset:offset+length], true
  769. }
  770. return
  771. }
  772. func rightMostBytes(data []byte, n int) []byte {
  773. size := MinInt(len(data), n)
  774. offset := len(data) - size
  775. return data[offset:]
  776. }
  777. func codeGetOp(code []byte, n int64) OpCode {
  778. if int64(len(code)) <= n {
  779. return OpCode(0) // stop
  780. } else {
  781. return OpCode(code[n])
  782. }
  783. }
  784. func jump(code []byte, to int64, pc *int64) (err error) {
  785. dest := codeGetOp(code, to)
  786. if dest != JUMPDEST {
  787. dbg.Printf(" ~> %v invalid jump dest %v\n", to, dest)
  788. return ErrInvalidJumpDest
  789. }
  790. dbg.Printf(" ~> %v\n", to)
  791. *pc = to
  792. return nil
  793. }
  794. func firstErr(errA, errB error) error {
  795. if errA != nil {
  796. return errA
  797. } else {
  798. return errB
  799. }
  800. }
  801. func transfer(from, to *Account, amount int64) error {
  802. if from.Balance < amount {
  803. return ErrInsufficientBalance
  804. } else {
  805. from.Balance -= amount
  806. to.Balance += amount
  807. return nil
  808. }
  809. }