Skip to main content
Developers
Cross-Chain Messaging
Examples
Cross-Chain NFT

Build a cross-chain NFT

In this tutorial you will create an NFT collection with cross-chain transfer capabilities using Zeta Connector.

Cross-chain NFT transfer

Set up your environment

note

This tutorial assumes that you have already completed the setup tutorial or cloned the template Hardhat project.

Install the dependencies:

yarn add --dev @openzeppelin/contracts @zetachain/protocol-contracts

Create a new wallet and request tokens from the testnet faucet if you haven't done so already:

npx hardhat account --save

npx hardhat faucet

Create a new contract

To create a cross-chain NFT collection you will need to deploy NFT contracts implementing Zeta's interfaces and functions to multiple chains.

In a nutshell, your contracts will need to:

  • Implement a crossChainTransfer function, that burns the NFT on the current chain and uses zeta.send to send a message that mints it on the other one.
  • Implement onZetaMessage to mint the NFT that was burned on the other chain.
  • Implement onZetaRevert to handle crossChainTransfer errors, and re-mint the previously burned NFT.
contracts/CrossChainWarriors.sol
loading...

Configure the Hardhat environment

The ZetaSwap contract expects a specific version of the Solidity compiler. Modify the Hardhat config to ensure that the correct version is used.

hardhat.config.ts
const config: HardhatUserConfig = {
solidity: "0.8.7",
// ...
};
npx hardhat compile

Create a deployment task

The deploy task is almost exactly the same as the one used in the cross-chain messaging example. The only difference is that CrossChainWarriors' constructor function accepts one additional argument (useEven), which is used to prevent collisions between cross-chain token IDs. We're using true as a value for useEven in the factory.deploy function call.

The deploy task will deploy the CrossChainWarriors contract to two or more chains and set the interactors for all chains.

tasks/deploy.ts
loading...

Run the following command to deploy the contract to two networks:

npx hardhat deploy --networks bsc-testnet,goerli
🚀 Successfully deployed contract on bsc-testnet.
📜 Contract address: 0x6Fd784c16219026Ab0349A1a8A6e99B6eE579C93

🚀 Successfully deployed contract on goerli.
📜 Contract address: 0xf1907bb130feb28D6e1305C53A4bfdb32140d8E6

🔗 Setting interactors for a contract on bsc-testnet
✅ Interactor address for 5 (goerli) is set to 0xf1907bb130feb28d6e1305c53a4bfdb32140d8e6

🔗 Setting interactors for a contract on goerli
✅ Interactor address for 97 (bsc-testnet) is set to 0x6fd784c16219026ab0349a1a8a6e99b6ee579c93

Create a mint task

The mint task accepts a contract address as an argument, calls the mint function on it, searches the events for a "Transfer" event and prints out the token ID.

tasks/mint.ts
loading...
npx hardhat mint --network goerli --contract 0xFeAF74733B6f046F3d609e663F667Ba61B19A148

🔑 Using account: 0x2cD3D070aE1BD365909dD859d29F387AA96911e1

✅ "mint" transaction has been broadcasted to goerli
📝 Transaction hash: 0x48498d595f7aa5ab2c1569fe56b9861c4902a05420af2b7054008d1c283d8e40
🌠 Minted NFT ID: 12

Please, refer to ZetaChain's explorer for updates on the progress of the cross-chain transaction.

🌍 Explorer: https://explorer.zetachain.com/cc/tx/0x48498d595f7aa5ab2c1569fe56b9861c4902a05420af2b7054008d1c283d8e40

Create a transfer task

The transfer task accepts the following arguments:

  • contract: the CrossChainWarriors contract address
  • address: recipient address
  • destination: destination chain ID
  • token: token ID
  • amount: amount of tokens to cover gas costs
tasks/transfer.ts
loading...
npx hardhat transfer --network goerli --contract 0xFeAF74733B6f046F3d609e663F667Ba61B19A148 --address 0x2cD3D070aE1BD365909dD859d29F387AA96911e1 --destination 97 --token 2 --amount 0.4

After the transfer transaction is confirmed, you will be able to see the NFT on the recipient address page on the destination chain (in this case, BSC).