Skip to content

Instantly share code, notes, and snippets.

@Thegaram
Last active August 19, 2020 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Thegaram/13534d482816a051c0d581eaee4ac4a2 to your computer and use it in GitHub Desktop.
Save Thegaram/13534d482816a051c0d581eaee4ac4a2 to your computer and use it in GitHub Desktop.
evm-tracing-0.1
build
$ cargo build --release --features final
run a dev node
$ ../target/release/openethereum --chain dev --jsonrpc-cors="*"
deploy contract
```sol
contract Storage {
uint256 public number;
mapping(address => uint256) public people;
...
}
```
----------------------------------------------------------
0. deploy contract
----------------------------------------------------------
```sol
constructor() public {
// EMPTY
}
```
<evm-trace> block #24, tx 0x35e34030bd167344a1153af9b9eac3c53e0bf9f50b60e3dba8dd89c920064d2d, accesses = {Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Create }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Create }}
explanation:
distribute tx fee to miner:
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read },
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update },
charge sender with tx fee:
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read },
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update },
deploy account and code:
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read },
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read },
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Create },
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Create }}
notes:
contract address is 0x83d85eeb38a2dc37eac0239c19b343a7653d8f79
code hash is 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064
it seems storage values or not pre-initialized
----------------------------------------------------------
1. read account balance
----------------------------------------------------------
```sol
function read() public returns (uint256 result) {
result = address(this).balance;
}
```
<evm-trace> block #25, tx 0xc56164a16b664b4cad1bd4e176c77b3e95513597a40b5c48450d15bb8075cc85, accesses = {Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }}
explanation:
distribute tx fee to miner:
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read },
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update },
charge sender with tx fee:
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read },
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update },
read contract code:
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read },
execute read():
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read },
----------------------------------------------------------
2. update account balance
----------------------------------------------------------
```sol
function update() public payable {
// EMPTY
}
```
<evm-trace> block #26, tx 0x7695d4c1b253678f70d1ac7f010d66b223756914643ea27eda54197f2f6685b7, accesses = {Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }}
explanation:
distribute tx fee to miner:
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read },
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update },
charge sender with tx fee:
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read },
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update },
read contract code:
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read },
execute update():
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read },
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update },
----------------------------------------------------------
3. update simple storage (uint256)
----------------------------------------------------------
```
function storage_1() public {
number = number + 1;
}
```
<evm-trace> block #31, tx 0x668aba887b436d2274c980d34e509fb92baa914fd9fcd4d18052276ed07ea115, accesses = {Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Update }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }}
explanation:
distribute tx fee to miner:
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read },
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update },
charge sender with tx fee:
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read },
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update },
read contract code:
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read },
execute storage_1():
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read },
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read },
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Update },
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }}
notes:
storage update corresponds to the `number = number + 1` assignment
account update corresponds to updating the storage root
----------------------------------------------------------
4. insert item into mapping
----------------------------------------------------------
```sol
function storage_2() public {
if (number % 2 == 1) {
people[msg.sender] = number; // --> this branch
}
else {
delete people[msg.sender];
}
}
```
<evm-trace> block #32, tx 0x3027cde50a595a984fa1572240abee7d8b62a79c715bbbe8147d854a613bc87f, accesses = {Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Create }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }}
explanation:
distribute tx fee to miner:
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read },
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update },
charge sender with tx fee:
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read },
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update },
read contract code:
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read },
execute storage_2():
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read },
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read },
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Read },
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Create },
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update },
notes:
first storage read corresponds to getting the value of `number`
----------------------------------------------------------
5. delete item from mapping
----------------------------------------------------------
```sol
function storage_2() public {
if (number % 2 == 1) {
people[msg.sender] = number;
}
else {
delete people[msg.sender]; // --> this branch
}
}
```
<evm-trace> block #34, tx 0xdd8f1e17a117924bf5cfd3159658814a78f78f4cbf37d9786467759e80ad6f76, accesses = {Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Delete }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }}
explanation:
distribute tx fee to miner:
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read },
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update },
charge sender with tx fee:
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read },
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update },
read contract code:
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read },
execute storage_2():
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }}
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x0000000000000000000000000000000000000000000000000000000000000000), mode: Read },
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Read },
Access { target: Storage(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0xec9c44aa227f46a89f0130caab01b432ec238b14fbffb236110797e3a4539bdb), mode: Delete },
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Update },
----------------------------------------------------------
6. destroy contract
----------------------------------------------------------
```sol
function destroy() public {
selfdestruct(msg.sender);
}
```
<evm-trace> block #35, tx 0xa38b9849a5031ad1c662c938752fe1a6cc1d4e269106994f55935a2a48a73156, accesses = {Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update }, Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update }, Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read }, Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read }, Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Delete }}
explanation:
distribute tx fee to miner:
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Read },
Access { target: Account(0x0000000000000000000000000000000000000000), mode: Update },
charge sender with tx fee:
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Read },
Access { target: Account(0x00a329c0648769a73afac7f9381e08fb43dbea72), mode: Update },
read contract code:
Access { target: Code(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79, 0x44bf2c5182fe5ab3abc1a573d497ca191168e67dd28d7c94dc379726cde64064), mode: Read },
execute destroy():
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Read },
Access { target: Account(0x83d85eeb38a2dc37eac0239c19b343a7653d8f79), mode: Delete }}
notes:
code is not destroyed
----------------------------------------------------------
7. real chain data
----------------------------------------------------------
https://etherscan.io/block/651688
<evm-trace> Start execution of block #651688
<evm-trace> block #651688, tx 0x0874843e04e93341dd5433c34abd9e2b098096e92da0bc733585888eaf325c24, accesses = {Access { target: Account(0xd8bd2c0f1ff677215f8b235db85bd5e7f3fbd59d), mode: Read }, Access { target: Account(0xd8bd2c0f1ff677215f8b235db85bd5e7f3fbd59d), mode: Update }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Read }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Update }, Access { target: Account(0x9d551f41fed6fc27b719777c224dfecce170004d), mode: Read }, Access { target: Code(0xd8bd2c0f1ff677215f8b235db85bd5e7f3fbd59d, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }, Access { target: Account(0x9d551f41fed6fc27b719777c224dfecce170004d), mode: Update }}
<evm-trace> block #651688, tx 0x3458fa8882378c6c0dbc5be2df0d27cb24f93b1a41eb6217a7ebeeeed06e6e42, accesses = {Access { target: Code(0xf9b3fc6160a6629840ed33f08e25b8ed8f70e8c6, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Read }, Access { target: Account(0xf9b3fc6160a6629840ed33f08e25b8ed8f70e8c6), mode: Read }, Access { target: Account(0xf9b3fc6160a6629840ed33f08e25b8ed8f70e8c6), mode: Update }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Update }}
<evm-trace> block #651688, tx 0xa245f8b562ee670bfdd5b5b30658b5b1a64f02cf3c22ee41dcec075c544c05dd, accesses = {Access { target: Account(0xa6191639b137cd47600a5242391a592f28a2c5a6), mode: Read }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Read }, Access { target: Account(0xa6191639b137cd47600a5242391a592f28a2c5a6), mode: Update }, Access { target: Account(0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5), mode: Update }, Access { target: Code(0xa6191639b137cd47600a5242391a592f28a2c5a6, 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), mode: Read }}
<evm-trace> Finish execution of block #651688. hash = 0x2165d7a4b98e44814a16bd7ed03812b1e9585dc8170a4fd74c4d87eb375ab8db
----------------------------------------------------------
----------------------------------------------------------
we need to define our granularity and/or execution model/
for example, if our "parallel evm" updates account.storage_root whenever a transaction commits,
then transactions operating on the same storage will conflict, even if they access different entries/
if, on the other hand, we collect commits in memory and update storage root once we've executed all block txs,
then these will not conflict.
```sol
function set(uint256 key) public {
my_mapping[key] += 1;
}
```
tx#0 calls `set(0)`, tx#1 calls `set(1)`
----------------------------------------------------------
----------------------------------------------------------
opcode-level tracing
Parity seems to have some built-in mechanisms for this
this might be a safer approach as this does not need to care about caches
need to know what low-level storage access patterns opcodes translate to
also reverts might be hard to handle
state-level tracing
current approach
storage-level tracing
trace all db get/set ops
does not really work unless we disable all higher-level caching
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment