1658805540
ethereum evm bytecode disassembler with static- and dynamic-analysis and function signature lookup
-L
to switch from table to listing mode)UNKNOWN_
Contract()
.disassembles evm bytecode
decompile a contract to pseudocode
#> pip3 install "ethereum-dasm[mythril,abidecoder]"
#> python3 -m ethereum_dasm --help # verify installation
#> pip3 install -r requirements*.txt
#> python3 setup.py install
#> python3 -m ethereum_dasm -a 0x44919b8026f38d70437a8eb3be47b06ab1c3e4bf # jusst to verify installation
Usage: ethereum_dasm.py [options]
example: ethereum_dasm.py [-L -F -v] <file_or_bytecode>
ethereum_dasm.py [-L -F -v] # read from stdin
ethereum_dasm.py [-L -F -a <address>] # fetch contract code from infura.io
Options:
-h, --help show this help message and exit
-v VERBOSITY, --verbosity=VERBOSITY
available loglevels:
critical,fatal,error,warning,warn,info,debug,notset
[default: critical]
-L, --listing disables table mode, outputs assembly only
-F, --no-online-lookup
disable online function signature lookup
-a ADDRESS, --address=ADDRESS
fetch contract bytecode from address
-C, --no-color disable color mode (requires pip install colorama)
-A, --guess-abi guess the ABI for that contract
-D, --no-dynamic-analysis
disable dynamic analysis / symolic execution
-S, --no-static-analysis
disable static analysis
-s, --simplify simplify disassembly to human readable code
-x, --simplify-show-asm
simplify: show or hide asm annotations in simplified
code
-y, --simplify-show-unreachable
simplify: show or hide annotations for unreachable
instructions in simplified code
-n NETWORK, --network=NETWORK
network for address lookup (default: mainnet, ropsten,
rinkeby, kovan
#> echo "0x12345678" | python3 -m ethereum_dasm
#> python3 -m ethereum_dasm 0x12345678
#> python3 -m ethereum_dasm ether_contract.evm
#> python3 -m ethereum_dasm -a <contract address>
#> python3 -m ethereum_dasm -a <contract address> -A
#> python3 -m ethereum_dasm -a <contract address> --simplify [--simplify-show-asm, --simplify-show-unreachable]
abi online lookup or reconstruction #>python3 -m ethereum_dasm -a 0x44919b8026f38d70437a8eb3be47b06ab1c3e4bf -A
# [....]
[{'stateMutability': 'nonpayable', 'constant': False, 'type': 'function', 'name': 'enter', 'signature': '0x124c32a1', 'outputs': [{'type': 'bool', 'name': ''}], 'inputs': [{'type': 'bytes32', 'name': '_passcode'
}, {'type': 'bytes8', 'name': '_gateKey'}], 'payable': False}, {'stateMutability': 'pure', 'constant': True, 'type': 'function', 'name': 'maxEntrants', 'signature': '0x60643652', 'outputs': [{'type': 'uint8', 'n
ame': ''}], 'inputs': [], 'payable': False}, {'stateMutability': 'view', 'constant': True, 'type': 'function', 'name': 'totalEntrants', 'signature': '0x694463a2', 'outputs': [{'type': 'uint8', 'name': ''}], 'inp
uts': [], 'payable': False}, {'stateMutability': 'nonpayable', 'constant': False, 'type': 'function', 'name': 'assignAll', 'signature': '0x90ae631d', 'outputs': [{'type': 'bool', 'name': ''}], 'inputs': [], 'pay
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
[{'signature': '0x95d89b41', 'outputs': [], 'stateMutability': None, 'name': 'symbol', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 598}, {'signature': '0x095ea7b3', 'outputs':
[], 'stateMutability': None, 'name': 'approve', 'constant': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 328}, {'signature': '0x313ce567', 'outputs': [], 'stateMutab
ility': None, 'name': 'decimals', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 486}, {'signature': '0xdd62ed3e', 'outputs': [], 'stateMutability': None, 'name': 'allowance', 'c
onstant': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 691}, {'signature': '0x66188463', 'outputs': [], 'stateMutability': None, 'name': 'decreaseApproval', 'constant
': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 529}, {'signature': '0x23b872dd', 'outputs': [], 'stateMutability': None, 'name': 'transferFrom', 'constant': None, 'i
nputs': ['bytes32', 'bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 423}, {'signature': '0x2ff2e9dc', 'outputs': [], 'stateMutability': None, 'name': 'INITIAL_SUPPLY', 'constant': None,
'inputs': [], 'payable': True, 'type': 'function', 'address': 465}, {'signature': '0x06fdde03', 'outputs': [], 'stateMutability': None, 'name': 'name', 'constant': None, 'inputs': [], 'payable': True, 'type': 'f
unction', 'address': 190}, {'signature': '0x18160ddd', 'outputs': [], 'stateMutability': None, 'name': 'totalSupply', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 384}, {'signa
ture': '0x70a08231', 'outputs': [], 'stateMutability': None, 'name': 'balanceOf', 'constant': None, 'inputs': ['<bytes??>'], 'payable': True, 'type': 'function', 'address': 565}, {'signature': '0xa9059cbb', 'out
puts': [], 'stateMutability': None, 'name': 'transfer', 'constant': None, 'inputs': [{'type': 'address', 'name': 'arg0'}, {'type': 'uint256', 'name': 'arg1'}], 'payable': True, 'type': 'function', 'address': 619
}, {'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
Inst addr hex gas | mnemonic operand xrefs description retval args
------------------------------------------------------------------------------------------------ ----------- -------------------------------------------------------------------- --------------- --------------------
:loc_0x0
0 [ 0 0x0000 ] 3 | PUSH1 0x60 # Place 1 byte item on stack. item
1 [ 2 0x0002 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
2 [ 4 0x0004 ] 3 | MSTORE # Save word to memory. value, offset
3 [ 5 0x0005 ] 3 | PUSH1 0x04 # Place 1 byte item on stack. item
4 [ 7 0x0007 ] 2 | CALLDATASIZE # Get size of input data in current environment. msg.data.length
5 [ 8 0x0008 ] 3 | LT # Lesser-than comparison flag a, b
6 [ 9 0x0009 ] 3 | PUSH2 0x0048 # Place 2-byte item on stack. item
7 [ 12 0x000c ] 10 | JUMPI @0x48 # Conditionally alter the program counter. evm.pc, condition
8 [ 13 0x000d ] 3 | PUSH4 0xffffffff # Place 4-byte item on stack. item
9 [ 18 0x0012 ] 3 | PUSH1 0xe0 # Place 1 byte item on stack. item
10 [ 20 0x0014 ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
11 [ 22 0x0016 ] 10 | EXP # Exponential operation. result base, exponent
12 [ 23 0x0017 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
13 [ 25 0x0019 ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
14 [ 26 0x001a ] 5 | DIV # Integer division operation. result a, b
15 [ 27 0x001b ] 3 | AND # Bitwise AND operation. result a, b
16 [ 28 0x001c ] 3 | PUSH4 0x124c32a1 --> 'function enter(bytes32,bytes8)' # Place 4-byte item on stack. item
17 [ 33 0x0021 ] 3 | DUP2 # Duplicate 2nd stack item.
18 [ 34 0x0022 ] 3 | EQ # Equality comparison flag a, b
19 [ 35 0x0023 ] 3 | PUSH2 0x004d # Place 2-byte item on stack. item
20 [ 38 0x0026 ] 10 | JUMPI @0x4d # Conditionally alter the program counter. evm.pc, condition
21 [ 39 0x0027 ] 3 | DUP1 # Duplicate 1st stack item.
22 [ 40 0x0028 ] 3 | PUSH4 0x60643652 --> 'function maxEntrants()' # Place 4-byte item on stack. item
23 [ 45 0x002d ] 3 | EQ # Equality comparison flag a, b
24 [ 46 0x002e ] 3 | PUSH2 0x0095 # Place 2-byte item on stack. item
25 [ 49 0x0031 ] 10 | JUMPI @0x95 # Conditionally alter the program counter. evm.pc, condition
26 [ 50 0x0032 ] 3 | DUP1 # Duplicate 1st stack item.
27 [ 51 0x0033 ] 3 | PUSH4 0x694463a2 --> 'function totalEntrants()' # Place 4-byte item on stack. item
28 [ 56 0x0038 ] 3 | EQ # Equality comparison flag a, b
29 [ 57 0x0039 ] 3 | PUSH2 0x00be # Place 2-byte item on stack. item
30 [ 60 0x003c ] 10 | JUMPI @0xbe # Conditionally alter the program counter. evm.pc, condition
31 [ 61 0x003d ] 3 | DUP1 # Duplicate 1st stack item.
32 [ 62 0x003e ] 3 | PUSH4 0x90ae631d --> 'function assignAll()' # Place 4-byte item on stack. item
33 [ 67 0x0043 ] 3 | EQ # Equality comparison flag a, b
34 [ 68 0x0044 ] 3 | PUSH2 0x00d1 # Place 2-byte item on stack. item
35 [ 71 0x0047 ] 10 | JUMPI @0xd1 # Conditionally alter the program counter. evm.pc, condition
:loc_0x48
36 [ 72 0x0048 ] 1 | JUMPDEST JUMPI@0xc # Mark a valid destination for jumps.
37 [ 73 0x0049 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
38 [ 75 0x004b ] 3 | DUP1 # Duplicate 1st stack item.
39 [ 76 0x004c ] 0 | REVERT # throw an error offset, size
:loc_0x4d
/*******************************************************************
function enter(bytes32,bytes8)
payable: False
inputs: (2) ['bytes32', '<bytes??>']
potential signatures: ['enter(bytes32,bytes8)']
*******************************************************************/
40 [ 77 0x004d ] 1 | JUMPDEST JUMPI@0x26 # Mark a valid destination for jumps.
41 [ 78 0x004e ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
this execution.
42 [ 79 0x004f ] 3 | ISZERO # Simple not operator flag a
43 [ 80 0x0050 ] 3 | PUSH2 0x0058 # Place 2-byte item on stack. item
44 [ 83 0x0053 ] 10 | JUMPI @0x58 # Conditionally alter the program counter. evm.pc, condition
45 [ 84 0x0054 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
46 [ 86 0x0056 ] 3 | DUP1 # Duplicate 1st stack item.
47 [ 87 0x0057 ] 0 | REVERT # throw an error offset, size
:loc_0x58
48 [ 88 0x0058 ] 1 | JUMPDEST JUMPI@0x53 # Mark a valid destination for jumps.
49 [ 89 0x0059 ] 3 | PUSH2 0x0081 # Place 2-byte item on stack. item
50 [ 92 0x005c ] 3 | PUSH1 0x04 # Place 1 byte item on stack. item
51 [ 94 0x005e ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
52 [ 95 0x005f ] 3 | PUSH24 0xffffffffffffffffffffffffffffffffffffffffffffffff # Place 24-byte item on stack. item
53 [ 120 0x0078 ] 3 | NOT # Bitwise NOT operation. result a, b
54 [ 121 0x0079 ] 3 | PUSH1 0x24 # Place 1 byte item on stack. item
55 [ 123 0x007b ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
56 [ 124 0x007c ] 3 | AND # Bitwise AND operation. result a, b
57 [ 125 0x007d ] 3 | PUSH2 0x00e4 # Place 2-byte item on stack. item
58 [ 128 0x0080 ] 8 | JUMP @0xe4 # Alter the program counter. evm.pc
:loc_0x81
59 [ 129 0x0081 ] 1 | JUMPDEST # Mark a valid destination for jumps.
60 [ 130 0x0082 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
61 [ 132 0x0084 ] 3 | MLOAD # Load word from memory. offset
62 [ 133 0x0085 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
63 [ 134 0x0086 ] 3 | ISZERO # Simple not operator flag a
64 [ 135 0x0087 ] 3 | ISZERO # Simple not operator flag a
65 [ 136 0x0088 ] 3 | DUP2 # Duplicate 2nd stack item.
66 [ 137 0x0089 ] 3 | MSTORE # Save word to memory. value, offset
67 [ 138 0x008a ] 3 | PUSH1 0x20 # Place 1 byte item on stack. item
68 [ 140 0x008c ] 3 | ADD # Addition operation. result a, b
69 [ 141 0x008d ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
70 [ 143 0x008f ] 3 | MLOAD # Load word from memory. offset
71 [ 144 0x0090 ] 3 | DUP1 # Duplicate 1st stack item.
72 [ 145 0x0091 ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
73 [ 146 0x0092 ] 3 | SUB # Subtraction operation. result a, b
74 [ 147 0x0093 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
75 [ 148 0x0094 ] 0 | RETURN # Halt execution returning output data. offset, size
:loc_0x95
/*******************************************************************
function maxEntrants()
payable: False
inputs: (0) []
potential signatures: ['maxEntrants()']
*******************************************************************/
76 [ 149 0x0095 ] 1 | JUMPDEST JUMPI@0x31 # Mark a valid destination for jumps.
77 [ 150 0x0096 ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
this execution.
78 [ 151 0x0097 ] 3 | ISZERO # Simple not operator flag a
79 [ 152 0x0098 ] 3 | PUSH2 0x00a0 # Place 2-byte item on stack. item
80 [ 155 0x009b ] 10 | JUMPI @0xa0 # Conditionally alter the program counter. evm.pc, condition
81 [ 156 0x009c ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
82 [ 158 0x009e ] 3 | DUP1 # Duplicate 1st stack item.
83 [ 159 0x009f ] 0 | REVERT # throw an error offset, size
:loc_0xa0
84 [ 160 0x00a0 ] 1 | JUMPDEST JUMPI@0x9b # Mark a valid destination for jumps.
85 [ 161 0x00a1 ] 3 | PUSH2 0x00a8 # Place 2-byte item on stack. item
86 [ 164 0x00a4 ] 3 | PUSH2 0x0314 # Place 2-byte item on stack. item
87 [ 167 0x00a7 ] 8 | JUMP @0x314 # Alter the program counter. evm.pc
:loc_0xa8
88 [ 168 0x00a8 ] 1 | JUMPDEST # Mark a valid destination for jumps.
89 [ 169 0x00a9 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
90 [ 171 0x00ab ] 3 | MLOAD # Load word from memory. offset
91 [ 172 0x00ac ] 3 | PUSH1 0xff # Place 1 byte item on stack. item
92 [ 174 0x00ae ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
93 [ 175 0x00af ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
94 [ 176 0x00b0 ] 3 | AND # Bitwise AND operation. result a, b
95 [ 177 0x00b1 ] 3 | DUP2 # Duplicate 2nd stack item.
96 [ 178 0x00b2 ] 3 | MSTORE # Save word to memory. value, offset
97 [ 179 0x00b3 ] 3 | PUSH1 0x20 # Place 1 byte item on stack. item
98 [ 181 0x00b5 ] 3 | ADD # Addition operation. result a, b
99 [ 182 0x00b6 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
100 [ 184 0x00b8 ] 3 | MLOAD # Load word from memory. offset
101 [ 185 0x00b9 ] 3 | DUP1 # Duplicate 1st stack item.
102 [ 186 0x00ba ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
103 [ 187 0x00bb ] 3 | SUB # Subtraction operation. result a, b
104 [ 188 0x00bc ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
105 [ 189 0x00bd ] 0 | RETURN # Halt execution returning output data. offset, size
:loc_0xbe
/*******************************************************************
function totalEntrants()
payable: False
inputs: (0) []
potential signatures: ['totalEntrants()']
*******************************************************************/
106 [ 190 0x00be ] 1 | JUMPDEST JUMPI@0x3c # Mark a valid destination for jumps.
107 [ 191 0x00bf ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
this execution.
108 [ 192 0x00c0 ] 3 | ISZERO # Simple not operator flag a
109 [ 193 0x00c1 ] 3 | PUSH2 0x00c9 # Place 2-byte item on stack. item
110 [ 196 0x00c4 ] 10 | JUMPI @0xc9 # Conditionally alter the program counter. evm.pc, condition
111 [ 197 0x00c5 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
112 [ 199 0x00c7 ] 3 | DUP1 # Duplicate 1st stack item.
113 [ 200 0x00c8 ] 0 | REVERT # throw an error offset, size
:loc_0xc9
114 [ 201 0x00c9 ] 1 | JUMPDEST JUMPI@0xc4 # Mark a valid destination for jumps.
115 [ 202 0x00ca ] 3 | PUSH2 0x00a8 # Place 2-byte item on stack. item
116 [ 205 0x00cd ] 3 | PUSH2 0x031a # Place 2-byte item on stack. item
117 [ 208 0x00d0 ] 8 | JUMP @0x31a # Alter the program counter. evm.pc
:loc_0xd1
/*******************************************************************
function assignAll()
payable: False
inputs: (0) []
potential signatures: ['assignAll()']
*******************************************************************/
118 [ 209 0x00d1 ] 1 | JUMPDEST JUMPI@0x47 # Mark a valid destination for jumps.
119 [ 210 0x00d2 ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
this execution.
120 [ 211 0x00d3 ] 3 | ISZERO # Simple not operator flag a
121 [ 212 0x00d4 ] 3 | PUSH2 0x00dc # Place 2-byte item on stack. item
122 [ 215 0x00d7 ] 10 | JUMPI @0xdc # Conditionally alter the program counter. evm.pc, condition
123 [ 216 0x00d8 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
124 [ 218 0x00da ] 3 | DUP1 # Duplicate 1st stack item.
125 [ 219 0x00db ] 0 | REVERT # throw an error offset, size
:loc_0xdc
126 [ 220 0x00dc ] 1 | JUMPDEST JUMPI@0xd7 # Mark a valid destination for jumps.
127 [ 221 0x00dd ] 3 | PUSH2 0x0081 # Place 2-byte item on stack. item
128 [ 224 0x00e0 ] 3 | PUSH2 0x0320 # Place 2-byte item on stack. item
129 [ 227 0x00e3 ] 8 | JUMP @0x320 # Alter the program counter. evm.pc
:loc_0xe4
130 [ 228 0x00e4 ] 1 | JUMPDEST JUMP@0x80 # Mark a valid destination for jumps.
131 [ 229 0x00e5 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
132 [ 231 0x00e7 ] 2 | ORIGIN # Get execution origination address. tx.origin
133 [ 232 0x00e8 ] 3 | PUSH1 0x01 # Place 1 byte item on stack. item
134 [ 234 0x00ea ] 3 | PUSH1 0xa0 # Place 1 byte item on stack. item
135 [ 236 0x00ec ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
136 [ 238 0x00ee ] 10 | EXP # Exponential operation. result base, exponent
137 [ 239 0x00ef ] 3 | SUB # Subtraction operation. result a, b
138 [ 240 0x00f0 ] 3 | AND # Bitwise AND operation. result a, b
139 [ 241 0x00f1 ] 2 | CALLER # Get caller address.This is the address of the account that is msg.sender
directly responsible for this execution.
140 [ 242 0x00f2 ] 3 | PUSH1 0x01 # Place 1 byte item on stack. item
141 [ 244 0x00f4 ] 3 | PUSH1 0xa0 # Place 1 byte item on stack. item
142 [ 246 0x00f6 ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
143 [ 248 0x00f8 ] 10 | EXP # Exponential operation. result base, exponent
144 [ 249 0x00f9 ] 3 | SUB # Subtraction operation. result a, b
145 [ 250 0x00fa ] 3 | AND # Bitwise AND operation. result a, b
146 [ 251 0x00fb ] 3 | EQ # Equality comparison flag a, b
147 [ 252 0x00fc ] 3 | ISZERO # Simple not operator flag a
148 [ 253 0x00fd ] 3 | ISZERO # Simple not operator flag a
149 [ 254 0x00fe ] 3 | ISZERO # Simple not operator flag a
150 [ 255 0x00ff ] 3 | PUSH2 0x0107 # Place 2-byte item on stack. item
151 [ 258 0x0102 ] 10 | JUMPI @0x107 # Conditionally alter the program counter. evm.pc, condition
152 [ 259 0x0103 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
153 [ 261 0x0105 ] 3 | DUP1 # Duplicate 1st stack item.
154 [ 262 0x0106 ] 0 | REVERT # throw an error offset, size
[...]
:loc_0x5d5
954 [1493 0x05d5 ] 1 | JUMPDEST JUMPI@0x5c9 # Mark a valid destination for jumps.
955 [1494 0x05d6 ] 2 | POP # Remove item from stack. #dummy
956 [1495 0x05d7 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
957 [1496 0x05d8 ] 8 | JUMP # Alter the program counter. evm.pc
958 [1497 0x05d9 ] 0 | STOP # Halts execution.
959 [1498 0x05da ] 750 | LOG1 0x65 # Append log record with one topic. start, size, topic1
960 [1500 0x05dc ] 3 | PUSH3 0x7a7a72 # Place 3-byte item on stack. item
961 [1504 0x05e0 ] 2 | ADDRESS # Get address of currently executing account. this.address
962 [1505 0x05e1 ] 2 | PC # Get the value of the program counter prior to the increment. evm.pc
963 [1506 0x05e2 ] 30 | SHA3 # Compute Keccak-256 hash. flag offset, size
964 [1507 0x05e3 ] -1 | UNKNOWN_0xf # Invalid opcode
965 [1508 0x05e4 ] 3 | SWAP4 # Exchange 1st and 5th stack items.
966 [1509 0x05e5 ] 3 | SWAP14 # Exchange 1st and 15th stack items.
967 [1510 0x05e6 ] 2 | CALLDATASIZE # Get size of input data in current environment. msg.data.length
968 [1511 0x05e7 ] -1 | UNKNOWN_0xe1 # Invalid opcode
969 [1512 0x05e8 ] -1 | UNKNOWN_0xcb # Invalid opcode
970 [1513 0x05e9 ] 3 | PUSH22 0xc68ec825da862dc7082ea12aea89eb3783b2e0423cd2 # Place 22-byte item on stack. item
971 [1536 0x0600 ] 30 | SHA3 # Compute Keccak-256 hash. flag offset, size
972 [1537 0x0601 ] -1 | UNKNOWN_0x28 # Invalid opcode
973 [1538 0x0602 ] 3 | PUSH16 0x0029 # Place 16-byte item on stack. item
==============================
reconstructed ABI:
[{'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]
======================[simplified]
:init
memory[0x40] = 0x60
if (Not(ULE(0x4, 1_calldatasize))) goto LOC_0x48
if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0xa1,
If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x32,
If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x4c,
If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x12)) goto function_enter (LOC_0x4d)
if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0x52,
If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x36,
If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x64,
If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x60)) goto function_maxEntrants (LOC_0x95)
if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0xa2,
If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x63,
If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x44,
If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x69)) goto function_totalEntrants (LOC_0xbe)
if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0x1d,
If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x63,
If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0xae,
If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x90)) goto function_assignAll (LOC_0xd1)
:LOC_0x48
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:function_enter (LOC_0x4d)
/*******************************************************************
function enter(bytes32,bytes8)
payable: False
inputs: (2) ['bytes32', '<bytes??>']
potential signatures: ['enter(bytes32,bytes8)']
*******************************************************************/
if (call_value1 == 0x0) goto LOC_0x58
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x58
goto LOC_0xe4
:LOC_0x81
:function_maxEntrants (LOC_0x95)
/*******************************************************************
function maxEntrants()
payable: False
inputs: (0) []
potential signatures: ['maxEntrants()']
*******************************************************************/
if (call_value1 == 0x0) goto LOC_0xa0
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0xa0
goto LOC_0x314
:LOC_0xa8
memory[0x60] = 0xfa
RETURN(offset=0x60, size=0x20)
/******* <<terminates execution>> *******/
:function_totalEntrants (LOC_0xbe)
/*******************************************************************
function totalEntrants()
payable: False
inputs: (0) []
potential signatures: ['totalEntrants()']
*******************************************************************/
if (call_value1 == 0x0) goto LOC_0xc9
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0xc9
goto LOC_0x31a
:function_assignAll (LOC_0xd1)
/*******************************************************************
function assignAll()
payable: False
inputs: (0) []
potential signatures: ['assignAll()']
*******************************************************************/
if (call_value1 == 0x0) goto LOC_0xdc
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0xdc
goto LOC_0x320
:LOC_0xe4
if (Not(Extract(159, 0, origin1) ==
0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef)) goto LOC_0x107
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x107
if (True) goto LOC_0x114
:LOC_0x114
if (bvurem_i(1_gas, 0x1fff) == 0x0) goto LOC_0x11f
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x11f
if (And(If(1_calldatasize <= 0x29, 0x0, 1_calldata[0x29]) == 0x0,
If(1_calldatasize <= 0x28, 0x0, 1_calldata[0x28]) == 0x0)) goto LOC_0x154
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x154
if (Not(And(If(1_calldatasize <= 0x27, 0x0, 1_calldata[0x27]) ==
0x0,
If(1_calldatasize <= 0x26, 0x0, 1_calldata[0x26]) ==
0x0,
If(1_calldatasize <= 0x25, 0x0, 1_calldata[0x25]) ==
0x0,
If(1_calldatasize <= 0x24, 0x0, 1_calldata[0x24]) ==
0x0))) goto LOC_0x18f
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x18f
if (And(Extract(7, 0, origin1) ==
If(1_calldatasize <= 0x2b, 0x0, 1_calldata[0x2b]),
Extract(15, 8, origin1) ==
If(1_calldatasize <= 0x2a, 0x0, 1_calldata[0x2a]),
If(1_calldatasize <= 0x29, 0x0, 1_calldata[0x29]) == 0x0,
If(1_calldatasize <= 0x28, 0x0, 1_calldata[0x28]) == 0x0)) goto LOC_0x1c0
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x1c0
if (True) goto LOC_0x1d1
:LOC_0x1d1
memory[0x0] = 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
memory[0x20] = 0x3
if (True) goto LOC_0x1f7
:LOC_0x1f7
memory[0x0] = Concat(0x0, Extract(159, 0, origin1))
memory[0x20] = 0x3
if (True) goto LOC_0x21d
:LOC_0x21d
memory[0x60] = Concat(If(1_calldatasize <= 0x4, 0x0, 1_calldata[0x4]),
If(1_calldatasize <= 0x5, 0x0, 1_calldata[0x5]),
If(1_calldatasize <= 0x6, 0x0, 1_calldata[0x6]),
If(1_calldatasize <= 0x7, 0x0, 1_calldata[0x7]),
If(1_calldatasize <= 0x8, 0x0, 1_calldata[0x8]),
If(1_calldatasize <= 0x9, 0x0, 1_calldata[0x9]),
If(1_calldatasize <= 0xa, 0x0, 1_calldata[0xa]),
If(1_calldatasize <= 0xb, 0x0, 1_calldata[0xb]),
If(1_calldatasize <= 0xc, 0x0, 1_calldata[0xc]),
If(1_calldatasize <= 0xd, 0x0, 1_calldata[0xd]),
If(1_calldatasize <= 0xe, 0x0, 1_calldata[0xe]),
If(1_calldatasize <= 0xf, 0x0, 1_calldata[0xf]),
If(1_calldatasize <= 0x10, 0x0, 1_calldata[0x10]),
If(1_calldatasize <= 0x11, 0x0, 1_calldata[0x11]),
If(1_calldatasize <= 0x12, 0x0, 1_calldata[0x12]),
If(1_calldatasize <= 0x13, 0x0, 1_calldata[0x13]),
If(1_calldatasize <= 0x14, 0x0, 1_calldata[0x14]),
If(1_calldatasize <= 0x15, 0x0, 1_calldata[0x15]),
If(1_calldatasize <= 0x16, 0x0, 1_calldata[0x16]),
If(1_calldatasize <= 0x17, 0x0, 1_calldata[0x17]),
If(1_calldatasize <= 0x18, 0x0, 1_calldata[0x18]),
If(1_calldatasize <= 0x19, 0x0, 1_calldata[0x19]),
If(1_calldatasize <= 0x1a, 0x0, 1_calldata[0x1a]),
If(1_calldatasize <= 0x1b, 0x0, 1_calldata[0x1b]),
If(1_calldatasize <= 0x1c, 0x0, 1_calldata[0x1c]),
If(1_calldatasize <= 0x1d, 0x0, 1_calldata[0x1d]),
If(1_calldatasize <= 0x1e, 0x0, 1_calldata[0x1e]),
If(1_calldatasize <= 0x1f, 0x0, 1_calldata[0x1f]),
If(1_calldatasize <= 0x20, 0x0, 1_calldata[0x20]),
If(1_calldatasize <= 0x21, 0x0, 1_calldata[0x21]),
If(1_calldatasize <= 0x22, 0x0, 1_calldata[0x22]),
If(1_calldatasize <= 0x23, 0x0, 1_calldata[0x23]))
memory[0x0] = KECCAC[If(1_calldatasize_<=_0x4,_0x0,_1_calldata[0x4])]
memory[0x20] = 0x4
if (False) goto LOC_0x257
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x257
:LOC_0x275
:LOC_0x2d6
:LOC_0x314
:LOC_0x317
goto LOC_0xa8
:LOC_0x31a
goto LOC_0xa8
:LOC_0x320
if (False) goto LOC_0x338
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x338
:LOC_0x347
:LOC_0x3a8
:LOC_0x3b9
:LOC_0x3d8
:LOC_0x3e0
:LOC_0x3f5
:LOC_0x459
:LOC_0x46a
:LOC_0x4de
:LOC_0x541
:LOC_0x552
:LOC_0x556
:LOC_0x55e
:LOC_0x588
:LOC_0x592
:LOC_0x5b6
:LOC_0x5bb
:LOC_0x5c1
:LOC_0x5d5
Download details:
Author: tintinweb
Source code: https://github.com/tintinweb/ethereum-dasm
License: GPL-2.0 license
#solidity #smartcontract #blockchain #ethereum
1604008800
Static code analysis refers to the technique of approximating the runtime behavior of a program. In other words, it is the process of predicting the output of a program without actually executing it.
Lately, however, the term “Static Code Analysis” is more commonly used to refer to one of the applications of this technique rather than the technique itself — program comprehension — understanding the program and detecting issues in it (anything from syntax errors to type mismatches, performance hogs likely bugs, security loopholes, etc.). This is the usage we’d be referring to throughout this post.
“The refinement of techniques for the prompt discovery of error serves as well as any other as a hallmark of what we mean by science.”
We cover a lot of ground in this post. The aim is to build an understanding of static code analysis and to equip you with the basic theory, and the right tools so that you can write analyzers on your own.
We start our journey with laying down the essential parts of the pipeline which a compiler follows to understand what a piece of code does. We learn where to tap points in this pipeline to plug in our analyzers and extract meaningful information. In the latter half, we get our feet wet, and write four such static analyzers, completely from scratch, in Python.
Note that although the ideas here are discussed in light of Python, static code analyzers across all programming languages are carved out along similar lines. We chose Python because of the availability of an easy to use ast
module, and wide adoption of the language itself.
Before a computer can finally “understand” and execute a piece of code, it goes through a series of complicated transformations:
As you can see in the diagram (go ahead, zoom it!), the static analyzers feed on the output of these stages. To be able to better understand the static analysis techniques, let’s look at each of these steps in some more detail:
The first thing that a compiler does when trying to understand a piece of code is to break it down into smaller chunks, also known as tokens. Tokens are akin to what words are in a language.
A token might consist of either a single character, like (
, or literals (like integers, strings, e.g., 7
, Bob
, etc.), or reserved keywords of that language (e.g, def
in Python). Characters which do not contribute towards the semantics of a program, like trailing whitespace, comments, etc. are often discarded by the scanner.
Python provides the tokenize
module in its standard library to let you play around with tokens:
Python
1
import io
2
import tokenize
3
4
code = b"color = input('Enter your favourite color: ')"
5
6
for token in tokenize.tokenize(io.BytesIO(code).readline):
7
print(token)
Python
1
TokenInfo(type=62 (ENCODING), string='utf-8')
2
TokenInfo(type=1 (NAME), string='color')
3
TokenInfo(type=54 (OP), string='=')
4
TokenInfo(type=1 (NAME), string='input')
5
TokenInfo(type=54 (OP), string='(')
6
TokenInfo(type=3 (STRING), string="'Enter your favourite color: '")
7
TokenInfo(type=54 (OP), string=')')
8
TokenInfo(type=4 (NEWLINE), string='')
9
TokenInfo(type=0 (ENDMARKER), string='')
(Note that for the sake of readability, I’ve omitted a few columns from the result above — metadata like starting index, ending index, a copy of the line on which a token occurs, etc.)
#code quality #code review #static analysis #static code analysis #code analysis #static analysis tools #code review tips #static code analyzer #static code analysis tool #static analyzer
1604023200
Peer code reviews as a process have increasingly been adopted by engineering teams around the world. And for good reason — code reviews have been proven to improve software quality and save developers’ time in the long run. A lot has been written about how code reviews help engineering teams by leading software engineering practitioners. My favorite is this quote by Karl Wiegers, author of the seminal paper on this topic, Humanizing Peer Reviews:
Peer review – an activity in which people other than the author of a software deliverable examine it for defects and improvement opportunities – is one of the most powerful software quality tools available. Peer review methods include inspections, walkthroughs, peer deskchecks, and other similar activities. After experiencing the benefits of peer reviews for nearly fifteen years, I would never work in a team that did not perform them.
It is worth the time and effort to put together a code review strategy and consistently follow it in the team. In essence, this has a two-pronged benefit: more pair of eyes looking at the code decreases the chances of bugs and bad design patterns entering your codebase, and embracing the process fosters knowledge sharing and positive collaboration culture in the team.
Here are 6 tips to ensure effective peer reviews in your team.
Code reviews require developers to look at someone else’s code, most of which is completely new most of the times. Too many lines of code to review at once requires a huge amount of cognitive effort, and the quality of review diminishes as the size of changes increases. While there’s no golden number of LOCs, it is recommended to create small pull-requests which can be managed easily. If there are a lot of changes going in a release, it is better to chunk it down into a number of small pull-requests.
Code reviews are the most effective when the changes are focused and have logical coherence. When doing refactoring, refrain from making behavioral changes. Similarly, behavioral changes should not include refactoring and style violation fixes. Following this convention prevents unintended changes creeping in unnoticed in the code base.
Automated tests of your preferred flavor — units, integration tests, end-to-end tests, etc. help automatically ensure correctness. Consistently ensuring that changes proposed are covered by some kind of automated frees up time for more qualitative review; allowing for a more insightful and in-depth conversation on deeper issues.
A change can implement a new feature or fix an existing issue. It is recommended that the requester submits only those changes that are complete, and tested for correctness manually. Before creating the pull-request, a quick glance on what changes are being proposed helps ensure that no extraneous files are added in the changeset. This saves tons of time for the reviewers.
Human review time is expensive, and the best use of a developer’s time is reviewing qualitative aspects of code — logic, design patterns, software architecture, and so on. Linting tools can help automatically take care of style and formatting conventions. Continuous Quality tools can help catch potential bugs, anti-patterns and security issues which can be fixed by the developer before they make a change request. Most of these tools integrate well with code hosting platforms as well.
Finally, be cognizant of the fact that people on both sides of the review are but human. Offer positive feedback, and accept criticism humbly. Instead of beating oneself upon the literal meaning of words, it really pays off to look at reviews as people trying to achieve what’s best for the team, albeit in possibly different ways. Being cognizant of this aspect can save a lot of resentment and unmitigated negativity.
#agile #code quality #code review #static analysis #code analysis #code reviews #static analysis tools #code review tips #continuous quality #static analyzer
1658805540
ethereum evm bytecode disassembler with static- and dynamic-analysis and function signature lookup
-L
to switch from table to listing mode)UNKNOWN_
Contract()
.disassembles evm bytecode
decompile a contract to pseudocode
#> pip3 install "ethereum-dasm[mythril,abidecoder]"
#> python3 -m ethereum_dasm --help # verify installation
#> pip3 install -r requirements*.txt
#> python3 setup.py install
#> python3 -m ethereum_dasm -a 0x44919b8026f38d70437a8eb3be47b06ab1c3e4bf # jusst to verify installation
Usage: ethereum_dasm.py [options]
example: ethereum_dasm.py [-L -F -v] <file_or_bytecode>
ethereum_dasm.py [-L -F -v] # read from stdin
ethereum_dasm.py [-L -F -a <address>] # fetch contract code from infura.io
Options:
-h, --help show this help message and exit
-v VERBOSITY, --verbosity=VERBOSITY
available loglevels:
critical,fatal,error,warning,warn,info,debug,notset
[default: critical]
-L, --listing disables table mode, outputs assembly only
-F, --no-online-lookup
disable online function signature lookup
-a ADDRESS, --address=ADDRESS
fetch contract bytecode from address
-C, --no-color disable color mode (requires pip install colorama)
-A, --guess-abi guess the ABI for that contract
-D, --no-dynamic-analysis
disable dynamic analysis / symolic execution
-S, --no-static-analysis
disable static analysis
-s, --simplify simplify disassembly to human readable code
-x, --simplify-show-asm
simplify: show or hide asm annotations in simplified
code
-y, --simplify-show-unreachable
simplify: show or hide annotations for unreachable
instructions in simplified code
-n NETWORK, --network=NETWORK
network for address lookup (default: mainnet, ropsten,
rinkeby, kovan
#> echo "0x12345678" | python3 -m ethereum_dasm
#> python3 -m ethereum_dasm 0x12345678
#> python3 -m ethereum_dasm ether_contract.evm
#> python3 -m ethereum_dasm -a <contract address>
#> python3 -m ethereum_dasm -a <contract address> -A
#> python3 -m ethereum_dasm -a <contract address> --simplify [--simplify-show-asm, --simplify-show-unreachable]
abi online lookup or reconstruction #>python3 -m ethereum_dasm -a 0x44919b8026f38d70437a8eb3be47b06ab1c3e4bf -A
# [....]
[{'stateMutability': 'nonpayable', 'constant': False, 'type': 'function', 'name': 'enter', 'signature': '0x124c32a1', 'outputs': [{'type': 'bool', 'name': ''}], 'inputs': [{'type': 'bytes32', 'name': '_passcode'
}, {'type': 'bytes8', 'name': '_gateKey'}], 'payable': False}, {'stateMutability': 'pure', 'constant': True, 'type': 'function', 'name': 'maxEntrants', 'signature': '0x60643652', 'outputs': [{'type': 'uint8', 'n
ame': ''}], 'inputs': [], 'payable': False}, {'stateMutability': 'view', 'constant': True, 'type': 'function', 'name': 'totalEntrants', 'signature': '0x694463a2', 'outputs': [{'type': 'uint8', 'name': ''}], 'inp
uts': [], 'payable': False}, {'stateMutability': 'nonpayable', 'constant': False, 'type': 'function', 'name': 'assignAll', 'signature': '0x90ae631d', 'outputs': [{'type': 'bool', 'name': ''}], 'inputs': [], 'pay
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
[{'signature': '0x95d89b41', 'outputs': [], 'stateMutability': None, 'name': 'symbol', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 598}, {'signature': '0x095ea7b3', 'outputs':
[], 'stateMutability': None, 'name': 'approve', 'constant': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 328}, {'signature': '0x313ce567', 'outputs': [], 'stateMutab
ility': None, 'name': 'decimals', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 486}, {'signature': '0xdd62ed3e', 'outputs': [], 'stateMutability': None, 'name': 'allowance', 'c
onstant': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 691}, {'signature': '0x66188463', 'outputs': [], 'stateMutability': None, 'name': 'decreaseApproval', 'constant
': None, 'inputs': ['bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 529}, {'signature': '0x23b872dd', 'outputs': [], 'stateMutability': None, 'name': 'transferFrom', 'constant': None, 'i
nputs': ['bytes32', 'bytes32', '<bytes??>'], 'payable': True, 'type': 'function', 'address': 423}, {'signature': '0x2ff2e9dc', 'outputs': [], 'stateMutability': None, 'name': 'INITIAL_SUPPLY', 'constant': None,
'inputs': [], 'payable': True, 'type': 'function', 'address': 465}, {'signature': '0x06fdde03', 'outputs': [], 'stateMutability': None, 'name': 'name', 'constant': None, 'inputs': [], 'payable': True, 'type': 'f
unction', 'address': 190}, {'signature': '0x18160ddd', 'outputs': [], 'stateMutability': None, 'name': 'totalSupply', 'constant': None, 'inputs': [], 'payable': True, 'type': 'function', 'address': 384}, {'signa
ture': '0x70a08231', 'outputs': [], 'stateMutability': None, 'name': 'balanceOf', 'constant': None, 'inputs': ['<bytes??>'], 'payable': True, 'type': 'function', 'address': 565}, {'signature': '0xa9059cbb', 'out
puts': [], 'stateMutability': None, 'name': 'transfer', 'constant': None, 'inputs': [{'type': 'address', 'name': 'arg0'}, {'type': 'uint256', 'name': 'arg1'}], 'payable': True, 'type': 'function', 'address': 619
}, {'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
Inst addr hex gas | mnemonic operand xrefs description retval args
------------------------------------------------------------------------------------------------ ----------- -------------------------------------------------------------------- --------------- --------------------
:loc_0x0
0 [ 0 0x0000 ] 3 | PUSH1 0x60 # Place 1 byte item on stack. item
1 [ 2 0x0002 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
2 [ 4 0x0004 ] 3 | MSTORE # Save word to memory. value, offset
3 [ 5 0x0005 ] 3 | PUSH1 0x04 # Place 1 byte item on stack. item
4 [ 7 0x0007 ] 2 | CALLDATASIZE # Get size of input data in current environment. msg.data.length
5 [ 8 0x0008 ] 3 | LT # Lesser-than comparison flag a, b
6 [ 9 0x0009 ] 3 | PUSH2 0x0048 # Place 2-byte item on stack. item
7 [ 12 0x000c ] 10 | JUMPI @0x48 # Conditionally alter the program counter. evm.pc, condition
8 [ 13 0x000d ] 3 | PUSH4 0xffffffff # Place 4-byte item on stack. item
9 [ 18 0x0012 ] 3 | PUSH1 0xe0 # Place 1 byte item on stack. item
10 [ 20 0x0014 ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
11 [ 22 0x0016 ] 10 | EXP # Exponential operation. result base, exponent
12 [ 23 0x0017 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
13 [ 25 0x0019 ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
14 [ 26 0x001a ] 5 | DIV # Integer division operation. result a, b
15 [ 27 0x001b ] 3 | AND # Bitwise AND operation. result a, b
16 [ 28 0x001c ] 3 | PUSH4 0x124c32a1 --> 'function enter(bytes32,bytes8)' # Place 4-byte item on stack. item
17 [ 33 0x0021 ] 3 | DUP2 # Duplicate 2nd stack item.
18 [ 34 0x0022 ] 3 | EQ # Equality comparison flag a, b
19 [ 35 0x0023 ] 3 | PUSH2 0x004d # Place 2-byte item on stack. item
20 [ 38 0x0026 ] 10 | JUMPI @0x4d # Conditionally alter the program counter. evm.pc, condition
21 [ 39 0x0027 ] 3 | DUP1 # Duplicate 1st stack item.
22 [ 40 0x0028 ] 3 | PUSH4 0x60643652 --> 'function maxEntrants()' # Place 4-byte item on stack. item
23 [ 45 0x002d ] 3 | EQ # Equality comparison flag a, b
24 [ 46 0x002e ] 3 | PUSH2 0x0095 # Place 2-byte item on stack. item
25 [ 49 0x0031 ] 10 | JUMPI @0x95 # Conditionally alter the program counter. evm.pc, condition
26 [ 50 0x0032 ] 3 | DUP1 # Duplicate 1st stack item.
27 [ 51 0x0033 ] 3 | PUSH4 0x694463a2 --> 'function totalEntrants()' # Place 4-byte item on stack. item
28 [ 56 0x0038 ] 3 | EQ # Equality comparison flag a, b
29 [ 57 0x0039 ] 3 | PUSH2 0x00be # Place 2-byte item on stack. item
30 [ 60 0x003c ] 10 | JUMPI @0xbe # Conditionally alter the program counter. evm.pc, condition
31 [ 61 0x003d ] 3 | DUP1 # Duplicate 1st stack item.
32 [ 62 0x003e ] 3 | PUSH4 0x90ae631d --> 'function assignAll()' # Place 4-byte item on stack. item
33 [ 67 0x0043 ] 3 | EQ # Equality comparison flag a, b
34 [ 68 0x0044 ] 3 | PUSH2 0x00d1 # Place 2-byte item on stack. item
35 [ 71 0x0047 ] 10 | JUMPI @0xd1 # Conditionally alter the program counter. evm.pc, condition
:loc_0x48
36 [ 72 0x0048 ] 1 | JUMPDEST JUMPI@0xc # Mark a valid destination for jumps.
37 [ 73 0x0049 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
38 [ 75 0x004b ] 3 | DUP1 # Duplicate 1st stack item.
39 [ 76 0x004c ] 0 | REVERT # throw an error offset, size
:loc_0x4d
/*******************************************************************
function enter(bytes32,bytes8)
payable: False
inputs: (2) ['bytes32', '<bytes??>']
potential signatures: ['enter(bytes32,bytes8)']
*******************************************************************/
40 [ 77 0x004d ] 1 | JUMPDEST JUMPI@0x26 # Mark a valid destination for jumps.
41 [ 78 0x004e ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
this execution.
42 [ 79 0x004f ] 3 | ISZERO # Simple not operator flag a
43 [ 80 0x0050 ] 3 | PUSH2 0x0058 # Place 2-byte item on stack. item
44 [ 83 0x0053 ] 10 | JUMPI @0x58 # Conditionally alter the program counter. evm.pc, condition
45 [ 84 0x0054 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
46 [ 86 0x0056 ] 3 | DUP1 # Duplicate 1st stack item.
47 [ 87 0x0057 ] 0 | REVERT # throw an error offset, size
:loc_0x58
48 [ 88 0x0058 ] 1 | JUMPDEST JUMPI@0x53 # Mark a valid destination for jumps.
49 [ 89 0x0059 ] 3 | PUSH2 0x0081 # Place 2-byte item on stack. item
50 [ 92 0x005c ] 3 | PUSH1 0x04 # Place 1 byte item on stack. item
51 [ 94 0x005e ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
52 [ 95 0x005f ] 3 | PUSH24 0xffffffffffffffffffffffffffffffffffffffffffffffff # Place 24-byte item on stack. item
53 [ 120 0x0078 ] 3 | NOT # Bitwise NOT operation. result a, b
54 [ 121 0x0079 ] 3 | PUSH1 0x24 # Place 1 byte item on stack. item
55 [ 123 0x007b ] 3 | CALLDATALOAD # Get input data of current environment. msg.data unknown
56 [ 124 0x007c ] 3 | AND # Bitwise AND operation. result a, b
57 [ 125 0x007d ] 3 | PUSH2 0x00e4 # Place 2-byte item on stack. item
58 [ 128 0x0080 ] 8 | JUMP @0xe4 # Alter the program counter. evm.pc
:loc_0x81
59 [ 129 0x0081 ] 1 | JUMPDEST # Mark a valid destination for jumps.
60 [ 130 0x0082 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
61 [ 132 0x0084 ] 3 | MLOAD # Load word from memory. offset
62 [ 133 0x0085 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
63 [ 134 0x0086 ] 3 | ISZERO # Simple not operator flag a
64 [ 135 0x0087 ] 3 | ISZERO # Simple not operator flag a
65 [ 136 0x0088 ] 3 | DUP2 # Duplicate 2nd stack item.
66 [ 137 0x0089 ] 3 | MSTORE # Save word to memory. value, offset
67 [ 138 0x008a ] 3 | PUSH1 0x20 # Place 1 byte item on stack. item
68 [ 140 0x008c ] 3 | ADD # Addition operation. result a, b
69 [ 141 0x008d ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
70 [ 143 0x008f ] 3 | MLOAD # Load word from memory. offset
71 [ 144 0x0090 ] 3 | DUP1 # Duplicate 1st stack item.
72 [ 145 0x0091 ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
73 [ 146 0x0092 ] 3 | SUB # Subtraction operation. result a, b
74 [ 147 0x0093 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
75 [ 148 0x0094 ] 0 | RETURN # Halt execution returning output data. offset, size
:loc_0x95
/*******************************************************************
function maxEntrants()
payable: False
inputs: (0) []
potential signatures: ['maxEntrants()']
*******************************************************************/
76 [ 149 0x0095 ] 1 | JUMPDEST JUMPI@0x31 # Mark a valid destination for jumps.
77 [ 150 0x0096 ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
this execution.
78 [ 151 0x0097 ] 3 | ISZERO # Simple not operator flag a
79 [ 152 0x0098 ] 3 | PUSH2 0x00a0 # Place 2-byte item on stack. item
80 [ 155 0x009b ] 10 | JUMPI @0xa0 # Conditionally alter the program counter. evm.pc, condition
81 [ 156 0x009c ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
82 [ 158 0x009e ] 3 | DUP1 # Duplicate 1st stack item.
83 [ 159 0x009f ] 0 | REVERT # throw an error offset, size
:loc_0xa0
84 [ 160 0x00a0 ] 1 | JUMPDEST JUMPI@0x9b # Mark a valid destination for jumps.
85 [ 161 0x00a1 ] 3 | PUSH2 0x00a8 # Place 2-byte item on stack. item
86 [ 164 0x00a4 ] 3 | PUSH2 0x0314 # Place 2-byte item on stack. item
87 [ 167 0x00a7 ] 8 | JUMP @0x314 # Alter the program counter. evm.pc
:loc_0xa8
88 [ 168 0x00a8 ] 1 | JUMPDEST # Mark a valid destination for jumps.
89 [ 169 0x00a9 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
90 [ 171 0x00ab ] 3 | MLOAD # Load word from memory. offset
91 [ 172 0x00ac ] 3 | PUSH1 0xff # Place 1 byte item on stack. item
92 [ 174 0x00ae ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
93 [ 175 0x00af ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
94 [ 176 0x00b0 ] 3 | AND # Bitwise AND operation. result a, b
95 [ 177 0x00b1 ] 3 | DUP2 # Duplicate 2nd stack item.
96 [ 178 0x00b2 ] 3 | MSTORE # Save word to memory. value, offset
97 [ 179 0x00b3 ] 3 | PUSH1 0x20 # Place 1 byte item on stack. item
98 [ 181 0x00b5 ] 3 | ADD # Addition operation. result a, b
99 [ 182 0x00b6 ] 3 | PUSH1 0x40 # Place 1 byte item on stack. item
100 [ 184 0x00b8 ] 3 | MLOAD # Load word from memory. offset
101 [ 185 0x00b9 ] 3 | DUP1 # Duplicate 1st stack item.
102 [ 186 0x00ba ] 3 | SWAP2 # Exchange 1st and 3rd stack items.
103 [ 187 0x00bb ] 3 | SUB # Subtraction operation. result a, b
104 [ 188 0x00bc ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
105 [ 189 0x00bd ] 0 | RETURN # Halt execution returning output data. offset, size
:loc_0xbe
/*******************************************************************
function totalEntrants()
payable: False
inputs: (0) []
potential signatures: ['totalEntrants()']
*******************************************************************/
106 [ 190 0x00be ] 1 | JUMPDEST JUMPI@0x3c # Mark a valid destination for jumps.
107 [ 191 0x00bf ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
this execution.
108 [ 192 0x00c0 ] 3 | ISZERO # Simple not operator flag a
109 [ 193 0x00c1 ] 3 | PUSH2 0x00c9 # Place 2-byte item on stack. item
110 [ 196 0x00c4 ] 10 | JUMPI @0xc9 # Conditionally alter the program counter. evm.pc, condition
111 [ 197 0x00c5 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
112 [ 199 0x00c7 ] 3 | DUP1 # Duplicate 1st stack item.
113 [ 200 0x00c8 ] 0 | REVERT # throw an error offset, size
:loc_0xc9
114 [ 201 0x00c9 ] 1 | JUMPDEST JUMPI@0xc4 # Mark a valid destination for jumps.
115 [ 202 0x00ca ] 3 | PUSH2 0x00a8 # Place 2-byte item on stack. item
116 [ 205 0x00cd ] 3 | PUSH2 0x031a # Place 2-byte item on stack. item
117 [ 208 0x00d0 ] 8 | JUMP @0x31a # Alter the program counter. evm.pc
:loc_0xd1
/*******************************************************************
function assignAll()
payable: False
inputs: (0) []
potential signatures: ['assignAll()']
*******************************************************************/
118 [ 209 0x00d1 ] 1 | JUMPDEST JUMPI@0x47 # Mark a valid destination for jumps.
119 [ 210 0x00d2 ] 2 | CALLVALUE # Get deposited value by the instruction/transaction responsible for msg.value
this execution.
120 [ 211 0x00d3 ] 3 | ISZERO # Simple not operator flag a
121 [ 212 0x00d4 ] 3 | PUSH2 0x00dc # Place 2-byte item on stack. item
122 [ 215 0x00d7 ] 10 | JUMPI @0xdc # Conditionally alter the program counter. evm.pc, condition
123 [ 216 0x00d8 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
124 [ 218 0x00da ] 3 | DUP1 # Duplicate 1st stack item.
125 [ 219 0x00db ] 0 | REVERT # throw an error offset, size
:loc_0xdc
126 [ 220 0x00dc ] 1 | JUMPDEST JUMPI@0xd7 # Mark a valid destination for jumps.
127 [ 221 0x00dd ] 3 | PUSH2 0x0081 # Place 2-byte item on stack. item
128 [ 224 0x00e0 ] 3 | PUSH2 0x0320 # Place 2-byte item on stack. item
129 [ 227 0x00e3 ] 8 | JUMP @0x320 # Alter the program counter. evm.pc
:loc_0xe4
130 [ 228 0x00e4 ] 1 | JUMPDEST JUMP@0x80 # Mark a valid destination for jumps.
131 [ 229 0x00e5 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
132 [ 231 0x00e7 ] 2 | ORIGIN # Get execution origination address. tx.origin
133 [ 232 0x00e8 ] 3 | PUSH1 0x01 # Place 1 byte item on stack. item
134 [ 234 0x00ea ] 3 | PUSH1 0xa0 # Place 1 byte item on stack. item
135 [ 236 0x00ec ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
136 [ 238 0x00ee ] 10 | EXP # Exponential operation. result base, exponent
137 [ 239 0x00ef ] 3 | SUB # Subtraction operation. result a, b
138 [ 240 0x00f0 ] 3 | AND # Bitwise AND operation. result a, b
139 [ 241 0x00f1 ] 2 | CALLER # Get caller address.This is the address of the account that is msg.sender
directly responsible for this execution.
140 [ 242 0x00f2 ] 3 | PUSH1 0x01 # Place 1 byte item on stack. item
141 [ 244 0x00f4 ] 3 | PUSH1 0xa0 # Place 1 byte item on stack. item
142 [ 246 0x00f6 ] 3 | PUSH1 0x02 # Place 1 byte item on stack. item
143 [ 248 0x00f8 ] 10 | EXP # Exponential operation. result base, exponent
144 [ 249 0x00f9 ] 3 | SUB # Subtraction operation. result a, b
145 [ 250 0x00fa ] 3 | AND # Bitwise AND operation. result a, b
146 [ 251 0x00fb ] 3 | EQ # Equality comparison flag a, b
147 [ 252 0x00fc ] 3 | ISZERO # Simple not operator flag a
148 [ 253 0x00fd ] 3 | ISZERO # Simple not operator flag a
149 [ 254 0x00fe ] 3 | ISZERO # Simple not operator flag a
150 [ 255 0x00ff ] 3 | PUSH2 0x0107 # Place 2-byte item on stack. item
151 [ 258 0x0102 ] 10 | JUMPI @0x107 # Conditionally alter the program counter. evm.pc, condition
152 [ 259 0x0103 ] 3 | PUSH1 0x00 # Place 1 byte item on stack. item
153 [ 261 0x0105 ] 3 | DUP1 # Duplicate 1st stack item.
154 [ 262 0x0106 ] 0 | REVERT # throw an error offset, size
[...]
:loc_0x5d5
954 [1493 0x05d5 ] 1 | JUMPDEST JUMPI@0x5c9 # Mark a valid destination for jumps.
955 [1494 0x05d6 ] 2 | POP # Remove item from stack. #dummy
956 [1495 0x05d7 ] 3 | SWAP1 # Exchange 1st and 2nd stack items.
957 [1496 0x05d8 ] 8 | JUMP # Alter the program counter. evm.pc
958 [1497 0x05d9 ] 0 | STOP # Halts execution.
959 [1498 0x05da ] 750 | LOG1 0x65 # Append log record with one topic. start, size, topic1
960 [1500 0x05dc ] 3 | PUSH3 0x7a7a72 # Place 3-byte item on stack. item
961 [1504 0x05e0 ] 2 | ADDRESS # Get address of currently executing account. this.address
962 [1505 0x05e1 ] 2 | PC # Get the value of the program counter prior to the increment. evm.pc
963 [1506 0x05e2 ] 30 | SHA3 # Compute Keccak-256 hash. flag offset, size
964 [1507 0x05e3 ] -1 | UNKNOWN_0xf # Invalid opcode
965 [1508 0x05e4 ] 3 | SWAP4 # Exchange 1st and 5th stack items.
966 [1509 0x05e5 ] 3 | SWAP14 # Exchange 1st and 15th stack items.
967 [1510 0x05e6 ] 2 | CALLDATASIZE # Get size of input data in current environment. msg.data.length
968 [1511 0x05e7 ] -1 | UNKNOWN_0xe1 # Invalid opcode
969 [1512 0x05e8 ] -1 | UNKNOWN_0xcb # Invalid opcode
970 [1513 0x05e9 ] 3 | PUSH22 0xc68ec825da862dc7082ea12aea89eb3783b2e0423cd2 # Place 22-byte item on stack. item
971 [1536 0x0600 ] 30 | SHA3 # Compute Keccak-256 hash. flag offset, size
972 [1537 0x0601 ] -1 | UNKNOWN_0x28 # Invalid opcode
973 [1538 0x0602 ] 3 | PUSH16 0x0029 # Place 16-byte item on stack. item
==============================
reconstructed ABI:
[{'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]
======================[simplified]
:init
memory[0x40] = 0x60
if (Not(ULE(0x4, 1_calldatasize))) goto LOC_0x48
if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0xa1,
If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x32,
If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x4c,
If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x12)) goto function_enter (LOC_0x4d)
if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0x52,
If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x36,
If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x64,
If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x60)) goto function_maxEntrants (LOC_0x95)
if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0xa2,
If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x63,
If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0x44,
If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x69)) goto function_totalEntrants (LOC_0xbe)
if (And(If(1_calldatasize <= 0x3, 0x0, 1_calldata[0x3]) == 0x1d,
If(1_calldatasize <= 0x2, 0x0, 1_calldata[0x2]) == 0x63,
If(1_calldatasize <= 0x1, 0x0, 1_calldata[0x1]) == 0xae,
If(1_calldatasize <= 0x0, 0x0, 1_calldata[0x0]) == 0x90)) goto function_assignAll (LOC_0xd1)
:LOC_0x48
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:function_enter (LOC_0x4d)
/*******************************************************************
function enter(bytes32,bytes8)
payable: False
inputs: (2) ['bytes32', '<bytes??>']
potential signatures: ['enter(bytes32,bytes8)']
*******************************************************************/
if (call_value1 == 0x0) goto LOC_0x58
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x58
goto LOC_0xe4
:LOC_0x81
:function_maxEntrants (LOC_0x95)
/*******************************************************************
function maxEntrants()
payable: False
inputs: (0) []
potential signatures: ['maxEntrants()']
*******************************************************************/
if (call_value1 == 0x0) goto LOC_0xa0
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0xa0
goto LOC_0x314
:LOC_0xa8
memory[0x60] = 0xfa
RETURN(offset=0x60, size=0x20)
/******* <<terminates execution>> *******/
:function_totalEntrants (LOC_0xbe)
/*******************************************************************
function totalEntrants()
payable: False
inputs: (0) []
potential signatures: ['totalEntrants()']
*******************************************************************/
if (call_value1 == 0x0) goto LOC_0xc9
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0xc9
goto LOC_0x31a
:function_assignAll (LOC_0xd1)
/*******************************************************************
function assignAll()
payable: False
inputs: (0) []
potential signatures: ['assignAll()']
*******************************************************************/
if (call_value1 == 0x0) goto LOC_0xdc
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0xdc
goto LOC_0x320
:LOC_0xe4
if (Not(Extract(159, 0, origin1) ==
0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef)) goto LOC_0x107
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x107
if (True) goto LOC_0x114
:LOC_0x114
if (bvurem_i(1_gas, 0x1fff) == 0x0) goto LOC_0x11f
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x11f
if (And(If(1_calldatasize <= 0x29, 0x0, 1_calldata[0x29]) == 0x0,
If(1_calldatasize <= 0x28, 0x0, 1_calldata[0x28]) == 0x0)) goto LOC_0x154
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x154
if (Not(And(If(1_calldatasize <= 0x27, 0x0, 1_calldata[0x27]) ==
0x0,
If(1_calldatasize <= 0x26, 0x0, 1_calldata[0x26]) ==
0x0,
If(1_calldatasize <= 0x25, 0x0, 1_calldata[0x25]) ==
0x0,
If(1_calldatasize <= 0x24, 0x0, 1_calldata[0x24]) ==
0x0))) goto LOC_0x18f
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x18f
if (And(Extract(7, 0, origin1) ==
If(1_calldatasize <= 0x2b, 0x0, 1_calldata[0x2b]),
Extract(15, 8, origin1) ==
If(1_calldatasize <= 0x2a, 0x0, 1_calldata[0x2a]),
If(1_calldatasize <= 0x29, 0x0, 1_calldata[0x29]) == 0x0,
If(1_calldatasize <= 0x28, 0x0, 1_calldata[0x28]) == 0x0)) goto LOC_0x1c0
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x1c0
if (True) goto LOC_0x1d1
:LOC_0x1d1
memory[0x0] = 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef
memory[0x20] = 0x3
if (True) goto LOC_0x1f7
:LOC_0x1f7
memory[0x0] = Concat(0x0, Extract(159, 0, origin1))
memory[0x20] = 0x3
if (True) goto LOC_0x21d
:LOC_0x21d
memory[0x60] = Concat(If(1_calldatasize <= 0x4, 0x0, 1_calldata[0x4]),
If(1_calldatasize <= 0x5, 0x0, 1_calldata[0x5]),
If(1_calldatasize <= 0x6, 0x0, 1_calldata[0x6]),
If(1_calldatasize <= 0x7, 0x0, 1_calldata[0x7]),
If(1_calldatasize <= 0x8, 0x0, 1_calldata[0x8]),
If(1_calldatasize <= 0x9, 0x0, 1_calldata[0x9]),
If(1_calldatasize <= 0xa, 0x0, 1_calldata[0xa]),
If(1_calldatasize <= 0xb, 0x0, 1_calldata[0xb]),
If(1_calldatasize <= 0xc, 0x0, 1_calldata[0xc]),
If(1_calldatasize <= 0xd, 0x0, 1_calldata[0xd]),
If(1_calldatasize <= 0xe, 0x0, 1_calldata[0xe]),
If(1_calldatasize <= 0xf, 0x0, 1_calldata[0xf]),
If(1_calldatasize <= 0x10, 0x0, 1_calldata[0x10]),
If(1_calldatasize <= 0x11, 0x0, 1_calldata[0x11]),
If(1_calldatasize <= 0x12, 0x0, 1_calldata[0x12]),
If(1_calldatasize <= 0x13, 0x0, 1_calldata[0x13]),
If(1_calldatasize <= 0x14, 0x0, 1_calldata[0x14]),
If(1_calldatasize <= 0x15, 0x0, 1_calldata[0x15]),
If(1_calldatasize <= 0x16, 0x0, 1_calldata[0x16]),
If(1_calldatasize <= 0x17, 0x0, 1_calldata[0x17]),
If(1_calldatasize <= 0x18, 0x0, 1_calldata[0x18]),
If(1_calldatasize <= 0x19, 0x0, 1_calldata[0x19]),
If(1_calldatasize <= 0x1a, 0x0, 1_calldata[0x1a]),
If(1_calldatasize <= 0x1b, 0x0, 1_calldata[0x1b]),
If(1_calldatasize <= 0x1c, 0x0, 1_calldata[0x1c]),
If(1_calldatasize <= 0x1d, 0x0, 1_calldata[0x1d]),
If(1_calldatasize <= 0x1e, 0x0, 1_calldata[0x1e]),
If(1_calldatasize <= 0x1f, 0x0, 1_calldata[0x1f]),
If(1_calldatasize <= 0x20, 0x0, 1_calldata[0x20]),
If(1_calldatasize <= 0x21, 0x0, 1_calldata[0x21]),
If(1_calldatasize <= 0x22, 0x0, 1_calldata[0x22]),
If(1_calldatasize <= 0x23, 0x0, 1_calldata[0x23]))
memory[0x0] = KECCAC[If(1_calldatasize_<=_0x4,_0x0,_1_calldata[0x4])]
memory[0x20] = 0x4
if (False) goto LOC_0x257
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x257
:LOC_0x275
:LOC_0x2d6
:LOC_0x314
:LOC_0x317
goto LOC_0xa8
:LOC_0x31a
goto LOC_0xa8
:LOC_0x320
if (False) goto LOC_0x338
REVERT(offset=0x0, size=0x0)
/******* <<terminates execution>> *******/
:LOC_0x338
:LOC_0x347
:LOC_0x3a8
:LOC_0x3b9
:LOC_0x3d8
:LOC_0x3e0
:LOC_0x3f5
:LOC_0x459
:LOC_0x46a
:LOC_0x4de
:LOC_0x541
:LOC_0x552
:LOC_0x556
:LOC_0x55e
:LOC_0x588
:LOC_0x592
:LOC_0x5b6
:LOC_0x5bb
:LOC_0x5c1
:LOC_0x5d5
Download details:
Author: tintinweb
Source code: https://github.com/tintinweb/ethereum-dasm
License: GPL-2.0 license
#solidity #smartcontract #blockchain #ethereum
1596134640
Do you like GitLab and don’t like bugs? Do you want to improve the quality of your source code? Then you’ve come to the right place. Today we will tell you how to configure the PVS-Studio C# analyzer for checking merge requests. Enjoy the reading and have a nice unicorn mood.
PVS-Studio is a tool designed to detect errors and potential vulnerabilities in the source code of programs, written in C, C++, C#, and Java. Works in 64-bit systems on Windows, Linux, and macOS. Can analyze the code meant for 32-bit, 64-bit, and embedded ARM platforms.
By the way, we’ve released PVS-Studio 7.08, which was full of new sapid features. For example:
Previously, to check certain files, one had to pass .xml to the analyzer with a list of files. But since this is not very convenient, we have added the ability to pass .txt, which makes life much simpler.
To check certain files, specify the –sourceFiles (-f) flag and pass .txt with the list of files. It looks like this:
C#
1
pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.json
If you are interested in configuring checks of commits or pull requests, you can also do this using this mode. The difference will be in getting a list of files for analysis and will depend on which systems you are using.
The main point of checking is to make sure that problems detected by the analyzer do not make it into the master branch when merging. We also don’t want to analyze the entire project every time. Moreover, when merging branches, we have a list of changed files. Therefore, I suggest adding a merge request check.
This is how a merge request looks like before introducing a static analyzer:
In other words, all errors in the changes branch will get to the master branch. Since we wouldn’t like this, we add the analysis, and now the scheme looks as follows:
We analyze changes2 and, if there are no errors, we accept the merge request, otherwise reject it.
By the way, if you are interested in analyzing commits and pull requests for C/C++, you are welcome to read about it here.
GitLab is an open-source DevOps lifecycle web tool that provides a code repository management system for Git with its wiki, bug tracking system, CI/CD pipeline, and other features.
Before you start implementing the merge request analysis, you need to register and upload your project. If you do not know how to do this, then I suggest an article by my colleague.
Note. One of the possible ways to configure the environment is described below. The point is to show the steps for configuring the environment needed for analyzing and running the analyzer. In your case, it may be better to separate the stages of environment preparation (adding repositories, installing the analyzer), and analysis. For example, preparing Docker instances with the necessary environment and their usage, or some other method.
To get a better understanding of what is going to happen next, I suggest taking a look at the following scheme:
The analyzer needs .NET Core SDK 3 for proper operation from which the necessary dependencies for the analyzer will be installed. Adding Microsoft repositories for various Linux distributions is described in the relevant document.
To install PVS-Studio via the package manager, you will also need to add PVS-Studio repositories. Adding repositories for various distributions is described in more detail in the relevant section of the documentation.
The analyzer needs a license key to operate. You can get a trial license on the analyzer download page.
Note. Please note that the described operating mode (merge requests analysis) requires an Enterprise license. Therefore, if you would like to try this mode of operation, don’t forget to specify that you need an Enterprise license in the “Message” field.
If a merge request occurs, we only need to analyze the list of changed files, otherwise, we analyze all files. After the analysis, we need to convert the logs to the format we need.
Now, with the algorithm in front of your eyes, you can proceed to writing the script. To do this, we need to change the .gitlab-ci.yml file or, if there is no such file, create one. To create it, click on the name of your project -> Set up CI/CD.
Now we are ready to write the script. Let’s first write the code that will install the analyzer and enter the license:
C#
1
before_script:
2
- apt-get update && apt-get -y install wget gnupg
3
4
- apt-get -y install git
5
- wget https://packages.microsoft.com/config/debian/10/
6
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
7
- dpkg -i packages-microsoft-prod.deb
8
- apt-get update
9
- apt-get install apt-transport-https
10
- apt-get update
11
12
- wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
13
- wget -O /etc/apt/sources.list.d/viva64.list
14
https://files.viva64.com/etc/viva64.list
15
- apt-get update
16
- apt-get -y install pvs-studio-dotnet
17
18
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
19
- dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln
Since installation and activation must occur before all other scripts, we use a special before_script label. Let me be clear on this fragment.
Preparation for the analyzer installation:
C#
1
- wget https://packages.microsoft.com/config/debian/10/
2
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
3
- dpkg -i packages-microsoft-prod.deb
4
- apt-get update
5
- apt-get install apt-transport-https
6
- apt-get update
Adding PVS-Studio repositories and the analyzer:
C#
1
- wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
2
- wget -O /etc/apt/sources.list.d/viva64.list
3
https://files.viva64.com/etc/viva64.list
4
- apt-get update
5
- apt-get -y install pvs-studio-dotnet
#devops #devsecops #csharp #static analysis #gitlab #static analysis tools #static analyzer
1625482158
#Heat Map Visualization in Dynamics 365 CRM
Maplytics integrates Dynamic 365 CRM with Bing Maps opening up vast opportunity for the Dynamics CRM users, peers and Partners to analyze graphic data using Heat Map. Heat Map brings forth comparative study of records by studying their density over a region. You can also visualize Heat map within Dynamics 365 CRM in context to boundary, no-boundary, Pie-chart and Column-chart.
#heat maps in dynamics 365 #heat map dynamics crm #sales heat map dynamics 365 #heatmap analytics dynamics 365 #map dynamics 365 data analysis