Interacting with a Smart Contract
Before starting this tutorial on interacting with a smart contract, you should have completed part 1 — Hello World Smart Contract (creating and deploying a smart contract). In part 3 we'll go over submitting our contract to Etherscan so anyone can understand how to interact with it!
Part 2: Interact with your Smart Contract
Now that we've successfully deployed a smart contract to the ropsten network, let's test out our web3 skills and interact with it!
Step 1: Create a interact.js file
This is the file where we'll write our interaction script. We'll be using the Ethers.js library that you previously installed in Part 1.
Inside your scripts/
folder for the hardhat tutorial, or your home directory for the Truffle tutorial, create a new file named interacts.js
add the following lines of code:
// interact.js
const API_KEY = process.env.API_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS;
Step 2: Update your .env file
We will be using new environment variables, so we need to define them in our .env
file and make sure that the dotenv
module is loading these variables.
We'll need to add a definition for our Alchemy API_KEY
and the CONTRACT_ADDRESS
where your smart contract was deployed.
Your .env
file should look something like this:
# .env
API_URL = "https://eth-ropsten.alchemyapi.io/v2/"
API_KEY = ""
PRIVATE_KEY = ""
CONTRACT_ADDRESS = "0x"
Step 3: Grab your contract ABI
Our contract ABI (Application Binary Interface) is the interface to interact with our smart contract. You can learn more about Contract ABIs in our eth_getLogs deep dive here. Hardhat (and Truffle) automatically generates an ABI for us and saves it in the HelloWorld.json file.
In order to use this we'll need to parse out the contents by adding the following lines of code to our contract-interact.js
file:
// interact.js
// For Truffle
const contract = require("./build/contracts/HelloWorld.json");
// For Hardhat
const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json");
If you want to see the ABI you can print it to your console:
console.log(JSON.stringify(contract.abi));
To run interact.js
and see your ABI printed to the console navigate to your terminal and run
Hardhat:
npx hardhat run scripts/interact.js
Truffle:
node interact.js
Step 4: Create an instance of your contract
In order to interact with our contract we need to create an instance of it in our code. To do so with Ethers.js, we'll need to work with three concepts:
Provider - this is a node provider that gives you read and write access to the blockchain.
Signer - this represents an Ethereum account that has the ability to sign transactions.
Contract - this is an Ethers.js object that represents a specific contract deployed on-chain.
We'll use the contract ABI from the previous step to create our instance of the contract:
// interact.js
// Provider
const alchemyProvider = new ethers.providers.AlchemyProvider(network="ropsten", API_KEY);
// Signer
const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider);
// Contract
const helloWorldContract = new ethers.Contract(CONTRACT_ADDRESS, contract.abi, signer);
You can read more about Providers, Signers, and Contracts in Alchemy's Ethers.js explainers.
Step 5: Read the init message
Remember when we deployed our contract with theinitMessage = "Hello world!"
? We are now going to read that message stored in our smart contract and print it to the console.
In JavaScript we use asynchronous functions to interact with networks.
Use the code below to call themessage
function in our smart contract and read the init message:
// interact.js
// ...
async function main() {
const message = await helloWorldContract.message();
console.log("The message is: " + message);
}
main();
After running the file using npx hardhat run scripts/interact.js
in the terminal we should see this response:
The message is: Hello world!
Congrats! You've just successfully read smart contract data from the Ethereum blockchain, way to go!
Step 6: Update the message
Now instead of just reading the message, we can also update the message saved in our smart contract using the update
function! Pretty cool, right?
In order to do so we can directly call the update
function on our instantiated Contract object, like so:
// interact.js
// ...
async function main() {
const message = await helloWorldContract.message();
console.log("The message is: " + message);
console.log("Updating the message...");
const tx = await helloWorldContract.update("This is the new message.");
await tx.wait();
}
main();
Note that we make a call to .wait()
on the returned transaction object. This ensures that our script waits for the transaction to be mined on the blockchain before proceeding onwards. If you were to leave this line out, your script may not be able to see the updated message
value in your contract.
Step 7: Read the new message
You should be able to repeat Step 5 to read the updated message
value. Take a moment and see if you can make the changes necessary to print out that new value!
If you need a hint, here's what your interact.js
file should look like at this point:
// interact.js
const API_KEY = process.env.API_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS;
const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json");
// provider - Alchemy
const alchemyProvider = new ethers.providers.AlchemyProvider(network="ropsten", API_KEY);
// signer - you
const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider);
// contract instance
const helloWorldContract = new ethers.Contract(CONTRACT_ADDRESS, contract.abi, signer);
async function main() {
const message = await helloWorldContract.message();
console.log("The message is: " + message);
console.log("Updating the message...");
const tx = await helloWorldContract.update("this is the new message");
await tx.wait();
const newMessage = await helloWorldContract.message();
console.log("The new message is: " + newMessage);
}
main();
Now just run the script and you should be able to see the old message, the updating status, and the new message printed out to your terminal!
npx hardhat run scripts/interact.js --network ropsten
The message is: Hello World!
Updating the message...
The new message is: This is the new message.
While you are running that script, you may notice that the Updating the message...
step takes a while to load before the new message is set. That is due to the mining process! If you are curious about how to track transactions while they are being mined, visit the Alchemy mempool to see the status of your transaction (whether it's pending, mined, or got dropped by the network). If your transaction got dropped, it's also helpful to check Ropsten Etherscan and search for your transaction hash.
And that's it! You've now deployed AND interacted with an Ethereum smart contract. If you'd like to publish your contract to Etherscan so that anyone will know how to interact with it, check out part 3: submitting your smart contract to etherscan! 🎉
Once you complete this tutorial, let us know how your experience was or if you have any feedback by tagging us on Twitter @alchemyplatform!
Related articles
Fostering an Open Ecosystem
Alchemy’s mission is to bring the next billion users onchain. Getting there will require a fast-growing ecosystem of projects working to build the future of web3.
2023 Web3 Development Report
Web3 developer activity reaches all-time-highs as new rollup frameworks and account abstraction take root.
Arbitrum Account Abstraction Workshop Series
Arbitrum and Alchemy are partnering together to bring you an exciting new educational series on Account Abstraction!