A question often asked by newbie learners while developing the smart contract is, “How to connect my frontend code with the smart contract?โ.
The answer should be web3.js
till day. web3.js
has a collection of libraries that allows you to interact with a local or remote Ethereum node. Consider it an interface connecting the front end with the blockchain world.
Today we will see how a simple, smart contract interacts with the react frontend using web3.js
.
I have my react app initialized inside the truffle development environment. We also have a very simple smart contract that will be deployed soon on the locally running test blockchain. In our case, the locally running test blockchain is ganache.
Letโs connect with the local blockchain first.
Connect Ganache with Truffle
Now move to ganache and create a new workspace. Locate the directory of “truffle-config.js
” file and save the workspace. You will get ten demo accounts that can be used for transactions on the local blockchain.
Move to “truffle-config.js
” file and uncomment the development section. Change the port to 7545, as it is the port of the ganache.
Now get back to the terminal and type:
truffle migrate
If the connection is established, you will see some balance deducted from the first account of the ganache.
Connect Metamask with Ganache
Itโs time to connect our locally running Ethereum network with the Metamask wallet.
Move to Metamask and choose the “add network” option from the dropdown. Letโs change the configuration. I am keeping the network name as ganache_host
. The new RPC URL would be as same as the ganache RPC SERVER i.e.;
Network Name: ganache_host
New RPC URL: http://127.0.0.1:7545
Chain ID: 1337
Currency symbol: eth
Press the save button. Your new ganache network is ready.
Connect Metamask to the React Frontend
To connect the front end with the Metamask wallet, we need to initiate web3. Move to the frontend directory by using the terminal and type:
npm install --save web3
Now import the web3 in the app.js
file.
import Web3 from "web3";
In the user interface, we will create a simple button connecting us with the Metamask wallet when clicked.
<button onClick={onConnect}>Connect to metamask</button>
An onConnect
function will be initiated when we click the “Connect to metamaskโ button. Letโs define the onConnect
function
const onConnect = async () => { let provider = window.ethereum; if (typeof provider !== "undefined") { await provider.request({ method: "eth_requestAccounts" }); const web3 = new Web3(provider); const accounts = await web3.eth.getAccounts(); const account = accounts[0]; console.log(account); } else { console.log("Non-ethereum browser detected.Please install Metamask"); } };
onConnect
is an async await
function that will trigger if the Metamask is installed on the browser. Otherwise, it will throw an error. You can consider “window.ethereum
โ as a synonym of Metamask.
If the Metamask connects with the user interface, the provider will request the accounts from the ganache. Then we will create an instance of the web3 with the provider. The web3.eth.getAccounts()
method will help us to get all the account’s addresses from the ganache. We will use the first account address as our account.
Deploy the Smart Contract
Let’s get familiar with our simple smart-contract. We have declared myNumber
as a publicly accessible unsigned integer.
We have created a function setMyNumber()
which allows us to change that number after the deployment. We will be able to set the number as we desire. So itโs a straightforward one. Just a couple of lines. Now let’s deploy the contract.
To deploy the contract, we need to create a migration file under the migration folder, the same as 1_initial_migration.js
. Let’s name it 2_twist_migration.js
. Now create a copy of the “1_initial_migrations.json
” file and replace the “migrations” word with our contract name “twist”.
Go back to the terminal and type
truffle migrate
truffle automatically understands which contracts to migrate. It will start deploying the 2nd one.
If the smart contract is deployed properly, you will see a “twist.json
” file inside the build
folder. That is actually the ABI or Application Binary Interface. This is simply a JSON format of our smart contract.
We will use this ABI to communicate with the smart contract.
But first, we need to create an instance of the abi inside the source folder so that the react app can locate the directory. There are several ways we can do it. But I will follow the easiest one: copy and paste the file inside the source folder.
Interact with the Smart Contract
Itโs time to import the file to app.js
from the directory.
import configuration from "./twist.json";
Now we can create an instance of the address and the ABI.
const contractAddress = configuration.networks["5777"].address; const contractABI = configuration.abi; const web3 = new Web3(Web3.givenProvider || "http://127.0.0.1:7545"); const contract = new web3.eth.Contract(contractABI, contractAddress);
We have just created a new instance of web3. web3.eth.contract
is a method of the web3 that will allow us to interact with the deployed smart contract. It takes two parameters; contractABI
and contractAddress
.
๐ Reference: https://web3js.readthedocs.io/en/v1.2.11/web3-eth.html
Since we have created an instance of our smart contract, we can now call different functions from the smart contracts.
Let’s call the setMyNumber()
function from the smart contract. โcontract.methods
โ will help us to call any functions or methods from the smart contract.
Set the myNumber
as 10. The send()
method is used to indicate the account from which the transaction will take place.
Now to check if the myNumber
is set to 10, call myNumber
variable of the smart contract from the onConnect
function.
let theNumber = await contract.methods.myNumber().call(); console.log(theNumber);
Move to the browser and check the console. I hope you get the myNumber
on the screen, which will be 10.
To display the number on the user interface, I will create a finalNumber
state variable with the help of the useState
hook of react.
const [finalNumber, setFinalNumber] = useState("");
Now just set theNumber
as the finalNumber
from the onConnect
function.
setFinalNumber(theNumber);
We will create a heading with <h1>
tag inside the return function to display the number on the user interface.
<h1>The number from the smart contract is : {finalNumber}</h1>
The finalNumber
will be displayed as dynamic content on the UI.
If you refresh the page and hit the connect to Metamask button, the number from the smart contract will be displayed on the UI.
Change the number
Now suppose you want to change the myNumber
integer of the smart contract. You can do it by calling the setMyNumber
function from the contract again.
Letโs call the function inside the onConnect
function.
Or you can just change the input inside the setMyNumber()
that we have previously declared as 10.
await contract.methods .setMyNumber(30) .send({ from: account });
We have set the new number as 30.
If you go back to the browser now and hit the “connect to metamask” button, Metamask will ask for permission to commit the transaction and the new number will be set as myNumber
. Refresh the page again and connect to Metamask; the new number will be displayed on the user interface.
That was all for today. We have seen how to call functions or methods and fetch data from the smart contract by using web3. In the next part, we will do the same thing from the Remix IDE. Hope this will be an interesting one.
๐ Recommended Tutorial: Learn to Build Smart Contracts in React with web3.js: Hereโs How! (2/2)