Presets
Presets are ready-to-deploy contracts provided by the library. Since presets are intended to be very simple
and as generic as possible, there’s no support for custom or complex contracts such as ERC20Pausable
or ERC721Mintable
.
For contract customization and combination of modules you can use Wizard for Cairo, our code-generation tool. |
Available presets
List of available presets and their corresponding Sierra class hashes.
Class hashes were computed using cairo 2.8.0. |
Name | Sierra Class Hash |
---|---|
|
|
|
|
|
|
|
|
|
|
|
starkli class-hash command can be used to compute the class hash from a Sierra artifact. |
Usage
These preset contracts are ready-to-deploy which means they should already be declared on the Sepolia network. Simply deploy the preset class hash and add the appropriate constructor arguments. Deploying the ERC20Upgradeable preset with starkli, for example, will look like this:
starkli deploy 0x041f57a27f2fba3477c38e6559a09bf5b7bb3244ec1ca3cbea4ca5918d253137 \
<CONSTRUCTOR_ARGS> \
--network="sepolia"
If a class hash has yet to be declared, copy/paste the preset contract code and declare it locally.
Start by setting up a project and installing the Contracts for Cairo library.
Copy the target preset contract from the presets directory and paste it in the new project’s src/lib.cairo
like this:
// src/lib.cairo
#[starknet::contract]
mod ERC20Upgradeable {
use openzeppelin::access::ownable::OwnableComponent;
use openzeppelin::token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
use openzeppelin::upgrades::UpgradeableComponent;
use openzeppelin::upgrades::interface::IUpgradeable;
use starknet::{ContractAddress, ClassHash};
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
component!(path: ERC20Component, storage: erc20, event: ERC20Event);
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);
// Ownable Mixin
#[abi(embed_v0)]
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;
// ERC20 Mixin
#[abi(embed_v0)]
impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;
// Upgradeable
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;
#[storage]
struct Storage {
#[substorage(v0)]
ownable: OwnableComponent::Storage,
#[substorage(v0)]
erc20: ERC20Component::Storage,
#[substorage(v0)]
upgradeable: UpgradeableComponent::Storage
}
#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
OwnableEvent: OwnableComponent::Event,
#[flat]
ERC20Event: ERC20Component::Event,
#[flat]
UpgradeableEvent: UpgradeableComponent::Event
}
#[constructor]
fn constructor(
ref self: ContractState,
name: ByteArray,
symbol: ByteArray,
fixed_supply: u256,
recipient: ContractAddress,
owner: ContractAddress
) {
self.ownable.initializer(owner);
self.erc20.initializer(name, symbol);
self.erc20.mint(recipient, fixed_supply);
}
#[abi(embed_v0)]
impl UpgradeableImpl of IUpgradeable<ContractState> {
fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {
self.ownable.assert_only_owner();
self.upgradeable.upgrade(new_class_hash);
}
}
}
Next, compile the contract.
scarb build
Finally, declare the preset.
starkli declare target/dev/my_project_ERC20Upgradeable.contract_class.json \
--network="sepolia"