instructions.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package vm
  17. import (
  18. "fmt"
  19. "math/big"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/common/math"
  22. "github.com/ethereum/go-ethereum/core/types"
  23. "github.com/ethereum/go-ethereum/crypto"
  24. "github.com/ethereum/go-ethereum/params"
  25. )
  26. func opAdd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  27. x, y := stack.pop(), stack.pop()
  28. stack.push(U256(x.Add(x, y)))
  29. return nil, nil
  30. }
  31. func opSub(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  32. x, y := stack.pop(), stack.pop()
  33. stack.push(U256(x.Sub(x, y)))
  34. return nil, nil
  35. }
  36. func opMul(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  37. x, y := stack.pop(), stack.pop()
  38. stack.push(U256(x.Mul(x, y)))
  39. return nil, nil
  40. }
  41. func opDiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  42. x, y := stack.pop(), stack.pop()
  43. if y.Cmp(common.Big0) != 0 {
  44. stack.push(U256(x.Div(x, y)))
  45. } else {
  46. stack.push(new(big.Int))
  47. }
  48. return nil, nil
  49. }
  50. func opSdiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  51. x, y := S256(stack.pop()), S256(stack.pop())
  52. if y.Cmp(common.Big0) == 0 {
  53. stack.push(new(big.Int))
  54. return nil, nil
  55. } else {
  56. n := new(big.Int)
  57. if new(big.Int).Mul(x, y).Cmp(common.Big0) < 0 {
  58. n.SetInt64(-1)
  59. } else {
  60. n.SetInt64(1)
  61. }
  62. res := x.Div(x.Abs(x), y.Abs(y))
  63. res.Mul(res, n)
  64. stack.push(U256(res))
  65. }
  66. return nil, nil
  67. }
  68. func opMod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  69. x, y := stack.pop(), stack.pop()
  70. if y.Cmp(common.Big0) == 0 {
  71. stack.push(new(big.Int))
  72. } else {
  73. stack.push(U256(x.Mod(x, y)))
  74. }
  75. return nil, nil
  76. }
  77. func opSmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  78. x, y := S256(stack.pop()), S256(stack.pop())
  79. if y.Cmp(common.Big0) == 0 {
  80. stack.push(new(big.Int))
  81. } else {
  82. n := new(big.Int)
  83. if x.Cmp(common.Big0) < 0 {
  84. n.SetInt64(-1)
  85. } else {
  86. n.SetInt64(1)
  87. }
  88. res := x.Mod(x.Abs(x), y.Abs(y))
  89. res.Mul(res, n)
  90. stack.push(U256(res))
  91. }
  92. return nil, nil
  93. }
  94. func opExp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  95. base, exponent := stack.pop(), stack.pop()
  96. stack.push(math.Exp(base, exponent))
  97. return nil, nil
  98. }
  99. func opSignExtend(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  100. back := stack.pop()
  101. if back.Cmp(big.NewInt(31)) < 0 {
  102. bit := uint(back.Uint64()*8 + 7)
  103. num := stack.pop()
  104. mask := back.Lsh(common.Big1, bit)
  105. mask.Sub(mask, common.Big1)
  106. if common.BitTest(num, int(bit)) {
  107. num.Or(num, mask.Not(mask))
  108. } else {
  109. num.And(num, mask)
  110. }
  111. stack.push(U256(num))
  112. }
  113. return nil, nil
  114. }
  115. func opNot(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  116. x := stack.pop()
  117. stack.push(U256(x.Not(x)))
  118. return nil, nil
  119. }
  120. func opLt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  121. x, y := stack.pop(), stack.pop()
  122. if x.Cmp(y) < 0 {
  123. stack.push(big.NewInt(1))
  124. } else {
  125. stack.push(new(big.Int))
  126. }
  127. return nil, nil
  128. }
  129. func opGt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  130. x, y := stack.pop(), stack.pop()
  131. if x.Cmp(y) > 0 {
  132. stack.push(big.NewInt(1))
  133. } else {
  134. stack.push(new(big.Int))
  135. }
  136. return nil, nil
  137. }
  138. func opSlt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  139. x, y := S256(stack.pop()), S256(stack.pop())
  140. if x.Cmp(S256(y)) < 0 {
  141. stack.push(big.NewInt(1))
  142. } else {
  143. stack.push(new(big.Int))
  144. }
  145. return nil, nil
  146. }
  147. func opSgt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  148. x, y := S256(stack.pop()), S256(stack.pop())
  149. if x.Cmp(y) > 0 {
  150. stack.push(big.NewInt(1))
  151. } else {
  152. stack.push(new(big.Int))
  153. }
  154. return nil, nil
  155. }
  156. func opEq(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  157. x, y := stack.pop(), stack.pop()
  158. if x.Cmp(y) == 0 {
  159. stack.push(big.NewInt(1))
  160. } else {
  161. stack.push(new(big.Int))
  162. }
  163. return nil, nil
  164. }
  165. func opIszero(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  166. x := stack.pop()
  167. if x.Cmp(common.Big0) > 0 {
  168. stack.push(new(big.Int))
  169. } else {
  170. stack.push(big.NewInt(1))
  171. }
  172. return nil, nil
  173. }
  174. func opAnd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  175. x, y := stack.pop(), stack.pop()
  176. stack.push(x.And(x, y))
  177. return nil, nil
  178. }
  179. func opOr(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  180. x, y := stack.pop(), stack.pop()
  181. stack.push(x.Or(x, y))
  182. return nil, nil
  183. }
  184. func opXor(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  185. x, y := stack.pop(), stack.pop()
  186. stack.push(x.Xor(x, y))
  187. return nil, nil
  188. }
  189. func opByte(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  190. th, val := stack.pop(), stack.pop()
  191. if th.Cmp(big.NewInt(32)) < 0 {
  192. byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
  193. stack.push(byte)
  194. } else {
  195. stack.push(new(big.Int))
  196. }
  197. return nil, nil
  198. }
  199. func opAddmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  200. x, y, z := stack.pop(), stack.pop(), stack.pop()
  201. if z.Cmp(Zero) > 0 {
  202. add := x.Add(x, y)
  203. add.Mod(add, z)
  204. stack.push(U256(add))
  205. } else {
  206. stack.push(new(big.Int))
  207. }
  208. return nil, nil
  209. }
  210. func opMulmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  211. x, y, z := stack.pop(), stack.pop(), stack.pop()
  212. if z.Cmp(Zero) > 0 {
  213. mul := x.Mul(x, y)
  214. mul.Mod(mul, z)
  215. stack.push(U256(mul))
  216. } else {
  217. stack.push(new(big.Int))
  218. }
  219. return nil, nil
  220. }
  221. func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  222. offset, size := stack.pop(), stack.pop()
  223. hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64()))
  224. stack.push(common.BytesToBig(hash))
  225. return nil, nil
  226. }
  227. func opAddress(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  228. stack.push(common.Bytes2Big(contract.Address().Bytes()))
  229. return nil, nil
  230. }
  231. func opBalance(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  232. addr := common.BigToAddress(stack.pop())
  233. balance := env.StateDB.GetBalance(addr)
  234. stack.push(new(big.Int).Set(balance))
  235. return nil, nil
  236. }
  237. func opOrigin(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  238. stack.push(env.Origin.Big())
  239. return nil, nil
  240. }
  241. func opCaller(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  242. stack.push(contract.Caller().Big())
  243. return nil, nil
  244. }
  245. func opCallValue(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  246. stack.push(new(big.Int).Set(contract.value))
  247. return nil, nil
  248. }
  249. func opCalldataLoad(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  250. stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
  251. return nil, nil
  252. }
  253. func opCalldataSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  254. stack.push(big.NewInt(int64(len(contract.Input))))
  255. return nil, nil
  256. }
  257. func opCalldataCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  258. var (
  259. mOff = stack.pop()
  260. cOff = stack.pop()
  261. l = stack.pop()
  262. )
  263. memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l))
  264. return nil, nil
  265. }
  266. func opExtCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  267. addr := common.BigToAddress(stack.pop())
  268. l := big.NewInt(int64(env.StateDB.GetCodeSize(addr)))
  269. stack.push(l)
  270. return nil, nil
  271. }
  272. func opCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  273. l := big.NewInt(int64(len(contract.Code)))
  274. stack.push(l)
  275. return nil, nil
  276. }
  277. func opCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  278. var (
  279. mOff = stack.pop()
  280. cOff = stack.pop()
  281. l = stack.pop()
  282. )
  283. codeCopy := getData(contract.Code, cOff, l)
  284. memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
  285. return nil, nil
  286. }
  287. func opExtCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  288. var (
  289. addr = common.BigToAddress(stack.pop())
  290. mOff = stack.pop()
  291. cOff = stack.pop()
  292. l = stack.pop()
  293. )
  294. codeCopy := getData(env.StateDB.GetCode(addr), cOff, l)
  295. memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
  296. return nil, nil
  297. }
  298. func opGasprice(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  299. stack.push(new(big.Int).Set(env.GasPrice))
  300. return nil, nil
  301. }
  302. func opBlockhash(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  303. num := stack.pop()
  304. n := new(big.Int).Sub(env.BlockNumber, common.Big257)
  305. if num.Cmp(n) > 0 && num.Cmp(env.BlockNumber) < 0 {
  306. stack.push(env.GetHash(num.Uint64()).Big())
  307. } else {
  308. stack.push(new(big.Int))
  309. }
  310. return nil, nil
  311. }
  312. func opCoinbase(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  313. stack.push(env.Coinbase.Big())
  314. return nil, nil
  315. }
  316. func opTimestamp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  317. stack.push(U256(new(big.Int).Set(env.Time)))
  318. return nil, nil
  319. }
  320. func opNumber(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  321. stack.push(U256(new(big.Int).Set(env.BlockNumber)))
  322. return nil, nil
  323. }
  324. func opDifficulty(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  325. stack.push(U256(new(big.Int).Set(env.Difficulty)))
  326. return nil, nil
  327. }
  328. func opGasLimit(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  329. stack.push(U256(new(big.Int).Set(env.GasLimit)))
  330. return nil, nil
  331. }
  332. func opPop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  333. stack.pop()
  334. return nil, nil
  335. }
  336. func opMload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  337. offset := stack.pop()
  338. val := common.BigD(memory.Get(offset.Int64(), 32))
  339. stack.push(val)
  340. return nil, nil
  341. }
  342. func opMstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  343. // pop value of the stack
  344. mStart, val := stack.pop(), stack.pop()
  345. memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
  346. return nil, nil
  347. }
  348. func opMstore8(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  349. off, val := stack.pop().Int64(), stack.pop().Int64()
  350. memory.store[off] = byte(val & 0xff)
  351. return nil, nil
  352. }
  353. func opSload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  354. loc := common.BigToHash(stack.pop())
  355. val := env.StateDB.GetState(contract.Address(), loc).Big()
  356. stack.push(val)
  357. return nil, nil
  358. }
  359. func opSstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  360. loc := common.BigToHash(stack.pop())
  361. val := stack.pop()
  362. env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
  363. return nil, nil
  364. }
  365. func opJump(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  366. pos := stack.pop()
  367. if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
  368. nop := contract.GetOp(pos.Uint64())
  369. return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
  370. }
  371. *pc = pos.Uint64()
  372. return nil, nil
  373. }
  374. func opJumpi(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  375. pos, cond := stack.pop(), stack.pop()
  376. if cond.Cmp(common.BigTrue) >= 0 {
  377. if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
  378. nop := contract.GetOp(pos.Uint64())
  379. return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
  380. }
  381. *pc = pos.Uint64()
  382. } else {
  383. *pc++
  384. }
  385. return nil, nil
  386. }
  387. func opJumpdest(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  388. return nil, nil
  389. }
  390. func opPc(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  391. stack.push(new(big.Int).SetUint64(*pc))
  392. return nil, nil
  393. }
  394. func opMsize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  395. stack.push(big.NewInt(int64(memory.Len())))
  396. return nil, nil
  397. }
  398. func opGas(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  399. stack.push(new(big.Int).Set(contract.Gas))
  400. return nil, nil
  401. }
  402. func opCreate(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  403. var (
  404. value = stack.pop()
  405. offset, size = stack.pop(), stack.pop()
  406. input = memory.Get(offset.Int64(), size.Int64())
  407. gas = new(big.Int).Set(contract.Gas)
  408. )
  409. if env.ChainConfig().IsEIP150(env.BlockNumber) {
  410. gas.Div(gas, n64)
  411. gas = gas.Sub(contract.Gas, gas)
  412. }
  413. contract.UseGas(gas)
  414. _, addr, suberr := env.Create(contract, input, gas, value)
  415. // Push item on the stack based on the returned error. If the ruleset is
  416. // homestead we must check for CodeStoreOutOfGasError (homestead only
  417. // rule) and treat as an error, if the ruleset is frontier we must
  418. // ignore this error and pretend the operation was successful.
  419. if env.ChainConfig().IsHomestead(env.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
  420. stack.push(new(big.Int))
  421. } else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
  422. stack.push(new(big.Int))
  423. } else {
  424. stack.push(addr.Big())
  425. }
  426. return nil, nil
  427. }
  428. func opCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  429. gas := stack.pop()
  430. // pop gas and value of the stack.
  431. addr, value := stack.pop(), stack.pop()
  432. value = U256(value)
  433. // pop input size and offset
  434. inOffset, inSize := stack.pop(), stack.pop()
  435. // pop return size and offset
  436. retOffset, retSize := stack.pop(), stack.pop()
  437. address := common.BigToAddress(addr)
  438. // Get the arguments from the memory
  439. args := memory.Get(inOffset.Int64(), inSize.Int64())
  440. if len(value.Bytes()) > 0 {
  441. gas.Add(gas, params.CallStipend)
  442. }
  443. ret, err := env.Call(contract, address, args, gas, value)
  444. if err != nil {
  445. stack.push(new(big.Int))
  446. } else {
  447. stack.push(big.NewInt(1))
  448. memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
  449. }
  450. return nil, nil
  451. }
  452. func opCallCode(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  453. gas := stack.pop()
  454. // pop gas and value of the stack.
  455. addr, value := stack.pop(), stack.pop()
  456. value = U256(value)
  457. // pop input size and offset
  458. inOffset, inSize := stack.pop(), stack.pop()
  459. // pop return size and offset
  460. retOffset, retSize := stack.pop(), stack.pop()
  461. address := common.BigToAddress(addr)
  462. // Get the arguments from the memory
  463. args := memory.Get(inOffset.Int64(), inSize.Int64())
  464. if len(value.Bytes()) > 0 {
  465. gas.Add(gas, params.CallStipend)
  466. }
  467. ret, err := env.CallCode(contract, address, args, gas, value)
  468. if err != nil {
  469. stack.push(new(big.Int))
  470. } else {
  471. stack.push(big.NewInt(1))
  472. memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
  473. }
  474. return nil, nil
  475. }
  476. func opDelegateCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  477. // if not homestead return an error. DELEGATECALL is not supported
  478. // during pre-homestead.
  479. if !env.ChainConfig().IsHomestead(env.BlockNumber) {
  480. return nil, fmt.Errorf("invalid opcode %x", DELEGATECALL)
  481. }
  482. gas, to, inOffset, inSize, outOffset, outSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
  483. toAddr := common.BigToAddress(to)
  484. args := memory.Get(inOffset.Int64(), inSize.Int64())
  485. ret, err := env.DelegateCall(contract, toAddr, args, gas)
  486. if err != nil {
  487. stack.push(new(big.Int))
  488. } else {
  489. stack.push(big.NewInt(1))
  490. memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
  491. }
  492. return nil, nil
  493. }
  494. func opReturn(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  495. offset, size := stack.pop(), stack.pop()
  496. ret := memory.GetPtr(offset.Int64(), size.Int64())
  497. return ret, nil
  498. }
  499. func opStop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  500. return nil, nil
  501. }
  502. func opSuicide(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  503. balance := env.StateDB.GetBalance(contract.Address())
  504. env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
  505. env.StateDB.Suicide(contract.Address())
  506. return nil, nil
  507. }
  508. // following functions are used by the instruction jump table
  509. // make log instruction function
  510. func makeLog(size int) executionFunc {
  511. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  512. topics := make([]common.Hash, size)
  513. mStart, mSize := stack.pop(), stack.pop()
  514. for i := 0; i < size; i++ {
  515. topics[i] = common.BigToHash(stack.pop())
  516. }
  517. d := memory.Get(mStart.Int64(), mSize.Int64())
  518. env.StateDB.AddLog(&types.Log{
  519. Address: contract.Address(),
  520. Topics: topics,
  521. Data: d,
  522. // This is a non-consensus field, but assigned here because
  523. // core/state doesn't know the current block number.
  524. BlockNumber: env.BlockNumber.Uint64(),
  525. })
  526. return nil, nil
  527. }
  528. }
  529. // make push instruction function
  530. func makePush(size uint64, bsize *big.Int) executionFunc {
  531. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  532. byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize)
  533. stack.push(common.Bytes2Big(byts))
  534. *pc += size
  535. return nil, nil
  536. }
  537. }
  538. // make push instruction function
  539. func makeDup(size int64) executionFunc {
  540. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  541. stack.dup(int(size))
  542. return nil, nil
  543. }
  544. }
  545. // make swap instruction function
  546. func makeSwap(size int64) executionFunc {
  547. // switch n + 1 otherwise n would be swapped with n
  548. size += 1
  549. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  550. stack.swap(int(size))
  551. return nil, nil
  552. }
  553. }