Javascript
This tutorial will guide you through the process of deploying and utilizing your EVM based contract using Hardhat and Javascript on the agung network.
For developers working within the peaq/agung ecosystem change the rpc url and chain id in the hardhat.config file to the endpoint/value for peaq or agung. Make sure the connected wallet contains peaq/agung to pay for deployment. This will allow seamless integration and functionality within these environments.
- Contract deployment network: agung
- EVM development environment: Hardhat
- Contract language: Solidity
- Contract interaction language: Javascript
Getting Started
Make sure you have Node.js installed on your local machine. It is recommended to go through the SDK Quickstart to ensure you have Javascript installed and to understand the basic utilization of the SDK. If you have prior experience and you want to deploy your EVM contract to interact with its functions, please follow the instructions below.
Fund EVM wallet
Follow the guide Get $AGUNG tokens to send tokens to your Substrate based wallet. Once you have agung you will need to send it to an EVM addressed wallet to deploy EVM smart contracts. Reference the Fund Evm Wallet documentation to see how it is done.
Deploying & Interacting with EVM Contracts
To deploy contracts on a local IDE we will be using Hardhat, a development environment software specifically for Ethereum developers. It streamlines the building, testing, and deployment process in smart contract production. For a formal explanation is it recommended to read through the Hardhat Quickstart page. To understand how Hardhat is used for our purposes please follow the instructions below.
1. Install & Initialize Hardhat
Create a new repository in the IDE of your choice and install Hardhat with the cmd:
npm install --save-dev hardhat
Next you will need to create a Hardhat project. Select create an empty hardhat.config.js as shown below
npx hardhat init
Next install the hardhat-toolbox dependency
npm install @nomicfoundation/hardhat-toolbox
Now we need to create a folder structure to organize our contracts, deployments, etc. You can see the image below for a standard format.
- contracts: Solidity files where you create smart contracts
- ignition/modules: Stores the deployment script that triggers the creation of a new contract
- node_modules: Stores packages that the project depends on
- scripts: Used to interact with the deployed contract
- .gitignore: Files that won't be tracked by git (node_modules, package-lock.json, .env, etc)
- hardhat.config.js: Configuration file for Hardhat that establishes network connections, compiler options, etc.
- package-lock.json: Ensures that the same versions of all packages and their dependencies are consistent.
- package.json: Stores configuration data for the local Node.js project and dependencies
2. Setup .env & hardhat.config.js files
There is one especially important file we will need to create. In the root directory create a file and name it '.env'. It will be used to store the rpc network url and our wallet's secret key.
- Install dotenv with cmd
npm install dotenv
- Add 2 variables inside .env file to store secrets
AGUNG_RPC_URL="agung_url"
PRIVATE_KEY="my_private_key"
The AGUNG_RPC_URL can be found here, and the PRIVATE_KEY is the private key for your agung supplied EVM wallet. Once you find both values place inside the quotation marks.
Now we must update the configuration in the hardhat.config.js to make sure it will deploy the smart contract on the agung network.
require("@nomicfoundation/hardhat-toolbox");
require('dotenv').config();
const AGUNG_RPC_URL = process.env.AGUNG_RPC_URL; // agung rpc url from .env
const PRIVATE_KEY = process.env.PRIVATE_KEY; // Private key from .env file
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.19",
networks: {
agung: {
url: AGUNG_RPC_URL,
chainId: 9990,
accounts: [`0x${PRIVATE_KEY}`], // Make sure to add 0x prefix to the private key
},
},
};
3. Create HelloWorld.sol contract
Now we will need to write a smart contract to deploy to the agung network. We will use an oversimplified example to make basic functionalities as clear as possible.
Create a new file called HelloWorld.sol in your contracts folder. Paste the following code into the .sol file:
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.19;
contract HelloWorld {
string private hello_string;
constructor(string memory _hello) {
hello_string = _hello;
}
function hello() public view returns (string memory) {
return hello_string;
}
function setHello(string memory _hello) public {
hello_string = _hello;
}
}
The contract is basic. It contains a constructor that sets the hello string initially, a getter function named hello to return the previously set string, and finally a setter named setHello to change the string value.
4. Create deployment Script
Now we must create the deployment script. Create a .js filed named HelloWorld.js inside of the modules folder found in the ignition directory.
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
module.exports = buildModule("HelloWorldModule", (m) => {
const greeting = "Hello World";
const HelloWorld = m.contract("HelloWorld", [greeting]);
return { HelloWorld };
});
The following code can be used to deploy the contract with the greeting of your choice.
5. Deploy the contract
Once all the prior steps have been completed you are ready to deploy the contract to the agung test network. To do so you can run the cmd in the root directory of the project:
npx hardhat ignition deploy ./ignition/modules/HelloWorld.js --network agung
The image below shows the expected behavior of a successful deployment. The contract address will be printed to the console. Record this value, as it will be needed for the interaction section.
6. Interacting with the Deployed EVM contract
Finally, an interaction script will be created to call the deployed contract's functions. Inside of the scripts directory create a new file called interact.js. Inside the file you can paste the following:
const contractAddress = ""; // Replace with your contract's address which is outputted after deployment
const ContractArtifact = require('../artifacts/contracts/HelloWorld.sol/HelloWorld.json');
async function main() {
// You can use a Hardhat runtime environment property to get a contract factory and then get a contract
const [deployer] = await ethers.getSigners();
// Get the contract instance at a specific address with the ABI and the signer
const contract = new ethers.Contract(contractAddress, ContractArtifact.abi, deployer);
// Now you can call your contract's methods using the contract object
// Perform a read
const helloWorld = await contract.hello();
console.log('Greeting:', helloWorld);
// Perform a write
const tx = await contract.setHello("Goodbye World");
await tx.wait(); // Wait for the transaction to be completed
// Ensure the greeting was changed
const goodbyeWorld = await contract.hello();
console.log('Greeting:', goodbyeWorld);
// Perform a write to change back to original strin
const tx2 = await contract.setHello("Hello World");
await tx2.wait(); // Wait for the transaction to be completed
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
The following cmd will execute the interact.js script that calls the functions on the deployed contract.
npx hardhat run scripts/interact.js --network agung
Congrats! You have just deployed and interacted with an EVM Smart Contract on the agung test network locally!