This proposal introduces a new opcode that allows contracts to inspect the transaction outcomes on-chain. This opcode will allow contract deveolopres to define assertions for state changes that can be enforced on-chain. These can protect Ethereum users by restricting the behavior of the smart contracts they are interacting with.
The total value of crypto assets that have been stolen to date exceeds the yearly GDP of a medium-sized nation. This level of loss and waste is indefensible and has a long list of negative consequences for everyone around the world.
The ability of an average user or a Wallet application to find, collect, review, and analyze the EVM code the transaction will execute is very limited.
This leaves the users with no mechanism to enforce any restrictions on what the transaction actually does once it is signed. This leads users to perform de-facto blind signing every time they interact with Ethereum, exposing themselves to significant risks.
By providing the Wallets and dApps with the ability to observe and restrict the possible outcomes of a transaction, we create a tool that users and apply to reduce their risk levels.
| Name | Value |
|---|---|
| TXTRACE_GAS_COST | TBD |
| EVENTDATACOPY_GAS_COST | TBD |
We introduce a new TXTRACE opcode.
It can be used to retrieve the full state diff of the current transaction up to this point.
It accepts a selection parameter similar to the TXPARAM opcode from EIP-8141.
The available parameters are listed in the table below.
param |
in2 |
Return value |
|---|---|---|
| 0x00 | must be 0 | balances_changed - the total number of changed balances |
| 0x01 | must be 0 | slots_changed - the total number of changes storage slots |
| 0x02 | must be 0 | contracts_deployed - the total number of newly deployed contracts |
| 0x03 | index in balances_changed |
change_address - the address of the account with balance change |
| 0x04 | index in balances_changed |
balance_before - the balance of the address before execution |
| 0x05 | index in balances_changed |
balance_after - the balance of the address after execution |
| 0x06 | index in slots_changed |
change_address - the address of the account with storage change |
| 0x07 | index in slots_changed |
slot_value_before - the balance of the slot before execution |
| 0x08 | index in slots_changed |
slot_value_after - the balance of the slot after execution |
| 0x09 | index in contracts_deployed |
deployed_address - the address of the newly deployed contract |
| 0x0A | index in contracts_deployed |
codehash_after - the codehash of the newly deployed contract |
| 0x0B | must be 0 | events_count - the total number of emitted events |
| 0x0C | index in events_count |
events_address - the address of the contract that emitted the event |
| 0x0D | index in events_count |
events_topics - the topics of the event (packed 32-byte values) |
| 0x0E | index in events_count |
events_data - the non-indexed data of the event |
EVENTDATACOPY opcodeThis opcode copies event data into memory. The gas cost matches CALLDATACOPY, i.e. the operation has a fixed cost of 3 and a variable cost that accounts for the memory expansion and copying.
| Stack | Value |
|---|---|
top - 0 |
event_index |
top - 1 |
memOffset |
top - 2 |
dataOffset |
top - 3 |
length |
No stack output value is produced.
The operation semantics match CALLDATACOPY, copying length bytes from the event's non-indexed data, starting at the given byte dataOffset, into a memory region starting at memOffset.
event_index >= events_count, an exceptional halt occurs.dataOffset + length exceeds the event's data length, an exceptional halt occurs.The TXTRACE opcode follows the same (param, index) pattern used by TXPARAM in EIP-8141. This keeps the interface consistent and avoids introducing a separate opcode for every piece of trace information.
EVENTDATACOPY as a Companion OpcodeEvent non-indexed data is variable-length and cannot be returned as a single 32-byte stack word. A memory-copy opcode with the same semantics as CALLDATACOPY is the idiomatic EVM approach for variable-length data access.
TXTRACE and EVENTDATACOPY occupy previously unused opcode slots. No changes are made to existing opcodes, transaction types, or precompiles, so existing contracts and tooling are unaffected.
The main risk is a false sense of security: an assertion contract that checks too little may mislead users into believing a transaction is safe when it is not.
Wallets and dApps that build on TXTRACE must ensure their assertion logic covers all relevant state changes for the protected operation. It is critical that the ecosystem treats incomplete assertions as no better than no assertion at all.
Copyright and related rights waived via CC0.