Skip to main content

web3.js

web3.js is a Javascript library for building on EVM-compatible networks.

It allows developers to interact with smart contracts, send transactions, and retrieve data from the network.

Installation​

This guide assumes you have the latest version of Node.js installed.

To install web3, run the following command:


_10
npm install web3

Connecting to Flow​

To use web3 in your project, start by imporing the module and initializing your Web3 provider the desired Flow RPC endpoint.


_10
const { Web3 } = require('web3')
_10
const web3 = new Web3('https://previewnet.evm.nodes.onflow.org')

info

Currently, only Previewnet is available. More networks are coming soon, see here for more info.

Interacting With Smart Contracts​

The web3 library allows developers to interact with smart contracts via the web3.eth.Contract API.

For this example we will use the following "Storage" contract, deployed on the Flow Previewnet to the address 0x4c7784ae96e7cfcf0224a95059573e96f03a4e70. However, if you wish to deploy your own contract, see the how to do so using Hardhat or Remix.


_14
// SPDX-License-Identifier: MIT
_14
pragma solidity ^0.8.0;
_14
_14
contract Storage {
_14
uint256 public storedData;
_14
_14
function store(uint256 x) public {
_14
storedData = x;
_14
}
_14
_14
function retrieve() public view returns (uint256) {
_14
return storedData;
_14
}
_14
}

The ABI for this contract can be generated using the solc compiler, or by using a tool like Hardhat or Remix.

Now that we have both the ABI and address of the contract, we can create a new Contract object.


_40
// Replace with the ABI of the deployed contract
_40
const abi = [
_40
{
_40
"inputs": [],
_40
"stateMutability": "nonpayable",
_40
"type": "constructor"
_40
},
_40
{
_40
"inputs": [
_40
{
_40
"internalType": "uint256",
_40
"name": "x",
_40
"type": "uint256"
_40
}
_40
],
_40
"name": "store",
_40
"outputs": [],
_40
"stateMutability": "nonpayable",
_40
"type": "function"
_40
},
_40
{
_40
"inputs": [],
_40
"name": "retrieve",
_40
"outputs": [
_40
{
_40
"internalType": "uint256",
_40
"name": "",
_40
"type": "uint256"
_40
}
_40
],
_40
"stateMutability": "view",
_40
"type": "function"
_40
}
_40
]
_40
_40
// Replace with the address of the deployed contract
_40
const contractAddress = "0x4c7784ae96e7cfcf0224a95059573e96f03a4e70"
_40
_40
// Create a new contract object with the ABI and address
_40
const contract = new web3.eth.Contract(abi, contractAddress)

By using this Contract object, we can now interact with the on-chain contract.

Querying State​

We can query data from the contract by using the call function on one of the contract's methods. This will not mutate the state and will not send a transaction.


_10
const result = await contract.methods.retrieve().call()
_10
console.log(result) // "0" (if the contract has not been interacted with yet)

Mutating State​

We can mutate the state of the contract by sending a transaction to the network.

In order to send a transaction to the network, you will need an account with sufficient funds to pay for the transaction.

For Flow Previewnet, you can fund your account using the Flow Faucet. You will need to use the private key of the account to sign the transaction.

First, we will need to be able to sign a transaction using an account. To do this, we can use the privateKeyToAccount function to create an Web3Account object from a private key.


_10
// You must replace this with the private key of the account you wish to use
_10
const account = web3.eth.accounts.privateKeyToAccount('0x1234')

Then, we can sign a transaction using the user's account and send it to the network.


_13
const newValue = 1337 // Replace with any value you want to store
_13
_13
let signed = await account.signTransaction({
_13
from: account.address,
_13
to: contractAddress,
_13
data: contract.methods.store(newValue).encodeABI(),
_13
gasPrice: 0,
_13
})
_13
_13
// Send signed transaction that stores a new value
_13
result = await web3.eth.sendSignedTransaction(signed.rawTransaction)
_13
_13
console.log(result) // { status: 1, transactionHash: '0x1234', ... }

Now that the transaction has been sent, the contract's state has been updated. We an verify this by querying the contract's state again.


_10
const result = await contract.methods.retrieve().call()
_10
console.log(result) // "1337"

For more information about using smart contracts in web3.js, see the official documentation.