Zero to Hero in Foundry - Part 2: Deploy & Interact


Recap
In the last part, we saw how to setup Foundry in our systems. We created a simple Counter contract project, compiled it and tested it all using the
forge
commandPlease read it if you haven't already before continuing
Foundry: Zero to Hero - Part 1
Learn Web3 through live and interactive challenges at Web3Compass
Today's Outcome
Tool of focus: anvil
& cast
Write a Greeting.sol contract
Compile & Test it using
forge
Simulate a local blockchain using
anvil
Deploy to the local blockchain using
forge
Interact with the deployed contract using
cast
Alright, let's dive in!
๐ ๏ธ Building the Contract
In a new folder let's use the forge
command to initialize our Greeting contract project
forge init Greeting
We'll now have a folder named Greeting
with all the necessary project files.
๐ Writing the Contract
Inside the src
folder we'll see that the contract file is corresponding to the Counter
contract. This will always be the case when we initialize a new project using forge
.
Let's go ahead and change it to our Greeting contract
The contract let's us set a state variable to whatever greeting message we desire and retrieve the stored message through a function call
๐งช Compile & Test the Contract
Let's do the same with test
folder
To compile and test the contract, let's go ahead and run the command
forge test
Our Greeting.sol contract is now compiled and tested, ready to be Deployed!
๐ Deploying the Contract
Deploying our contract is a two step process
Use
anvil
to simulate a local blockchainDeploy to it using an account
anvil
provides
Spinning up a local blockchain
All we have to do here is spin up a new instance of terminal and run the command
anvil
Now, we have a local blockchain running in our system with sample wallets to do transactions from
๏ฉ anvil
_ _
(_) | |
__ _ _ __ __ __ _ | |
/ _` | | '_ \ \ \ / / | | | |
| (_| | | | | | \ V / | | | |
\__,_| |_| |_| \_/ |_| |_|
1.2.3-stable (a813a2cee7 2025-06-08T15:42:40.147013149Z)
https://github.com/foundry-rs/foundry
Available Accounts
==================
(0) 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000.000000000000000000 ETH)
(1) 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 (10000.000000000000000000 ETH)
(2) 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC (10000.000000000000000000 ETH)
(3) 0x90F79bf6EB2c4f870365E785982E1f101E93b906 (10000.000000000000000000 ETH)
(4) 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 (10000.000000000000000000 ETH)
(5) 0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc (10000.000000000000000000 ETH)
(6) 0x976EA74026E726554dB657fA54763abd0C3a0aa9 (10000.000000000000000000 ETH)
(7) 0x14dC79964da2C08b23698B3D3cc7Ca32193d9955 (10000.000000000000000000 ETH)
(8) 0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f (10000.000000000000000000 ETH)
(9) 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 (10000.000000000000000000 ETH)
Private Keys
==================
(0) 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
(1) 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
(2) 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
(3) 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6
(4) 0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a
(5) 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
(6) 0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e
(7) 0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356
(8) 0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97
(9) 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
Wallet
==================
Mnemonic: test test test test test test test test test test test junk
Derivation path: m/44'/60'/0'/0/
Chain ID
==================
31337
Base Fee
==================
1000000000
Gas Limit
==================
30000000
Genesis Timestamp
==================
1754829094
Genesis Number
==================
0
Listening on 127.0.0.1:8545
Let's Deploy
With our local blockchain running and providing us dummy wallets with test ETH, only think left to do is deploy out contract to it
Each deployment is considered as a transaction on the blockchain. And for a transaction to happen it needs to be initiated from an address in the blockchain. Hence, we need to use a wallet's Private Key provided by anvil
in the previous step
Cool, let's deploy
forge create Greeting --interactive --broadcast
forge create
- initiates the deployment--interactive
- opens interactive mode to enter wallet private key--broadcast
- broadcasts the deployment transaction across the chain
Okay, we have the address of the wallet from which the contract was deployed, the deployed contract address and the associated transaction hash!
AANDDD... DEPLOYED!!!
๐ป Interacting with the Contract
Awesome! Great getting this far! :clap:
When it comes to interacting with our deployed contract, cast
is our friend
Set our Greeting Message
Let's see the cast
command to do this
cast send <Deployed Contract Address> "setGreeting(string)" "Hello from cast!" --private-key <wallet private key> --rpc-url http://127.0.0.1:8545/
Let's break it down
cast send
- send a transaction- in my case it's 0x5FbDB2315678afecb367f032d93F642f64180aa3
The name of the function to call along with any return types and arguments it has
--private-key
- follow this option with a wallet private key--rpc-url
- http://127.0.0.1:8545/, the default url to whichanvil
deploys
Your greeting
state variable should now be updated with the value "Hello from cast!". But, let's see for ourselves and not just assume
Get our Greeting Message
The function to get the greeting message is a view
only function. This means we are only reading from the state variable and doesn't need to initiate a transaction to do this
Here's the cast
command
cast call <Deployed Contract Address> "goGreet() returns (string)" -- --abi-decode
Let's break it down
cast call
- calls a function without broadcasting as a transaction- in my case it's 0x5FbDB2315678afecb367f032d93F642f64180aa3
The name of the function to call along with any return types and arguments it has
-- --abi-decode
- (IMPORTANT)The response we get while calling the function will be in hex. This flag helps decode it to a readable string
Read more about ABIs here
This should return "Hello from cast!".
If that's the case, well my friend, CONGRATULATIONS are in order!! ๐ ๐
And that's a Wrap! (For now ๐ฌ)
By now we should have
Our Greeting.sol contract compiled, tested
anvil
running a local blockchainGreeting.sol deployed to our local blockchain
Used
cast
to interact with the deployed contract
What's Next?
Part 3, we'll be
Writing a simple bank contract
Focusing majorly on writing proper tests for the logic while handling all edge cases
Don't miss it! I'll see you soon! ๐
Subscribe to my newsletter
Read articles from Abhiram A directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
