Foundry/Anvil: A local Ethereum node for development.
Introduction
Smart contracts are the backbone of decentralized applications (DApps) on the Ethereum blockchain. To streamline development and testing, we can use Anvil, a local Ethereum node provided by Foundry. This article will guide you through writing, deploying, and testing a simple smart contract using Anvil.
Prerequisites
Before we begin, ensure you have the following installed:
- Foundry: Install Foundry by running:
curl -L https://foundry.paradigm.xyz | bash
foundryup
Step 1: Create a Simple Smart Contract
First, let’s write a basic smart contract in Solidity. We’ll create a contract that allows us to store and retrieve an integer value.
- Create a new directory for your project:
mkdir StorageProject
cd StorageProject
2. Initialize a Foundry project:
forge init
Create the smart contract file: Create a file named SimpleStorage.sol
in the src
directory with the following content:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract SimpleStorage {
uint256 private storedData;
function set(uint256 x) public {
storedData = x;
}
function get() public view returns (uint256) {
return storedData;
}
}
Step 2: Set Up Anvil
Anvil is a local Ethereum node that simulates the Ethereum network, making it ideal for testing and development.
- Start Anvil: Open a terminal and start Anvil by running:
anvil
Step 3: Deploy the Smart Contract
Next, we’ll deploy the SimpleStorage
contract to the Anvil node.
- Create a deployment script: Create a new file named
deploy.js
in thescripts
deploy.js
directory with the following content:
const { ethers } = require("ethers");
async function main() {
// Connect to Anvil
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
const signer = provider.getSigner(0);
// Compile the contract
const fs = require("fs");
const solc = require("solc");
const source = fs.readFileSync("src/SimpleStorage.sol", "utf8");
const input = {
language: "Solidity",
sources: {
"SimpleStorage.sol": {
content: source,
},
},
settings: {
outputSelection: {
"*": {
"*": ["abi", "evm.bytecode"],
},
},
},
};
const output = JSON.parse(solc.compile(JSON.stringify(input)));
const contractData = output.contracts["SimpleStorage.sol"]["SimpleStorage"];
const bytecode = contractData.evm.bytecode.object;
const abi = contractData.abi;
// Deploy the contract
const factory = new ethers.ContractFactory(abi, bytecode, signer);
const contract = await factory.deploy();
await contract.deployed();
console.log("SimpleStorage deployed to:", contract.address);
}
main().catch((error) => {
console.error(error);
process.exit(1);
});
Explaning the contract deploy.js
Import Libraries
const { ethers } = require(“ethers”);
const fs = require(“fs”);
const solc = require(“solc”);
ethers
: This library is used for interacting with the Ethereum blockchain.fs
: This module provides an API for interacting with the file system, allowing you to read and write files.solc
: This is the Solidity compiler used to compile Solidity source code.
Main Function
The main function is declared as an async
function, which allows the use of await
to handle asynchronous operations.
async function main() {
Connect to Anvil
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");
const signer = provider.getSigner(0);
provider
: This connects to the Anvil local Ethereum node running athttp://localhost:8545
.signer
: This is the default signer (account) used to sign transactions.getSigner(0)
gets the first account generated by Anvil.
Compile the Contract
const source = fs.readFileSync("src/SimpleStorage.sol", "utf8");
const input = {
language: "Solidity",
sources: {
"SimpleStorage.sol": {
content: source,
},
},
settings: {
outputSelection: {
"*": {
"*": ["abi", "evm.bytecode"],
},
},
},
};
const output = JSON.parse(solc.compile(JSON.stringify(input)));
const contractData = output.contracts["SimpleStorage.sol"]["SimpleStorage"];
const bytecode = contractData.evm.bytecode.object;
const abi = contractData.abi;
fs.readFileSync("src/SimpleStorage.sol", "utf8")
: Reads the content of theSimpleStorage.sol
file as a string.input
: Prepares the input for the Solidity compiler. It specifies the language (Solidity), the source code, and the desired outputs (ABI and bytecode).solc.compile
: Compiles the Solidity source code.JSON.parse
: Parses the compiler output from JSON format.contractData
: Extracts the compiled contract data, specifically the ABI and bytecode, for theSimpleStorage
contract.bytecode
: The compiled bytecode of the contract.abi
: The Application Binary Interface of the contract, which defines how to interact with it.
Deploy the Contract
const factory = new ethers.ContractFactory(abi, bytecode, signer);
const contract = await factory.deploy();
await contract.deployed();
console.log("SimpleStorage deployed to:", contract.address);
ethers.ContractFactory
: This is a factory for deploying new smart contracts. It takes the contract's ABI, bytecode, and signer as arguments.factory.deploy()
: Deploys the contract to the blockchain. This is an asynchronous operation, soawait
is used.contract.deployed()
: Waits until the deployment transaction is mined, ensuring the contract is deployed.contract.address
: Logs the deployed contract's address to the console.
Handle Errors
main().catch((error) => {
console.error(error);
process.exit(1);
});
.catch((error) => { ... })
: Catches any errors that occur during the execution of themain
function.console.error(error)
: Logs the error to the console.process.exit(1)
: Exits the process with a status code of 1, indicating an error occurred.
Install necessary dependencies:
Make sure you have ethers
and solc
installed. You can install them via npm:
npm install ethers solc
Run the deployment script:
Execute the script to deploy the contract:
node scripts/deploy.js
My GitHub profile where I have been actively contributing to various projects and repositories. I believe you might find my work interesting and valuable.
Here is the link to my GitHub profile: https://github.com/DCVglobalnetwork
I would be honored if you could follow me and explore my contributions.