NFT Contract Tutorial
Introduction
Non-Fungible Tokens (NFTs) are unique digital assets, each possessing distinct identities and attributes. Unlike fungible tokens created by the Token Factory, NFTs cannot be exchanged on a like-for-like basis.

Colony NFT

Seiyan NFT
This tutorial guides you through the creation and deployment of an NFT contract on Sei. By the end, you’ll have deployed your own NFT contract. Select one of the tabs below to get started!
Deploying a CW721 Contract
In this section, we’ll be deploying a CW721 contract, a standard for NFTs in the CosmWasm ecosystem. For more about CW721, visit here .
Requirements
Before starting, ensure you have:
seid
CLI: The Sei command-line interface tool, for interacting with the blockchain.- Wallet with SEI tokens on devnet: Contains SEI tokens for transaction fees.
- Rust Programming Environment: Install Rust for CosmWasm contract development. Installation guide here .
- Understanding of CosmWasm: Familiarize yourself with CosmWasm smart contracts. Start with the CosmWasm Book .
- Docker: Required for using the CosmWasm Rust Optimizer tool. Install from Docker’s official website .
Setting Up Your Environment
To work with CosmWasm smart contracts, you’ll need the Wasm rust compiler installed to build Wasm binaries. To install it, run:
rustup target add wasm32-unknown-unknown
Next, clone the CW721-base
contract from the
cw-nfts repository:
git clone https://github.com/CosmWasm/cw-nfts.git
cd cw-nfts/contracts/cw721-base
To test your setup, run:
cargo test
You should see that everything in the repository gets compiled and all tests pass.
Customizing the Contract
Review and modify the cw721-base
contract to meet your requirements. This
might include updating metadata structures or changing the minting process.
Build the Contract
To build the contract, run:
cargo wasm
This compiles a Wasm binary for uploading to Sei.
cw-nfts
repository, not in the cw721-base
subdirectory. Make sure to navigate to the root directory to see your compiled .wasm
file in target/wasm32-unknown-unknown/
.Before we can upload the contract to the chain, we have to use the CosmWasm Rust Optimizer to reduce the contract size. While not required, this is highly recommended for live contracts.
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/optimizer:0.15.0 ./contracts/cw721-base/
This will generate an optimized Wasm contract in /artifacts
.
Deploy the Contract
Upload your contract:
seid tx wasm store artifacts/cw721_base.wasm --from=$ACCOUNT --chain-id=arctic-1 --node=https://rpc.arctic-1.seinetwork.io/ --broadcast-mode=block --gas=5000000 --fees=500000usei
Replace $ACCOUNT
with your account name or address. This command stores the
contract on the chain and outputs a code ID.
seid help
in the CLI.Instantiate your contract using the code ID:
seid tx wasm instantiate $CONTRACT_CODE_ID '{"name":"$COLLECTION_NAME", "symbol":"$SYMBOL"}' --from=$ACCOUNT --admin=$ADMIN_ADDRESS --label=$LABEL --chain-id=arctic-1 --node=https://rpc.arctic-1.seinetwork.io/ --broadcast-mode=block --gas=250000 --fees=25000usei
Replace $CONTRACT_CODE_ID
, $ACCOUNT
, $LABEL
, and $ADMIN_ADDRESS
appropriately. Successful instantiation will provide the NFT contract address.
$CONTRACT_CODE_ID
: Code ID of the uploaded contract (can be found in the output of the previousstore
command)$COLLECTION_NAME
: Name of the collection$SYMBOL
: Symbol of the collection$ACCOUNT
: Your account name or address$LABEL
: Any label for easy identification, can be used to look up the contract in future$ADMIN_ADDRESS
(Optional): Address that will have administrative privileges over the contract, such as the ability to upgrade it
Create Pointer Contract
To enable seamless use of this NFT contract in EVM environments, you can create a pointer contract. This process results in an ERC721 token that can be imported and used in EVM wallets and applications.
seid tx evm deploy-erccw721 $CW721_TOKEN_ADDRESS $NAME $SYMBOL --from=$SENDER --evm-rpc=https://evm-rpc.arctic-1.seinetwork.io/
Parameters
CW721_TOKEN_ADDRESS
: The contract address of the CW721 NFT you want to create an ERC721 pointer for.NAME
: The name you want to assign to your ERC721 pointer token. This should match the name from the CW721 NFT.SYMBOL
: The symbol for your ERC721 pointer token. This should match the symbol from the CW721 NFT.
Flags
--from
: The Sei address from which the deployment transaction is sent. This address must have enough balance to cover transaction fees.--evm-rpc
: The endpoint URL for the EVM RPC interface of the Sei blockchain. This URL is used by theseid
command to interact with the Sei EVM.
Executing this command creates an ERC721 NFT contract and outputs the contract address. This NFT contract is linked to the CW721 NFT contract, meaning any activities involving CW721 NFTs will also reflect on the state of the ERC721 NFTs and vice versa.