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.

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