How to Interact with ERC-721 Tokens in Solidity
Learn how to interact with, and build on top of existing ERC-721 tokens using Solidity
One of the greatest benefits of NFTs (and smart contracts, in general) is universal interoperability. Any contract on a blockchain can theoretically interact and build on top of any other contract on the same blockchain.
Crypto Coven NFTs
Interoperability helps NFT collections provide continuing utility to their holders, allows other projects to entice top buyers with discounts and exclusive access, and in some cases allows creators to do damage control for security breaches in the original contract.
In a previous tutorial, we learned how to interact with existing ERC-721 tokens to create custom allowlists. In this tutorial, we will explore a more advanced case. We will write a smart contract using Solidity and Hardhat that allows users who have paid and minted NFTs from a compromised contract to mint the same token IDs from a new contract for free.
Creating the Interaction Contract
Imagine you are the creator of an NFT project. You launch a collection and your buyers start minting NFTs by paying a certain amount of ETH. However, after a point of time, you realize that you haven’t added functionality to your contract to withdraw the ETH that buyers have paid.
You immediately halt any further sales. You decide to launch a new contract but you do not want buyers who have already paid and minted their NFTs to pay a price again. This project will explore how we go about handling this.
Interacting with other ERC-721 contracts
In order to interact with any ERC-721 contract deployed on the blockchain of your choice, you will need to setup the following in your own contract:
- Define a Solidity interface that lists all the functions (and their signatures) that you plan on calling.
- Define an instance of the interface using the address of the contract you want to interface with.
- Call the functions listed in the interface.
A very simple example would look something like this:
In the following sections, we will implement a more concrete solution for the problem highlighted above.
Step 1: Install Node and npm
In case you haven’t already, install node and npm on your local machine. Make sure that node is at least v14 or higher by typing the following in your terminal:
Step 2: Create a Hardhat project
We’re going to set up our project using Hardhat, the industry-standard development environment for Ethereum smart contracts. Additionally, we’ll also install OpenZeppelin contracts.
To set up Hardhat, run the following commands in your terminal:
Choose Create a Javascript project
from the menu and accept all defaults. To ensure everything is installed correctly, run the following command in your terminal:
To install OpenZeppelin:
Step 3: Write the incorrect NFT smart contract
Let’s now create the original (but incorrect) NFT smart contract. This contract will have all the basic functionalities expected of an NFT PFP collection except the withdraw
function.
Open the nft-interaction
project in your favorite code editor (e.g. VS Code). Create a file named ICNft.sol
in the contracts
folder and add the following code:
Step 4: Write the replacement NFT smart contract
Our replacement smart contract will implement all the functionalities of the original smart contract (plus withdrawal) and add a remint feature.
Remint will allow users who have NFTs from the original contract to mint the corresponding IDs on the new contract without having to pay the base price. This will be done by calling the tokensOfOwner
function in the original contract.
To make sure that our contract can actually call the aforementioned function, we need to provide it with the function’s signature. We will do this using Solidity interfaces.
In the contracts
folder, create another file named RCNft.sol
and add the following code:
The contract ensures the following:
- NFTs that had already been minted in the old collection can only be reminted by existing owners. These NFTs won’t be available for public sale.
- All NFTs that were not minted in the old collection will be available for public sale and will function as expected.
Compile the contracts and make sure everything is working by running:
Step 5: Simulate functionality locally
Let’s now simulate our functionality locally. We will write a script that sequentially does the following:
- Owner deploys the original (incorrect) NFT smart contract
- Wallet 1 mints three NFTs (IDs 0, 1, and 2) by paying 0.15 ETH.
- Wallet 2 mints two NFTs (IDs 3 and 4) by paying 0.1 ETH.
- Owner realizes mistake and halts sales.
- Owner deploys the replacement NFT smart contract.
- Wallet 2 mints NFTs 3 and 4 from the replacement contract without paying a price.
Create a new file called run.js
in the scripts folder, and add the following code:
Run this script by running the following command in your terminal:
You should see output that looks like this:
Conclusion
Congratulations! You now know how to interact with ERC-721 tokens and smart contracts on any EVM-based blockchain using Solidity.
If you enjoyed this tutorial about creating on-chain allowlists, tweet us at @Alchemy and give us a shoutout!
Don’t forget to join our Discord server to meet other blockchain devs, builders, and entrepreneurs!
Ready to start building your NFT collection?
Create a free Alchemy account and do share your project with us!