opcodes.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. // Copyright 2014 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. )
  20. // OpCode is an EVM opcode
  21. type OpCode byte
  22. func (op OpCode) IsPush() bool {
  23. switch op {
  24. 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:
  25. return true
  26. }
  27. return false
  28. }
  29. func (op OpCode) IsStaticJump() bool {
  30. return op == JUMP
  31. }
  32. const (
  33. // 0x0 range - arithmetic ops
  34. STOP OpCode = iota
  35. ADD
  36. MUL
  37. SUB
  38. DIV
  39. SDIV
  40. MOD
  41. SMOD
  42. ADDMOD
  43. MULMOD
  44. EXP
  45. SIGNEXTEND
  46. )
  47. const (
  48. LT OpCode = iota + 0x10
  49. GT
  50. SLT
  51. SGT
  52. EQ
  53. ISZERO
  54. AND
  55. OR
  56. XOR
  57. NOT
  58. BYTE
  59. SHL
  60. SHR
  61. SAR
  62. SHA3 = 0x20
  63. )
  64. const (
  65. // 0x30 range - closure state
  66. ADDRESS OpCode = 0x30 + iota
  67. BALANCE
  68. ORIGIN
  69. CALLER
  70. CALLVALUE
  71. CALLDATALOAD
  72. CALLDATASIZE
  73. CALLDATACOPY
  74. CODESIZE
  75. CODECOPY
  76. GASPRICE
  77. EXTCODESIZE
  78. EXTCODECOPY
  79. RETURNDATASIZE
  80. RETURNDATACOPY
  81. )
  82. const (
  83. // 0x40 range - block operations
  84. BLOCKHASH OpCode = 0x40 + iota
  85. COINBASE
  86. TIMESTAMP
  87. NUMBER
  88. DIFFICULTY
  89. GASLIMIT
  90. )
  91. const (
  92. // 0x50 range - 'storage' and execution
  93. POP OpCode = 0x50 + iota
  94. MLOAD
  95. MSTORE
  96. MSTORE8
  97. SLOAD
  98. SSTORE
  99. JUMP
  100. JUMPI
  101. PC
  102. MSIZE
  103. GAS
  104. JUMPDEST
  105. )
  106. const (
  107. // 0x60 range
  108. PUSH1 OpCode = 0x60 + iota
  109. PUSH2
  110. PUSH3
  111. PUSH4
  112. PUSH5
  113. PUSH6
  114. PUSH7
  115. PUSH8
  116. PUSH9
  117. PUSH10
  118. PUSH11
  119. PUSH12
  120. PUSH13
  121. PUSH14
  122. PUSH15
  123. PUSH16
  124. PUSH17
  125. PUSH18
  126. PUSH19
  127. PUSH20
  128. PUSH21
  129. PUSH22
  130. PUSH23
  131. PUSH24
  132. PUSH25
  133. PUSH26
  134. PUSH27
  135. PUSH28
  136. PUSH29
  137. PUSH30
  138. PUSH31
  139. PUSH32
  140. DUP1
  141. DUP2
  142. DUP3
  143. DUP4
  144. DUP5
  145. DUP6
  146. DUP7
  147. DUP8
  148. DUP9
  149. DUP10
  150. DUP11
  151. DUP12
  152. DUP13
  153. DUP14
  154. DUP15
  155. DUP16
  156. SWAP1
  157. SWAP2
  158. SWAP3
  159. SWAP4
  160. SWAP5
  161. SWAP6
  162. SWAP7
  163. SWAP8
  164. SWAP9
  165. SWAP10
  166. SWAP11
  167. SWAP12
  168. SWAP13
  169. SWAP14
  170. SWAP15
  171. SWAP16
  172. )
  173. const (
  174. LOG0 OpCode = 0xa0 + iota
  175. LOG1
  176. LOG2
  177. LOG3
  178. LOG4
  179. )
  180. // unofficial opcodes used for parsing
  181. const (
  182. PUSH OpCode = 0xb0 + iota
  183. DUP
  184. SWAP
  185. )
  186. const (
  187. // 0xf0 range - closures
  188. CREATE OpCode = 0xf0 + iota
  189. CALL
  190. CALLCODE
  191. RETURN
  192. DELEGATECALL
  193. STATICCALL = 0xfa
  194. REVERT = 0xfd
  195. SELFDESTRUCT = 0xff
  196. )
  197. // Since the opcodes aren't all in order we can't use a regular slice
  198. var opCodeToString = map[OpCode]string{
  199. // 0x0 range - arithmetic ops
  200. STOP: "STOP",
  201. ADD: "ADD",
  202. MUL: "MUL",
  203. SUB: "SUB",
  204. DIV: "DIV",
  205. SDIV: "SDIV",
  206. MOD: "MOD",
  207. SMOD: "SMOD",
  208. EXP: "EXP",
  209. NOT: "NOT",
  210. LT: "LT",
  211. GT: "GT",
  212. SLT: "SLT",
  213. SGT: "SGT",
  214. EQ: "EQ",
  215. ISZERO: "ISZERO",
  216. SIGNEXTEND: "SIGNEXTEND",
  217. // 0x10 range - bit ops
  218. AND: "AND",
  219. OR: "OR",
  220. XOR: "XOR",
  221. BYTE: "BYTE",
  222. SHL: "SHL",
  223. SHR: "SHR",
  224. SAR: "SAR",
  225. ADDMOD: "ADDMOD",
  226. MULMOD: "MULMOD",
  227. // 0x20 range - crypto
  228. SHA3: "SHA3",
  229. // 0x30 range - closure state
  230. ADDRESS: "ADDRESS",
  231. BALANCE: "BALANCE",
  232. ORIGIN: "ORIGIN",
  233. CALLER: "CALLER",
  234. CALLVALUE: "CALLVALUE",
  235. CALLDATALOAD: "CALLDATALOAD",
  236. CALLDATASIZE: "CALLDATASIZE",
  237. CALLDATACOPY: "CALLDATACOPY",
  238. CODESIZE: "CODESIZE",
  239. CODECOPY: "CODECOPY",
  240. GASPRICE: "GASPRICE",
  241. EXTCODESIZE: "EXTCODESIZE",
  242. EXTCODECOPY: "EXTCODECOPY",
  243. RETURNDATASIZE: "RETURNDATASIZE",
  244. RETURNDATACOPY: "RETURNDATACOPY",
  245. // 0x40 range - block operations
  246. BLOCKHASH: "BLOCKHASH",
  247. COINBASE: "COINBASE",
  248. TIMESTAMP: "TIMESTAMP",
  249. NUMBER: "NUMBER",
  250. DIFFICULTY: "DIFFICULTY",
  251. GASLIMIT: "GASLIMIT",
  252. // 0x50 range - 'storage' and execution
  253. POP: "POP",
  254. //DUP: "DUP",
  255. //SWAP: "SWAP",
  256. MLOAD: "MLOAD",
  257. MSTORE: "MSTORE",
  258. MSTORE8: "MSTORE8",
  259. SLOAD: "SLOAD",
  260. SSTORE: "SSTORE",
  261. JUMP: "JUMP",
  262. JUMPI: "JUMPI",
  263. PC: "PC",
  264. MSIZE: "MSIZE",
  265. GAS: "GAS",
  266. JUMPDEST: "JUMPDEST",
  267. // 0x60 range - push
  268. PUSH1: "PUSH1",
  269. PUSH2: "PUSH2",
  270. PUSH3: "PUSH3",
  271. PUSH4: "PUSH4",
  272. PUSH5: "PUSH5",
  273. PUSH6: "PUSH6",
  274. PUSH7: "PUSH7",
  275. PUSH8: "PUSH8",
  276. PUSH9: "PUSH9",
  277. PUSH10: "PUSH10",
  278. PUSH11: "PUSH11",
  279. PUSH12: "PUSH12",
  280. PUSH13: "PUSH13",
  281. PUSH14: "PUSH14",
  282. PUSH15: "PUSH15",
  283. PUSH16: "PUSH16",
  284. PUSH17: "PUSH17",
  285. PUSH18: "PUSH18",
  286. PUSH19: "PUSH19",
  287. PUSH20: "PUSH20",
  288. PUSH21: "PUSH21",
  289. PUSH22: "PUSH22",
  290. PUSH23: "PUSH23",
  291. PUSH24: "PUSH24",
  292. PUSH25: "PUSH25",
  293. PUSH26: "PUSH26",
  294. PUSH27: "PUSH27",
  295. PUSH28: "PUSH28",
  296. PUSH29: "PUSH29",
  297. PUSH30: "PUSH30",
  298. PUSH31: "PUSH31",
  299. PUSH32: "PUSH32",
  300. DUP1: "DUP1",
  301. DUP2: "DUP2",
  302. DUP3: "DUP3",
  303. DUP4: "DUP4",
  304. DUP5: "DUP5",
  305. DUP6: "DUP6",
  306. DUP7: "DUP7",
  307. DUP8: "DUP8",
  308. DUP9: "DUP9",
  309. DUP10: "DUP10",
  310. DUP11: "DUP11",
  311. DUP12: "DUP12",
  312. DUP13: "DUP13",
  313. DUP14: "DUP14",
  314. DUP15: "DUP15",
  315. DUP16: "DUP16",
  316. SWAP1: "SWAP1",
  317. SWAP2: "SWAP2",
  318. SWAP3: "SWAP3",
  319. SWAP4: "SWAP4",
  320. SWAP5: "SWAP5",
  321. SWAP6: "SWAP6",
  322. SWAP7: "SWAP7",
  323. SWAP8: "SWAP8",
  324. SWAP9: "SWAP9",
  325. SWAP10: "SWAP10",
  326. SWAP11: "SWAP11",
  327. SWAP12: "SWAP12",
  328. SWAP13: "SWAP13",
  329. SWAP14: "SWAP14",
  330. SWAP15: "SWAP15",
  331. SWAP16: "SWAP16",
  332. LOG0: "LOG0",
  333. LOG1: "LOG1",
  334. LOG2: "LOG2",
  335. LOG3: "LOG3",
  336. LOG4: "LOG4",
  337. // 0xf0 range
  338. CREATE: "CREATE",
  339. CALL: "CALL",
  340. RETURN: "RETURN",
  341. CALLCODE: "CALLCODE",
  342. DELEGATECALL: "DELEGATECALL",
  343. STATICCALL: "STATICCALL",
  344. REVERT: "REVERT",
  345. SELFDESTRUCT: "SELFDESTRUCT",
  346. PUSH: "PUSH",
  347. DUP: "DUP",
  348. SWAP: "SWAP",
  349. }
  350. func (o OpCode) String() string {
  351. str := opCodeToString[o]
  352. if len(str) == 0 {
  353. return fmt.Sprintf("Missing opcode 0x%x", int(o))
  354. }
  355. return str
  356. }
  357. var stringToOp = map[string]OpCode{
  358. "STOP": STOP,
  359. "ADD": ADD,
  360. "MUL": MUL,
  361. "SUB": SUB,
  362. "DIV": DIV,
  363. "SDIV": SDIV,
  364. "MOD": MOD,
  365. "SMOD": SMOD,
  366. "EXP": EXP,
  367. "NOT": NOT,
  368. "LT": LT,
  369. "GT": GT,
  370. "SLT": SLT,
  371. "SGT": SGT,
  372. "EQ": EQ,
  373. "ISZERO": ISZERO,
  374. "SIGNEXTEND": SIGNEXTEND,
  375. "AND": AND,
  376. "OR": OR,
  377. "XOR": XOR,
  378. "BYTE": BYTE,
  379. "SHL": SHL,
  380. "SHR": SHR,
  381. "SAR": SAR,
  382. "ADDMOD": ADDMOD,
  383. "MULMOD": MULMOD,
  384. "SHA3": SHA3,
  385. "ADDRESS": ADDRESS,
  386. "BALANCE": BALANCE,
  387. "ORIGIN": ORIGIN,
  388. "CALLER": CALLER,
  389. "CALLVALUE": CALLVALUE,
  390. "CALLDATALOAD": CALLDATALOAD,
  391. "CALLDATASIZE": CALLDATASIZE,
  392. "CALLDATACOPY": CALLDATACOPY,
  393. "DELEGATECALL": DELEGATECALL,
  394. "STATICCALL": STATICCALL,
  395. "CODESIZE": CODESIZE,
  396. "CODECOPY": CODECOPY,
  397. "GASPRICE": GASPRICE,
  398. "EXTCODESIZE": EXTCODESIZE,
  399. "EXTCODECOPY": EXTCODECOPY,
  400. "RETURNDATASIZE": RETURNDATASIZE,
  401. "RETURNDATACOPY": RETURNDATACOPY,
  402. "BLOCKHASH": BLOCKHASH,
  403. "COINBASE": COINBASE,
  404. "TIMESTAMP": TIMESTAMP,
  405. "NUMBER": NUMBER,
  406. "DIFFICULTY": DIFFICULTY,
  407. "GASLIMIT": GASLIMIT,
  408. "POP": POP,
  409. "MLOAD": MLOAD,
  410. "MSTORE": MSTORE,
  411. "MSTORE8": MSTORE8,
  412. "SLOAD": SLOAD,
  413. "SSTORE": SSTORE,
  414. "JUMP": JUMP,
  415. "JUMPI": JUMPI,
  416. "PC": PC,
  417. "MSIZE": MSIZE,
  418. "GAS": GAS,
  419. "JUMPDEST": JUMPDEST,
  420. "PUSH1": PUSH1,
  421. "PUSH2": PUSH2,
  422. "PUSH3": PUSH3,
  423. "PUSH4": PUSH4,
  424. "PUSH5": PUSH5,
  425. "PUSH6": PUSH6,
  426. "PUSH7": PUSH7,
  427. "PUSH8": PUSH8,
  428. "PUSH9": PUSH9,
  429. "PUSH10": PUSH10,
  430. "PUSH11": PUSH11,
  431. "PUSH12": PUSH12,
  432. "PUSH13": PUSH13,
  433. "PUSH14": PUSH14,
  434. "PUSH15": PUSH15,
  435. "PUSH16": PUSH16,
  436. "PUSH17": PUSH17,
  437. "PUSH18": PUSH18,
  438. "PUSH19": PUSH19,
  439. "PUSH20": PUSH20,
  440. "PUSH21": PUSH21,
  441. "PUSH22": PUSH22,
  442. "PUSH23": PUSH23,
  443. "PUSH24": PUSH24,
  444. "PUSH25": PUSH25,
  445. "PUSH26": PUSH26,
  446. "PUSH27": PUSH27,
  447. "PUSH28": PUSH28,
  448. "PUSH29": PUSH29,
  449. "PUSH30": PUSH30,
  450. "PUSH31": PUSH31,
  451. "PUSH32": PUSH32,
  452. "DUP1": DUP1,
  453. "DUP2": DUP2,
  454. "DUP3": DUP3,
  455. "DUP4": DUP4,
  456. "DUP5": DUP5,
  457. "DUP6": DUP6,
  458. "DUP7": DUP7,
  459. "DUP8": DUP8,
  460. "DUP9": DUP9,
  461. "DUP10": DUP10,
  462. "DUP11": DUP11,
  463. "DUP12": DUP12,
  464. "DUP13": DUP13,
  465. "DUP14": DUP14,
  466. "DUP15": DUP15,
  467. "DUP16": DUP16,
  468. "SWAP1": SWAP1,
  469. "SWAP2": SWAP2,
  470. "SWAP3": SWAP3,
  471. "SWAP4": SWAP4,
  472. "SWAP5": SWAP5,
  473. "SWAP6": SWAP6,
  474. "SWAP7": SWAP7,
  475. "SWAP8": SWAP8,
  476. "SWAP9": SWAP9,
  477. "SWAP10": SWAP10,
  478. "SWAP11": SWAP11,
  479. "SWAP12": SWAP12,
  480. "SWAP13": SWAP13,
  481. "SWAP14": SWAP14,
  482. "SWAP15": SWAP15,
  483. "SWAP16": SWAP16,
  484. "LOG0": LOG0,
  485. "LOG1": LOG1,
  486. "LOG2": LOG2,
  487. "LOG3": LOG3,
  488. "LOG4": LOG4,
  489. "CREATE": CREATE,
  490. "CALL": CALL,
  491. "RETURN": RETURN,
  492. "CALLCODE": CALLCODE,
  493. "REVERT": REVERT,
  494. "SELFDESTRUCT": SELFDESTRUCT,
  495. }
  496. func StringToOp(str string) OpCode {
  497. return stringToOp[str]
  498. }