Anyone who has built applications or been a user of Ethereum mainnet is likely familiar with its...
How to Deploy a Contract with Foundry on Hedera
Deploying smart contracts efficiently and securely is paramount for blockchain developers. Hedera Hashgraph stands out with its unique consensus algorithm and high chain throughput, offering developers a robust platform for decentralized applications. Combining this with Foundry, a smart contract development toolkit designed for Solidity, developers can streamline the process of building, testing, and deploying smart contracts. This guide delves into the step-by-step procedure for deploying a smart contract on Hedera using Foundry, providing a comprehensive overview for both novice and experienced developers.
Foundry offers a powerful suite of tools that simplifies the development lifecycle of smart contracts. By leveraging its capabilities, developers can benefit from enhanced testing frameworks, seamless integration, and efficient deployment processes. This guide will walk you through setting up Foundry, writing your first smart contract, and deploying it on the Hedera network. Whether you're looking to build decentralized applications, automate transactions, or explore new possibilities in the blockchain space, this tutorial will equip you with the essential knowledge and practical skills needed to harness the full potential of Hedera and Foundry.
Setting Up Your Development Environment
Before diving into smart contract deployment, it's essential to set up a robust development environment. This section will guide you through the installation of necessary tools and dependencies, ensuring a smooth workflow as you progress through this tutorial.
Prerequisites:
- A valid Hedera testnet wallet and private key. Ensure this wallet is completely separate from all production wallets!
- Node.js and npm: Ensure you have Node.js (version 14.x or later) and npm installed. You can download and install them from Node.js.
- Foundry: Foundry is a powerful smart contract development toolkit. To install Foundry, run the following command in your terminal: curl -L https://foundry.paradigm.xyz | bash
- Hedera CLI: The Hedera Command Line Interface (CLI) tool is crucial for interacting with the Hedera network. Install it using npm: npm install -g @hashgraph/hedera-cli
- Solidity Compiler: Foundry requires the Solidity compiler. You can install it via npm: npm install -g solc
Creating the Project
Step 1: Setting Up Foundry
Once you have installed Foundry, initialize a new project. Open your terminal and execute the following commands:
mkdir my-hedera-project && cd my-hedera-project
forge init
Your project will now populate with a series of directories. The “src” directory will contain a default “Counter.sol” contract
Step 2: Writing the Smart Contract
Navigate to the src directory and create a new Solidity file named HelloHedera.sol:
cd contracts
touch HelloHedera.sol
Open HelloHedera.sol in your preferred text editor and add the following code:
// Solidity:
pragma solidity ^0.8.0;
contract HelloHedera {
string public message;
uint256 public number;
constructor(string memory initialMessage) {
message = initialMessage;
}
function updateMessage(string memory newMessage) public {
message = newMessage;
}
function setNumber(uint256 newNumber) public {
number = newNumber;
}
function increment() public {
number++;
}
}
Step 3: Configuring Foundry
Similar to Hardhat environments, it is important that the compiler version lines up with the Solidity version used when writing the smart contract. For the purposes of this tutorial, we used ^0.8.0, therefore it is prudent that the compiler version match this.
To compile your smart contract, configure Foundry by editing the foundry.toml file. Ensure it includes the following TOML configuration:
[profile.default]
compiler_version = "0.8.0"
src = "src"
out = "out"
libs = ["lib"]
Step 4: Compiling the Smart Contract
With the contract written and configuration in place, the next step is to compile the smart contract. To compile using Foundry:
forge build
If everything is set up correctly, you should see a build directory created with the compiled contract artifacts. We are getting close now!
Step 5: Deploying to Hedera
For deploying to the Hedera network, you'll need your Hedera account ID and private key. If you don’t have an account, you can create a new one using the Hedera CLI. Just don’t forget to fund it with testnet tokens so that you can actually deploy the contract later:
hedera-cli account create
Or
forge create --rpc-url <your_validation_cloud_Hedera_rpc_url> --private-key <your_private_key_hex> src/HelloHedera.sol:HelloHedera –constructor-args <what you want to the constructor parameter to be>
Note the added constructor args parameter, since the contract does contain a constructor.
You can also optionally create a script that deploys the contract. In this case, you can create a new file named deploy.js:
cd scripts
touch deploy.js
Add the following JavaScript code to deploy.js:
const { Client, FileCreateTransaction, ContractCreateTransaction, ContractFunctionParameters, Hbar } = require('@hashgraph/sdk');
require('dotenv').config();
const fs = require('fs');
async function main() {
const client = Client.forTestnet();
client.setOperator(process.env.MY_ACCOUNT_ID, process.env.MY_PRIVATE_KEY);
const contractBytecode = fs.readFileSync('out/HelloHedera.sol/HelloHedera.json').bytecode;
const fileCreateTx = new FileCreateTransaction()
.setContents(contractBytecode)
.setMaxTransactionFee(new Hbar(2));
const fileCreateSubmit = await fileCreateTx.execute(client);
const fileCreateReceipt = await fileCreateSubmit.getReceipt(client);
const bytecodeFileId = fileCreateReceipt.fileId;
const contractCreateTx = new ContractCreateTransaction()
.setBytecodeFileId(bytecodeFileId)
.setConstructorParameters(new ContractFunctionParameters().addString("Hello, Hedera!"))
.setMaxTransactionFee(new Hbar(10));
const contractCreateSubmit = await contractCreateTx.execute(client);
const contractCreateReceipt = await contractCreateSubmit.getReceipt(client);
const contractId = contractCreateReceipt.contractId;
console.log(`Contract ID: ${contractId}`);
}
main();
Step 6: Running the Deployment Script
Create a .env file in the root of your project and add your Hedera credentials:
MY_ACCOUNT_ID=your-account-id
MY_PRIVATE_KEY=your-private-key-hex
Finally, execute the deployment script:
node scripts/deploy.js
If successful, you’ll see the contract ID printed in the terminal, indicating your smart contract is now deployed on the Hedera network.
Interacting with the Deployed Smart Contract
After successfully deploying your smart contract, the next step is to interact with it. This section will guide you through writing a simple script to interact with your deployed contract and retrieve the message.
Step 7: Writing the Interaction Script
Create a new file named interact.js in the scripts directory:
touch interact.js
Add the following JavaScript code to interact.js:
const { Client, ContractCallQuery, ContractExecuteTransaction, ContractFunctionParameters, Hbar } = require('@hashgraph/sdk');
require('dotenv').config();
async function main() {
const client = Client.forTestnet();
client.setOperator(process.env.MY_ACCOUNT_ID, process.env.MY_PRIVATE_KEY);
const contractId = '0.0.12345'; // Replace with your contract ID
// Step 1: Query the current message
let query = new ContractCallQuery()
.setContractId(contractId)
.setGas(100000)
.setFunction("message");
let response = await query.execute(client);
let message = response.getString(0);
console.log(`Initial contract message: ${message}`);
// Step 2: Update the message
const newMessage = "Hello, Hedera - Updated!";
const updateMessageTx = new ContractExecuteTransaction()
.setContractId(contractId)
.setGas(100000)
.setFunction("updateMessage", new ContractFunctionParameters().addString(newMessage))
.setMaxTransactionFee(new Hbar(10));
await updateMessageTx.execute(client);
// Step 3: Query the updated message
query = new ContractCallQuery()
.setContractId(contractId)
.setGas(100000)
.setFunction("message");
response = await query.execute(client);
message = response.getString(0);
console.log(`Updated contract message: ${message}`);
}
main();
- Client Setup: Initializes the Hedera client with your account credentials.
- Contract ID: Uses the contract ID obtained from the deployment step.
- Contract Call Query: Sets up a query to call the message function of the deployed contract.
- Execute Query: Executes the query and retrieves the message stored in the contract.
Step 8: Running the Interaction Script
Ensure your .env file contains the correct Hedera credentials, and then execute the interaction script:
node scripts/interact.js
If everything is set up correctly, you should see the contract's message printed in the terminal. Try to interact with the increment functions for an additional exercise.
By following this tutorial, you have successfully set up your development environment, written and deployed a smart contract on the Hedera network, and interacted with it using JavaScript. This process demonstrates the utility of Foundry with Hedera, enabling efficient smart contract development and interaction. As you continue exploring Hedera's capabilities, you'll soon be able to build more complex and sophisticated decentralized applications.
Validation Cloud x Hedera
Validation Cloud is the leading platform that supports Hedera via our Node API. Connect to Hedera Mainnet or Testnet on our Node API. Get started with our JSON RPC How-To Guide, our Mirror Nodes How-To Guide, or check out our guide to Hashpack.
About Validation Cloud
Validation Cloud is a Web3 data streaming and infrastructure company that connects organizations into Web3 through a fast, scalable, and intelligent platform. Headquartered in Zug, Switzerland, Validation Cloud offers highly performant and customizable products in staking, node, and data-as-a-service. Learn more at Validationcloud.io | LinkedIn | X