इस ट्यूटोरियल में, हम Viem टाइपस्क्रिप्ट लाइब्रेरी + React (Next.js) के साथ एक पूरी तरह से कार्यात्मक Dapp बनाएंगे। हम आपके वॉलेट को कनेक्ट करने, क्रिप्टो ट्रांसफर करने, स्मार्ट कॉन्ट्रैक्ट्स के साथ इंटरैक्ट करने (जैसे कि NFT मिंट करना) और ब्लॉकचेन को क्वेरी करने के आवश्यक चरणों को कवर करेंगे।
Viem मौजूदा लो-लेवल Ethereum इंटरफेस जैसे web3.js और ethers.js का एक Typescript विकल्प है। यह ब्राउज़र नेटिव BigInt का समर्थन करता है और स्वचालित रूप से ABIs और EIP-712 से infer types करता है। इसका बंडल साइज़ 35kb है, अंतिम बंडल को कम करने के लिए ट्री-शेकेबल डिज़ाइन है, और 99.8% टेस्ट कवरेज है। उनके benchmarks and full documentation देखें।
हमने इस ट्यूटोरियल को इन-लाइन कोड कमेंट्स के माध्यम से दिए गए संक्षिप्त स्पष्टीकरण के साथ तैयार किया है। बस कोड को कॉपी-पेस्ट करें और स्पष्टीकरण पढ़ें।
यहाँ ट्यूटोरियल की रूपरेखा दी गई है:
- Viem शब्दावली स्पष्टीकरण: Client | Transport | Chain
- शुरुआत करना: React + Viem के साथ Client और Transport सेटअप करें
- भाग 1: React + Viem के साथ Web3 वॉलेट से कनेक्ट करें
- भाग 2: React + Viem के साथ क्रिप्टो ट्रांसफर करना
- भाग 3: React + Viem के साथ NFT मिंट करना
आप जो बनाएंगे उसकी एक झलक:

Viem शब्दावली स्पष्टीकरण: Client | Transport | Chain
Viem में तीन मूलभूत अवधारणाएँ हैं: Client, Transport और Chain
- viem में Client, Ether.js Provider के समान है। यह Ethereum पर सामान्य कार्य करने के लिए टाइपस्क्रिप्ट फ़ंक्शंस प्रदान करता है। कार्य के आधार पर, यह तीन प्रकार के क्लाइंट्स में से किसी एक के अंतर्गत आएगा।
- Public Client “सार्वजनिक” JSON RPC API विधियों का एक इंटरफ़ेस है, जैसे कि ब्लॉक नंबर प्राप्त करना, अकाउंट बैलेंस क्वेरी करना, स्मार्ट कॉन्ट्रैक्ट्स पर “view” फ़ंक्शंस तक पहुँचना, और अन्य रीड-ओनली, नॉन-स्टेट-चेंजिंग ऑपरेशन्स। इन फ़ंक्शंस को Public Actions कहा जाता है।
- Wallet Client Ethereum अकाउंट्स के साथ इंटरैक्ट करने का एक इंटरफ़ेस है, जैसे कि लेनदेन भेजना, संदेशों पर हस्ताक्षर करना, पतों का अनुरोध करना, चेन बदलना, और उपयोगकर्ता की अनुमति की आवश्यकता वाले ऑपरेशन्स। उदाहरण के लिए, NFT मिंट करना एक स्टेट-चेंजिंग कार्य है, इसलिए यह वॉलेट क्लाइंट के अंतर्गत किया जाएगा। इन फ़ंक्शंस को Wallet Actions कहा जाता है।
- Test Client का उपयोग परीक्षण के लिए सिम्युलेटेड लेनदेन बनाने के लिए किया जाता है। इसका उपयोग आमतौर पर यूनिट टेस्ट में किया जाएगा।
- Transport को Client के साथ इंस्टेंटिएट (instantiate) किया जाता है, यह अनुरोधों को निष्पादित करने के लिए मध्यस्थ परत (intermediary layer) का प्रतिनिधित्व करता है। Transport तीन प्रकार के होते हैं:
- HTTP Transport, जो HTTP JSON-RPC का उपयोग करता है;
- WebSocket JSON-RPC के माध्यम से रीयल-टाइम कनेक्शन के लिए WebSocket Transport;
- Custom Transport, जो EIP-1193 रिक्वेस्ट मेथड के माध्यम से अनुरोधों को संभालता है;
- Fallback आपको सूची में कई ट्रांसपॉर्ट्स निर्दिष्ट करने की अनुमति देता है। यदि एक विफल हो जाता है, तो यह कार्यशील को खोजने के लिए सूची में नीचे जाता है। इसका एक उदाहरण बाद में प्रदान किया जाएगा।
- Chain एक कनेक्शन स्थापित करने के लिए EVM-संगत चेन को संदर्भित करता है, उन्हें चेन ऑब्जेक्ट (चेन आईडी द्वारा पहचाना गया) के माध्यम से पहचाना जाता है। क्लाइंट के साथ केवल एक चेन को इंस्टेंटिएट किया जा सकता है। हम प्रदान की गई viem चेन लाइब्रेरी का उपयोग कर सकते हैं, उदा., polygon, eth mainnet या आप मैन्युअल रूप से अपना स्वयं का निर्माण कर सकते हैं।
Public Client
एक Public Client को इस प्रकार घोषित किया जाता है।
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
const publicClient = createPublicClient({
chain: mainnet,
transport: http()
})
इस प्रकार आप Public actions का उपयोग करते हैं।
const balance = await publicClient.getBalance({
address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
})
const block = await publicClient.getBlockNumber()
ये उपलब्ध Public Actions हैं:
- getChainId
- getGasPrice
- signMessage
- verifyMessage
- getTransactionReceipt
- Public Action Documentation पर अधिक जानकारी
Viem में Optimization Public Client नामक एक विशेषता है, जो बैच अनुरोध भेजकर बेहतर प्रदर्शन के लिए eth_call Aggregation का समर्थन करता है। इसका बहुत अच्छी तरह से दस्तावेजीकरण किया गया है।
Wallet Client
एक Wallet Client स्थापित करने का तरीका यहां दिया गया है:
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'
const walletClient = createWalletClient({
chain: mainnet,transport: custom(window.ethereum)
})
Wallet Actions का उपयोग इस प्रकार किया जाता है:
// Get's the user address
const [address] = await walletClient.getAddresses()
// Sends a transaction
const hash = await walletClient.sendTransaction({
account: address,
to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC',
value: parseEther('0.001')
})
उपलब्ध वॉलेट फ़ंक्शंस:
- requestAddresses (Metamask जैसे वॉलेट्स को पहले उपयोगकर्ता से requestAddresses की आवश्यकता हो सकती है)
- switchChain
- signMessage
- getPermissions
- sendTransaction
- Wallet Action Documentation पर अधिक जानकारी
हम इस ट्यूटोरियल में यह प्रदर्शित करेंगे कि sendTransaction और getAddresses का उपयोग कैसे किया जाए।
वैकल्पिक
आप Wallet Client को Public Actions के साथ विस्तारित (extend) कर सकते हैं। यह आपको कई क्लाइंट्स को संभालने से बचने में मदद करता है। निम्नलिखित कोड स्निपेट सार्वजनिक कार्यों के साथ वॉलेट क्लाइंट का विस्तार करता है।
import { createWalletClient, http, publicActions } from 'viem'
import { mainnet } from 'viem/chains'
const extendedClient = createWalletClient({
chain: mainnet,
transport: http()
}).extend(publicActions)
// Public Action
const block = await extendedClient.getBlockNumber()
// Wallet Action
const [address] = await extendedClient.getAddresses();
Test Client
Test Client शैडो अकाउंट्स, माइनिंग ब्लॉक्स और Anvil या Hardhat जैसे स्थानीय टेस्ट नोड के माध्यम से लेनदेन का प्रतिरूपण (impersonate) करने के लिए एक इंटरफ़ेस प्रदान करता है। हम इस पर विस्तार से चर्चा नहीं करेंगे लेकिन आप Test Client Documentation पर अधिक पढ़ सकते हैं।
Transport
हम एक बार में केवल एक ट्रांसपोर्ट का माध्यम (वह प्रोटोकॉल जिसका उपयोग हम ब्लॉकचेन से जुड़ने के लिए करेंगे) पास कर सकते हैं, यहाँ एक उदाहरण दिया गया है कि प्रत्येक ट्रांसपोर्ट का उपयोग कैसे किया जा सकता है।
HTTP
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
const transport = http('https://eth-mainnet.g.alchemy.com/v2/...')
const client = createPublicClient({
chain: mainnet,
transport,
})
यदि कोई url प्रदान नहीं किया गया है तो ट्रांसपोर्ट सार्वजनिक RPC URL पर फ़ॉलबैक करेगा। रेट-लिमिटिंग की समस्याओं को कम करने के लिए एक प्रमाणित (authenticated) RPC URL पास करने की अनुशंसा की जाती है।
WebSocket
import { createPublicClient, webSocket } from 'viem'
import { mainnet } from 'viem/chains'
const transport = webSocket('wss://eth-mainnet.g.alchemy.com/v2/...')
const client = createPublicClient({
chain: mainnet,
transport,
})
उपरोक्त समान कारणों से ट्रांसपोर्ट सार्वजनिक RPC URL पर फ़ॉलबैक करेगा।
नोट करें कि ऊपर के दोनों उदाहरणों में, ट्रांसपोर्ट को ट्रांसपोर्ट के लिए निर्दिष्ट URL के प्रकार द्वारा परिभाषित किया गया है। पहला URL एक HTTPS url है, दूसरा एक WSS url है।
Custom (EIP-1193) (हम इसका उपयोग करेंगे)
इस ट्रांसपोर्ट का उपयोग उन इंजेक्टेड वॉलेट्स के साथ इंटीग्रेट करने के लिए किया जाता है जो EIP-1193 प्रोवाइडर प्रदान करते हैं जैसे WalletConnect, Coinbase SDK और Metamask।
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'
const client = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum)
})
Fallback
यह ट्रांसपोर्ट कई ट्रांसपॉर्ट्स को लेता है। यदि कोई ट्रांसपोर्ट विफल हो जाता है, तो यह दी गई अगली ट्रांसपोर्ट विधि का सहारा लेगा। निम्नलिखित उदाहरण में, यदि Alchemy विफल हो जाता है, तो यह Infura पर फ़ॉलबैक करेगा।
import { createPublicClient, fallback, http } from 'viem'
import { mainnet } from 'viem/chains'
const alchemy = http('https://eth-mainnet.g.alchemy.com/v2/...')
const infura = http('https://mainnet.infura.io/v3/...')
const client = createPublicClient({
chain: mainnet,
transport: fallback([alchemy, infura]),
})
Chains
Viem viem/chains लाइब्रेरी के माध्यम से लोकप्रिय EVM-संगत चेन प्रदान करता है जैसे: Polygon, Optimism, Avalanche, और Viem Chains Documentation पर अधिक उपलब्ध है।
आप उन्हें आर्ग्यूमेंट के रूप में पास करके चेन बदल सकते हैं, उदा. polygonMumbai।
import { createPublicClient, http } from 'viem'
import { polygonMumbai } from 'viem/chains'
const client = createPublicClient({
chain: polygonMumbai,
transport: http(),
})
आप अपना स्वयं का चेन ऑब्जेक्ट भी बना सकते हैं जो Chain प्रकार को इनहेरिट करता है (श्रेय: Viem.sh)
import { Chain } from 'viem'
export const avalanche = {
id: 43_114,
name: 'Avalanche',
network: 'avalanche',
nativeCurrency: {
decimals: 18,
name: 'Avalanche',
symbol: 'AVAX',
},
rpcUrls: {
public: {
https: ['https://api.avax.network/ext/bc/C/rpc']
},
default: {
https: ['https://api.avax.network/ext/bc/C/rpc']
},
},
blockExplorers: {
etherscan: {
name: 'SnowTrace',
url: 'https://snowtrace.io'
},
default: {
name: 'SnowTrace',
url: 'https://snowtrace.io'
},
},
contracts: {multicall3: {
address: '0xca11bde05977b3631167028862be2a173976ca11',
blockCreated: 11_907_934,
},
},
} as const satisfies Chain
याद रखें, एक समय में किसी क्लाइंट को केवल एक ही चेन असाइन की जा सकती है।
शुरुआत करना: React + Viem के साथ Client और Transport सेटअप करें
सरलता के लिए हम आपके टेस्ट नेटवर्क के रूप में polygonMumbai या Sepolia का उपयोग करने की सलाह देते हैं।
चरण 1: एक Next.js प्रोजेक्ट बनाएं और Viem इंस्टॉल करें
सबसे पहले इसके साथ अपना Next.js प्रोजेक्ट बनाएं
npx create-next-app@latest myapp
निम्नलिखित के लिए [yes] चेक करें:
- Typescript
- ESLint
- Tailwind
- App Router (प्राथमिकता से)
अपना प्रोजेक्ट vscode में खोलें।
निम्नलिखित में से किसी एक कमांड के साथ viem इंस्टॉल करें:
npm i viem
pnpm i viem
yarn add viem
चरण 2: Client और Transport सेटअप करें
ऐप डायरेक्टरी (app directory) में, दो नई फाइलें बनाएं:
- client.ts
- walletButton.tsx
आपकी ऐप डायरेक्टरी इस तरह दिखनी चाहिए:
app
├── client.ts
├── globals.css
├── layout.tsx
├── page.tsx
└── walletButton.tsx
Client.ts
हम Client और Transport को एक अलग टाइपस्क्रिप्ट फ़ाइल में इनिशियलाइज़ करेंगे। आगे बढ़ें और निम्नलिखित कोड को client.ts में कॉपी-पेस्ट करें।
// client.ts
import { createWalletClient, createPublicClient, custom, http } from "viem";
import { polygonMumbai, mainnet } from "viem/chains";
import "viem/window";
// Instantiate Public Client
const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
});
// Instantiate Wallet Clientconst walletClient = createWalletClient({
chain: polygonMumbai,
transport: custom(window.ethereum),
});
यह अनिवार्य रूप से एक टाइप त्रुटि (type error) थ्रो करेगा, window.ethereum, undefined हो सकता है क्योंकि सफारी जैसे कुछ ब्राउज़र window.ethereum ऑब्जेक्ट का समर्थन नहीं करते हैं।
हम यह जांच कर त्रुटि को संभाल सकते हैं कि window.ethereum मौजूद है या अपरिभाषित (undefined) है।
// client.ts
import { createWalletClient, createPublicClient, custom, http } from "viem";
import { polygonMumbai } from "viem/chains";
import "viem/window";
export function ConnectWalletClient() {
// Check for window.ethereum
let transport;
if (window.ethereum) {
transport = custom(window.ethereum);
} else {
const errorMessage ="MetaMask or another web3 wallet is not installed. Please install one to proceed.";
throw new Error(errorMessage);
}
// Delcalre a Wallet Client
const walletClient = createWalletClient({
chain: polygonMumbai,
transport: transport,
});
return walletClient;
}
export function ConnectPublicClient() {
// Check for window.ethereum
let transport;
if (window.ethereum) {
transport = custom(window.ethereum);
} else {
const errorMessage ="MetaMask or another web3 wallet is not installed. Please install one to proceed.";
throw new Error(errorMessage);
}
// Delcare a Public Client
const publicClient = createPublicClient({
chain: polygonMumbai,
transport: transport,
});
return publicClient;
}
यह अभी भी आपको उस ब्राउज़र में वेबसाइट खोलने की अनुमति देगा जो window.ethereum का समर्थन नहीं करता है।
यह अनुशंसा की जाती है कि walletClient और publicClient के लिए चेन को सुसंगत (consistent) रखा जाए अन्यथा आपको असंगत (incompatible) चेन त्रुटियों का सामना करना पड़ सकता है।
भाग 1: React + Viem के साथ Web3 वॉलेट से कनेक्ट करें
यह अनुभाग प्रदर्शित करता है कि viem Client आपके web3 वॉलेट से कैसे जुड़ता है।
चरण 2: एक ऐसा बटन बनाएं जो Web3 वॉलेट से कनेक्ट हो
walletButton.tsx
अब हम एक क्लाइंट कंपोनेंट बनाएंगे, जो आपके web3 वॉलेट के कनेक्शन लॉजिक को संभालता है।
बटन एक walletClient को इंस्टेंटिएट करता है और उपयोगकर्ता के वॉलेट पते का अनुरोध करता है, यदि वॉलेट पहले से कनेक्ट नहीं है तो यह उसे कनेक्ट करने के लिए संकेत देगा, और अंत में इसके पते को आउटपुट करेगा।
यहाँ बहुत सारा कोड है, लेकिन handleClick() फ़ंक्शन पर ध्यान केंद्रित करें।
// walletButton.tsx
"use client";
import { useState } from "react";
import { ConnectWalletClient, ConnectPublicClient } from "./client";
export default function WalletButton() {
//State variables for address & balance
const [address, setAddress] = useState<string | null>(null);
const [balance, setBalance] = useState<BigInt>(BigInt(0));
// Function requests connection and retrieves the address of wallet
// Then it retrievies the balance of the address
// Finally it updates the value for address & balance variable
async function handleClick() {
try {
// Instantiate a Wallet & Public Client
const walletClient = ConnectWalletClient();
const publicClient = ConnectPublicClient();
// Performs Wallet Action to retrieve wallet address
const [address] = await walletClient.getAddresses();
// Performs Public Action to retrieve address balance
const balance = await publicClient.getBalance({ address });
// Update values for address & balance state variable
setAddress(address);
setBalance(balance);
} catch (error) {
// Error handling
alert(`Transaction failed: ${error}`);
}
}
// Unimportant Section Below / Nice to Have UI
return (
<>
<Status address={address} balance={balance} />
<button className="px-8 py-2 rounded-md bg-[#1e2124] flex flex-row items-center justify-center border border-[#1e2124] hover:border hover:border-indigo-600 shadow-md shadow-indigo-500/10"
onClick={handleClick}
>
<img src="https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg" alt="MetaMask Fox" style={{ width: "25px", height: "25px" }} />
<h1 className="mx-auto">Connect Wallet</h1>
</button></>);}
// Displays the wallet address once it’s successfuly connected
// You do not have to read it, it's just frontend stuff
function Status({
address,
balance,}: {
address: string | null;
balance: BigInt;
}) {
if (!address) {
return (
<div className="flex items-center">
<div className="border bg-red-600 border-red-600 rounded-full w-1.5 h-1.5 mr-2">
</div>
<div>Disconnected</div>
</div>);
}
return (
<div className="flex items-center w-full">
<div className="border bg-green-500 border-green-500 rounded-full w-1.5 h-1.5 mr-2"></div>
<div className="text-xs md:text-xs">{address} <br /> Balance: {balance.toString()}</div>
</div>
);
}
चरण 3: walletButton कंपोनेंट डालें
page.tsx
अब जो बचा है वह मुख्य पृष्ठ (main page) को डिज़ाइन करना और WalletButton कंपोनेंट को इंपोर्ट करना है। हमने कुछ कोड को कमेंट आउट कर दिया है जिसे आप बाद में जोड़ेंगे।
import WalletButton from "./walletButton";
// import MintButton from "./mintButton";
// import SendButton from "./sendButton";
export default function Home() {
return (
<main className="min-h-screen">
<div className="flex flex-col items-center justify-center h-screen ">
<a href="https://rareskills.io" target="_blank" className="text-white font-bold text-3xl hover:text-[#0044CC]" > Viem.sh </a>
<div className="h-[300px] min-w-[150px] flex flex-col justify-between backdrop-blur-2xl bg-[#290330]/30 rounded-lg mx-auto p-7 text-white border border-purple-950">
<WalletButton />
{/* <SendButton />
<MintButton /> */}
</div>
<a href="https://rareskills.io" target="_blank" className="text-white font-bold text-3xl hover:text-[#0044CC]" > Rareskills.io </a>
</div>
</main>
);
}
globals.css
कुछ अच्छे बैकग्राउंड UI के लिए, globals.css को नीचे दिए गए कोड से बदलें।
@tailwind base;@tailwind components;@tailwind utilities;
body {
background-color: #0c002e;
background-image: radial-gradient(
at 100% 100%,rgb(84, 2, 103) 0px,
transparent 50%),
radial-gradient(at 0% 0%, rgb(97, 0, 118) 0px, transparent 50%);}
चरण 4: वेबसाइट चलाएं और इसका परीक्षण करें
जब आप बटन पर क्लिक करते हैं, तो यह आपके वॉलेट से कनेक्शन शुरू करेगा। आपके द्वारा स्वीकृत (approve) कर दिए जाने के बाद, यह इस तरह दिखना चाहिए:
npm run dev

बटन क्लिक होने के बाद, निम्नलिखित दिखाई देगा:

भाग 2: React + Viem के साथ क्रिप्टो ट्रांसफर करना
अब जबकि हमारा वॉलेट कनेक्ट हो गया है, हम क्रिप्टोकरेंसी ट्रांसफर करना शुरू कर सकते हैं। हम sendTransaction वॉलेट एक्शन का उपयोग करेंगे।
- Matic Faucet से कुछ Matic प्राप्त करें
चरण 5: क्रिप्टोकरेंसी ट्रांसफर करने की सुविधा जोड़ें
ऐप डायरेक्टरी में एक नई tsx फ़ाइल sendButton.tsx बनाएं
app
├── client.ts
├── globals.css
├── layout.tsx
├── page.tsx
├── sendButton.tsx
└── walletButton.tsx
sendButton.tsx
हम एक बटन बनाएंगे जो sendTransaction एक्शन शुरू करता है। Viem हमारे लिए ऐसा करना बहुत आसान बना देता है। लॉजिक फ्लो walletButton.tsx के समान होना चाहिए, walletClient को इंस्टेंटिएट करें और Wallet Client एक्शन निष्पादित करें।
"use client";
import { parseEther } from "viem";
import { ConnectWalletClient} from "./client";
export default function SendButton() {
//Send Transaction Function
async function handleClick() {
try {
// Declare wallet client
const walletClient = ConnectWalletClient();
// Get the main wallet address
const [address] = await walletClient.getAddresses();
// sendTransaction is a Wallet action.
// It returns the transaction hash
// requires 3 parameters to transfer cryptocurrency,
// account, to and value
const hash = await walletClient.sendTransaction({
account: address,
to: "Account_Address",
value: parseEther("0.001"), // send 0.001 matic
});
// Display the transaction hash in an alert
alert(`Transaction successful. Transaction Hash: ${hash}`);
} catch (error) {
// Handle Error
alert(`Transaction failed: ${error}`);
}
}
return (
<button
className="py-2.5 px-2 rounded-md bg-[#1e2124] flex flex-row items-center justify-center border border-[#1e2124] hover:border hover:border-indigo-600 shadow-md shadow-indigo-500/10"
onClick={handleClick}>
Send Transaction
</button>
);
}
चरण 6: sendButton कंपोनेंट डालें
page.tsx
sendButton कंपोनेंट से संबंधित लाइनों को अनकमेंट करें।
import WalletButton from "./walletButton";
import SendButton from "./sendButton";
// import MintButton from "./mintButton";
export default function Home() {
return (
<main className="min-h-screen">
<div className="flex flex-col items-center justify-center h-screen ">
<a href="https://rareskills.io" target="_blank" className="text-white font-bold text-3xl hover:text-[#0044CC]" > Viem.sh </a>
<div className="h-[300px] min-w-[150px] flex flex-col justify-between backdrop-blur-2xl bg-[#290330]/30 rounded-lg mx-auto p-7 text-white border border-purple-950">
<WalletButton />
<SendButton />
{/* <MintButton /> */}
</div>
<a href="https://rareskills.io" target="_blank" className="text-white font-bold text-3xl hover:text-[#0044CC]" > Rareskills.io </a>
</div>
</main>
);
}
आपका ब्राउज़र अब इस तरह दिखना चाहिए!

भाग 3: React + Viem के साथ NFT मिंट करना
यह अनुभाग चर्चा करेगा कि स्मार्ट कॉन्ट्रैक्ट के साथ कैसे इंटरैक्ट किया जाए और NFT मिंट करने के माध्यम से एक उदाहरण देगा।
स्मार्ट कॉन्ट्रैक्ट के साथ इंटरैक्ट करने के लिए, हमें दो चीजों की आवश्यकता होती है:
- Contract Address
- Contract ABI
इस उदाहरण के लिए, हम इसे Rareskill के कॉन्ट्रैक्ट के साथ प्रदर्शित करेंगे जिसमें एक Mint फ़ंक्शन है जो वास्तव में कुछ नहीं करता है बल्कि आपके द्वारा मिंट किए जाने की संख्या को ट्रैक करता है।
- Rareskill का Contract Address: 0x7E6Ddd9dC419ee2F10eeAa8cBB72C215B9Eb5E23
- Rareskill का Contract ABI
बेझिझक अपने स्वयं के कॉन्ट्रैक्ट का उपयोग करें।
चरण 7: स्मार्ट कॉन्ट्रैक्ट के साथ इंटरैक्ट करने के लिए कार्यक्षमता जोड़ें
दो नई फ़ाइलें abi.ts और mintButton.tsx बनाएं
app
├── abi.ts
├── client.ts
├── globals.css
├── layout.tsx
├── mintButton.tsx
├── page.tsx
├── sendButton.tsx
└── walletButton.tsx
abi.ts
Rareskill के कॉन्ट्रैक्ट ABI या अपने स्वयं के ABI को कॉपी पेस्ट करें।
// abi.ts
export const wagmiAbi = [...contract abi...] as const;
इस सटीक प्रारूप का पालन करना याद रखें और अंत में “as const;” को न भूलें।
Contract Instance और Contract Action Method
Contract Instance method
//Contract Instance
const contract = getContract({
address: "0x7E6Ddd9dC419ee2F10eeAa8cBB72C215B9Eb5E23",
abi: wagmiAbi,
publicClient,
walletClient,
});
getContract फ़ंक्शन हमारा कॉन्ट्रैक्ट इंस्टेंस contract बनाता है। निर्माण (creation) पर हम कॉन्ट्रैक्ट विधियों (methods) को आमंत्रित कर सकते हैं, इवेंट्स सुन सकते हैं, आदि। यह एक सरल तरीका है क्योंकि कॉन्ट्रैक्ट कार्य करने के लिए हमें बार-बार address और abi प्रॉपर्टीज़ पास नहीं करनी पड़ती हैं।
Parameters:
- address
- abi
- publicClient (वैकल्पिक)
- walletClient (वैकल्पिक)
हमें address और abi पैरामीटर्स पास करने की आवश्यकता है। publicClient और walletClient को पास करना वैकल्पिक है, लेकिन यह क्लाइंट के प्रकार के आधार पर हमें कॉन्ट्रैक्ट विधियों के एक सेट तक पहुंच प्रदान करता है।
publicClient के लिए उपलब्ध कॉन्ट्रैक्ट विधियां:
walletClient के लिए उपलब्ध कॉन्ट्रैक्ट विधियां:
सामान्य तौर पर, कॉन्ट्रैक्ट Instance विधि को कॉल करना नीचे दिए गए प्रारूप का पालन करता है:
// function
contract.(estimateGas|read|simulate|write).(functionName)(args, options)
// event
contract.(createEventFilter|watchEvent).(eventName)(args, options)
Contract Instance का उपयोग करके Contract Methods को कॉल करना
// Read Contract symbol
const symbol = await contract.read.symbol();
// Read Contract name
const name = await contract.read.name();
// Call mint method
const result = await contract.write.mint({account: address});
उपरोक्त उदाहरण contract इंस्टेंस के माध्यम से रीड और राइट कॉन्ट्रैक्ट विधि को कॉल करते हैं। यदि आप टाइप-स्क्रिप्ट का उपयोग कर रहे हैं तो यह उपलब्ध कॉन्ट्रैक्ट विधियों के सुझावों को स्वतः पूर्ण (auto-complete) कर देगा।
read.symbol() और read.name() सीधे (straight forward) हैं। दूसरी ओर, राइट फ़ंक्शन
const result = await contract.write.mint({account: address});
को अपने आवश्यक पैरामीटर के रूप में {account: address} की आवश्यकता होती है और अन्य सभी वैकल्पिक होते हैं। यदि आपको परेशानी होती है कि कौन से पैरामीटर जोड़ने हैं, तो अपने माउस को “mint()” कीवर्ड पर घुमाएँ, VS Code आपको संकेत (hint) दे देगा।
Contract Action Method — थकाऊ (Tedious) तरीका
उपरोक्त अनुभाग में कोड निम्नलिखित के लिए सिंटैक्टिक शुगर (syntactic sugar) है। हम इस अनुभाग को यह दिखाने के लिए शामिल कर रहे हैं कि पर्दे के पीछे (under the hood) क्या हो रहा है।
यह कोड कॉन्ट्रैक्ट का totalSupply प्राप्त करता है:
const totalSupply = await publicClient.readContract({
address: '0x7E6Ddd9dC419ee2F10eeAa8cBB72C215B9Eb5E23',
abi: wagmiAbi,
functionName: 'totalSupply',
})
थकाऊ है ना? आपको बार-बार address और abi पास करना पड़ता है।
यह Contract Action विधि का उपयोग करके ऊपर दिए गए उदाहरण से mint फ़ंक्शन को कॉल करने के बराबर है। सफल होने पर यह ट्रांजेक्शन हैश लौटाता है।
const hash = await walletClient.writeContract({
address: "0x7E6Ddd9dC419ee2F10eeAa8cBB72C215B9Eb5E23",
abi: wagmiAbi,
functionName: "mint",
account,
});
बंडल के आकार को न्यूनतम रखने के लिए, Contract Action का उपयोग करें; जबकि Contract instance अधिक फ़ंक्शंस प्रदान करता है, यह मेमोरी का उपयोग बढ़ाता है।
mintButton.tsx
एक स्टेट-चेंजिंग ट्रांजेक्शन प्रदर्शित करने के लिए, हम एक बटन बनाएंगे जो स्मार्ट कॉन्ट्रैक्ट के mint फ़ंक्शन को कॉल करता है और साथ ही इसके name, symbol और totalSupply को क्वेरी करता है।
हमने यह दिखाने के लिए Contract Instance और Contract Action दोनों विधियों का उपयोग किया है कि इसे कैसे लागू किया जाता है।
"use client";
import { formatEther, getContract } from "viem";
import { wagmiAbi } from "./abi";
import { ConnectWalletClient, ConnectPublicClient } from "./client";
export default function MintButton() {
// Function to Interact With Smart Contract
async function handleClick() {
// Declare Client
const walletClient = ConnectWalletClient();
const publicClient = ConnectPublicClient();
// Create a Contract Instance
// Pass publicClient to perform Public Client Contract Methods
// Pass walletClient to perform Wallet Client Contract Methods
const contract = getContract({
address: "0x7E6Ddd9dC419ee2F10eeAa8cBB72C215B9Eb5E23",
abi: wagmiAbi,
publicClient,
walletClient,
});
// Reads the view state function symbol via Contract Instance method
const symbol = await contract.read.symbol();
// Reads the view state function name via Contract Instance method
const name = await contract.read.name();
// Reads the view state function symbol via Contract Action method
const totalSupply = await publicClient.readContract({
address: '0x7E6Ddd9dC419ee2F10eeAa8cBB72C215B9Eb5E23',
abi: wagmiAbi,
functionName: 'totalSupply',
})
// Format ether converts BigInt(Wei) to String(Ether)
const totalSupplyInEther = formatEther(totalSupply);
alert(`Symbol: ${symbol}\nName: ${name}\ntotalSupply: ${totalSupplyInEther}`);
try {
// Declare Wallet Client and Retrieve wallet address
const client = walletClient;
const [address] = await client.getAddresses();
// Writes the state-changin function mint via Contract Instance method.
const result = await contract.write.mint({
account: address
});
alert(`${result} ${name}`);
} catch (error) {
// Handle any errors that occur during the transaction
alert(`Transaction failed: ${error}`);
}}
return (
<>
<button
className="py-2.5 px-2 rounded-md bg-[#1e2124] flex flex-row items-center justify-center border border-[#1e2124] hover:border hover:border-indigo-600 shadow-md shadow-indigo-500/10"
onClick={handleClick}>
<svg
className="w-4 h-4 mr-2 -ml-1 text-[#626890]"
aria-hidden="true"
focusable="false"
data-prefix="fab"
data-icon="ethereum"
role="img"
xmlns="https://www.w3.org/2000/svg"
viewBox="0 0 320 512">
<path
fill="currentColor"
d="M311.9 260.8L160 353.6 8 260.8 160 0l151.9 260.8zM160 383.4L8 290.6 160 512l152-221.4-152 92.8z">
</path>
</svg>
<h1 className="text-center">Mint</h1>
</button>
</>
);
}
इस ट्यूटोरियल को पूरा करने पर बधाई! आपका अंतिम उत्पाद (final product) इस तरह दिखना चाहिए:

लेखकत्व (Authorship)
यह लेख Aymeric Taylor (LinkedIn, X), RareSkills के एक रिसर्च इंटर्न द्वारा सह-लिखा गया था।
मूल रूप से 10 अगस्त, 2023 को प्रकाशित