Skip to content

fix(contracts): swap init_code_hash and code_hash keccak256 inputs#249

Open
AuburyEssentian wants to merge 1 commit into
paradigmxyz:mainfrom
AuburyEssentian:fix/contracts-code-hash-swap
Open

fix(contracts): swap init_code_hash and code_hash keccak256 inputs#249
AuburyEssentian wants to merge 1 commit into
paradigmxyz:mainfrom
AuburyEssentian:fix/contracts-code-hash-swap

Conversation

@AuburyEssentian

Copy link
Copy Markdown

Problem

init_code_hash and code_hash in the contracts dataset are populated with each other's values. The two keccak256 calls on lines 101–102 of contracts.rs reference the wrong inputs:

// Before (incorrect):
store!(schema, columns, init_code_hash, keccak256(result.code.clone()).to_vec());
store!(schema, columns, code_hash,      keccak256(create.init.clone()).to_vec());
  • init_code_hash should hash create.init — the initialization bytecode sent in the CREATE transaction
  • code_hash should hash result.code — the runtime bytecode stored at the contract address

This was confirmed in ethpandaops/xatu#688 by comparing against geth snapshot inspect-account: the value in init_code_hash matches geth's account.codehash (the deployed code hash), and distinct count of code_hash (~4.5M) far exceeds the known unique deployed code count (~1.7M).

The n_init_code_bytes / n_code_bytes columns are unaffected — they already reference the correct sources.

Fix

Swap the two keccak256 arguments so each column hashes the right input.

// After (correct):
store!(schema, columns, init_code_hash, keccak256(create.init.clone()).to_vec());
store!(schema, columns, code_hash,      keccak256(result.code.clone()).to_vec());

init_code_hash should hash create.init (the initialization bytecode),
and code_hash should hash result.code (the deployed runtime bytecode).
The two keccak256 calls were reversed, causing the columns to contain
each other's values in the canonical_execution_contracts table.

The n_init_code_bytes / n_code_bytes byte-count columns reference the
correct inputs already — only the hash columns were affected.

Fixes ethpandaops/xatu#688.
trial123Zel added a commit to trial123Zel/cryo-ocd that referenced this pull request May 17, 2026
process_contracts hashed the wrong inputs: init_code_hash held
keccak256(result.code) -- the deployed runtime code -- and code_hash
held keccak256(create.init) -- the deployment init code. The adjacent
init_code/code and n_init_code_bytes/n_code_bytes columns map the
inputs correctly, confirming the two hashes were transposed.

Swap them so init_code_hash is the keccak256 of the init code and
code_hash is the keccak256 of the deployed code.

Added a regression test: a contract-creation trace with distinct init
and deployed bytecode now produces each hash from its correct input.

Cross-referenced candidate PR paradigmxyz#249.

Closes #35.

Co-Authored-By: AuburyEssentian <263089372+AuburyEssentian@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@stiliyanaa stiliyanaa left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Join Holders! Your personalized invite is available at the link below. Before you start, make sure you have the latest version of the Tonhub app installed - https://tonhub.com/holders/invite/cmpm7bei61h1r933v07326shs

@AuburyEssentian

Copy link
Copy Markdown
Author

The hash swap appears already implemented in the current code; init_code_hash hashes create.init and code_hash hashes result.code as described. Could you clarify the remaining concerns?

@AuburyEssentian

Copy link
Copy Markdown
Author

@maintainer Could you take a look at the hash swap changes? Let me know if any further tweaks are needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants