项目作者: tintinweb

项目描述 :
An ethereum evm bytecode disassembler and static/dynamic analysis tool
高级语言: Python
项目地址: git://github.com/tintinweb/ethereum-dasm.git
创建时间: 2016-07-13T22:17:51Z
项目社区:https://github.com/tintinweb/ethereum-dasm

开源协议:GNU General Public License v2.0

下载


ethereum-dasm

ethereum evm bytecode disassembler with static- and dynamic-analysis and function signature lookup

[https://github.com/ethereum/] [https://www.ethereum.org/]

windows

disassembles evm bytecode

asciicast

decompile a contract to pseudocode

asciicast

install

pip

  1. #> pip3 install "ethereum-dasm[mythril,abidecoder]"
  2. #> python3 -m ethereum_dasm --help # verify installation

code

  1. #> pip3 install -r requirements*.txt
  2. #> python3 setup.py install
  1. #> python3 -m ethereum_dasm -a 0x44919b8026f38d70437a8eb3be47b06ab1c3e4bf # jusst to verify installation

usage

  1. Usage: ethereum_dasm.py [options]
  2. example: ethereum_dasm.py [-L -F -v] <file_or_bytecode>
  3. ethereum_dasm.py [-L -F -v] # read from stdin
  4. ethereum_dasm.py [-L -F -a <address>] # fetch contract code from infura.io
  5. Options:
  6. -h, --help show this help message and exit
  7. -v VERBOSITY, --verbosity=VERBOSITY
  8. available loglevels:
  9. critical,fatal,error,warning,warn,info,debug,notset
  10. [default: critical]
  11. -L, --listing disables table mode, outputs assembly only
  12. -F, --no-online-lookup
  13. disable online function signature lookup
  14. -a ADDRESS, --address=ADDRESS
  15. fetch contract bytecode from address
  16. -C, --no-color disable color mode (requires pip install colorama)
  17. -A, --guess-abi guess the ABI for that contract
  18. -D, --no-dynamic-analysis
  19. disable dynamic analysis / symolic execution
  20. -S, --no-static-analysis
  21. disable static analysis
  22. -s, --simplify simplify disassembly to human readable code
  23. -x, --simplify-show-asm
  24. simplify: show or hide asm annotations in simplified
  25. code
  26. -y, --simplify-show-unreachable
  27. simplify: show or hide annotations for unreachable
  28. instructions in simplified code
  29. -n NETWORK, --network=NETWORK
  30. network for address lookup (default: mainnet, ropsten,
  31. rinkeby, kovan
  1. #> echo "0x12345678" | python3 -m ethereum_dasm
  2. #> python3 -m ethereum_dasm 0x12345678
  3. #> python3 -m ethereum_dasm ether_contract.evm
  4. #> python3 -m ethereum_dasm -a <contract address>
  5. #> python3 -m ethereum_dasm -a <contract address> -A
  6. #> python3 -m ethereum_dasm -a <contract address> --simplify [--simplify-show-asm, --simplify-show-unreachable]

features

  • disassemble evm bytecode
  • decompile evm bytecode to pseudocode
  • provide the path to the ethereum vm bytecode or the bytecode as an argument to evmdasm. Tries to read from stdin by default.
  • returns !=0 on errors
  • various output modes (-L to switch from table to listing mode)
  • color-mode
  • invalid opcodes are prefixed with UNKNOWN_
  • gas consumption for instruction
  • return value and arguments for instruction
  • basic jump/xref analysis
  • basicblocking
  • online function signature and method name lookup, operand annotations
  • payable modifier detection
  • dynamic analysis based on symbolic execution (depends on mythril)
  • ABI.json download (from etherchain.org)
  • ABI.json reconstruction from static analysis of the evm bytecode
  • main interface Contract().

examples

abi online lookup or reconstruction
#>python3 -m ethereum_dasm -a 0x44919b8026f38d70437a8eb3be47b06ab1c3e4bf -A

  1. # [....]
  2. [{'stateMutability': 'nonpayable', 'constant': False, 'type': 'function', 'name': 'enter', 'signature': '0x124c32a1', 'outputs': [{'type': 'bool', 'name': ''}], 'inputs': [{'type': 'bytes32', 'name': '_passcode'
  3. }, {'type': 'bytes8', 'name': '_gateKey'}], 'payable': False}, {'stateMutability': 'pure', 'constant': True, 'type': 'function', 'name': 'maxEntrants', 'signature': '0x60643652', 'outputs': [{'type': 'uint8', 'n
  4. ame': ''}], 'inputs': [], 'payable': False}, {'stateMutability': 'view', 'constant': True, 'type': 'function', 'name': 'totalEntrants', 'signature': '0x694463a2', 'outputs': [{'type': 'uint8', 'name': ''}], 'inp
  5. uts': [], 'payable': False}, {'stateMutability': 'nonpayable', 'constant': False, 'type': 'function', 'name': 'assignAll', 'signature': '0x90ae631d', 'outputs': [{'type': 'bool', 'name': ''}], 'inputs': [], 'pay
  6. able': False}, {'inputs': [], 'stateMutability': 'nonpayable', 'payable': False, 'type': 'constructor'}]

abi reconstruction from dasm if abi is not available
#> python3 -m ethereum_dasm -a 0x8f8bed23a644f3bbb4e227e28704c050e67c35be -A

  1. [{'signature': '0x95d89b41', 'outputs': [], 'stateMutability': None, 'name': 'symbol', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 598}, {'signature': '0x095ea7b3', 'outputs':
  2. [], 'stateMutability': None, 'name': 'approve', 'constant': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 328}, {'signature': '0x313ce567', 'outputs': [], 'stateMutab
  3. ility': None, 'name': 'decimals', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 486}, {'signature': '0xdd62ed3e', 'outputs': [], 'stateMutability': None, 'name': 'allowance', 'c
  4. onstant': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 691}, {'signature': '0x66188463', 'outputs': [], 'stateMutability': None, 'name': 'decreaseApproval', 'constant
  5. ': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 529}, {'signature': '0x23b872dd', 'outputs': [], 'stateMutability': None, 'name': 'transferFrom', 'constant': None, 'i
  6. nputs': ['bytes32', 'bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 423}, {'signature': '0x2ff2e9dc', 'outputs': [], 'stateMutability': None, 'name': 'INITIAL_SUPPLY', 'constant': None,
  7. 'inputs': [], 'payable': True, 'type': 'function', 'address': 465}, {'signature': '0x06fdde03', 'outputs': [], 'stateMutability': None, 'name': 'name', 'constant': None, 'inputs': [], 'payable': True, 'type': 'f
  8. unction', 'address': 190}, {'signature': '0x18160ddd', 'outputs': [], 'stateMutability': None, 'name': 'totalSupply', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 384}, {'signa
  9. ture': '0x70a08231', 'outputs': [], 'stateMutability': None, 'name': 'balanceOf', 'constant': None, 'inputs': ['<bytes??>'], 'payable': True, 'type': 'function', 'address': 565}, {'signature': '0xa9059cbb', 'out
  10. puts': [], 'stateMutability': None, 'name': 'transfer', 'constant': None, 'inputs': [{'type': 'address', 'name': 'arg0'}, {'type': 'uint256', 'name': 'arg1'}], 'payable': True, 'type': 'function', 'address': 619
  11. }, {'signature': '0xd73dd623', 'outputs': [], 'stateMutability': None, 'name': 'increaseApproval', 'constant': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 655}]

detailed listing

python3 -m ethereum_dasm -a 0x44919b8026f38d70437a8eb3be47b06ab1c3e4bf -A --no-color

  1. Inst addr hex gas | mnemonic operand xrefs description retval args
  2. ------------------------------------------------------------------------------------------------ ----------- -------------------------------------------------------------------- --------------- --------------------
  3. :loc_0x0
  4. 0 [ 0 0x0000 ] 3 | PUSH1 0x60 # Place 1 byte item on stack. item
  5. 1 [ 2 0x0002 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
  6. 2 [ 4 0x0004 ] 3 | MSTORE # Save word to memory. value, offset
  7. 3 [ 5 0x0005 ] 3 | PUSH1 0x04 # Place 1 byte item on stack. item
  8. 4 [ 7 0x0007 ] 2 | CALLDATASIZE # Get size of input data in current environment. msg.data.length
  9. 5 [ 8 0x0008 ] 3 | LT # Lesser-than comparison flag a, b
  10. 6 [ 9 0x0009 ] 3 | PUSH2 0x0048 # Place 2-byte item on stack. item
  11. 7 [ 12 0x000c ] 10 | JUMPI @0x48 # Conditionally alter the program counter. evm.pc, condition
  12. 8 [ 13 0x000d ] 3 | PUSH4 0xffffffff # Place 4-byte item on stack. item
  13. 9 [ 18 0x0012 ] 3 | PUSH1 0xe0 # Place 1 byte item on stack. item
  14. 10 [ 20 0x0014 ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
  15. 11 [ 22 0x0016 ] 10 | EXP # Exponential operation. result base, exponent
  16. 12 [ 23 0x0017 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
  17. 13 [ 25 0x0019 ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
  18. 14 [ 26 0x001a ] 5 | DIV # Integer division operation. result a, b
  19. 15 [ 27 0x001b ] 3 | AND # Bitwise AND operation. result a, b
  20. 16 [ 28 0x001c ] 3 | PUSH4 0x124c32a1 --> 'function enter(bytes32,bytes8)' # Place 4-byte item on stack. item
  21. 17 [ 33 0x0021 ] 3 | DUP2 # Duplicate 2nd stack item.
  22. 18 [ 34 0x0022 ] 3 | EQ # Equality comparison flag a, b
  23. 19 [ 35 0x0023 ] 3 | PUSH2 0x004d # Place 2-byte item on stack. item
  24. 20 [ 38 0x0026 ] 10 | JUMPI @0x4d # Conditionally alter the program counter. evm.pc, condition
  25. 21 [ 39 0x0027 ] 3 | DUP1 # Duplicate 1st stack item.
  26. 22 [ 40 0x0028 ] 3 | PUSH4 0x60643652 --> 'function maxEntrants()' # Place 4-byte item on stack. item
  27. 23 [ 45 0x002d ] 3 | EQ # Equality comparison flag a, b
  28. 24 [ 46 0x002e ] 3 | PUSH2 0x0095 # Place 2-byte item on stack. item
  29. 25 [ 49 0x0031 ] 10 | JUMPI @0x95 # Conditionally alter the program counter. evm.pc, condition
  30. 26 [ 50 0x0032 ] 3 | DUP1 # Duplicate 1st stack item.
  31. 27 [ 51 0x0033 ] 3 | PUSH4 0x694463a2 --> 'function totalEntrants()' # Place 4-byte item on stack. item
  32. 28 [ 56 0x0038 ] 3 | EQ # Equality comparison flag a, b
  33. 29 [ 57 0x0039 ] 3 | PUSH2 0x00be # Place 2-byte item on stack. item
  34. 30 [ 60 0x003c ] 10 | JUMPI @0xbe # Conditionally alter the program counter. evm.pc, condition
  35. 31 [ 61 0x003d ] 3 | DUP1 # Duplicate 1st stack item.
  36. 32 [ 62 0x003e ] 3 | PUSH4 0x90ae631d --> 'function assignAll()' # Place 4-byte item on stack. item
  37. 33 [ 67 0x0043 ] 3 | EQ # Equality comparison flag a, b
  38. 34 [ 68 0x0044 ] 3 | PUSH2 0x00d1 # Place 2-byte item on stack. item
  39. 35 [ 71 0x0047 ] 10 | JUMPI @0xd1 # Conditionally alter the program counter. evm.pc, condition
  40. :loc_0x48
  41. 36 [ 72 0x0048 ] 1 | JUMPDEST JUMPI@0xc # Mark a valid destination for jumps.
  42. 37 [ 73 0x0049 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
  43. 38 [ 75 0x004b ] 3 | DUP1 # Duplicate 1st stack item.
  44. 39 [ 76 0x004c ] 0 | REVERT # throw an error offset, size
  45. :loc_0x4d
  46. /*******************************************************************
  47. function enter(bytes32,bytes8)
  48. payable: False
  49. inputs: (2) ['bytes32', '<bytes??>']
  50. potential signatures: ['enter(bytes32,bytes8)']
  51. *******************************************************************/
  52. 40 [ 77 0x004d ] 1 | JUMPDEST JUMPI@0x26 # Mark a valid destination for jumps.
  53. 41 [ 78 0x004e ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
  54. this execution.
  55. 42 [ 79 0x004f ] 3 | ISZERO # Simple not operator flag a
  56. 43 [ 80 0x0050 ] 3 | PUSH2 0x0058 # Place 2-byte item on stack. item
  57. 44 [ 83 0x0053 ] 10 | JUMPI @0x58 # Conditionally alter the program counter. evm.pc, condition
  58. 45 [ 84 0x0054 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
  59. 46 [ 86 0x0056 ] 3 | DUP1 # Duplicate 1st stack item.
  60. 47 [ 87 0x0057 ] 0 | REVERT # throw an error offset, size
  61. :loc_0x58
  62. 48 [ 88 0x0058 ] 1 | JUMPDEST JUMPI@0x53 # Mark a valid destination for jumps.
  63. 49 [ 89 0x0059 ] 3 | PUSH2 0x0081 # Place 2-byte item on stack. item
  64. 50 [ 92 0x005c ] 3 | PUSH1 0x04 # Place 1 byte item on stack. item
  65. 51 [ 94 0x005e ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
  66. 52 [ 95 0x005f ] 3 | PUSH24 0xffffffffffffffffffffffffffffffffffffffffffffffff # Place 24-byte item on stack. item
  67. 53 [ 120 0x0078 ] 3 | NOT # Bitwise NOT operation. result a, b
  68. 54 [ 121 0x0079 ] 3 | PUSH1 0x24 # Place 1 byte item on stack. item
  69. 55 [ 123 0x007b ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
  70. 56 [ 124 0x007c ] 3 | AND # Bitwise AND operation. result a, b
  71. 57 [ 125 0x007d ] 3 | PUSH2 0x00e4 # Place 2-byte item on stack. item
  72. 58 [ 128 0x0080 ] 8 | JUMP @0xe4 # Alter the program counter. evm.pc
  73. :loc_0x81
  74. 59 [ 129 0x0081 ] 1 | JUMPDEST # Mark a valid destination for jumps.
  75. 60 [ 130 0x0082 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
  76. 61 [ 132 0x0084 ] 3 | MLOAD # Load word from memory. offset
  77. 62 [ 133 0x0085 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
  78. 63 [ 134 0x0086 ] 3 | ISZERO # Simple not operator flag a
  79. 64 [ 135 0x0087 ] 3 | ISZERO # Simple not operator flag a
  80. 65 [ 136 0x0088 ] 3 | DUP2 # Duplicate 2nd stack item.
  81. 66 [ 137 0x0089 ] 3 | MSTORE # Save word to memory. value, offset
  82. 67 [ 138 0x008a ] 3 | PUSH1 0x20 # Place 1 byte item on stack. item
  83. 68 [ 140 0x008c ] 3 | ADD # Addition operation. result a, b
  84. 69 [ 141 0x008d ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
  85. 70 [ 143 0x008f ] 3 | MLOAD # Load word from memory. offset
  86. 71 [ 144 0x0090 ] 3 | DUP1 # Duplicate 1st stack item.
  87. 72 [ 145 0x0091 ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
  88. 73 [ 146 0x0092 ] 3 | SUB # Subtraction operation. result a, b
  89. 74 [ 147 0x0093 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
  90. 75 [ 148 0x0094 ] 0 | RETURN # Halt execution returning output data. offset, size
  91. :loc_0x95
  92. /*******************************************************************
  93. function maxEntrants()
  94. payable: False
  95. inputs: (0) []
  96. potential signatures: ['maxEntrants()']
  97. *******************************************************************/
  98. 76 [ 149 0x0095 ] 1 | JUMPDEST JUMPI@0x31 # Mark a valid destination for jumps.
  99. 77 [ 150 0x0096 ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
  100. this execution.
  101. 78 [ 151 0x0097 ] 3 | ISZERO # Simple not operator flag a
  102. 79 [ 152 0x0098 ] 3 | PUSH2 0x00a0 # Place 2-byte item on stack. item
  103. 80 [ 155 0x009b ] 10 | JUMPI @0xa0 # Conditionally alter the program counter. evm.pc, condition
  104. 81 [ 156 0x009c ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
  105. 82 [ 158 0x009e ] 3 | DUP1 # Duplicate 1st stack item.
  106. 83 [ 159 0x009f ] 0 | REVERT # throw an error offset, size
  107. :loc_0xa0
  108. 84 [ 160 0x00a0 ] 1 | JUMPDEST JUMPI@0x9b # Mark a valid destination for jumps.
  109. 85 [ 161 0x00a1 ] 3 | PUSH2 0x00a8 # Place 2-byte item on stack. item
  110. 86 [ 164 0x00a4 ] 3 | PUSH2 0x0314 # Place 2-byte item on stack. item
  111. 87 [ 167 0x00a7 ] 8 | JUMP @0x314 # Alter the program counter. evm.pc
  112. :loc_0xa8
  113. 88 [ 168 0x00a8 ] 1 | JUMPDEST # Mark a valid destination for jumps.
  114. 89 [ 169 0x00a9 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
  115. 90 [ 171 0x00ab ] 3 | MLOAD # Load word from memory. offset
  116. 91 [ 172 0x00ac ] 3 | PUSH1 0xff # Place 1 byte item on stack. item
  117. 92 [ 174 0x00ae ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
  118. 93 [ 175 0x00af ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
  119. 94 [ 176 0x00b0 ] 3 | AND # Bitwise AND operation. result a, b
  120. 95 [ 177 0x00b1 ] 3 | DUP2 # Duplicate 2nd stack item.
  121. 96 [ 178 0x00b2 ] 3 | MSTORE # Save word to memory. value, offset
  122. 97 [ 179 0x00b3 ] 3 | PUSH1 0x20 # Place 1 byte item on stack. item
  123. 98 [ 181 0x00b5 ] 3 | ADD # Addition operation. result a, b
  124. 99 [ 182 0x00b6 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
  125. 100 [ 184 0x00b8 ] 3 | MLOAD # Load word from memory. offset
  126. 101 [ 185 0x00b9 ] 3 | DUP1 # Duplicate 1st stack item.
  127. 102 [ 186 0x00ba ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
  128. 103 [ 187 0x00bb ] 3 | SUB # Subtraction operation. result a, b
  129. 104 [ 188 0x00bc ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
  130. 105 [ 189 0x00bd ] 0 | RETURN # Halt execution returning output data. offset, size
  131. :loc_0xbe
  132. /*******************************************************************
  133. function totalEntrants()
  134. payable: False
  135. inputs: (0) []
  136. potential signatures: ['totalEntrants()']
  137. *******************************************************************/
  138. 106 [ 190 0x00be ] 1 | JUMPDEST JUMPI@0x3c # Mark a valid destination for jumps.
  139. 107 [ 191 0x00bf ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
  140. this execution.
  141. 108 [ 192 0x00c0 ] 3 | ISZERO # Simple not operator flag a
  142. 109 [ 193 0x00c1 ] 3 | PUSH2 0x00c9 # Place 2-byte item on stack. item
  143. 110 [ 196 0x00c4 ] 10 | JUMPI @0xc9 # Conditionally alter the program counter. evm.pc, condition
  144. 111 [ 197 0x00c5 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
  145. 112 [ 199 0x00c7 ] 3 | DUP1 # Duplicate 1st stack item.
  146. 113 [ 200 0x00c8 ] 0 | REVERT # throw an error offset, size
  147. :loc_0xc9
  148. 114 [ 201 0x00c9 ] 1 | JUMPDEST JUMPI@0xc4 # Mark a valid destination for jumps.
  149. 115 [ 202 0x00ca ] 3 | PUSH2 0x00a8 # Place 2-byte item on stack. item
  150. 116 [ 205 0x00cd ] 3 | PUSH2 0x031a # Place 2-byte item on stack. item
  151. 117 [ 208 0x00d0 ] 8 | JUMP @0x31a # Alter the program counter. evm.pc
  152. :loc_0xd1
  153. /*******************************************************************
  154. function assignAll()
  155. payable: False
  156. inputs: (0) []
  157. potential signatures: ['assignAll()']
  158. *******************************************************************/
  159. 118 [ 209 0x00d1 ] 1 | JUMPDEST JUMPI@0x47 # Mark a valid destination for jumps.
  160. 119 [ 210 0x00d2 ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
  161. this execution.
  162. 120 [ 211 0x00d3 ] 3 | ISZERO # Simple not operator flag a
  163. 121 [ 212 0x00d4 ] 3 | PUSH2 0x00dc # Place 2-byte item on stack. item
  164. 122 [ 215 0x00d7 ] 10 | JUMPI @0xdc # Conditionally alter the program counter. evm.pc, condition
  165. 123 [ 216 0x00d8 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
  166. 124 [ 218 0x00da ] 3 | DUP1 # Duplicate 1st stack item.
  167. 125 [ 219 0x00db ] 0 | REVERT # throw an error offset, size
  168. :loc_0xdc
  169. 126 [ 220 0x00dc ] 1 | JUMPDEST JUMPI@0xd7 # Mark a valid destination for jumps.
  170. 127 [ 221 0x00dd ] 3 | PUSH2 0x0081 # Place 2-byte item on stack. item
  171. 128 [ 224 0x00e0 ] 3 | PUSH2 0x0320 # Place 2-byte item on stack. item
  172. 129 [ 227 0x00e3 ] 8 | JUMP @0x320 # Alter the program counter. evm.pc
  173. :loc_0xe4
  174. 130 [ 228 0x00e4 ] 1 | JUMPDEST JUMP@0x80 # Mark a valid destination for jumps.
  175. 131 [ 229 0x00e5 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
  176. 132 [ 231 0x00e7 ] 2 | ORIGIN # Get execution origination address. tx.origin
  177. 133 [ 232 0x00e8 ] 3 | PUSH1 0x01 # Place 1 byte item on stack. item
  178. 134 [ 234 0x00ea ] 3 | PUSH1 0xa0 # Place 1 byte item on stack. item
  179. 135 [ 236 0x00ec ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
  180. 136 [ 238 0x00ee ] 10 | EXP # Exponential operation. result base, exponent
  181. 137 [ 239 0x00ef ] 3 | SUB # Subtraction operation. result a, b
  182. 138 [ 240 0x00f0 ] 3 | AND # Bitwise AND operation. result a, b
  183. 139 [ 241 0x00f1 ] 2 | CALLER # Get caller address.This is the address of the account that is msg.sender
  184. directly responsible for this execution.
  185. 140 [ 242 0x00f2 ] 3 | PUSH1 0x01 # Place 1 byte item on stack. item
  186. 141 [ 244 0x00f4 ] 3 | PUSH1 0xa0 # Place 1 byte item on stack. item
  187. 142 [ 246 0x00f6 ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
  188. 143 [ 248 0x00f8 ] 10 | EXP # Exponential operation. result base, exponent
  189. 144 [ 249 0x00f9 ] 3 | SUB # Subtraction operation. result a, b
  190. 145 [ 250 0x00fa ] 3 | AND # Bitwise AND operation. result a, b
  191. 146 [ 251 0x00fb ] 3 | EQ # Equality comparison flag a, b
  192. 147 [ 252 0x00fc ] 3 | ISZERO # Simple not operator flag a
  193. 148 [ 253 0x00fd ] 3 | ISZERO # Simple not operator flag a
  194. 149 [ 254 0x00fe ] 3 | ISZERO # Simple not operator flag a
  195. 150 [ 255 0x00ff ] 3 | PUSH2 0x0107 # Place 2-byte item on stack. item
  196. 151 [ 258 0x0102 ] 10 | JUMPI @0x107 # Conditionally alter the program counter. evm.pc, condition
  197. 152 [ 259 0x0103 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
  198. 153 [ 261 0x0105 ] 3 | DUP1 # Duplicate 1st stack item.
  199. 154 [ 262 0x0106 ] 0 | REVERT # throw an error offset, size
  200. [...]
  201. :loc_0x5d5
  202. 954 [1493 0x05d5 ] 1 | JUMPDEST JUMPI@0x5c9 # Mark a valid destination for jumps.
  203. 955 [1494 0x05d6 ] 2 | POP # Remove item from stack. #dummy
  204. 956 [1495 0x05d7 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
  205. 957 [1496 0x05d8 ] 8 | JUMP # Alter the program counter. evm.pc
  206. 958 [1497 0x05d9 ] 0 | STOP # Halts execution.
  207. 959 [1498 0x05da ] 750 | LOG1 0x65 # Append log record with one topic. start, size, topic1
  208. 960 [1500 0x05dc ] 3 | PUSH3 0x7a7a72 # Place 3-byte item on stack. item
  209. 961 [1504 0x05e0 ] 2 | ADDRESS # Get address of currently executing account. this.address
  210. 962 [1505 0x05e1 ] 2 | PC # Get the value of the program counter prior to the increment. evm.pc
  211. 963 [1506 0x05e2 ] 30 | SHA3 # Compute Keccak-256 hash. flag offset, size
  212. 964 [1507 0x05e3 ] -1 | UNKNOWN_0xf # Invalid opcode
  213. 965 [1508 0x05e4 ] 3 | SWAP4 # Exchange 1st and 5th stack items.
  214. 966 [1509 0x05e5 ] 3 | SWAP14 # Exchange 1st and 15th stack items.
  215. 967 [1510 0x05e6 ] 2 | CALLDATASIZE # Get size of input data in current environment. msg.data.length
  216. 968 [1511 0x05e7 ] -1 | UNKNOWN_0xe1 # Invalid opcode
  217. 969 [1512 0x05e8 ] -1 | UNKNOWN_0xcb # Invalid opcode
  218. 970 [1513 0x05e9 ] 3 | PUSH22 0xc68ec825da862dc7082ea12aea89eb3783b2e0423cd2 # Place 22-byte item on stack. item
  219. 971 [1536 0x0600 ] 30 | SHA3 # Compute Keccak-256 hash. flag offset, size
  220. 972 [1537 0x0601 ] -1 | UNKNOWN_0x28 # Invalid opcode
  221. 973 [1538 0x0602 ] 3 | PUSH16 0x0029 # Place 16-byte item on stack. item
  222. ==============================
  223. reconstructed ABI:
  224. [{'name': 'enter', 'stateMutability': 'nonpayable', 'signature': '0x124c32a1', 'payable': False, 'inputs': [{'name': '_passcode', 'type': 'bytes32'}, {'name': '_gateKey', 'type': 'bytes8'}], 'constant': False, 'type': 'function', 'outputs': [{'name': '', 'type': 'bool'}]}, {'name': 'maxEntrants', 'stateMutability': 'pure', 'signature': '0x60643652', 'payable': False, 'inputs': [], 'constant': True, 'type': 'function', 'outputs': [{'name': '', 'type': 'uint8'}]}, {'name': 'totalEntrants', 'stateMutability': 'view', 'signature': '0x694463a2', 'payable': False, 'inputs': [], 'constant': True, 'type': 'function', 'outputs': [{'name': '', 'type': 'uint8'}]}, {'name': 'assignAll', 'stateMutability': 'nonpayable', 'signature': '0x90ae631d', 'payable': False, 'inputs': [], 'constant': False, 'type': 'function', 'outputs': [{'name': '', 'type': 'bool'}]}, {'stateMutability': 'nonpayable', 'type': 'constructor', 'payable': False, 'inputs': []}]

decompile to pseudocode

python3 -m ethereum_dasm -a 0x44919b8026f38d70437a8eb3be47b06ab1c3e4bf --simplify #[--simplify-show-asm, --simplify-show-unreachable]

  1. ======================[simplified]
  2. :init
  3. memory[0x40] = 0x60
  4. if (Not(ULE(0x4, 1_calldatasize))) goto LOC_0x48
  5. if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0xa1,
  6. If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x32,
  7. If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x4c,
  8. If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x12)) goto function_enter (LOC_0x4d)
  9. if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0x52,
  10. If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x36,
  11. If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x64,
  12. If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x60)) goto function_maxEntrants (LOC_0x95)
  13. if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0xa2,
  14. If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x63,
  15. If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x44,
  16. If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x69)) goto function_totalEntrants (LOC_0xbe)
  17. if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0x1d,
  18. If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x63,
  19. If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0xae,
  20. If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x90)) goto function_assignAll (LOC_0xd1)
  21. :LOC_0x48
  22. REVERT(offset=0x0, size=0x0)
  23. /******* <<terminates execution>> *******/
  24. :function_enter (LOC_0x4d)
  25. /*******************************************************************
  26. function enter(bytes32,bytes8)
  27. payable: False
  28. inputs: (2) ['bytes32', '<bytes??>']
  29. potential signatures: ['enter(bytes32,bytes8)']
  30. *******************************************************************/
  31. if (call_value1 == 0x0) goto LOC_0x58
  32. REVERT(offset=0x0, size=0x0)
  33. /******* <<terminates execution>> *******/
  34. :LOC_0x58
  35. goto LOC_0xe4
  36. :LOC_0x81
  37. :function_maxEntrants (LOC_0x95)
  38. /*******************************************************************
  39. function maxEntrants()
  40. payable: False
  41. inputs: (0) []
  42. potential signatures: ['maxEntrants()']
  43. *******************************************************************/
  44. if (call_value1 == 0x0) goto LOC_0xa0
  45. REVERT(offset=0x0, size=0x0)
  46. /******* <<terminates execution>> *******/
  47. :LOC_0xa0
  48. goto LOC_0x314
  49. :LOC_0xa8
  50. memory[0x60] = 0xfa
  51. RETURN(offset=0x60, size=0x20)
  52. /******* <<terminates execution>> *******/
  53. :function_totalEntrants (LOC_0xbe)
  54. /*******************************************************************
  55. function totalEntrants()
  56. payable: False
  57. inputs: (0) []
  58. potential signatures: ['totalEntrants()']
  59. *******************************************************************/
  60. if (call_value1 == 0x0) goto LOC_0xc9
  61. REVERT(offset=0x0, size=0x0)
  62. /******* <<terminates execution>> *******/
  63. :LOC_0xc9
  64. goto LOC_0x31a
  65. :function_assignAll (LOC_0xd1)
  66. /*******************************************************************
  67. function assignAll()
  68. payable: False
  69. inputs: (0) []
  70. potential signatures: ['assignAll()']
  71. *******************************************************************/
  72. if (call_value1 == 0x0) goto LOC_0xdc
  73. REVERT(offset=0x0, size=0x0)
  74. /******* <<terminates execution>> *******/
  75. :LOC_0xdc
  76. goto LOC_0x320
  77. :LOC_0xe4
  78. if (Not(Extract(159, 0, origin1) ==
  79. 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef)) goto LOC_0x107
  80. REVERT(offset=0x0, size=0x0)
  81. /******* <<terminates execution>> *******/
  82. :LOC_0x107
  83. if (True) goto LOC_0x114
  84. :LOC_0x114
  85. if (bvurem_i(1_gas, 0x1fff) == 0x0) goto LOC_0x11f
  86. REVERT(offset=0x0, size=0x0)
  87. /******* <<terminates execution>> *******/
  88. :LOC_0x11f
  89. if (And(If(1_calldatasize <= 0x29, 0x0, 1_calldata[0x29]) == 0x0,
  90. If(1_calldatasize <= 0x28, 0x0, 1_calldata[0x28]) == 0x0)) goto LOC_0x154
  91. REVERT(offset=0x0, size=0x0)
  92. /******* <<terminates execution>> *******/
  93. :LOC_0x154
  94. if (Not(And(If(1_calldatasize <= 0x27, 0x0, 1_calldata[0x27]) ==
  95. 0x0,
  96. If(1_calldatasize <= 0x26, 0x0, 1_calldata[0x26]) ==
  97. 0x0,
  98. If(1_calldatasize <= 0x25, 0x0, 1_calldata[0x25]) ==
  99. 0x0,
  100. If(1_calldatasize <= 0x24, 0x0, 1_calldata[0x24]) ==
  101. 0x0))) goto LOC_0x18f
  102. REVERT(offset=0x0, size=0x0)
  103. /******* <<terminates execution>> *******/
  104. :LOC_0x18f
  105. if (And(Extract(7, 0, origin1) ==
  106. If(1_calldatasize <= 0x2b, 0x0, 1_calldata[0x2b]),
  107. Extract(15, 8, origin1) ==
  108. If(1_calldatasize <= 0x2a, 0x0, 1_calldata[0x2a]),
  109. If(1_calldatasize <= 0x29, 0x0, 1_calldata[0x29]) == 0x0,
  110. If(1_calldatasize <= 0x28, 0x0, 1_calldata[0x28]) == 0x0)) goto LOC_0x1c0
  111. REVERT(offset=0x0, size=0x0)
  112. /******* <<terminates execution>> *******/
  113. :LOC_0x1c0
  114. if (True) goto LOC_0x1d1
  115. :LOC_0x1d1
  116. memory[0x0] = 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
  117. memory[0x20] = 0x3
  118. if (True) goto LOC_0x1f7
  119. :LOC_0x1f7
  120. memory[0x0] = Concat(0x0, Extract(159, 0, origin1))
  121. memory[0x20] = 0x3
  122. if (True) goto LOC_0x21d
  123. :LOC_0x21d
  124. memory[0x60] = Concat(If(1_calldatasize <= 0x4, 0x0, 1_calldata[0x4]),
  125. If(1_calldatasize <= 0x5, 0x0, 1_calldata[0x5]),
  126. If(1_calldatasize <= 0x6, 0x0, 1_calldata[0x6]),
  127. If(1_calldatasize <= 0x7, 0x0, 1_calldata[0x7]),
  128. If(1_calldatasize <= 0x8, 0x0, 1_calldata[0x8]),
  129. If(1_calldatasize <= 0x9, 0x0, 1_calldata[0x9]),
  130. If(1_calldatasize <= 0xa, 0x0, 1_calldata[0xa]),
  131. If(1_calldatasize <= 0xb, 0x0, 1_calldata[0xb]),
  132. If(1_calldatasize <= 0xc, 0x0, 1_calldata[0xc]),
  133. If(1_calldatasize <= 0xd, 0x0, 1_calldata[0xd]),
  134. If(1_calldatasize <= 0xe, 0x0, 1_calldata[0xe]),
  135. If(1_calldatasize <= 0xf, 0x0, 1_calldata[0xf]),
  136. If(1_calldatasize <= 0x10, 0x0, 1_calldata[0x10]),
  137. If(1_calldatasize <= 0x11, 0x0, 1_calldata[0x11]),
  138. If(1_calldatasize <= 0x12, 0x0, 1_calldata[0x12]),
  139. If(1_calldatasize <= 0x13, 0x0, 1_calldata[0x13]),
  140. If(1_calldatasize <= 0x14, 0x0, 1_calldata[0x14]),
  141. If(1_calldatasize <= 0x15, 0x0, 1_calldata[0x15]),
  142. If(1_calldatasize <= 0x16, 0x0, 1_calldata[0x16]),
  143. If(1_calldatasize <= 0x17, 0x0, 1_calldata[0x17]),
  144. If(1_calldatasize <= 0x18, 0x0, 1_calldata[0x18]),
  145. If(1_calldatasize <= 0x19, 0x0, 1_calldata[0x19]),
  146. If(1_calldatasize <= 0x1a, 0x0, 1_calldata[0x1a]),
  147. If(1_calldatasize <= 0x1b, 0x0, 1_calldata[0x1b]),
  148. If(1_calldatasize <= 0x1c, 0x0, 1_calldata[0x1c]),
  149. If(1_calldatasize <= 0x1d, 0x0, 1_calldata[0x1d]),
  150. If(1_calldatasize <= 0x1e, 0x0, 1_calldata[0x1e]),
  151. If(1_calldatasize <= 0x1f, 0x0, 1_calldata[0x1f]),
  152. If(1_calldatasize <= 0x20, 0x0, 1_calldata[0x20]),
  153. If(1_calldatasize <= 0x21, 0x0, 1_calldata[0x21]),
  154. If(1_calldatasize <= 0x22, 0x0, 1_calldata[0x22]),
  155. If(1_calldatasize <= 0x23, 0x0, 1_calldata[0x23]))
  156. memory[0x0] = KECCAC[If(1_calldatasize_<=_0x4,_0x0,_1_calldata[0x4])]
  157. memory[0x20] = 0x4
  158. if (False) goto LOC_0x257
  159. REVERT(offset=0x0, size=0x0)
  160. /******* <<terminates execution>> *******/
  161. :LOC_0x257
  162. :LOC_0x275
  163. :LOC_0x2d6
  164. :LOC_0x314
  165. :LOC_0x317
  166. goto LOC_0xa8
  167. :LOC_0x31a
  168. goto LOC_0xa8
  169. :LOC_0x320
  170. if (False) goto LOC_0x338
  171. REVERT(offset=0x0, size=0x0)
  172. /******* <<terminates execution>> *******/
  173. :LOC_0x338
  174. :LOC_0x347
  175. :LOC_0x3a8
  176. :LOC_0x3b9
  177. :LOC_0x3d8
  178. :LOC_0x3e0
  179. :LOC_0x3f5
  180. :LOC_0x459
  181. :LOC_0x46a
  182. :LOC_0x4de
  183. :LOC_0x541
  184. :LOC_0x552
  185. :LOC_0x556
  186. :LOC_0x55e
  187. :LOC_0x588
  188. :LOC_0x592
  189. :LOC_0x5b6
  190. :LOC_0x5bb
  191. :LOC_0x5c1
  192. :LOC_0x5d5