Logo

dev-resources.site

for different kinds of informations.

How to deploy smart contracts using Foundry

Published at
11/15/2024
Categories
solidity
smartcontracts
foundry
hardhat
Author
awesamarth
Author
10 person written this
awesamarth
open
How to deploy smart contracts using Foundry

Introduction

If you've been following this series so far, you already know how to write and compile smart contracts in Foundry. You also know how to use keystores to safely store and use your private keys. Now it is time to learn how you can deploy smart contracts. This article will cover both local and on-chain deployment.

Which way, Solidity dev?

There are two ways you can deploy your contracts using Foundry- the first is by using the forge create command and the second is by using Solidity scripts. Solidity scripting is a way to declaratively deploy contracts using Solidity, instead of using the more limiting and less user friendly forge create. If you are deploying a simple contract which has no constructor arguments and no reliance on other contracts that need to be deployed, it makes sense to just use forge create instead of making a separate script.

If you're coming from a Hardhat background, think of Solidity scripts as the scripts you write in Hardhat, except they're in Solidity instead of JavaScript, and they are run on the fast Foundry EVM backend, which provides dry-run capabilities.

We'll cover both ways in this article.

Initial Setup

If you haven't created a foundry project, go ahead and create one using this command:

forge init project-name
Enter fullscreen mode Exit fullscreen mode

Open src/Counter.sol and add a constructor function to the contract

constructor (uint _initNumber){ number= _initNumber;}
Enter fullscreen mode Exit fullscreen mode

Your final code should look like this:

// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.13;contract Counter { uint256 public number; constructor (uint _initNumber){ number= _initNumber; } function setNumber(uint256 newNumber) public { number = newNumber; } function increment() public { number++; }}
Enter fullscreen mode Exit fullscreen mode

Navigate to your projects folder using your terminal and compile the contract like so:

cd project-nameforge build# you can also use forge compile
Enter fullscreen mode Exit fullscreen mode

You should see something like this in your terminal:

We'll use anvil to start a local blockchain with chainId 31337. Go to your terminal and run:

anvil
Enter fullscreen mode Exit fullscreen mode

You'll then see a list of accounts and their corresponding private keys which already have a balance of 10000 ETH on chain ID 31337. Copy one of these private keys, make a .env file in the root of your project and paste it there like so:

LOCAL_PRIVATE_KEY=thecopiedkey
Enter fullscreen mode Exit fullscreen mode

We're not using keystores for local deployments since this is a known private key which everyone sees when using Foundry and is only used locally.

Now enter the URL of a Sepolia RPC endpoint in the .env file. I'm using a public RPC in this example:

SEPOLIA_RPC_URL=https://1rpc.io/sepolia
Enter fullscreen mode Exit fullscreen mode

Now open your foundry.toml file. It should be present in the root of the project. At the end of the file, add:

[rpc_endpoints]sepolia = "${SEPOLIA_RPC_URL}"
Enter fullscreen mode Exit fullscreen mode

This creates an RPC alias for Sepolia and provides cheatcodes to access the RPC endpoint we added.

Keep your anvil terminal running. Open a new terminal and run:

source .env
Enter fullscreen mode Exit fullscreen mode

This updates your terminals environment variables and adds the ones we added in the .env file.

Awesome! Now let's see how we can deploy our contract

Deploying via forge create

The contract that needs to be deployed is a pretty simple one and it takes one constructor argument. Let's see how we can deploy it using forge create

Local Deployment

In your terminal, run:

forge create --rpc-url http://localhost:8545 --private-key $LOCAL_PRIVATE_KEY src/Counter.sol:Counter --constructor-args 23
Enter fullscreen mode Exit fullscreen mode

We've specified the constructor argument as 23 here, so the value of number in our contract will be set to 23. If the transaction goes through, you'll see something like this:

Sepolia Deployment

This process is pretty similar to deploying locally. After all, we're only deploying to a chain which has a different ID. The only things we'll need are an account which has Sepolia ETH and an RPC URL. For accessing an account which has Sepolia ETH, we'll use keystores. We already set up one such account in the previous article and named it dev. You can read it here.

In your terminal, run this command:

forge create --rpc-url $SEPOLIA_RPC_URL --account dev src/Counter.sol:Counter --constructor-args 23
Enter fullscreen mode Exit fullscreen mode

This time we're using our keystore, so it will ask you to enter its password. If you enter the right password and the transaction goes through, you'll see something like this:

Deploying via scripts

Open script/Counter.sol. For the most part, the required code is already written there. Lets go through it step-by-step

// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.13;import {Script, console} from "forge-std/Script.sol";import {Counter} from "../src/Counter.sol";contract CounterScript is Script { Counter public counter; function setUp() public {} function run() public { vm.startBroadcast(); counter = new Counter(); vm.stopBroadcast(); }}
Enter fullscreen mode Exit fullscreen mode

The import statements get Script and console from the forge standard library, and the Counter contract we modified.

We then specify that the contract in this file inherits the Script contract from the forge standard library. Notice that everything in Foundry is a Solidity smart contract.

Then, we declare a new variable counter of the type Counter (our contract)

setUp is a function that runs every time we run a script. Since we don't have anything to set up right now, we'll leave this empty.

By default, scripts are executed by calling the function named run. In run, everything between vm.startBroadcast and vm.stopBroadcast creates transactions that can later be signed and sent on-chain- local, testnet, or mainnet.

If you have the right extensions for Solidity, you might be seeing an error in the line which creates a new instance of Counter.

This is because we now need to specify a value of type uint256 as the argument of our contracts constructor. Just add a number in the brackets like so:

counter = new Counter(2);
Enter fullscreen mode Exit fullscreen mode

This will set the number to be 2 when the contract is deployed.

Local Deployment

Just run this command in your terminal:

forge script script/Counter.s.sol:CounterScript --fork-url http://localhost:8545 --broadcast --private-key $LOCAL_PRIVATE_KEY
Enter fullscreen mode Exit fullscreen mode

Here http://localhost:8545 is the URL that is used to fetch the state of the local chain (id 31337) and then sending the transaction to it. You should see something like this:

and in the terminal running anvil:

Sepolia Deployment

Again, this process is pretty similar to deploying locally and we only need an account which has Sepolia ETH along with an RPC URL for Ethereum Sepolia. We'll use keystores for this case too.

Open your terminal and write:

forge script --chain sepolia script/Counter.s.sol:CounterScript --rpc-url $SEPOLIA_RPC_URL --broadcast --account dev
Enter fullscreen mode Exit fullscreen mode

It will ask you to enter the password of the keystore (dev). If you enter the correct password, it attempts to send your transaction using the account corresponding to the keystore. If it succeeds, you'll get something like this

Conclusion

That's pretty much it! You now know how you can deploy your contracts locally and on-chain using keystores and environment variables. In the next lesson, we'll learn how we can fork Ethereum Mainnet to get the entire state of the blockchain locally. Sounds interesting? Well that's because it is! Stay tuned, see you all soon. Thanks a lot for reading to the end 🫡🫡

hardhat Article's
30 articles in total
Favicon
How to deploy smart contracts using Foundry
Favicon
Node modules confusion??
Favicon
Simple Smart Contract and Hardhat
Favicon
Building Mystic Vault: A Step-by-Step Guide to Creating a Simple Ethereum DApp from Scratch 🔮✨ ( 30 min )
Favicon
Building a Blockchain-Based Blog dApp with Hardhat: A Step-by-Step Guide
Favicon
Building a Decentralized Voting System with Solidity and Hardhat
Favicon
Ethereum Development: Foundry or Hardhat
Favicon
Full Stack Ethereum and Dapp Development. A comprehensive guide: 2024
Favicon
Roadmap to Blockchain Development: 2024
Favicon
A task vs a script in Hardhat
Favicon
Testing a solidity house-swap contract using HardHat and Typescript
Favicon
How to Change the Bytecode of an Already Deployed Smart Contract
Favicon
How to Fork Mainnet for Testing
Favicon
How to Add a New Pool to Uniswap V3
Favicon
Creating a house swap contract using Solidity and Hardhat
Favicon
Solution to the ConnectTimeoutError Encountered When Verifying Smart Contracts with Hardhat
Favicon
Verified Mainnet Polygon Contract
Favicon
Verify Your Smart Contract Code
Favicon
Programmatically Verifying Solidity Smart Contract Code with Hardhat
Favicon
Getting Started with Hardhat for Smart Contracts
Favicon
How Hardhat Simplifies Smart Contract Verification on Ethereum
Favicon
Hardhat vs Truffle: Which One Is the Best for Developing Ethereum dApps?
Favicon
Fix : TokenService Error: ChainId 0x539 is not supported :(
Favicon
How to mint tokens from the backend using Nest.js on Celo Alfajores network
Favicon
My first Solidity Smart Contract
Favicon
"Deploying a Blockchain Application Nextjs / Hardhat on Netlify: A Comprehensive Guide"
Favicon
How to convert Solidity JSON ABI to Human Readable ABI in Hardhat
Favicon
Optimize Your Gas Costs with eth-gas-reporter for Hardhat
Favicon
Introduction to EVM Smart Contract development
Favicon
Top Tools for Solidity Smart Contract Developers

Featured ones: