Skip to content

Adds EIP-2935 HISTORY_STORAGE contract support#1618

Open
moglu2017 wants to merge 5 commits into
eth-equivalencefrom
moglu/eip2935
Open

Adds EIP-2935 HISTORY_STORAGE contract support#1618
moglu2017 wants to merge 5 commits into
eth-equivalencefrom
moglu/eip2935

Conversation

@moglu2017
Copy link
Copy Markdown
Contributor

Description

Introduces a historical block hash contract with a fixed address per EIP-2935, enabling dApps using the EIP-2935 convention to function seamlessly. Loads the contract code at the fork activation block to ensure compatibility and interoperability.

The different with Ethereum

  1. Thor's contract only implements the Get logic, redirect to the executor builtin contract.
  2. The contract's codehash is different.
  3. The contract's nonce is 0, etherem is 1.

Fixes # (issue)

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • New and existing E2E tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have not added any vulnerable dependencies to my code

Introduces a historical block hash contract with a fixed address
per EIP-2935, enabling dApps using the EIP-2935 convention
to function seamlessly. Loads the contract code at the fork
activation block to ensure compatibility and interoperability.
@moglu2017 moglu2017 requested a review from a team as a code owner May 15, 2026 08:05
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 15, 2026

Codecov Report

❌ Patch coverage is 87.27273% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
thorclient/builtin/history.go 89.79% 3 Missing and 2 partials ⚠️
runtime/runtime.go 33.33% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Member

@otherview otherview left a comment

Choose a reason for hiding this comment

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

Might be worth adding structs and tests in the thorclient/builtin package too.

Comment thread builtin/history_test.go Outdated
Comment thread builtin/history_test.go Outdated
Comment thread builtin/gen/history.sol Outdated
Comment thread builtin/history_test.go Outdated
Comment thread builtin/gen/history.sol
// builtin.Extension.Address == thor.BytesToAddress([]byte("Extension"))
address constant EXTENSION = 0x0000000000000000000000457874656E73696F6e;

fallback(bytes calldata input) external returns (bytes memory) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this return bytes32 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, at the end of function , it will return bytes32 data.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ooc, why do we need the assembly ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's equivalent this:
return abi.encodePacked(_Extension(EXTENSION).blockID(num));
Assembly is used because it is more concise.

Comment thread builtin/gen/history.sol Outdated
2. Change SERVE_WINDOW -> HISTORY_SERVE_WINDOW
Comment thread builtin/gen/history.sol
// builtin.Extension.Address == thor.BytesToAddress([]byte("Extension"))
address constant EXTENSION = 0x0000000000000000000000457874656E73696F6e;

fallback(bytes calldata input) external returns (bytes memory) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be a view ?

Suggested change
fallback(bytes calldata input) external returns (bytes memory) {
fallback(bytes calldata input) external view returns (bytes memory) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It can't set 'view', the fallback method only could be set 'payable' or 'non-payable', default is 'non-payable'.

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.

5 participants