StateInit of an account, calculate its hash, and build the address in the desired format.
The StateInit is distinct from the account’s current state. It is the initial state, which an account stores at deployment. After that, state can be changed by the smart contract itself — for example, by updating the data. Since the address depends on StateInit, to derive the address it is necessary to compose the initial state rather than the current one. In practice, address derivation is mostly about composing the correct StateInit.
On-chain derivation
On-chain — simple
If it’s known how to compose the contract’s initialcode and data, it’s enough to follow the general algorithm mentioned above as is. Code and data form a StateInit, and the workchain is usually hardcoded. Below is one of the most common patterns when code is a constant cell known in advance and data is composed at runtime.
b5ee9c724101010100020000004cacb9cd in the getCode function is a placeholder for a hardcoded code cell in BoC format known at compile-time. The getData function is a placeholder for building a data cell, and the actual implementation depends on the storage layout of the target smart contract. Usually, data is composed in a parametrized way, but this does not alter the rest of the logic — only the getData function.
The calculateAddress function uses the AutoDeployAddress built-in that handles all the underlying StateInit and address composing logic. In the Tolk stdlib, the code and data pair is represented by ContractState. The buildAddress method returns a builder containing the resulting address, which can be cheaply stored in another builder — the most common use case.
On-chain — contract sharding
When working with the contract sharding pattern, child contracts usually have aStateInit that depends on the parent. In the example below, the dependence is implemented by adding the parent address to the child StateInit. The same logic from the simple on-chain case works here, and only getData has to be changed.
StateInit.
On-chain — vanity
A vanity contract allows customizing the address of a smart contract that is being deployed. It does that by making its ownStateInit depend on some salt that is randomly generated many times until a desired address is found.
In this case, there is no real correlation between the data the contract holds and its final address. So there is no way to actually derive the address. The only option left is to define a constant with the actual address that is obtained in advance.
On-chain — prefixed
ThetoShard field in AutoDeployAddress allows smart contracts to have a specific prefix in the address for the purpose of deploying it to a certain shardchain. This can be useful for cross-contract latency optimization, as in Jetton 2.0.
This may seem similar to the vanity case, but it serves a different purpose. A vanity generator finds such a StateInit that an address composed from its hash will have certain letters in a prefix or suffix. The toShard does not alter the whole address and only tells the blockchain to replace the first few bits of the address to which the contract is being deployed. This optimization is used in Jetton 2.0.
The logic here is more similar to the simple case. The only difference is the additional toShard field.
Prefix length limitThe max possible prefix length is defined in the blockchain config’s
param 43
as
max_acc_fixed_prefix_length.Off-chain derivation
Off-chain — simple
The logic mirrors the on-chain example. The@ton/core library has the contractAddress function that handles StateInit hash calculation and composes the address.
Off-chain — contract sharding
The logic mirrors the on-chain example. The parent address is hardcoded in this example but could just as well be derived on its own.Off-chain — vanity
Similarly to the on-chain case, there is no way to derive the address. Define a constant with the predetermined address obtained in advance.Off-chain — prefixed
The logic mirrors the on-chain example. Since@ton/core does not define helpers for prefixed addresses, the prefix must be replaced manually.