In the Byzantium Revision of the Yellow Paper, Appendix K:

anomalies on main network

Here is equation 195:

equation 195, precompiled

Here is the transaction, It was made during efforts to de-bloat the state post EIP-150. It appears that the txn was a call to a contract which called to the RIPEMD precompile (at address 0x03), with 0 gas, 0 value, and 0x0 for data:

"action": {
  "callType": "call",
  "from": "0x0e879ae28cdddeb31a405a9db354505a5560b0bd",
  "gas": "0x0",
  "input": "0x",
  "to": "0x0000000000000000000000000000000000000003",
  "value": "0x0"

^ taken from the parity trace

My rough understanding of what happened: the precompile was added to the list of 'touched addresses', and then it was removed from the state because it had no balance and no code. Then the transaction ran out of gas, but it seems the contract wasn't restored to the state. (Please correct any errors).

I'm very curious about what happened here! A few specific questions:

  1. What does it mean to 'delete' account 0x03? (Presumably the precompile was still available after being deleted, since it's hard coded into the client).
  2. How was there not a consensus failure? Did all clients correctly implement the exact same bug?
  3. The same transaction also called to the precompiles at the addresses 0x01, 0x02, and 0x04. Why were they not affected?

1 Answer 1

  1. EIP-161 makes a distinction between empty accounts and non-existent accounts.

An account is considered empty when it has no code and zero nonce and zero balance.

An account is considered dead when either it is non-existent or it is empty.

Precompile accounts are supposed to be empty (their code is not on-chain), but the state clearing of 0x03 apparently made it non-existent (not part of state).

  1. This is puzzling. There were consensus failures associated with the state-clearing at the time (see note at the bottom of EIP-161), but that was after this transaction. I can only assume all the clients implemented the same behaviour with respect to the precompiles and OOG (at least in this instance).

  2. This one's easy :-) All of 0x01, 0x02, and 0x04 had balances due to pre-existing incoming Txs. 0x03 had no previous incoming balance, and obviously no outgoing Txs, so it met the criteria for a dust account, i.e. empty. Note that at block 2687391 1 Wei was transferred in presumably to prevent this happening again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.