Deploy your first NFT contract with Foundry

Or just any Solidity smart contract

Deploy your first NFT contract with Foundry

Introduction

What is Foundry

Foundry started as a testing framework for smart contracts in Solidity with a simple premise: Solidity testing should be made using Solidity, not Javascript or Python. From there it has evolved into a fully-fledged development framework that includes:

  • Forge: Command line tool that allows you to build, test and deploy your smart contracts using only Solidity. The test themselves are written using the Forge Standard Library and Forge`s Cheatcodes which allows altering the state of the blockchain.
  • Cast: Another powerful cli tool used to interact with existing contracts in the blockchain. You can use it to call a contract, send transactions and view on-chain data.
  • Anvil: Local blockchain node implementation, written in Rust (fast!). It is the equivalent of Ganache-cli or Hardhat Local Node.

Why Foundry

If you ask me, it just makes more sense, right? Develop your smart contracts in Solidity, test them in Solidity, and deploy them using Solidity scripts (plus a bit of bash here and there).

With other frameworks, (which I use and really like btw, let's not be a framework maxi) you can end up writing more Javascript than Solidity. This has 3 problems:

  • You need to be switching contexts often.
  • You miss out on the opportunity of actually practicing your Solidity.
  • If you don´t know Javascript, it doubles the learning curve. Want to be a smart contract developer? Learn Solidity AND Javascript or Python. Not very efficient.

On the other side, if you already know Javascript it may be helpful to use other frameworks that abstract a lot of details on the inner workings of blockchain. But there will be a point where you need to make complex test use cases or simply want to get better at Solidity. That is when you should head over to Foundry.

As if this was not enough, Foundry is fast. Blazing fast. With each test case running in milliseconds instead of seconds, you won't lose your day looking at the screen and seeing the test suite painfully and sluggishly advancing.

Deploy your smart contract with Foundry

Enough with the Intro, I assume that if you are reading this you already have Foundry installed, you have a smart contract and you are ready to deploy it. Bookmark this article and use it as a cheatsheet.

Have a smart contract handy.

To keep this to the point, I have prepared a simple Alien-themed NFT contract as part of the Road to Web3 course made by the Alchemy team (check it out).

You can see the full code here.

00000.png

Prepare a basic deployment script.

Foundry lets you prepare a script for deployment similar to the one you would prepare on Hardhat, but written in Solidity instead. Under the folder script create a file like deployScript.s.sol. This is a minimal example of what should go inside the script:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "forge-std/Script.sol";
import "../src/CryptoAlien.sol"; //Your smart contract goes here

contract NftDeploy is Script {
    function setUp() public {}

    function run() public {
        vm.broadcast();

        CryptoAlien nft = new CryptoAlien();

        vm.stopBroadcast();
    }
}

Important to note

  1. The name of the contract is not important, but having the run() function is essential.
  2. vm.broadcast() is a cheatcode to record calls and send the transactions to the actual blockchain.
  3. Any constructor arguments would go inside the new CryptoAlien("name", "symbol") object.

Deploy locally to Anvil

Photo by Jonathan Kemper

First, run anvil in your shell.

You will need to get one of the 10 private keys that Anvil creates for you. Store it in a .env file (not essential, but it is nice to do things right even in localhost) and run source .env in your Bash shell. to import the .env parameters as environment variables. If it doesn't work, head over the Troubleshooting area.

forge script script/nftDeploy.s.sol:NftDeploy --fork-url http://localhost:8545  --private-key $PRIVATE_KEY0 --broadcast

If everything went well you will see a message like this. Congrats!

sucess_local.png

Deploy to any network.

Deploying to an arbitrary network is almost the same as before. You don´t need to run Anvil and you will substitute http:localhost:8545 for a public RPC on the network you want to deploy.

In our case, we will deploy to the Goerli testnet and in the same command, we will be submitting the contract´s bytecode for verification on Etherscan so you will also need to have your Etherscan API key in the .env file.

source .env
forge script script/nftDeploy.s.sol:NftDeploy --rpc-url $GOERLI_RPC_URL  --private-key $PRIVATE_KEY --broadcast --verify --etherscan-api-key $ETHERSCAN_KEY -vvvv

And that`s it! Here is the link for our deployed and verified contract.

Bonus: troubleshooting

Solidity plugin and Remappings. If you are using the Solidity extension in VS Code, chances are the remapping in the imports are not working well for you. The quick solution is to create a remappings.txt in the root of your project, and then copy all the remappings to that file, either from your foundry.toml file or using forge remappings > remappings.txt if you are using Foundry´s default remappings.

.env files If you are like me and not THAT familiar with Bash, you may find that running source .env gives you an unexpected "Command not Found" error. If this happens make sure that your .env file has this structure on all its elements KEY="VALUE" with no whitespaces anywhere and value properly quoted.

Sources