Skip to content

feature(starknet): Adding injected class-hash values into code.#10160

Draft
orizi wants to merge 1 commit into
orizi/06-24-feature_sierra-gen_added_support_for_injecting_constant_values_externallyfrom
orizi/06-24-feature_starknet_adding_injected_class-hash_values_into_code
Draft

feature(starknet): Adding injected class-hash values into code.#10160
orizi wants to merge 1 commit into
orizi/06-24-feature_sierra-gen_added_support_for_injecting_constant_values_externallyfrom
orizi/06-24-feature_starknet_adding_injected_class-hash_values_into_code

Conversation

@orizi

@orizi orizi commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a ContractClass::class_hash() method that computes the Starknet Sierra class hash using Poseidon over the contract class version marker, entry-point groups, ABI keccak hash, and Sierra program hash. Integrates this into compile_path via a two-pass compilation strategy: a first pass compiles with the class hash stubbed to zero, computes the resulting class hash, then a second pass re-compiles with that hash injected via the reserved __externally_provided_const__ extern. The Starknet plugin now generates a hidden __class_hash__ module in every contract, exposing a class_hash() function and a generic ForwardingClassHashImpl that delegates to it.


Type of change

Please check one:

  • Bug fix (fixes incorrect behavior)
  • New feature
  • Performance improvement
  • Documentation change with concrete technical impact
  • Style, wording, formatting, or typo-only change

⚠️ Note:
To keep maintainer workload sustainable, we generally do not accept PRs that
are only minor wording, grammar, formatting, or style changes.
Such PRs may be closed without detailed review.


Why is this change needed?

Contracts previously had no way to statically reference their own class hash at compile time. The TEST_CLASS_HASH constant existed only under #[cfg(target: 'test')]. This change makes the class hash available at runtime via a generated accessor backed by a compiler-injected constant, enabling patterns like forwarding contracts that need to statically embed their own class hash.


What was the behavior or documentation before?

Contracts could not call their own class hash from within Cairo code outside of test targets. Sierra generation would fail if __externally_provided_const__ was referenced without a registered provider.


What is the behavior or documentation after?

Every #[starknet::contract] module now contains a generated __class_hash__ submodule with:

  • class_hash() -> starknet::ClassHash — returns the contract's own class hash as a compile-time constant injected during Sierra generation.
  • ForwardingClassHashImpl<T> — a generic impl of starknet::ForwardingClassHash<T> that returns this contract's class hash, usable by forwarding contracts.

compile_path performs two compilation passes: the first compiles with the hash stubbed to zero to obtain the Sierra output, computes its class hash via ContractClass::class_hash(), then re-compiles with that hash injected. The injected value is an approximation because embedding the hash changes the bytecode, but the result is deterministic across runs.


Related issue or discussion (if any)


Additional context

The ContractClass::class_hash() implementation mirrors the algorithm used by the sequencer (starknet_api): a Poseidon hash over CONTRACT_CLASS_V0.1.0, the three entry-point group hashes, the ABI keccak hash, and the Sierra program hash. The ABI is hashed via its canonical JSON string representation, so the exact serialization affects the result. A test (test_class_hash_is_deterministic_and_sensitive) verifies determinism and sensitivity to entry-point mutations. An end-to-end compilation test (class_hash_injection_compiles) verifies that a contract calling __class_hash__::class_hash() compiles successfully and produces a deterministic Sierra program.

@reviewable-StarkWare

Copy link
Copy Markdown

This change is Reviewable

orizi commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@orizi orizi force-pushed the orizi/06-24-feature_starknet_adding_injected_class-hash_values_into_code branch from 8404305 to 8294d7a Compare June 24, 2026 11:48
@orizi orizi force-pushed the orizi/06-24-feature_sierra-gen_added_support_for_injecting_constant_values_externally branch from 4d2e354 to 7ff65e3 Compare June 24, 2026 11:48
@orizi orizi mentioned this pull request Jun 24, 2026
5 tasks
Comment on lines +69 to +71
// to zero (to obtain the class hash), then with that hash injected. Embedding the hash changes
// the bytecode, so the final class's true hash differs from the injected value (a deliberate,
// documented approximation).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Well that's no good for us

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

ignore this - it is not correct - as long as you set the data in the provider - by asking for a calculation it shouldn't matter at all. this is just an example in any case.

@Arcticae

Copy link
Copy Markdown
Collaborator

@orizi also this is not what we want to achieve - we want to embed external contracts, and that implementation self-embeds the class hash which is totally unneeded

@orizi orizi left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@orizi made 1 comment.
Reviewable status: 0 of 34 files reviewed, 1 unresolved discussion (waiting on Arcticae).

Comment on lines +69 to +71
// to zero (to obtain the class hash), then with that hash injected. Embedding the hash changes
// the bytecode, so the final class's true hash differs from the injected value (a deliberate,
// documented approximation).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

ignore this - it is not correct - as long as you set the data in the provider - by asking for a calculation it shouldn't matter at all. this is just an example in any case.

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.

3 participants