Taking here the conversation about a new syscall for getting the class hash of a deployed contract, from within a contract execution environment.
Simple Summary
Introduce a new syscall get_class_hash_at
, aimed to get a contract class hash at a certain address.
Abstract
Starknet adopted a system of contract classes to reduce duplication of deployed bytecode. It works in the following way: to deploy a piece of code that has never been deployed before, you must first declare it. You are effectively “declaring” a class to the Starknet network. From this point onward, one may instantiate this class by requesting the sequencer to deploy it at a certain address. The simple usecase goes: you declare a fungible token contract, the sequencer stores the code once; then, any number of deployments of the exact same smart contract will not further bloat the chain’s storage. This is different from the way Ethereum and the Ethereum Virtual Machine (EVM) works. In EVM world, if you deploy a hundred times an ERC20 contract, the chain will store a copy of the code a hundred times. More information: https://docs.starknet.io/architecture-and-concepts/smart-contracts/contract-classes/
While there is a way for one to check the class hash of a deployed contract at the RPC level (starknet_getClassHashAt
method), there is no way to perform this at the smart contract level. In EVM world, this is achieved using the EXTCODEHASH
opcode. The purpose is for a contract to check on-chain whether another contract is an instantiation of a particular class. This is more precise/powerful (and more costly?) than SNIP-5 (inspired by ERC-165).
Motivation
At Kakarot, we utilize replace_class_hash
syscall for upgrades at the contract level, as well as use class hashes as mediums of checking a contract’s version. We need the ability to check a contract’s class hash. We currently achieve this by enforcing every Kakarot Account to store its own class hash in a storage variable.
We would benefit from a syscall that would enable a contract to check a particular class hash at an address.
Simple use-case for Kakarot: enable the contract-level orchestration of versioning and auto-upgrade of our swarm of Kakarot Account Contracts
How?
- Set the new version (a class hash) in the Core EVM Kakarot Contract
- Every contract is now able to compare their class hash with the current correct version (situated in Kakarot Core EVM) and decide to self upgrade
- Before calling a contract, one may check that it is in the correct version.
Specification
One might want to name the syscall in the same way as the corresponding RPC method.
extern fn get_class_hash_at_syscall(
contract_address: ContractAddress
) -> SyscallResult<ClassHash> implicits(GasBuiltin, System) nopanic;
Alternative API:
extern fn class_hash_syscall(
contract_address: ContractAddress
) -> SyscallResult<ClassHash> implicits(GasBuiltin, System) nopanic;
Arguments
contract_address: The contract address one wants to know the class hash of.
Returns
Returns the ClassHash
if the contract is deployed, an Result::Error
if the contract is not deployed. Note that the syscall should never panic. Calling get_class_hash_at_syscall
on an address where no contract is deployed will result in a catchable error (equivalent to returning a sentinel value null), not a CairoVM error.
Implementation
We will require help from the Starkware team to define precisely the implementation.
Copyright
Copyright and related rights waived via MIT.