erc721.test.ts.md•83.3 kB
# Snapshot report for `src/erc721.test.ts`
The actual snapshot is saved in `erc721.test.ts.snap`.
Generated by [AVA](https://avajs.dev).
## basic non-upgradeable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
}␊
}␊
`
## basic
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## base uri
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "https://gateway.pinata.cloud/ipfs/QmcP9hxrnC1T5ATPmq2saFeAM1ypFX9BnAswCdHB9JCjLA/");␊
self.ownable.initializer(owner);␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## burnable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use core::num::traits::Zero;␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress, get_caller_address};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
}␊
␊
#[generate_trait]␊
#[abi(per_item)]␊
impl ExternalImpl of ExternalTrait {␊
#[external(v0)]␊
fn burn(ref self: ContractState, token_id: u256) {␊
self.erc721.update(Zero::zero(), token_id, get_caller_address());␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## pausable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::security::pausable::PausableComponent;␊
use openzeppelin::token::erc721::ERC721Component;␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: PausableComponent, storage: pausable, event: PausableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
pausable: PausableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
PausableEvent: PausableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
}␊
␊
impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {␊
fn before_update(␊
ref self: ERC721Component::ComponentState<ContractState>,␊
to: ContractAddress,␊
token_id: u256,␊
auth: ContractAddress,␊
) {␊
let contract_state = self.get_contract();␊
contract_state.pausable.assert_not_paused();␊
}␊
}␊
␊
#[generate_trait]␊
#[abi(per_item)]␊
impl ExternalImpl of ExternalTrait {␊
#[external(v0)]␊
fn pause(ref self: ContractState) {␊
self.ownable.assert_only_owner();␊
self.pausable.pause();␊
}␊
␊
#[external(v0)]␊
fn unpause(ref self: ContractState) {␊
self.ownable.assert_only_owner();␊
self.pausable.unpause();␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## mintable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
}␊
␊
#[generate_trait]␊
#[abi(per_item)]␊
impl ExternalImpl of ExternalTrait {␊
#[external(v0)]␊
fn safe_mint(␊
ref self: ContractState,␊
recipient: ContractAddress,␊
token_id: u256,␊
data: Span<felt252>,␊
) {␊
self.ownable.assert_only_owner();␊
self.erc721.safe_mint(recipient, token_id, data);␊
}␊
␊
#[external(v0)]␊
fn safeMint(␊
ref self: ContractState,␊
recipient: ContractAddress,␊
tokenId: u256,␊
data: Span<felt252>,␊
) {␊
self.safe_mint(recipient, tokenId, data);␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## enumerable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::ERC721Component;␊
use openzeppelin::token::erc721::extensions::ERC721EnumerableComponent;␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: ERC721EnumerableComponent, storage: erc721_enumerable, event: ERC721EnumerableEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC721EnumerableImpl = ERC721EnumerableComponent::ERC721EnumerableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl ERC721EnumerableInternalImpl = ERC721EnumerableComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
erc721_enumerable: ERC721EnumerableComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
ERC721EnumerableEvent: ERC721EnumerableComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.erc721_enumerable.initializer();␊
self.ownable.initializer(owner);␊
}␊
␊
impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {␊
fn before_update(␊
ref self: ERC721Component::ComponentState<ContractState>,␊
to: ContractAddress,␊
token_id: u256,␊
auth: ContractAddress,␊
) {␊
let mut contract_state = self.get_contract_mut();␊
contract_state.erc721_enumerable.before_update(to, token_id);␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## pausable + enumerable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::security::pausable::PausableComponent;␊
use openzeppelin::token::erc721::ERC721Component;␊
use openzeppelin::token::erc721::extensions::ERC721EnumerableComponent;␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: PausableComponent, storage: pausable, event: PausableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: ERC721EnumerableComponent, storage: erc721_enumerable, event: ERC721EnumerableEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC721EnumerableImpl = ERC721EnumerableComponent::ERC721EnumerableImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl ERC721EnumerableInternalImpl = ERC721EnumerableComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
pausable: PausableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
erc721_enumerable: ERC721EnumerableComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
PausableEvent: PausableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
ERC721EnumerableEvent: ERC721EnumerableComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
self.erc721_enumerable.initializer();␊
}␊
␊
impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {␊
fn before_update(␊
ref self: ERC721Component::ComponentState<ContractState>,␊
to: ContractAddress,␊
token_id: u256,␊
auth: ContractAddress,␊
) {␊
let mut contract_state = self.get_contract_mut();␊
contract_state.pausable.assert_not_paused();␊
contract_state.erc721_enumerable.before_update(to, token_id);␊
}␊
}␊
␊
#[generate_trait]␊
#[abi(per_item)]␊
impl ExternalImpl of ExternalTrait {␊
#[external(v0)]␊
fn pause(ref self: ContractState) {␊
self.ownable.assert_only_owner();␊
self.pausable.pause();␊
}␊
␊
#[external(v0)]␊
fn unpause(ref self: ContractState) {␊
self.ownable.assert_only_owner();␊
self.pausable.unpause();␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## mintable + roles
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
const MINTER_ROLE: felt252 = selector!("MINTER_ROLE");␊
const UPGRADER_ROLE: felt252 = selector!("UPGRADER_ROLE");␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::accesscontrol::{AccessControlComponent, DEFAULT_ADMIN_ROLE};␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
use super::{MINTER_ROLE, UPGRADER_ROLE};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: AccessControlComponent, storage: accesscontrol, event: AccessControlEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlWithDelayImpl = AccessControlComponent::AccessControlWithDelayImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
accesscontrol: AccessControlComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
AccessControlEvent: AccessControlComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(␊
ref self: ContractState,␊
default_admin: ContractAddress,␊
minter: ContractAddress,␊
upgrader: ContractAddress,␊
) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.accesscontrol.initializer();␊
␊
self.accesscontrol._grant_role(DEFAULT_ADMIN_ROLE, default_admin);␊
self.accesscontrol._grant_role(MINTER_ROLE, minter);␊
self.accesscontrol._grant_role(UPGRADER_ROLE, upgrader);␊
}␊
␊
#[generate_trait]␊
#[abi(per_item)]␊
impl ExternalImpl of ExternalTrait {␊
#[external(v0)]␊
fn safe_mint(␊
ref self: ContractState,␊
recipient: ContractAddress,␊
token_id: u256,␊
data: Span<felt252>,␊
) {␊
self.accesscontrol.assert_only_role(MINTER_ROLE);␊
self.erc721.safe_mint(recipient, token_id, data);␊
}␊
␊
#[external(v0)]␊
fn safeMint(␊
ref self: ContractState,␊
recipient: ContractAddress,␊
tokenId: u256,␊
data: Span<felt252>,␊
) {␊
self.safe_mint(recipient, tokenId, data);␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[abi(embed_v0)]␊
impl UpgradeableImpl of IUpgradeable<ContractState> {␊
fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {␊
self.accesscontrol.assert_only_role(UPGRADER_ROLE);␊
self.upgradeable.upgrade(new_class_hash);␊
}␊
}␊
}␊
`
## royalty info disabled
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## royalty info enabled default + ownable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::common::erc2981::{DefaultConfig, ERC2981Component};␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: ERC2981Component, storage: erc2981, event: ERC2981Event);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981Impl = ERC2981Component::ERC2981Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981InfoImpl = ERC2981Component::ERC2981InfoImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981AdminOwnableImpl = ERC2981Component::ERC2981AdminOwnableImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl ERC2981InternalImpl = ERC2981Component::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
erc2981: ERC2981Component::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
ERC2981Event: ERC2981Component::Event,␊
}␊
␊
#[constructor]␊
fn constructor(␊
ref self: ContractState,␊
owner: ContractAddress,␊
default_royalty_receiver: ContractAddress,␊
) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
self.erc2981.initializer(default_royalty_receiver, 500);␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## royalty info enabled default + roles
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
const UPGRADER_ROLE: felt252 = selector!("UPGRADER_ROLE");␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::accesscontrol::{AccessControlComponent, DEFAULT_ADMIN_ROLE};␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::common::erc2981::{DefaultConfig, ERC2981Component};␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
use super::UPGRADER_ROLE;␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: AccessControlComponent, storage: accesscontrol, event: AccessControlEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: ERC2981Component, storage: erc2981, event: ERC2981Event);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlWithDelayImpl = AccessControlComponent::AccessControlWithDelayImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981Impl = ERC2981Component::ERC2981Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981InfoImpl = ERC2981Component::ERC2981InfoImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981AdminAccessControlImpl = ERC2981Component::ERC2981AdminAccessControlImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl ERC2981InternalImpl = ERC2981Component::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
accesscontrol: AccessControlComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
erc2981: ERC2981Component::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
AccessControlEvent: AccessControlComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
ERC2981Event: ERC2981Component::Event,␊
}␊
␊
#[constructor]␊
fn constructor(␊
ref self: ContractState,␊
default_admin: ContractAddress,␊
upgrader: ContractAddress,␊
default_royalty_receiver: ContractAddress,␊
royalty_admin: ContractAddress,␊
) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.accesscontrol.initializer();␊
self.erc2981.initializer(default_royalty_receiver, 500);␊
␊
self.accesscontrol._grant_role(DEFAULT_ADMIN_ROLE, default_admin);␊
self.accesscontrol._grant_role(UPGRADER_ROLE, upgrader);␊
self.accesscontrol._grant_role(ERC2981Component::ROYALTY_ADMIN_ROLE, royalty_admin);␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[abi(embed_v0)]␊
impl UpgradeableImpl of IUpgradeable<ContractState> {␊
fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {␊
self.accesscontrol.assert_only_role(UPGRADER_ROLE);␊
self.upgradeable.upgrade(new_class_hash);␊
}␊
}␊
}␊
`
## royalty info enabled custom + ownable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::common::erc2981::ERC2981Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: ERC2981Component, storage: erc2981, event: ERC2981Event);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981Impl = ERC2981Component::ERC2981Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981InfoImpl = ERC2981Component::ERC2981InfoImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981AdminOwnableImpl = ERC2981Component::ERC2981AdminOwnableImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl ERC2981InternalImpl = ERC2981Component::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
erc2981: ERC2981Component::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
ERC2981Event: ERC2981Component::Event,␊
}␊
␊
#[constructor]␊
fn constructor(␊
ref self: ContractState,␊
owner: ContractAddress,␊
default_royalty_receiver: ContractAddress,␊
) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
self.erc2981.initializer(default_royalty_receiver, 15125);␊
}␊
␊
impl ERC2981ImmutableConfig of ERC2981Component::ImmutableConfig {␊
const FEE_DENOMINATOR: u128 = 100000;␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## royalty info enabled custom + roles
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
const UPGRADER_ROLE: felt252 = selector!("UPGRADER_ROLE");␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::accesscontrol::{AccessControlComponent, DEFAULT_ADMIN_ROLE};␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::common::erc2981::ERC2981Component;␊
use openzeppelin::token::erc721::{ERC721Component, ERC721HooksEmptyImpl};␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use starknet::{ClassHash, ContractAddress};␊
use super::UPGRADER_ROLE;␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: AccessControlComponent, storage: accesscontrol, event: AccessControlEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: ERC2981Component, storage: erc2981, event: ERC2981Event);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlWithDelayImpl = AccessControlComponent::AccessControlWithDelayImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981Impl = ERC2981Component::ERC2981Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981InfoImpl = ERC2981Component::ERC2981InfoImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981AdminAccessControlImpl = ERC2981Component::ERC2981AdminAccessControlImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl ERC2981InternalImpl = ERC2981Component::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
accesscontrol: AccessControlComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
erc2981: ERC2981Component::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
AccessControlEvent: AccessControlComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
ERC2981Event: ERC2981Component::Event,␊
}␊
␊
#[constructor]␊
fn constructor(␊
ref self: ContractState,␊
default_admin: ContractAddress,␊
upgrader: ContractAddress,␊
default_royalty_receiver: ContractAddress,␊
royalty_admin: ContractAddress,␊
) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.accesscontrol.initializer();␊
self.erc2981.initializer(default_royalty_receiver, 15125);␊
␊
self.accesscontrol._grant_role(DEFAULT_ADMIN_ROLE, default_admin);␊
self.accesscontrol._grant_role(UPGRADER_ROLE, upgrader);␊
self.accesscontrol._grant_role(ERC2981Component::ROYALTY_ADMIN_ROLE, royalty_admin);␊
}␊
␊
impl ERC2981ImmutableConfig of ERC2981Component::ImmutableConfig {␊
const FEE_DENOMINATOR: u128 = 100000;␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[abi(embed_v0)]␊
impl UpgradeableImpl of IUpgradeable<ContractState> {␊
fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {␊
self.accesscontrol.assert_only_role(UPGRADER_ROLE);␊
self.upgradeable.upgrade(new_class_hash);␊
}␊
}␊
}␊
`
## full non-upgradeable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use core::num::traits::Zero;␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::governance::votes::VotesComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::security::pausable::PausableComponent;␊
use openzeppelin::token::common::erc2981::{DefaultConfig, ERC2981Component};␊
use openzeppelin::token::erc721::ERC721Component;␊
use openzeppelin::token::erc721::extensions::ERC721EnumerableComponent;␊
use openzeppelin::utils::cryptography::nonces::NoncesComponent;␊
use openzeppelin::utils::cryptography::snip12::SNIP12Metadata;␊
use starknet::{ContractAddress, get_caller_address};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: PausableComponent, storage: pausable, event: PausableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: ERC721EnumerableComponent, storage: erc721_enumerable, event: ERC721EnumerableEvent);␊
component!(path: ERC2981Component, storage: erc2981, event: ERC2981Event);␊
component!(path: NoncesComponent, storage: nonces, event: NoncesEvent);␊
component!(path: VotesComponent, storage: votes, event: VotesEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC721EnumerableImpl = ERC721EnumerableComponent::ERC721EnumerableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981Impl = ERC2981Component::ERC2981Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981InfoImpl = ERC2981Component::ERC2981InfoImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981AdminOwnableImpl = ERC2981Component::ERC2981AdminOwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl NoncesImpl = NoncesComponent::NoncesImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl VotesImpl = VotesComponent::VotesImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl ERC721EnumerableInternalImpl = ERC721EnumerableComponent::InternalImpl<ContractState>;␊
impl ERC2981InternalImpl = ERC2981Component::InternalImpl<ContractState>;␊
impl VotesInternalImpl = VotesComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
pausable: PausableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
erc721_enumerable: ERC721EnumerableComponent::Storage,␊
#[substorage(v0)]␊
erc2981: ERC2981Component::Storage,␊
#[substorage(v0)]␊
nonces: NoncesComponent::Storage,␊
#[substorage(v0)]␊
votes: VotesComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
PausableEvent: PausableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
ERC721EnumerableEvent: ERC721EnumerableComponent::Event,␊
#[flat]␊
ERC2981Event: ERC2981Component::Event,␊
#[flat]␊
NoncesEvent: NoncesComponent::Event,␊
#[flat]␊
VotesEvent: VotesComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(␊
ref self: ContractState,␊
owner: ContractAddress,␊
default_royalty_receiver: ContractAddress,␊
) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
self.erc721_enumerable.initializer();␊
self.erc2981.initializer(default_royalty_receiver, 500);␊
}␊
␊
impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {␊
fn before_update(␊
ref self: ERC721Component::ComponentState<ContractState>,␊
to: ContractAddress,␊
token_id: u256,␊
auth: ContractAddress,␊
) {␊
let mut contract_state = self.get_contract_mut();␊
contract_state.pausable.assert_not_paused();␊
contract_state.erc721_enumerable.before_update(to, token_id);␊
let previous_owner = self._owner_of(token_id);␊
contract_state.votes.transfer_voting_units(previous_owner, to, 1);␊
}␊
}␊
␊
#[generate_trait]␊
#[abi(per_item)]␊
impl ExternalImpl of ExternalTrait {␊
#[external(v0)]␊
fn pause(ref self: ContractState) {␊
self.ownable.assert_only_owner();␊
self.pausable.pause();␊
}␊
␊
#[external(v0)]␊
fn unpause(ref self: ContractState) {␊
self.ownable.assert_only_owner();␊
self.pausable.unpause();␊
}␊
␊
#[external(v0)]␊
fn burn(ref self: ContractState, token_id: u256) {␊
self.erc721.update(Zero::zero(), token_id, get_caller_address());␊
}␊
␊
#[external(v0)]␊
fn safe_mint(␊
ref self: ContractState,␊
recipient: ContractAddress,␊
token_id: u256,␊
data: Span<felt252>,␊
) {␊
self.ownable.assert_only_owner();␊
self.erc721.safe_mint(recipient, token_id, data);␊
}␊
␊
#[external(v0)]␊
fn safeMint(␊
ref self: ContractState,␊
recipient: ContractAddress,␊
tokenId: u256,␊
data: Span<felt252>,␊
) {␊
self.safe_mint(recipient, tokenId, data);␊
}␊
}␊
␊
//␊
// SNIP12 Metadata␊
//␊
␊
impl SNIP12MetadataImpl of SNIP12Metadata {␊
fn name() -> felt252 {␊
'MY_DAPP_NAME'␊
}␊
␊
fn version() -> felt252 {␊
'MY_DAPP_VERSION'␊
}␊
}␊
}␊
`
## erc721 votes
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::governance::votes::VotesComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::ERC721Component;␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use openzeppelin::utils::cryptography::nonces::NoncesComponent;␊
use openzeppelin::utils::cryptography::snip12::SNIP12Metadata;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: NoncesComponent, storage: nonces, event: NoncesEvent);␊
component!(path: VotesComponent, storage: votes, event: VotesEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl NoncesImpl = NoncesComponent::NoncesImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl VotesImpl = VotesComponent::VotesImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl VotesInternalImpl = VotesComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
nonces: NoncesComponent::Storage,␊
#[substorage(v0)]␊
votes: VotesComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
NoncesEvent: NoncesComponent::Event,␊
#[flat]␊
VotesEvent: VotesComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
}␊
␊
impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {␊
fn before_update(␊
ref self: ERC721Component::ComponentState<ContractState>,␊
to: ContractAddress,␊
token_id: u256,␊
auth: ContractAddress,␊
) {␊
let mut contract_state = self.get_contract_mut();␊
let previous_owner = self._owner_of(token_id);␊
contract_state.votes.transfer_voting_units(previous_owner, to, 1);␊
}␊
}␊
␊
//␊
// SNIP12 Metadata␊
//␊
␊
impl SNIP12MetadataImpl of SNIP12Metadata {␊
fn name() -> felt252 {␊
'MY_DAPP_NAME'␊
}␊
␊
fn version() -> felt252 {␊
'v1'␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## erc721 votes, version
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::governance::votes::VotesComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::ERC721Component;␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use openzeppelin::utils::cryptography::nonces::NoncesComponent;␊
use openzeppelin::utils::cryptography::snip12::SNIP12Metadata;␊
use starknet::{ClassHash, ContractAddress};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: NoncesComponent, storage: nonces, event: NoncesEvent);␊
component!(path: VotesComponent, storage: votes, event: VotesEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl NoncesImpl = NoncesComponent::NoncesImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl VotesImpl = VotesComponent::VotesImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl VotesInternalImpl = VotesComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
nonces: NoncesComponent::Storage,␊
#[substorage(v0)]␊
votes: VotesComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
NoncesEvent: NoncesComponent::Event,␊
#[flat]␊
VotesEvent: VotesComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState, owner: ContractAddress) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
}␊
␊
impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {␊
fn before_update(␊
ref self: ERC721Component::ComponentState<ContractState>,␊
to: ContractAddress,␊
token_id: u256,␊
auth: ContractAddress,␊
) {␊
let mut contract_state = self.get_contract_mut();␊
let previous_owner = self._owner_of(token_id);␊
contract_state.votes.transfer_voting_units(previous_owner, to, 1);␊
}␊
}␊
␊
//␊
// SNIP12 Metadata␊
//␊
␊
impl SNIP12MetadataImpl of SNIP12Metadata {␊
fn name() -> felt252 {␊
'MY_DAPP_NAME'␊
}␊
␊
fn version() -> felt252 {␊
'MY_DAPP_VERSION'␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`
## erc721 votes, non-upgradeable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use openzeppelin::governance::votes::VotesComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::token::erc721::ERC721Component;␊
use openzeppelin::utils::cryptography::nonces::NoncesComponent;␊
use openzeppelin::utils::cryptography::snip12::SNIP12Metadata;␊
use starknet::ContractAddress;␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: NoncesComponent, storage: nonces, event: NoncesEvent);␊
component!(path: VotesComponent, storage: votes, event: VotesEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl NoncesImpl = NoncesComponent::NoncesImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl VotesImpl = VotesComponent::VotesImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl VotesInternalImpl = VotesComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
nonces: NoncesComponent::Storage,␊
#[substorage(v0)]␊
votes: VotesComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
NoncesEvent: NoncesComponent::Event,␊
#[flat]␊
VotesEvent: VotesComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(ref self: ContractState) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
}␊
␊
impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {␊
fn before_update(␊
ref self: ERC721Component::ComponentState<ContractState>,␊
to: ContractAddress,␊
token_id: u256,␊
auth: ContractAddress,␊
) {␊
let mut contract_state = self.get_contract_mut();␊
let previous_owner = self._owner_of(token_id);␊
contract_state.votes.transfer_voting_units(previous_owner, to, 1);␊
}␊
}␊
␊
//␊
// SNIP12 Metadata␊
//␊
␊
impl SNIP12MetadataImpl of SNIP12Metadata {␊
fn name() -> felt252 {␊
'MY_DAPP_NAME'␊
}␊
␊
fn version() -> felt252 {␊
'v1'␊
}␊
}␊
}␊
`
## full upgradeable
> Snapshot 1
`// SPDX-License-Identifier: MIT␊
// Compatible with OpenZeppelin Contracts for Cairo ^2.0.0␊
␊
#[starknet::contract]␊
mod MyToken {␊
use core::num::traits::Zero;␊
use openzeppelin::access::ownable::OwnableComponent;␊
use openzeppelin::governance::votes::VotesComponent;␊
use openzeppelin::introspection::src5::SRC5Component;␊
use openzeppelin::security::pausable::PausableComponent;␊
use openzeppelin::token::common::erc2981::{DefaultConfig, ERC2981Component};␊
use openzeppelin::token::erc721::ERC721Component;␊
use openzeppelin::token::erc721::extensions::ERC721EnumerableComponent;␊
use openzeppelin::upgrades::interface::IUpgradeable;␊
use openzeppelin::upgrades::UpgradeableComponent;␊
use openzeppelin::utils::cryptography::nonces::NoncesComponent;␊
use openzeppelin::utils::cryptography::snip12::SNIP12Metadata;␊
use starknet::{ClassHash, ContractAddress, get_caller_address};␊
␊
component!(path: ERC721Component, storage: erc721, event: ERC721Event);␊
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
component!(path: PausableComponent, storage: pausable, event: PausableEvent);␊
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
component!(path: ERC721EnumerableComponent, storage: erc721_enumerable, event: ERC721EnumerableEvent);␊
component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);␊
component!(path: ERC2981Component, storage: erc2981, event: ERC2981Event);␊
component!(path: NoncesComponent, storage: nonces, event: NoncesEvent);␊
component!(path: VotesComponent, storage: votes, event: VotesEvent);␊
␊
// External␊
#[abi(embed_v0)]␊
impl ERC721MixinImpl = ERC721Component::ERC721MixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC721EnumerableImpl = ERC721EnumerableComponent::ERC721EnumerableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981Impl = ERC2981Component::ERC2981Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981InfoImpl = ERC2981Component::ERC2981InfoImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC2981AdminOwnableImpl = ERC2981Component::ERC2981AdminOwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl NoncesImpl = NoncesComponent::NoncesImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl VotesImpl = VotesComponent::VotesImpl<ContractState>;␊
␊
// Internal␊
impl ERC721InternalImpl = ERC721Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
impl ERC721EnumerableInternalImpl = ERC721EnumerableComponent::InternalImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl ERC2981InternalImpl = ERC2981Component::InternalImpl<ContractState>;␊
impl VotesInternalImpl = VotesComponent::InternalImpl<ContractState>;␊
␊
#[storage]␊
struct Storage {␊
#[substorage(v0)]␊
erc721: ERC721Component::Storage,␊
#[substorage(v0)]␊
src5: SRC5Component::Storage,␊
#[substorage(v0)]␊
pausable: PausableComponent::Storage,␊
#[substorage(v0)]␊
ownable: OwnableComponent::Storage,␊
#[substorage(v0)]␊
erc721_enumerable: ERC721EnumerableComponent::Storage,␊
#[substorage(v0)]␊
upgradeable: UpgradeableComponent::Storage,␊
#[substorage(v0)]␊
erc2981: ERC2981Component::Storage,␊
#[substorage(v0)]␊
nonces: NoncesComponent::Storage,␊
#[substorage(v0)]␊
votes: VotesComponent::Storage,␊
}␊
␊
#[event]␊
#[derive(Drop, starknet::Event)]␊
enum Event {␊
#[flat]␊
ERC721Event: ERC721Component::Event,␊
#[flat]␊
SRC5Event: SRC5Component::Event,␊
#[flat]␊
PausableEvent: PausableComponent::Event,␊
#[flat]␊
OwnableEvent: OwnableComponent::Event,␊
#[flat]␊
ERC721EnumerableEvent: ERC721EnumerableComponent::Event,␊
#[flat]␊
UpgradeableEvent: UpgradeableComponent::Event,␊
#[flat]␊
ERC2981Event: ERC2981Component::Event,␊
#[flat]␊
NoncesEvent: NoncesComponent::Event,␊
#[flat]␊
VotesEvent: VotesComponent::Event,␊
}␊
␊
#[constructor]␊
fn constructor(␊
ref self: ContractState,␊
owner: ContractAddress,␊
default_royalty_receiver: ContractAddress,␊
) {␊
self.erc721.initializer("MyToken", "MTK", "");␊
self.ownable.initializer(owner);␊
self.erc721_enumerable.initializer();␊
self.erc2981.initializer(default_royalty_receiver, 500);␊
}␊
␊
impl ERC721HooksImpl of ERC721Component::ERC721HooksTrait<ContractState> {␊
fn before_update(␊
ref self: ERC721Component::ComponentState<ContractState>,␊
to: ContractAddress,␊
token_id: u256,␊
auth: ContractAddress,␊
) {␊
let mut contract_state = self.get_contract_mut();␊
contract_state.pausable.assert_not_paused();␊
contract_state.erc721_enumerable.before_update(to, token_id);␊
let previous_owner = self._owner_of(token_id);␊
contract_state.votes.transfer_voting_units(previous_owner, to, 1);␊
}␊
}␊
␊
#[generate_trait]␊
#[abi(per_item)]␊
impl ExternalImpl of ExternalTrait {␊
#[external(v0)]␊
fn pause(ref self: ContractState) {␊
self.ownable.assert_only_owner();␊
self.pausable.pause();␊
}␊
␊
#[external(v0)]␊
fn unpause(ref self: ContractState) {␊
self.ownable.assert_only_owner();␊
self.pausable.unpause();␊
}␊
␊
#[external(v0)]␊
fn burn(ref self: ContractState, token_id: u256) {␊
self.erc721.update(Zero::zero(), token_id, get_caller_address());␊
}␊
␊
#[external(v0)]␊
fn safe_mint(␊
ref self: ContractState,␊
recipient: ContractAddress,␊
token_id: u256,␊
data: Span<felt252>,␊
) {␊
self.ownable.assert_only_owner();␊
self.erc721.safe_mint(recipient, token_id, data);␊
}␊
␊
#[external(v0)]␊
fn safeMint(␊
ref self: ContractState,␊
recipient: ContractAddress,␊
tokenId: u256,␊
data: Span<felt252>,␊
) {␊
self.safe_mint(recipient, tokenId, data);␊
}␊
}␊
␊
//␊
// SNIP12 Metadata␊
//␊
␊
impl SNIP12MetadataImpl of SNIP12Metadata {␊
fn name() -> felt252 {␊
'MY_DAPP_NAME'␊
}␊
␊
fn version() -> felt252 {␊
'MY_DAPP_VERSION'␊
}␊
}␊
␊
//␊
// Upgradeable␊
//␊
␊
#[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);␊
}␊
}␊
}␊
`