Skip to main content
Glama

OpenZeppelin Contracts MCP Server

Official
by OpenZeppelin
erc721.test.ts.md83.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);␊ }␊ }␊ }␊ `

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/OpenZeppelin/contracts-wizard'

If you have feedback or need assistance with the MCP directory API, please join our Discord server