Skip to main content

viem

Viem is a typescript interface for Ethereum that provides low-level primitives for interacting with Ethereum and other EVM-Compatible blockchain. With Klaytn supporting features for Ethereum Equivalence, Ethereum tools such as viem can be used on Klaytn without any significant modifications.

For that reason, developers can leverage this compatibility and use the viem library to interact with a Klaytn node.

In this guide, you'll learn how to use the viem library to read data from the blockchain, send a transaction, and interact with an existing contract on the Klaytn Network.

Prerequisites

  • Code-Editor: a source-code editor such as VS-Code.
  • Metamask: used to deploy the contracts, sign transactions and interact with the contracts.
  • RPC Endpoint: you can get this from one of the supported Endpoint Providers.
  • Test KLAY from Faucet: fund your account with sufficient KLAY.
  • NodeJS and NPM
  • TS-node: used for running TypeScript scripts.

Setup Project

To get started, you need to create a project directory to house the files to be created in this guide.


mkdir viem-example
cd viem-example

1. Install viem

To install viem run the following command in your terminal:


npm i viem

In this tutorial, we will create a bunch of scripts file to read data from the blockchain, send transactions, and also interact with existing smart contract. To get started, you need to know how to set up viem for each of your script files.

2. Set up Public Client & Transport

Firstly, you need to set up your Public Client with a desired Transport & Chain. A Public Client is an interface to public JSON-RPC API methods such as retrieving block numbers, transactions, reading from smart contracts, etc through Public Actions.


import { createPublicClient, http } from 'viem'
import { klaytnBaobab } from 'viem/chains'
const client = createPublicClient({
chain: klaytnBaobab,
transport: http("https://klaytn-baobab-rpc.allthatnode.com:8551"),
})

3. Set up Wallet Client and account

Secondly, you need to set a wallet client to interact with an account. With wallet client, you can perform actions such as retrieving accounts, executing transactions, signing messages, etc through Wallet Actions.


import { createWalletClient } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
const walletClient = createWalletClient({
chain: klaytnBaobab,
transport: http("https://klaytn-baobab-rpc.allthatnode.com:8551")
})
const account = privateKeyToAccount("PASTE PRIVATE KEY HERE");

Reading data from the blockchain

To read data from the blockchain, create a new read.ts file in your project folder by running this command:


touch read.ts

After creating this file, set up your public client as done in the set up section above. In this section, you will learn how to read data from the blockchain (e.g., blockNumber, KLAY balance).

To see this in action, paste the following code in your read.ts.


import { createPublicClient, http, formatEther } from 'viem'
import { klaytnBaobab } from 'viem/chains'
const client = createPublicClient({
chain: klaytnBaobab,
transport: http("https://klaytn-baobab-rpc.allthatnode.com:8551"),
})
async function getBlockNumber() {
const blockNumber = await client.getBlockNumber()
console.log(`Current block number is: ${blockNumber}`);
}
async function getKlayBalance() {
const balance = await client.getBalance({
address: '0x75Bc50a5664657c869Edc0E058d192EeEfD570eb',
})
const formatBal = formatEther(balance);
console.log(`Current KLAY balance is ${formatBal}`);
}
getBlockNumber();
getKlayBalance();

Output

To run the script and read data from the blockchain, paste the following command in your terminal:


npx ts-node read.ts

If the transaction was successful, you'll see the block number and user’s KLAY balance in your terminal.

Sending a transaction to the blockchain

To send a transaction to the blockchain, create a new send.ts file in your project folder by running this command:


touch send.ts

After creating this file, set up your wallet client as done in the set up section above. In this section, you will learn how to send a transaction to the blockchain (for example, send KLAY to an address).

To see this in action, paste the following code in your send.ts.


import { createWalletClient, http, parseEther } from 'viem'
import { klaytnBaobab } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'
const walletClient = createWalletClient({
chain: klaytnBaobab,
transport: http("https://klaytn-baobab-rpc.allthatnode.com:8551")
})
const account = privateKeyToAccount("PASTE PRIVATE KEY");
async function sendKlayToRecipient() {
const hash = await walletClient.sendTransaction({
account,
to: "PASTE RECIPIENT ADDRESS",
value: parseEther('0.01')
})
console.log(`Send KLAY tx hash is: ${hash}`);
}
sendKlayToRecipient();

Output

To run the script and send transaction to the blockchain, paste the following command in your terminal:


npx ts-node send.ts

If the transaction was successful, you'll see the transaction hash logged in your terminal.

Interacting with smart contracts

To interact with an existing smart contract on Klaytn, create a new interact.ts file in your project folder by running this command:


touch interact.ts

After creating this file, set up your public and wallet client as done in the set up section above. In this section, you will use viem to both:

  • Read from the contract; and
  • Write to a contract.

For the purpose of this guide, a simple_storage contract was compiled and deployed on Remix IDE. For that reason, we will read from this contract by calling the retrieve function, and also send a transaction to this contract by calling the store function.

1. Read from contract

To read from the contract, we used readContract method which Internally  uses a Public Client to call the call action with ABI-encoded data. To see this in action, paste the following code in your interact.js.


import { createPublicClient, http } from 'viem'
import { klaytnBaobab } from 'viem/chains'
const client = createPublicClient({
chain: klaytnBaobab,
transport: http("https://klaytn-baobab-rpc.allthatnode.com:8551"),
})
const abi = [
{
"inputs": [],
"name": "retrieve",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "num",
"type": "uint256"
}
],
"name": "store",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
async function readFromContract() {
const retrieve = await client.readContract({
address: "0x472a1226796b6a0918DC78d40b87d750881fdbDC", // Contract Address
abi: abi,
functionName: 'retrieve'
})
console.log(`Value read from contract is: ${retrieve}`);
}

2. Write to contract

To write to the contract, we used writeContract method which Internally uses a Wallet Client to call the sendTransaction action with ABI-encoded data. To see this in action, paste the following code in your interact.js.


import { createWalletClient, http } from 'viem'
import { klaytnBaobab } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'
const walletClient = createWalletClient({
chain: klaytnBaobab,
transport: http("https://klaytn-baobab-rpc.allthatnode.com:8551")
})
const account = privateKeyToAccount("PASTE PRIVATE KEY");
const abi = [
{
"inputs": [],
"name": "retrieve",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "num",
"type": "uint256"
}
],
"name": "store",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
async function writeToContract() {
const { request } = await client.simulateContract({
address: "0x472a1226796b6a0918DC78d40b87d750881fdbDC", // Contract Address
abi: abi,
functionName: "store",
account: account,
args: [694n],
})
const hash = await walletClient.writeContract(request)
console.log(`Hash from writing to a contract: ${hash}`);
}
writeToContract();

Output

To run the script and interact with smart contracts, paste the following command in your terminal:


npx ts-node interact.ts

If the transaction was successful, you'll see the transaction hash and the value stored in your terminal.

For more in-depth guide on viem, please refer to viem docs. Also, you can find the full implementation of the code for this guide on GitHub.

Make this page better