মূল কন্টেন্টে যান

নতুনদের জন্য হ্যালো ওয়ার্ল্ড স্মার্ট কন্ট্রাক্ট - ফুলস্ট্যাক

Solidity
Hardhat
Alchemy
স্মার্ট কন্ট্রাক্ট
ডিপ্লয়িং
ব্লক এক্সপ্লোরার
ফ্রন্টএন্ড
লেনদেন
ফ্রেমওয়ার্ক
শিক্ষানবিস
nstrike2
25 অক্টোবর, 2021
45 মিনিট পড়া

আপনি যদি ব্লকচেইন ডেভেলপমেন্টে নতুন হয়ে থাকেন এবং কোথা থেকে শুরু করবেন বা কীভাবে স্মার্ট কন্ট্রাক্ট ডিপ্লয় এবং এর সাথে ইন্টারঅ্যাক্ট করবেন তা না জানেন, তবে এই গাইডটি আপনার জন্য। আমরা MetaMask (opens in a new tab), Solidity (opens in a new tab), Hardhat (opens in a new tab), এবং Alchemy (opens in a new tab) ব্যবহার করে Goerli টেস্ট নেটওয়ার্কে একটি সাধারণ স্মার্ট কন্ট্রাক্ট তৈরি এবং ডিপ্লয় করার প্রক্রিয়া ধাপে ধাপে দেখব।

এই টিউটোরিয়ালটি সম্পূর্ণ করতে আপনার একটি Alchemy একাউন্ট প্রয়োজন হবে। একটি বিনামূল্যের একাউন্টের জন্য সাইন আপ করুন (opens in a new tab)

যেকোনো পর্যায়ে আপনার যদি কোনো প্রশ্ন থাকে, তবে নির্দ্বিধায় Alchemy Discord (opens in a new tab)-এ যোগাযোগ করুন!

পর্ব 1 - Hardhat ব্যবহার করে আপনার স্মার্ট কন্ট্রাক্ট তৈরি এবং ডিপ্লয় করুন

ইথিরিয়াম নেটওয়ার্ক-এর সাথে কানেক্ট করুন

ইথিরিয়াম চেইনে রিকোয়েস্ট করার অনেক উপায় আছে। সহজে করার জন্য, আমরা Alchemy-তে একটি ফ্রি একাউন্ট ব্যবহার করব, যা একটি ব্লকচেইন ডেভেলপার প্ল্যাটফর্ম এবং API, এটি আমাদের নিজেদের কোনো নোড না চালিয়েই ইথিরিয়াম চেইনের সাথে যোগাযোগ করতে দেয়। Alchemy-তে মনিটরিং এবং অ্যানালিটিক্সের জন্য ডেভেলপার টুলসও রয়েছে; আমাদের স্মার্ট কন্ট্রাক্ট ডিপ্লয়মেন্টের ভেতরে কী ঘটছে তা বোঝার জন্য আমরা এই টিউটোরিয়ালে সেগুলোর সুবিধা নেব।

আপনার অ্যাপ এবং API কি তৈরি করুন

একবার আপনি একটি Alchemy একাউন্ট তৈরি করলে, আপনি একটি অ্যাপ তৈরি করে একটি API কি জেনারেট করতে পারেন। এটি আপনাকে Goerli টেস্টনেট-এ রিকোয়েস্ট করার অনুমতি দেবে। আপনি যদি টেস্টনেট-এর সাথে পরিচিত না হন তবে আপনি নেটওয়ার্ক বেছে নেওয়ার বিষয়ে Alchemy-এর গাইড পড়তে পারেন (opens in a new tab)

Alchemy ড্যাশবোর্ডে, নেভিগেশন বারে Apps ড্রপডাউনটি খুঁজুন এবং Create App-এ ক্লিক করুন।

Hello world create app

আপনার অ্যাপটির নাম দিন 'Hello World' এবং একটি ছোট বিবরণ লিখুন। আপনার এনভায়রনমেন্ট হিসেবে Staging এবং আপনার নেটওয়ার্ক হিসেবে Goerli নির্বাচন করুন।

create app view hello world

নোট: অবশ্যই Goerli নির্বাচন করবেন, অন্যথায় এই টিউটোরিয়ালটি কাজ করবে না।

Create app-এ ক্লিক করুন। আপনার অ্যাপটি নিচের টেবিলে দেখা যাবে।

একটি ইথিরিয়াম একাউন্ট তৈরি করুন

লেনদেন পাঠানো এবং গ্রহণ করার জন্য আপনার একটি ইথিরিয়াম একাউন্ট প্রয়োজন। আমরা MetaMask ব্যবহার করব, যা ব্রাউজারের একটি ভার্চুয়াল ওয়ালেট এবং এটি ব্যবহারকারীদের তাদের ইথিরিয়াম একাউন্ট এডড্রেস পরিচালনা করতে দেয়।

আপনি বিনামূল্যে এখানে (opens in a new tab) একটি MetaMask একাউন্ট ডাউনলোড এবং তৈরি করতে পারেন। যখন আপনি একটি একাউন্ট তৈরি করছেন, বা আপনার যদি আগে থেকেই একটি একাউন্ট থাকে, তবে নিশ্চিত করুন যে আপনি উপরের ডানদিকে "Goerli Test Network"-এ সুইচ করেছেন (যাতে আমরা আসল টাকা নিয়ে কাজ না করি)।

ধাপ 4: একটি ফাসেট থেকে ইথার যোগ করুন

টেস্ট নেটওয়ার্ক-এ আপনার স্মার্ট কন্ট্রাক্ট ডিপ্লয় করতে, আপনার কিছু ফেক ETH প্রয়োজন হবে। Goerli নেটওয়ার্ক-এ ETH পেতে, একটি Goerli ফাসেট-এ যান এবং আপনার Goerli একাউন্ট এডড্রেস লিখুন। মনে রাখবেন যে Goerli ফাসেটগুলো সম্প্রতি কিছুটা অবিশ্বস্ত হতে পারে - চেষ্টা করার মতো বিকল্পগুলোর একটি তালিকার জন্য টেস্ট নেটওয়ার্ক পেজ দেখুন:

নোট: নেটওয়ার্ক কনজেশনের কারণে, এতে কিছুটা সময় লাগতে পারে। ``

ধাপ 5: আপনার ব্যালেন্স চেক করুন

আপনার ওয়ালেট-এ ETH আছে কিনা তা ডাবল-চেক করতে, চলুন Alchemy-এর কম্পোজার টুল (opens in a new tab) ব্যবহার করে একটি eth_getBalance (opens in a new tab) রিকোয়েস্ট করি। এটি আমাদের ওয়ালেট-এ থাকা ETH-এর পরিমাণ রিটার্ন করবে। আরও জানতে কম্পোজার টুল কীভাবে ব্যবহার করতে হয় সে সম্পর্কে Alchemy-এর ছোট টিউটোরিয়ালটি (opens in a new tab) দেখুন।

আপনার MetaMask একাউন্ট এডড্রেস ইনপুট দিন এবং Send Request-এ ক্লিক করুন। আপনি নিচের কোড স্নিপেটের মতো একটি রেসপন্স দেখতে পাবেন।

1{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }

নোট: এই ফলাফলটি wei-তে, ETH-এ নয়। Wei ইথারের সবচেয়ে ছোট একক হিসেবে ব্যবহৃত হয়।

যাক! আমাদের ফেক টাকা সব সেখানেই আছে।

ধাপ 6: আমাদের প্রজেক্ট ইনিশিয়ালাইজ করুন

প্রথমে, আমাদের প্রজেক্টের জন্য একটি ফোল্ডার তৈরি করতে হবে। আপনার কমান্ড লাইনে যান এবং নিচের কমান্ডগুলো ইনপুট দিন।

1mkdir hello-world
2cd hello-world

এখন যেহেতু আমরা আমাদের প্রজেক্ট ফোল্ডারের ভেতরে আছি, আমরা প্রজেক্টটি ইনিশিয়ালাইজ করতে npm init ব্যবহার করব।

আপনার যদি এখনও npm ইনস্টল করা না থাকে, তবে Node.js এবং npm ইনস্টল করার জন্য এই নির্দেশিকাগুলো (opens in a new tab) অনুসরণ করুন।

এই টিউটোরিয়ালের উদ্দেশ্যে, আপনি ইনিশিয়ালাইজেশনের প্রশ্নগুলোর উত্তর কীভাবে দিচ্ছেন তা কোনো ব্যাপার না। রেফারেন্সের জন্য আমরা এটি কীভাবে করেছি তা এখানে দেওয়া হলো:

1package name: (hello-world)
2version: (1.0.0)
3description: hello world smart contract
4entry point: (index.js)
5test command:
6git repository:
7keywords:
8author:
9license: (ISC)
10
11About to write to /Users/.../.../.../hello-world/package.json:
12
13{
14 "name": "hello-world",
15 "version": "1.0.0",
16 "description": "hello world smart contract",
17 "main": "index.js",
18 "scripts": {
19 "test": "echo \"Error: no test specified\" && exit 1"
20 },
21 "author": "",
22 "license": "ISC"
23}

package.json অনুমোদন করুন এবং আমরা কাজ শুরু করতে প্রস্তুত!

ধাপ 7: Hardhat ডাউনলোড করুন

Hardhat হলো আপনার ইথিরিয়াম সফটওয়্যার কম্পাইল, ডিপ্লয়, টেস্ট এবং ডিবাগ করার জন্য একটি ডেভেলপমেন্ট এনভায়রনমেন্ট। এটি লাইভ চেইনে ডিপ্লয় করার আগে লোকালি স্মার্ট কন্ট্রাক্ট এবং ডিএ্যাপস তৈরি করার সময় ডেভেলপারদের সাহায্য করে।

আমাদের hello-world প্রজেক্টের ভেতরে রান করুন:

1npm install --save-dev hardhat

ইনস্টলেশন নির্দেশিকা (opens in a new tab) সম্পর্কে আরও বিস্তারিত জানতে এই পেজটি দেখুন।

ধাপ 8: Hardhat প্রজেক্ট তৈরি করুন

আমাদের hello-world প্রজেক্ট ফোল্ডারের ভেতরে, রান করুন:

1npx hardhat

এরপর আপনি একটি ওয়েলকাম মেসেজ এবং আপনি কী করতে চান তা নির্বাচন করার অপশন দেখতে পাবেন। "create an empty hardhat.config.js" নির্বাচন করুন:

1888 888 888 888 888
2888 888 888 888 888
3888 888 888 888 888
48888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
5888 888 "88b 888P" d88" 888 888 "88b "88b 888
6888 888 .d888888 888 888 888 888 888 .d888888 888
7888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
8888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
9
10👷 Welcome to Hardhat v2.0.11 👷‍
11
12What do you want to do? …
13Create a sample project
14❯ Create an empty hardhat.config.js
15Quit

এটি প্রজেক্টে একটি hardhat.config.js ফাইল জেনারেট করবে। আমাদের প্রজেক্টের সেটআপ নির্দিষ্ট করার জন্য আমরা টিউটোরিয়ালের পরে এটি ব্যবহার করব।

ধাপ 9: প্রজেক্ট ফোল্ডার যোগ করুন

প্রজেক্টটি গুছিয়ে রাখতে, চলুন দুটি নতুন ফোল্ডার তৈরি করি। কমান্ড লাইনে, আপনার hello-world প্রজেক্টের রুট ডিরেক্টরিতে যান এবং টাইপ করুন:

1mkdir contracts
2mkdir scripts
  • contracts/ হলো সেই জায়গা যেখানে আমরা আমাদের হ্যালো ওয়ার্ল্ড স্মার্ট কন্ট্রাক্ট কোড ফাইল রাখব
  • scripts/ হলো সেই জায়গা যেখানে আমরা আমাদের কন্ট্রাক্ট ডিপ্লয় এবং ইন্টারঅ্যাক্ট করার জন্য স্ক্রিপ্টগুলো রাখব

ধাপ 10: আমাদের কন্ট্রাক্ট লিখুন

আপনি হয়তো নিজেকে জিজ্ঞাসা করছেন, আমরা কখন কোড লিখতে যাচ্ছি? এখনই সময়!

আপনার পছন্দের এডিটরে hello-world প্রজেক্টটি খুলুন। স্মার্ট কন্ট্রাক্ট সাধারণত Solidity-তে লেখা হয়, যা আমরা আমাদের স্মার্ট কন্ট্রাক্ট লিখতে ব্যবহার করব।‌

  1. contracts ফোল্ডারে যান এবং HelloWorld.sol নামে একটি নতুন ফাইল তৈরি করুন
  2. নিচে একটি নমুনা হ্যালো ওয়ার্ল্ড স্মার্ট কন্ট্রাক্ট দেওয়া হলো যা আমরা এই টিউটোরিয়ালের জন্য ব্যবহার করব। নিচের বিষয়বস্তুগুলো HelloWorld.sol ফাইলে কপি করুন।

নোট: এই কন্ট্রাক্টটি কী করে তা বোঝার জন্য অবশ্যই কমেন্টগুলো পড়বেন।

1// Specifies the version of Solidity, using semantic versioning.
2// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
3pragma solidity >=0.7.3;
4
5// Defines a contract named `HelloWorld`.
6// A contract is a collection of functions and data (its state). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
7contract HelloWorld {
8
9 //Emitted when update function is called
10 //Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen.
11 event UpdatedMessages(string oldStr, string newStr);
12
13 // Declares a state variable `message` of type `string`.
14 // State variables are variables whose values are permanently stored in contract storage. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value.
15 string public message;
16
17 // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation.
18 // Constructors are used to initialize the contract's data. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
19 constructor(string memory initMessage) {
20
21 // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable).
22 message = initMessage;
23 }
24
25 // A public function that accepts a string argument and updates the `message` storage variable.
26 function update(string memory newMessage) public {
27 string memory oldMsg = message;
28 message = newMessage;
29 emit UpdatedMessages(oldMsg, newMessage);
30 }
31}

এটি একটি বেসিক স্মার্ট কন্ট্রাক্ট যা তৈরি করার সময় একটি মেসেজ স্টোর করে। update ফাংশন কল করে এটি আপডেট করা যেতে পারে।

ধাপ 11: আপনার প্রজেক্টের সাথে MetaMask এবং Alchemy কানেক্ট করুন

আমরা একটি MetaMask ওয়ালেট, Alchemy একাউন্ট তৈরি করেছি এবং আমাদের স্মার্ট কন্ট্রাক্ট লিখেছি, এখন এই তিনটিকে কানেক্ট করার সময়।

আপনার ওয়ালেট থেকে পাঠানো প্রতিটি লেনদেন-এর জন্য আপনার ইউনিক প্রাইভেট কি ব্যবহার করে একটি সিগনেচার প্রয়োজন। আমাদের প্রোগ্রামকে এই অনুমতি দেওয়ার জন্য, আমরা নিরাপদে আমাদের প্রাইভেট কি একটি এনভায়রনমেন্ট ফাইলে স্টোর করতে পারি। আমরা এখানে Alchemy-এর জন্য একটি API কি-ও স্টোর করব।

লেনদেন পাঠানো সম্পর্কে আরও জানতে, web3 ব্যবহার করে লেনদেন পাঠানোর উপর এই টিউটোরিয়ালটি (opens in a new tab) দেখুন।

প্রথমে, আপনার প্রজেক্ট ডিরেক্টরিতে dotenv প্যাকেজটি ইনস্টল করুন:

1npm install dotenv --save

তারপর, প্রজেক্টের রুট ডিরেক্টরিতে একটি .env ফাইল তৈরি করুন। এতে আপনার MetaMask প্রাইভেট কি এবং HTTP Alchemy API URL যোগ করুন।

আপনার এনভায়রনমেন্ট ফাইলের নাম অবশ্যই .env হতে হবে, অন্যথায় এটি এনভায়রনমেন্ট ফাইল হিসেবে চেনা যাবে না।

এর নাম process.env বা .env-custom বা অন্য কিছু দেবেন না।

Animated walkthrough of getting an Alchemy API key

আপনার .env ফাইলটি দেখতে এরকম হওয়া উচিত:

1API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
2PRIVATE_KEY = "your-metamask-private-key"

এগুলোকে আমাদের কোডের সাথে কানেক্ট করতে, আমরা 13 নম্বর ধাপে আমাদের hardhat.config.js ফাইলে এই ভেরিয়েবলগুলোর রেফারেন্স দেব।

ধাপ 12: Ethers.js ইনস্টল করুন

Ethers.js হলো একটি লাইব্রেরি যা স্ট্যান্ডার্ড JSON-RPC মেথডগুলোকে (opens in a new tab) আরও ইউজার ফ্রেন্ডলি মেথড দিয়ে র‍্যাপ করে ইথিরিয়ামের সাথে ইন্টারঅ্যাক্ট করা এবং রিকোয়েস্ট করা সহজ করে তোলে।

Hardhat আমাদের অতিরিক্ত টুলিং এবং বর্ধিত কার্যকারিতার জন্য প্লাগইন (opens in a new tab) ইন্টিগ্রেট করার অনুমতি দেয়। আমরা কন্ট্রাক্ট ডিপ্লয়মেন্টের জন্য Ethers প্লাগইন (opens in a new tab)-এর সুবিধা নেব।

আপনার প্রজেক্ট ডিরেক্টরিতে টাইপ করুন:

npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"

ধাপ 13: hardhat.config.js আপডেট করুন

আমরা এ পর্যন্ত বেশ কয়েকটি ডিপেন্ডেন্সি এবং প্লাগইন যোগ করেছি, এখন আমাদের hardhat.config.js আপডেট করতে হবে যাতে আমাদের প্রজেক্ট সেগুলোর সব সম্পর্কে জানতে পারে।

আপনার hardhat.config.js আপডেট করে এরকম করুন:

1/* *
2 * @type import('hardhat/config').HardhatUserConfig */
3
4require("dotenv").config()
5require("@nomiclabs/hardhat-ethers")
6
7const { API_URL, PRIVATE_KEY } = process.env
8
9module.exports = {
10 solidity: "0.7.3",
11 defaultNetwork: "goerli",
12 networks: {
13 hardhat: {},
14 goerli: {
15 url: API_URL,
16 accounts: [`0x${PRIVATE_KEY}`],
17 },
18 },
19}

ধাপ 14: আমাদের কন্ট্রাক্ট কম্পাইল করুন

এ পর্যন্ত সবকিছু ঠিকঠাক কাজ করছে কিনা তা নিশ্চিত করতে, চলুন আমাদের কন্ট্রাক্ট কম্পাইল করি। compile টাস্কটি হলো বিল্ট-ইন hardhat টাস্কগুলোর মধ্যে একটি।

কমান্ড লাইন থেকে রান করুন:

npx hardhat compile

আপনি SPDX license identifier not provided in source file সম্পর্কে একটি ওয়ার্নিং পেতে পারেন, তবে এটি নিয়ে চিন্তা করার কোনো কারণ নেই — আশা করি অন্য সবকিছু ঠিক আছে! যদি তা না হয়, তবে আপনি সবসময় Alchemy ডিসকর্ড (opens in a new tab)-এ মেসেজ করতে পারেন।

ধাপ 15: আমাদের ডিপ্লয় স্ক্রিপ্ট লিখুন

এখন যেহেতু আমাদের কন্ট্রাক্ট লেখা হয়ে গেছে এবং আমাদের কনফিগারেশন ফাইল প্রস্তুত, তাই এখন আমাদের কন্ট্রাক্ট ডিপ্লয় স্ক্রিপ্ট লেখার সময়।

scripts/ ফোল্ডারে যান এবং deploy.js নামে একটি নতুন ফাইল তৈরি করুন, এতে নিচের বিষয়বস্তুগুলো যোগ করুন:

1async function main() {
2 const HelloWorld = await ethers.getContractFactory("HelloWorld")
3
4 // ডিপ্লয়মেন্ট শুরু করুন, একটি প্রমিস রিটার্ন করে যা একটি কন্ট্রাক্ট অবজেক্টে রিজলভ হয়
5 const hello_world = await HelloWorld.deploy("Hello World!")
6 console.log("Contract deployed to address:", hello_world.address)
7}
8
9main()
10 .then(() => process.exit(0))
11 .catch((error) => {
12 console.error(error)
13 process.exit(1)
14 })

Hardhat তাদের কন্ট্রাক্টস টিউটোরিয়ালে (opens in a new tab) এই কোডের প্রতিটি লাইন কী করে তা খুব সুন্দরভাবে ব্যাখ্যা করেছে, আমরা এখানে তাদের ব্যাখ্যাগুলো গ্রহণ করেছি।

1const HelloWorld = await ethers.getContractFactory("HelloWorld")

ethers.js-এ একটি ContractFactory হলো নতুন স্মার্ট কন্ট্রাক্ট ডিপ্লয় করার জন্য ব্যবহৃত একটি অ্যাবস্ট্রাকশন, তাই এখানে HelloWorld হলো আমাদের হ্যালো ওয়ার্ল্ড কন্ট্রাক্টের ইনস্ট্যান্সগুলোর জন্য একটি ফ্যাক্টরি (opens in a new tab)hardhat-ethers প্লাগইন ব্যবহার করার সময় ContractFactory এবং Contract, ইনস্ট্যান্সগুলো ডিফল্টভাবে প্রথম সাইনার (মালিক)-এর সাথে কানেক্টেড থাকে।

1const hello_world = await HelloWorld.deploy()

একটি ContractFactory-তে deploy() কল করলে ডিপ্লয়মেন্ট শুরু হবে, এবং একটি Promise রিটার্ন করবে যা একটি Contract অবজেক্টে রিজলভ হয়। এটি এমন একটি অবজেক্ট যার মধ্যে আমাদের স্মার্ট কন্ট্রাক্টের প্রতিটি ফাংশনের জন্য একটি মেথড রয়েছে।

ধাপ 16: আমাদের কন্ট্রাক্ট ডিপ্লয় করুন

আমরা অবশেষে আমাদের স্মার্ট কন্ট্রাক্ট ডিপ্লয় করতে প্রস্তুত! কমান্ড লাইনে যান এবং রান করুন:

npx hardhat run scripts/deploy.js --network goerli

এরপর আপনি এরকম কিছু দেখতে পাবেন:

Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570

অনুগ্রহ করে এই এডড্রেসটি সেভ করুন। আমরা টিউটোরিয়ালের পরে এটি ব্যবহার করব।

আমরা যদি Goerli etherscan (opens in a new tab)-এ যাই এবং আমাদের কন্ট্রাক্ট এডড্রেস সার্চ করি তবে আমরা দেখতে পাব যে এটি সফলভাবে ডিপ্লয় হয়েছে। লেনদেন-টি দেখতে এরকম হবে:

The From এডড্রেসটি আপনার MetaMask একাউন্ট এডড্রেস-এর সাথে মিলতে হবে এবং To এডড্রেসটি Contract Creation বলবে। আমরা যদি লেনদেন-এ ক্লিক করি তবে আমরা To ফিল্ডে আমাদের কন্ট্রাক্ট এডড্রেস দেখতে পাব।

অভিনন্দন! আপনি এইমাত্র একটি ইথিরিয়াম টেস্টনেট-এ একটি স্মার্ট কন্ট্রাক্ট ডিপ্লয় করেছেন।

ভেতরে কী ঘটছে তা বোঝার জন্য, চলুন আমাদের Alchemy ড্যাশবোর্ডের (opens in a new tab) এক্সপ্লোরার ট্যাবে যাই। আপনার যদি একাধিক Alchemy অ্যাপ থাকে তবে নিশ্চিত করুন যে আপনি অ্যাপ অনুযায়ী ফিল্টার করেছেন এবং Hello World নির্বাচন করেছেন।

এখানে আপনি বেশ কয়েকটি JSON-RPC মেথড দেখতে পাবেন যা Hardhat/Ethers আমাদের জন্য ভেতরে তৈরি করেছে যখন আমরা .deploy() ফাংশনটি কল করেছিলাম। এখানকার দুটি গুরুত্বপূর্ণ মেথড হলো eth_sendRawTransaction (opens in a new tab), যা Goerli চেইনে আমাদের কন্ট্রাক্ট লেখার রিকোয়েস্ট, এবং eth_getTransactionByHash (opens in a new tab), যা হ্যাস দেওয়া থাকলে আমাদের লেনদেন সম্পর্কে তথ্য পড়ার রিকোয়েস্ট। লেনদেন পাঠানো সম্পর্কে আরও জানতে, Web3 ব্যবহার করে লেনদেন পাঠানোর উপর আমাদের টিউটোরিয়ালটি দেখুন।

পর্ব 2: আপনার স্মার্ট কন্ট্রাক্ট এর সাথে ইন্টারঅ্যাক্ট করুন

যেহেতু আমরা সফলভাবে Goerli নেটওয়ার্ক-এ একটি স্মার্ট কন্ট্রাক্ট ডিপ্লয় করেছি, চলুন এখন শিখে নিই কীভাবে এর সাথে ইন্টারঅ্যাক্ট করতে হয়।

একটি interact.js ফাইল তৈরি করুন

এটি সেই ফাইল যেখানে আমরা আমাদের ইন্টারঅ্যাকশন স্ক্রিপ্ট লিখব। আমরা Ethers.js লাইব্রেরি ব্যবহার করব যা আপনি আগে পর্ব 1-এ ইনস্টল করেছিলেন।

scripts/ ফোল্ডারের ভেতরে, interact.js নামের একটি নতুন ফাইল তৈরি করুন এবং নিচের কোডটি যোগ করুন:

1// interact.js
2
3const API_KEY = process.env.API_KEY
4const PRIVATE_KEY = process.env.PRIVATE_KEY
5const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS

আপনার .env ফাইল আপডেট করুন

আমরা নতুন এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করব, তাই আমাদের সেগুলোকে .env ফাইলে সংজ্ঞায়িত করতে হবে যা আমরা আগে তৈরি করেছিলাম

আমাদের Alchemy API_KEY এবং CONTRACT_ADDRESS এর জন্য একটি সংজ্ঞা যোগ করতে হবে যেখানে আপনার স্মার্ট কন্ট্রাক্ট ডিপ্লয় করা হয়েছিল।

আপনার .env ফাইলটি দেখতে অনেকটা এরকম হওয়া উচিত:

# .env
API_URL = "https://eth-goerli.alchemyapi.io/v2/<your-api-key>"
API_KEY = "<your-api-key>"
PRIVATE_KEY = "<your-metamask-private-key>"
CONTRACT_ADDRESS = "0x<your contract address>"

আপনার কন্ট্রাক্ট ABI সংগ্রহ করুন

আমাদের কন্ট্রাক্ট হলো আমাদের স্মার্ট কন্ট্রাক্ট এর সাথে ইন্টারঅ্যাক্ট করার ইন্টারফেস। Hardhat স্বয়ংক্রিয়ভাবে একটি ABI তৈরি করে এবং এটি HelloWorld.json-এ সেভ করে। ABI ব্যবহার করার জন্য, আমাদের interact.js ফাইলে নিচের কোডের লাইনগুলো যোগ করে এর কন্টেন্ট পার্স করতে হবে:

1// interact.js
2const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")

আপনি যদি ABI দেখতে চান তবে আপনি এটি আপনার কনসোলে প্রিন্ট করতে পারেন:

1console.log(JSON.stringify(contract.abi))

আপনার ABI কনসোলে প্রিন্ট হওয়া দেখতে, আপনার টার্মিনালে যান এবং রান করুন:

npx hardhat run scripts/interact.js

আপনার কন্ট্রাক্টের একটি ইনস্ট্যান্স তৈরি করুন

আমাদের কন্ট্রাক্টের সাথে ইন্টারঅ্যাক্ট করতে, আমাদের কোডে একটি কন্ট্রাক্ট ইনস্ট্যান্স তৈরি করতে হবে। Ethers.js এর সাথে এটি করতে, আমাদের তিনটি কনসেপ্ট নিয়ে কাজ করতে হবে:

  1. Provider - একটি নোড প্রোভাইডার যা আপনাকে ব্লকচেইন-এ রিড এবং রাইট অ্যাক্সেস দেয়
  2. Signer - একটি ইথিরিয়াম একাউন্ট উপস্থাপন করে যা লেনদেন সাইন করতে পারে
  3. Contract - একটি Ethers.js অবজেক্ট যা অনচেইন-এ ডিপ্লয় করা একটি নির্দিষ্ট কন্ট্রাক্টকে উপস্থাপন করে

আমরা কন্ট্রাক্টের ইনস্ট্যান্স তৈরি করতে আগের ধাপ থেকে কন্ট্রাক্ট ABI ব্যবহার করব:

1// interact.js
2
3// প্রোভাইডার
4const alchemyProvider = new ethers.providers.AlchemyProvider(
5 (network = "goerli"),
6 API_KEY
7)
8
9// সাইনার
10const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider)
11
12// কন্ট্রাক্ট
13const helloWorldContract = new ethers.Contract(
14 CONTRACT_ADDRESS,
15 contract.abi,
16 signer
17)

Providers, Signers এবং Contracts সম্পর্কে আরও জানুন ethers.js ডকুমেন্টেশন (opens in a new tab)-এ।

init মেসেজটি পড়ুন

মনে আছে যখন আমরা initMessage = "Hello world!" দিয়ে আমাদের কন্ট্রাক্ট ডিপ্লয় করেছিলাম? আমরা এখন আমাদের স্মার্ট কন্ট্রাক্ট-এ সংরক্ষিত সেই মেসেজটি পড়ব এবং কনসোলে প্রিন্ট করব।

জাভাস্ক্রিপ্টে, নেটওয়ার্ক-এর সাথে ইন্টারঅ্যাক্ট করার সময় অ্যাসিনক্রোনাস ফাংশন ব্যবহার করা হয়। অ্যাসিনক্রোনাস ফাংশন সম্পর্কে আরও জানতে, এই মিডিয়াম আর্টিকেলটি পড়ুন (opens in a new tab)

আমাদের স্মার্ট কন্ট্রাক্ট-এ message ফাংশন কল করতে এবং init মেসেজটি পড়তে নিচের কোডটি ব্যবহার করুন:

1// interact.js
2
3// ...
4
5async function main() {
6 const message = await helloWorldContract.message()
7 console.log("The message is: " + message)
8}
9main()

টার্মিনালে npx hardhat run scripts/interact.js ব্যবহার করে ফাইলটি রান করার পর আমাদের এই রেসপন্সটি দেখা উচিত:

1The message is: Hello world!

অভিনন্দন! আপনি এইমাত্র ইথিরিয়াম ব্লকচেইন থেকে সফলভাবে স্মার্ট কন্ট্রাক্ট ডাটা পড়েছেন, দারুণ কাজ!

মেসেজটি আপডেট করুন

শুধুমাত্র মেসেজটি পড়ার পরিবর্তে, আমরা update ফাংশন ব্যবহার করে আমাদের স্মার্ট কন্ট্রাক্ট-এ সেভ করা মেসেজটিও আপডেট করতে পারি! বেশ দারুণ, তাই না?

মেসেজটি আপডেট করতে, আমরা সরাসরি আমাদের ইনস্ট্যানশিয়েটেড Contract অবজেক্টে update ফাংশন কল করতে পারি:

1// interact.js
2
3// ...
4
5async function main() {
6 const message = await helloWorldContract.message()
7 console.log("The message is: " + message)
8
9 console.log("Updating the message...")
10 const tx = await helloWorldContract.update("This is the new message.")
11 await tx.wait()
12}
13main()

লক্ষ্য করুন যে 11 নম্বর লাইনে, আমরা রিটার্ন করা লেনদেন অবজেক্টে .wait() কল করেছি। এটি নিশ্চিত করে যে ফাংশন থেকে বের হওয়ার আগে আমাদের স্ক্রিপ্টটি ব্লকচেইন-এ লেনদেন মাইন হওয়ার জন্য অপেক্ষা করবে। যদি .wait() কলটি অন্তর্ভুক্ত না থাকে, তবে স্ক্রিপ্টটি কন্ট্রাক্টে আপডেট করা message ভ্যালু দেখতে নাও পারে।

নতুন মেসেজটি পড়ুন

আপডেট করা message ভ্যালু পড়তে আপনার আগের ধাপটি পুনরাবৃত্তি করতে পারা উচিত। একটু সময় নিন এবং দেখুন আপনি সেই নতুন ভ্যালুটি প্রিন্ট করার জন্য প্রয়োজনীয় পরিবর্তনগুলো করতে পারেন কিনা!

আপনার যদি কোনো হিন্ট বা সূত্রের প্রয়োজন হয়, তবে এই পর্যায়ে আপনার interact.js ফাইলটি দেখতে যেমন হওয়া উচিত তা নিচে দেওয়া হলো:

1// interact.js
2
3const API_KEY = process.env.API_KEY
4const PRIVATE_KEY = process.env.PRIVATE_KEY
5const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS
6
7const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")
8
9// প্রোভাইডার - অ্যালকেমি
10const alchemyProvider = new ethers.providers.AlchemyProvider(
11 (network = "goerli"),
12 API_KEY
13)
14
15// সাইনার - আপনি
16const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider)
17
18// কন্ট্রাক্ট ইন্সট্যান্স
19const helloWorldContract = new ethers.Contract(
20 CONTRACT_ADDRESS,
21 contract.abi,
22 signer
23)
24
25async function main() {
26 const message = await helloWorldContract.message()
27 console.log("The message is: " + message)
28
29 console.log("Updating the message...")
30 const tx = await helloWorldContract.update("this is the new message")
31 await tx.wait()
32
33 const newMessage = await helloWorldContract.message()
34 console.log("The new message is: " + newMessage)
35}
36
37main()

এখন শুধু স্ক্রিপ্টটি রান করুন এবং আপনি আপনার টার্মিনালে পুরনো মেসেজ, আপডেটিং স্ট্যাটাস এবং নতুন মেসেজ প্রিন্ট হওয়া দেখতে পাবেন!

npx hardhat run scripts/interact.js --network goerli

1The message is: Hello World!
2Updating the message...
3The new message is: This is the new message.

সেই স্ক্রিপ্টটি রান করার সময়, আপনি লক্ষ্য করতে পারেন যে নতুন মেসেজ লোড হওয়ার আগে Updating the message... ধাপটি লোড হতে কিছুটা সময় নেয়। এটি মাইনিং প্রক্রিয়ার কারণে হয়; আপনি যদি লেনদেন মাইন হওয়ার সময় সেগুলো ট্র্যাক করতে আগ্রহী হন, তবে একটি লেনদেন এর স্ট্যাটাস দেখতে Alchemy mempool (opens in a new tab) ভিজিট করুন। যদি লেনদেন ড্রপ হয়ে যায়, তবে Goerli Etherscan (opens in a new tab) চেক করা এবং আপনার লেনদেন হ্যাস সার্চ করাও সহায়ক হতে পারে।

পার্ট 3: Etherscan-এ আপনার স্মার্ট কন্ট্রাক্ট পাবলিশ করুন

আপনার স্মার্ট কন্ট্রাক্টকে বাস্তবে রূপ দিতে আপনি অনেক পরিশ্রম করেছেন; এখন এটি বিশ্বের সাথে শেয়ার করার সময় এসেছে!

Etherscan-এ আপনার স্মার্ট কন্ট্রাক্ট ভেরিফাই করার মাধ্যমে, যে কেউ আপনার সোর্স কোড দেখতে পারবে এবং আপনার স্মার্ট কন্ট্রাক্টের সাথে ইন্টারঅ্যাক্ট করতে পারবে। চলুন শুরু করা যাক!

ধাপ 1: আপনার Etherscan একাউন্টে একটি API Key তৈরি করুন

আপনি যে স্মার্ট কন্ট্রাক্টটি পাবলিশ করার চেষ্টা করছেন তার মালিক যে আপনিই, তা ভেরিফাই করার জন্য একটি Etherscan API Key প্রয়োজন।

আপনার যদি আগে থেকে কোনো Etherscan একাউন্ট না থাকে, তাহলে একটি একাউন্টের জন্য সাইন আপ করুন (opens in a new tab)

লগ ইন করার পর, নেভিগেশন বারে আপনার ইউজারনেম খুঁজুন, এর উপর হোভার করুন এবং My profile বোতামটি নির্বাচন করুন।

আপনার প্রোফাইল পেজে, আপনি একটি সাইড নেভিগেশন বার দেখতে পাবেন। সাইড নেভিগেশন বার থেকে, API Keys নির্বাচন করুন। এরপর, একটি নতুন API key তৈরি করতে "Add" বোতাম টিপুন, আপনার অ্যাপের নাম দিন hello-world এবং Create New API Key বোতাম টিপুন।

আপনার নতুন API key-টি API key টেবিলে দেখা যাবে। API key-টি আপনার ক্লিপবোর্ডে কপি করুন।

এরপর, আমাদের .env ফাইলে Etherscan API key যোগ করতে হবে।

এটি যোগ করার পর, আপনার .env ফাইলটি দেখতে এরকম হবে:

1API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
2PUBLIC_KEY = "your-public-account-address"
3PRIVATE_KEY = "your-private-account-address"
4CONTRACT_ADDRESS = "your-contract-address"
5ETHERSCAN_API_KEY = "your-etherscan-key"

Hardhat-এর মাধ্যমে ডিপ্লয় করা স্মার্ট কন্ট্রাক্ট

hardhat-etherscan ইনস্টল করুন

Hardhat ব্যবহার করে Etherscan-এ আপনার কন্ট্রাক্ট পাবলিশ করা বেশ সহজ। শুরু করার জন্য আপনাকে প্রথমে hardhat-etherscan প্লাগইনটি ইনস্টল করতে হবে। hardhat-etherscan স্বয়ংক্রিয়ভাবে Etherscan-এ স্মার্ট কন্ট্রাক্টের সোর্স কোড এবং ABI ভেরিফাই করবে। এটি যোগ করতে, hello-world ডিরেক্টরিতে রান করুন:

1npm install --save-dev @nomiclabs/hardhat-etherscan

ইনস্টল হয়ে গেলে, আপনার hardhat.config.js-এর একদম উপরে নিচের স্টেটমেন্টটি অন্তর্ভুক্ত করুন এবং Etherscan কনফিগ অপশনগুলো যোগ করুন:

1// hardhat.config.js
2
3require("dotenv").config()
4require("@nomiclabs/hardhat-ethers")
5require("@nomiclabs/hardhat-etherscan")
6
7const { API_URL, PRIVATE_KEY, ETHERSCAN_API_KEY } = process.env
8
9module.exports = {
10 solidity: "0.7.3",
11 defaultNetwork: "goerli",
12 networks: {
13 hardhat: {},
14 goerli: {
15 url: API_URL,
16 accounts: [`0x${PRIVATE_KEY}`],
17 },
18 },
19 etherscan: {
20 // ইথারস্ক্যানের জন্য আপনার এপিআই (API) কী
21 // https://etherscan.io/ থেকে একটি সংগ্রহ করুন
22 apiKey: ETHERSCAN_API_KEY,
23 },
24}

Etherscan-এ আপনার স্মার্ট কন্ট্রাক্ট ভেরিফাই করুন

নিশ্চিত করুন যে সমস্ত ফাইল সেভ করা হয়েছে এবং সমস্ত .env ভেরিয়েবল সঠিকভাবে কনফিগার করা হয়েছে।

কন্ট্রাক্ট এডড্রেস এবং এটি যে নেটওয়ার্ক-এ ডিপ্লয় করা হয়েছে তা পাস করে verify টাস্কটি রান করুন:

1npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS 'Hello World!'

নিশ্চিত করুন যে DEPLOYED_CONTRACT_ADDRESS হলো Goerli টেস্টনেট-এ আপনার ডিপ্লয় করা স্মার্ট কন্ট্রাক্টের এডড্রেস। এছাড়া, চূড়ান্ত আর্গুমেন্ট ('Hello World!') অবশ্যই পার্ট 1-এর ডিপ্লয়মেন্ট ধাপে ব্যবহৃত স্ট্রিং ভ্যালুর সমান হতে হবে।

সবকিছু ঠিকঠাক থাকলে, আপনি আপনার টার্মিনালে নিচের মেসেজটি দেখতে পাবেন:

1Successfully submitted source code for contract
2contracts/HelloWorld.sol:HelloWorld at 0xdeployed-contract-address
3for verification on Etherscan. Waiting for verification result...
4
5
6Successfully verified contract HelloWorld on Etherscan.
7https: // goerli.etherscan.io/address/<contract-address>#contracts

অভিনন্দন! আপনার স্মার্ট কন্ট্রাক্ট কোড এখন Etherscan-এ আছে!

Etherscan-এ আপনার স্মার্ট কন্ট্রাক্টটি দেখে নিন!

আপনার টার্মিনালে দেওয়া লিঙ্কে গেলে, আপনি Etherscan-এ পাবলিশ হওয়া আপনার স্মার্ট কন্ট্রাক্ট কোড এবং ABI দেখতে পাবেন!

ওয়াহু - আপনি পেরেছেন চ্যাম্প! এখন যে কেউ আপনার স্মার্ট কন্ট্রাক্টে কল বা রাইট করতে পারবে! আপনি পরবর্তীতে কী তৈরি করবেন তা দেখার জন্য আমরা অধীর আগ্রহে অপেক্ষা করছি!

পর্ব 4 - ফ্রন্টএন্ডের সাথে আপনার স্মার্ট কন্ট্রাক্ট ইন্টিগ্রেট করা

এই টিউটোরিয়ালের শেষে, আপনি জানতে পারবেন কীভাবে:

  • আপনার ডিএ্যাপ এর সাথে একটি MetaMask ওয়ালেট কানেক্ট করতে হয়
  • Alchemy Web3 (opens in a new tab) API ব্যবহার করে আপনার স্মার্ট কন্ট্রাক্ট থেকে ডেটা রিড করতে হয়
  • MetaMask ব্যবহার করে ইথিরিয়াম লেনদেন সাইন করতে হয়

এই ডিএ্যাপ এর জন্য, আমরা আমাদের ফ্রন্টএন্ড ফ্রেমওয়ার্ক হিসেবে React (opens in a new tab) ব্যবহার করব; তবে, এটি মনে রাখা গুরুত্বপূর্ণ যে আমরা এর মৌলিক বিষয়গুলো ব্যাখ্যা করতে খুব বেশি সময় ব্যয় করব না, কারণ আমরা মূলত আমাদের প্রজেক্টে Web3 কার্যকারিতা আনার দিকেই বেশি মনোযোগ দেব।

পূর্বশর্ত হিসেবে, আপনার React সম্পর্কে প্রাথমিক স্তরের ধারণা থাকা উচিত। যদি না থাকে, তবে আমরা অফিসিয়াল Intro to React tutorial (opens in a new tab) সম্পন্ন করার পরামর্শ দিচ্ছি।

স্টার্টার ফাইলগুলো ক্লোন করুন

প্রথমে, এই প্রজেক্টের স্টার্টার ফাইলগুলো পেতে hello-world-part-four GitHub repository (opens in a new tab)-তে যান এবং এই রিপোজিটরিটি আপনার লোকাল মেশিনে ক্লোন করুন।

ক্লোন করা রিপোজিটরিটি লোকালি খুলুন। লক্ষ্য করুন যে এতে দুটি ফোল্ডার রয়েছে: starter-files এবং completed

  • starter-files- আমরা এই ডিরেক্টরিতে কাজ করব, আমরা UI-কে আপনার ইথিরিয়াম ওয়ালেট এবং Part 3-এ Etherscan-এ পাবলিশ করা স্মার্ট কন্ট্রাক্ট এর সাথে কানেক্ট করব।
  • completed-এ সম্পূর্ণ টিউটোরিয়ালটি রয়েছে এবং আপনি যদি কোথাও আটকে যান তবে এটি শুধুমাত্র রেফারেন্স হিসেবে ব্যবহার করা উচিত।

এরপর, আপনার প্রিয় কোড এডিটরে starter-files এর কপিটি খুলুন এবং তারপর src ফোল্ডারে নেভিগেট করুন।

আমরা যে কোডগুলো লিখব তার সবই src ফোল্ডারের অধীনে থাকবে। আমাদের প্রজেক্টে Web3 কার্যকারিতা দিতে আমরা HelloWorld.js কম্পোনেন্ট এবং util/interact.js জাভাস্ক্রিপ্ট ফাইলগুলো এডিট করব।

স্টার্টার ফাইলগুলো চেক করুন

কোডিং শুরু করার আগে, চলুন দেখে নিই স্টার্টার ফাইলগুলোতে আমাদের কী কী দেওয়া হয়েছে।

আপনার react প্রজেক্ট চালু করুন

চলুন আমাদের ব্রাউজারে React প্রজেক্টটি রান করার মাধ্যমে শুরু করি। React এর সৌন্দর্য হলো, একবার আমাদের প্রজেক্ট ব্রাউজারে রান করলে, আমরা যে পরিবর্তনগুলো সেভ করব তা ব্রাউজারে লাইভ আপডেট হবে।

প্রজেক্টটি রান করতে, starter-files ফোল্ডারের রুট ডিরেক্টরিতে নেভিগেট করুন এবং প্রজেক্টের ডিপেন্ডেন্সিগুলো ইনস্টল করতে আপনার টার্মিনালে npm install রান করুন:

cd starter-files
npm install

সেগুলো ইনস্টল করা শেষ হলে, আপনার টার্মিনালে npm start রান করুন:

npm start

এটি করলে আপনার ব্রাউজারে http://localhost:3000/ (opens in a new tab) খুলবে, যেখানে আপনি আমাদের প্রজেক্টের ফ্রন্টএন্ড দেখতে পাবেন। এতে একটি ফিল্ড (আপনার স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত মেসেজ আপডেট করার জায়গা), একটি "Connect Wallet" বোতাম এবং একটি "Update" বোতাম থাকা উচিত।

আপনি যদি কোনো বোতামে ক্লিক করার চেষ্টা করেন, তবে আপনি লক্ষ্য করবেন যে সেগুলো কাজ করছে না—কারণ আমাদের এখনও সেগুলোর কার্যকারিতা প্রোগ্রাম করতে হবে।

HelloWorld.js কম্পোনেন্ট

চলুন আমাদের এডিটরের src ফোল্ডারে ফিরে যাই এবং HelloWorld.js ফাইলটি খুলি। এই ফাইলের সবকিছু বোঝা আমাদের জন্য অত্যন্ত গুরুত্বপূর্ণ, কারণ এটিই প্রাথমিক React কম্পোনেন্ট যার ওপর আমরা কাজ করব।

এই ফাইলের শীর্ষে, আপনি লক্ষ্য করবেন যে আমাদের প্রজেক্টটি রান করার জন্য প্রয়োজনীয় বেশ কয়েকটি ইমপোর্ট স্টেটমেন্ট রয়েছে, যার মধ্যে রয়েছে React লাইব্রেরি, useEffect এবং useState হুক, ./util/interact.js থেকে কিছু আইটেম (আমরা শীঘ্রই সেগুলোর বিস্তারিত বর্ণনা করব!), এবং Alchemy লোগো।

1// HelloWorld.js
2
3import React from "react"
4import { useEffect, useState } from "react"
5import {
6 helloWorldContract,
7 connectWallet,
8 updateMessage,
9 loadCurrentMessage,
10 getCurrentWalletConnected,
11} from "./util/interact.js"
12
13import alchemylogo from "./alchemylogo.svg"

এরপর, আমাদের স্টেট ভেরিয়েবলগুলো রয়েছে যা আমরা নির্দিষ্ট ইভেন্টের পরে আপডেট করব।

1// HelloWorld.js
2
3// স্টেট ভেরিয়েবল
4const [walletAddress, setWallet] = useState("")
5const [status, setStatus] = useState("")
6const [message, setMessage] = useState("No connection to the network.")
7const [newMessage, setNewMessage] = useState("")

এখানে প্রতিটি ভেরিয়েবল যা উপস্থাপন করে তা দেওয়া হলো:

  • walletAddress - একটি স্ট্রিং যা ব্যবহারকারীর ওয়ালেট এডড্রেস সংরক্ষণ করে
  • status- একটি স্ট্রিং যা একটি সহায়ক মেসেজ সংরক্ষণ করে যা ব্যবহারকারীকে ডিএ্যাপ এর সাথে কীভাবে ইন্টারঅ্যাক্ট করতে হয় সে সম্পর্কে গাইড করে
  • message - একটি স্ট্রিং যা স্মার্ট কন্ট্রাক্ট এ বর্তমান মেসেজটি সংরক্ষণ করে
  • newMessage - একটি স্ট্রিং যা নতুন মেসেজটি সংরক্ষণ করে যা স্মার্ট কন্ট্রাক্ট এ লেখা হবে

স্টেট ভেরিয়েবলগুলোর পরে, আপনি পাঁচটি ইমপ্লিমেন্ট না করা ফাংশন দেখতে পাবেন: useEffect ,addSmartContractListener, addWalletListener , connectWalletPressed, এবং onUpdatePressed। আমরা নিচে ব্যাখ্যা করব এগুলো কী কাজ করে:

1// HelloWorld.js
2
3// শুধুমাত্র একবার কল করা হয়
4useEffect(async () => {
5 // TODO: ইমপ্লিমেন্ট করুন
6}, [])
7
8function addSmartContractListener() {
9 // TODO: ইমপ্লিমেন্ট করুন
10}
11
12function addWalletListener() {
13 // TODO: ইমপ্লিমেন্ট করুন
14}
15
16const connectWalletPressed = async () => {
17 // TODO: ইমপ্লিমেন্ট করুন
18}
19
20const onUpdatePressed = async () => {
21 // TODO: ইমপ্লিমেন্ট করুন
22}
  • useEffect (opens in a new tab)- এটি একটি React হুক যা আপনার কম্পোনেন্ট রেন্ডার হওয়ার পরে কল করা হয়। যেহেতু এতে একটি খালি অ্যারে [] প্রপ পাস করা হয়েছে (লাইন 4 দেখুন), এটি শুধুমাত্র কম্পোনেন্টের প্রথম রেন্ডারে কল করা হবে। এখানে আমরা আমাদের স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত বর্তমান মেসেজটি লোড করব, আমাদের স্মার্ট কন্ট্রাক্ট এবং ওয়ালেট লিসেনারদের কল করব এবং কোনো ওয়ালেট আগে থেকেই কানেক্ট করা আছে কিনা তা প্রতিফলিত করতে আমাদের UI আপডেট করব।
  • addSmartContractListener- এই ফাংশনটি একটি লিসেনার সেট আপ করে যা আমাদের HelloWorld কন্ট্রাক্টের UpdatedMessages ইভেন্টের জন্য নজর রাখবে এবং আমাদের স্মার্ট কন্ট্রাক্ট এ মেসেজ পরিবর্তন হলে আমাদের UI আপডেট করবে।
  • addWalletListener- এই ফাংশনটি একটি লিসেনার সেট আপ করে যা ব্যবহারকারীর MetaMask ওয়ালেট স্টেট এ পরিবর্তনগুলো শনাক্ত করে, যেমন যখন ব্যবহারকারী তাদের ওয়ালেট ডিসকানেক্ট করে বা এডড্রেস পরিবর্তন করে।
  • connectWalletPressed- ব্যবহারকারীর MetaMask ওয়ালেট কে আমাদের ডিএ্যাপ এর সাথে কানেক্ট করতে এই ফাংশনটি কল করা হবে।
  • onUpdatePressed - যখন ব্যবহারকারী স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত মেসেজটি আপডেট করতে চাইবেন তখন এই ফাংশনটি কল করা হবে।

এই ফাইলের শেষের দিকে, আমাদের কম্পোনেন্টের UI রয়েছে।

1// HelloWorld.js
2
3// আমাদের কম্পোনেন্টের ইউআই (UI)
4return (
5 <div id="container">
6 <img id="logo" src={alchemylogo}></img>
7 <button id="walletButton" onClick={connectWalletPressed}>
8 {walletAddress.length > 0 ? (
9 "Connected: " +
10 String(walletAddress).substring(0, 6) +
11 "..." +
12 String(walletAddress).substring(38)
13 ) : (
14 <span>Connect Wallet</span>
15 )}
16 </button>
17
18 <h2 style={{ paddingTop: "50px" }}>Current Message:</h2>
19 <p>{message}</p>
20
21 <h2 style={{ paddingTop: "18px" }}>New Message:</h2>
22
23 <div>
24 <input
25 type="text"
26 placeholder="Update the message in your smart contract."
27 onChange={(e) => setNewMessage(e.target.value)}
28 value={newMessage}
29 />
30 <p id="status">{status}</p>
31
32 <button id="publishButton" onClick={onUpdatePressed}>
33 Update
34 </button>
35
36</div>
37
38</div>
39)

আপনি যদি এই কোডটি মনোযোগ সহকারে স্ক্যান করেন, তবে আপনি লক্ষ্য করবেন যে আমরা আমাদের UI-তে আমাদের বিভিন্ন স্টেট ভেরিয়েবলগুলো কোথায় ব্যবহার করি:

  • 6-12 লাইনে, যদি ব্যবহারকারীর ওয়ালেট কানেক্ট করা থাকে (অর্থাৎ, walletAddress.length > 0), আমরা "walletButton" আইডি সহ বোতামে ব্যবহারকারীর walletAddress এর একটি সংক্ষিপ্ত সংস্করণ প্রদর্শন করি; অন্যথায় এটি কেবল "Connect Wallet" বলে।
  • 17 লাইনে, আমরা স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত বর্তমান মেসেজটি প্রদর্শন করি, যা message স্ট্রিংয়ে ক্যাপচার করা হয়েছে।
  • 23-26 লাইনে, টেক্সট ফিল্ডে ইনপুট পরিবর্তন হলে আমাদের newMessage স্টেট ভেরিয়েবল আপডেট করতে আমরা একটি controlled component (opens in a new tab) ব্যবহার করি।

আমাদের স্টেট ভেরিয়েবলগুলো ছাড়াও, আপনি দেখতে পাবেন যে publishButton এবং walletButton আইডি সহ বোতামগুলোতে ক্লিক করা হলে যথাক্রমে connectWalletPressed এবং onUpdatePressed ফাংশনগুলো কল করা হয়।

অবশেষে, চলুন দেখি এই HelloWorld.js কম্পোনেন্টটি কোথায় যোগ করা হয়েছে।

আপনি যদি App.js ফাইলে যান, যা React-এর প্রধান কম্পোনেন্ট এবং অন্যান্য সমস্ত কম্পোনেন্টের জন্য একটি কন্টেইনার হিসেবে কাজ করে, আপনি দেখতে পাবেন যে আমাদের HelloWorld.js কম্পোনেন্টটি 7 নম্বর লাইনে ইনজেক্ট করা হয়েছে।

সবশেষে, চলুন আপনার জন্য দেওয়া আরও একটি ফাইল, interact.js ফাইলটি চেক করি।

interact.js ফাইল

যেহেতু আমরা M-V-C (opens in a new tab) প্যারাডাইম অনুসরণ করতে চাই, তাই আমরা একটি আলাদা ফাইল চাইব যাতে আমাদের ডিএ্যাপ এর লজিক, ডেটা এবং নিয়মগুলো পরিচালনা করার জন্য আমাদের সমস্ত ফাংশন থাকে এবং তারপর সেই ফাংশনগুলোকে আমাদের ফ্রন্টএন্ডে (আমাদের HelloWorld.js কম্পোনেন্ট) এক্সপোর্ট করতে সক্ষম হই।

👆🏽এটিই আমাদের interact.js ফাইলের আসল উদ্দেশ্য!

আপনার src ডিরেক্টরির util ফোল্ডারে নেভিগেট করুন, এবং আপনি লক্ষ্য করবেন যে আমরা interact.js নামের একটি ফাইল অন্তর্ভুক্ত করেছি যাতে আমাদের সমস্ত স্মার্ট কন্ট্রাক্ট ইন্টারঅ্যাকশন এবং ওয়ালেট ফাংশন এবং ভেরিয়েবলগুলো থাকবে।

1// interact.js
2
3// export const helloWorldContract;
4
5export const loadCurrentMessage = async () => {}
6
7export const connectWallet = async () => {}
8
9const getCurrentWalletConnected = async () => {}
10
11export const updateMessage = async (message) => {}

আপনি ফাইলের শীর্ষে লক্ষ্য করবেন যে আমরা helloWorldContract অবজেক্টটি কমেন্ট আউট করেছি। এই টিউটোরিয়ালের পরে, আমরা এই অবজেক্টটি আনকমেন্ট করব এবং এই ভেরিয়েবলে আমাদের স্মার্ট কন্ট্রাক্ট ইনস্ট্যানশিয়েট করব, যা আমরা পরে আমাদের HelloWorld.js কম্পোনেন্টে এক্সপোর্ট করব।

আমাদের helloWorldContract অবজেক্টের পরে চারটি ইমপ্লিমেন্ট না করা ফাংশন নিচের কাজগুলো করে:

  • loadCurrentMessage - এই ফাংশনটি স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত বর্তমান মেসেজ লোড করার লজিক পরিচালনা করে। এটি Alchemy Web3 API (opens in a new tab) ব্যবহার করে Hello World স্মার্ট কন্ট্রাক্ট এ একটি read কল করবে।
  • connectWallet - এই ফাংশনটি ব্যবহারকারীর MetaMask-কে আমাদের ডিএ্যাপ এর সাথে কানেক্ট করবে।
  • getCurrentWalletConnected - এই ফাংশনটি পেজ লোড হওয়ার সময় কোনো ইথিরিয়াম একাউন্ট আগে থেকেই আমাদের ডিএ্যাপ এর সাথে কানেক্ট করা আছে কিনা তা চেক করবে এবং সেই অনুযায়ী আমাদের UI আপডেট করবে।
  • updateMessage - এই ফাংশনটি স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত মেসেজটি আপডেট করবে। এটি Hello World স্মার্ট কন্ট্রাক্ট এ একটি write কল করবে, তাই মেসেজটি আপডেট করার জন্য ব্যবহারকারীর MetaMask ওয়ালেট কে একটি ইথিরিয়াম লেনদেন সাইন করতে হবে।

এখন যেহেতু আমরা বুঝতে পেরেছি আমরা কী নিয়ে কাজ করছি, চলুন বের করি কীভাবে আমাদের স্মার্ট কন্ট্রাক্ট থেকে রিড করতে হয়!

ধাপ 3: আপনার স্মার্ট কন্ট্রাক্ট থেকে রিড করুন

আপনার স্মার্ট কন্ট্রাক্ট থেকে রিড করতে, আপনাকে সফলভাবে সেট আপ করতে হবে:

  • ইথিরিয়াম চেইনের সাথে একটি API কানেকশন
  • আপনার স্মার্ট কন্ট্রাক্ট এর একটি লোড করা ইনস্ট্যান্স
  • আপনার স্মার্ট কন্ট্রাক্ট ফাংশনে কল করার জন্য একটি ফাংশন
  • স্মার্ট কন্ট্রাক্ট থেকে আপনি যে ডেটা রিড করছেন তা পরিবর্তন হলে আপডেটের জন্য নজর রাখার একটি লিসেনার

এটি শুনতে অনেকগুলো ধাপ মনে হতে পারে, তবে চিন্তা করবেন না! আমরা আপনাকে ধাপে ধাপে দেখাব কীভাবে এগুলোর প্রতিটি করতে হয়! :)

ইথিরিয়াম চেইনের সাথে একটি API কানেকশন স্থাপন করুন

তাহলে মনে আছে কীভাবে এই টিউটোরিয়ালের পার্ট 2-এ, আমরা আমাদের Alchemy Web3 key to read from our smart contract (opens in a new tab) ব্যবহার করেছিলাম? চেইন থেকে রিড করার জন্য আপনার ডিএ্যাপ এও একটি Alchemy Web3 কি প্রয়োজন হবে।

যদি আপনার কাছে এটি আগে থেকে না থাকে, তবে প্রথমে আপনার starter-files এর রুট ডিরেক্টরিতে নেভিগেট করে এবং আপনার টার্মিনালে নিচের কমান্ডটি রান করে Alchemy Web3 (opens in a new tab) ইনস্টল করুন:

1npm install @alch/alchemy-web3

Alchemy Web3 (opens in a new tab) হলো Web3.js (opens in a new tab) এর চারপাশে একটি র‍্যাপার, যা উন্নত API মেথড এবং অন্যান্য গুরুত্বপূর্ণ সুবিধা প্রদান করে যাতে একজন web3 ডেভেলপার হিসেবে আপনার জীবন সহজ হয়। এটি এমনভাবে ডিজাইন করা হয়েছে যাতে ন্যূনতম কনফিগারেশনের প্রয়োজন হয়, ফলে আপনি এখনই আপনার অ্যাপে এটি ব্যবহার করা শুরু করতে পারেন!

তারপর, আপনার প্রজেক্ট ডিরেক্টরিতে dotenv (opens in a new tab) প্যাকেজটি ইনস্টল করুন, যাতে আমাদের API কি ফেচ করার পরে এটি সংরক্ষণ করার জন্য একটি নিরাপদ জায়গা থাকে।

1npm install dotenv --save

আমাদের ডিএ্যাপ এর জন্য, আমরা আমাদের HTTP API কি এর পরিবর্তে আমাদের Websockets API কি ব্যবহার করব, কারণ এটি আমাদের একটি লিসেনার সেট আপ করতে দেবে যা স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত মেসেজ পরিবর্তন হলে তা শনাক্ত করে।

আপনার API কি পাওয়ার পর, আপনার রুট ডিরেক্টরিতে একটি .env ফাইল তৈরি করুন এবং এতে আপনার Alchemy Websockets url যোগ করুন। এরপর, আপনার .env ফাইলটি দেখতে এরকম হওয়া উচিত:

1REACT_APP_ALCHEMY_KEY = wss: // eth-goerli.ws.alchemyapi.io/v2/<key>

এখন, আমরা আমাদের ডিএ্যাপ এ আমাদের Alchemy Web3 এন্ডপয়েন্ট সেট আপ করতে প্রস্তুত! চলুন আমাদের interact.js-এ ফিরে যাই, যা আমাদের util ফোল্ডারের ভেতরে নেস্টেড করা আছে এবং ফাইলের শীর্ষে নিচের কোডটি যোগ করি:

1// interact.js
2
3require("dotenv").config()
4const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
5const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
6const web3 = createAlchemyWeb3(alchemyKey)
7
8// export const helloWorldContract;

উপরে, আমরা প্রথমে আমাদের .env ফাইল থেকে Alchemy কি ইমপোর্ট করেছি এবং তারপর আমাদের Alchemy Web3 এন্ডপয়েন্ট স্থাপন করতে createAlchemyWeb3-তে আমাদের alchemyKey পাস করেছি।

এই এন্ডপয়েন্ট প্রস্তুত হওয়ার সাথে সাথে, আমাদের স্মার্ট কন্ট্রাক্ট লোড করার সময় এসেছে!

আপনার Hello World স্মার্ট কন্ট্রাক্ট লোড করা

আপনার Hello World স্মার্ট কন্ট্রাক্ট লোড করতে, আপনার এর কন্ট্রাক্ট এডড্রেস এবং ABI প্রয়োজন হবে, যার উভয়ই Etherscan-এ পাওয়া যাবে যদি আপনি Part 3 of this tutorial. সম্পন্ন করে থাকেন।

Etherscan থেকে কীভাবে আপনার কন্ট্রাক্ট ABI পাবেন

আপনি যদি এই টিউটোরিয়ালের পার্ট 3 এড়িয়ে গিয়ে থাকেন, তবে আপনি 0x6f3f635A9762B47954229Ea479b4541eAF402A6A (opens in a new tab) এডড্রেস সহ HelloWorld কন্ট্রাক্ট ব্যবহার করতে পারেন। এর ABI এখানে (opens in a new tab) পাওয়া যাবে।

একটি কন্ট্রাক্ট কোন ফাংশনটি ইনভোক করবে তা নির্দিষ্ট করার পাশাপাশি ফাংশনটি আপনার প্রত্যাশিত ফরম্যাটে ডেটা রিটার্ন করবে তা নিশ্চিত করার জন্য একটি কন্ট্রাক্ট ABI প্রয়োজনীয়। একবার আমরা আমাদের কন্ট্রাক্ট ABI কপি করার পর, চলুন এটিকে আপনার src ডিরেক্টরিতে contract-abi.json নামের একটি JSON ফাইল হিসেবে সেভ করি।

আপনার contract-abi.json আপনার src ফোল্ডারে সংরক্ষণ করা উচিত।

আমাদের কন্ট্রাক্ট এডড্রেস, ABI এবং Alchemy Web3 এন্ডপয়েন্ট দিয়ে সজ্জিত হয়ে, আমরা আমাদের স্মার্ট কন্ট্রাক্ট এর একটি ইনস্ট্যান্স লোড করতে contract method (opens in a new tab) ব্যবহার করতে পারি। interact.js ফাইলে আপনার কন্ট্রাক্ট ABI ইমপোর্ট করুন এবং আপনার কন্ট্রাক্ট এডড্রেস যোগ করুন।

1// interact.js
2
3const contractABI = require("../contract-abi.json")
4const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A"

আমরা এখন অবশেষে আমাদের helloWorldContract ভেরিয়েবলটি আনকমেন্ট করতে পারি এবং আমাদের AlchemyWeb3 এন্ডপয়েন্ট ব্যবহার করে স্মার্ট কন্ট্রাক্ট লোড করতে পারি:

1// interact.js
2export const helloWorldContract = new web3.eth.Contract(
3 contractABI,
4 contractAddress
5)

সংক্ষেপে বলতে গেলে, আপনার interact.js এর প্রথম 12 লাইন এখন এরকম হওয়া উচিত:

1// interact.js
2
3require("dotenv").config()
4const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
5const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
6const web3 = createAlchemyWeb3(alchemyKey)
7
8const contractABI = require("../contract-abi.json")
9const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A"
10
11export const helloWorldContract = new web3.eth.Contract(
12 contractABI,
13 contractAddress
14)

এখন যেহেতু আমাদের কন্ট্রাক্ট লোড করা হয়েছে, আমরা আমাদের loadCurrentMessage ফাংশন ইমপ্লিমেন্ট করতে পারি!

আপনার interact.js ফাইলে loadCurrentMessage ইমপ্লিমেন্ট করা

এই ফাংশনটি খুবই সহজ। আমরা আমাদের কন্ট্রাক্ট থেকে রিড করার জন্য একটি সাধারণ async web3 কল করতে যাচ্ছি। আমাদের ফাংশনটি স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত মেসেজটি রিটার্ন করবে:

আপনার interact.js ফাইলে loadCurrentMessage নিচের মতো আপডেট করুন:

1// interact.js
2
3export const loadCurrentMessage = async () => {
4 const message = await helloWorldContract.methods.message().call()
5 return message
6}

যেহেতু আমরা আমাদের UI-তে এই স্মার্ট কন্ট্রাক্ট প্রদর্শন করতে চাই, তাই চলুন আমাদের HelloWorld.js কম্পোনেন্টে useEffect ফাংশনটি নিচের মতো আপডেট করি:

1// HelloWorld.js
2
3// শুধুমাত্র একবার কল করা হয়
4useEffect(async () => {
5 const message = await loadCurrentMessage()
6 setMessage(message)
7}, [])

লক্ষ্য করুন, আমরা চাই আমাদের loadCurrentMessage শুধুমাত্র কম্পোনেন্টের প্রথম রেন্ডারের সময় একবার কল করা হোক। স্মার্ট কন্ট্রাক্ট এ মেসেজ পরিবর্তন হওয়ার পরে স্বয়ংক্রিয়ভাবে UI আপডেট করতে আমরা শীঘ্রই addSmartContractListener ইমপ্লিমেন্ট করব।

আমাদের লিসেনারে প্রবেশ করার আগে, চলুন দেখে নিই এ পর্যন্ত আমাদের কী আছে! আপনার HelloWorld.js এবং interact.js ফাইলগুলো সেভ করুন এবং তারপর http://localhost:3000/ (opens in a new tab)-এ যান

আপনি লক্ষ্য করবেন যে বর্তমান মেসেজটি আর "No connection to the network" বলছে না। এর পরিবর্তে এটি স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত মেসেজটি প্রতিফলিত করে। দারুণ!

আপনার UI এখন স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত মেসেজটি প্রতিফলিত করা উচিত

এখন সেই লিসেনারের কথা বলতে গেলে...

addSmartContractListener ইমপ্লিমেন্ট করুন

আপনি যদি Part 1 of this tutorial series (opens in a new tab)-এ আমাদের লেখা HelloWorld.sol ফাইলটির কথা মনে করেন, তবে আপনার মনে পড়বে যে UpdatedMessages নামের একটি স্মার্ট কন্ট্রাক্ট ইভেন্ট রয়েছে যা আমাদের স্মার্ট কন্ট্রাক্ট এর update ফাংশন ইনভোক হওয়ার পরে এমিট হয় (লাইন 9 এবং 27 দেখুন):

1// HelloWorld.sol
2
3// সিম্যান্টিক ভার্সনিং ব্যবহার করে সলিডিটির ভার্সন নির্দিষ্ট করে।
4// আরও জানুন: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
5pragma solidity ^0.7.3;
6
7// `HelloWorld` নামের একটি কন্ট্রাক্ট ডিফাইন করে।
8// একটি কন্ট্রাক্ট হলো ফাংশন এবং ডেটার (এর স্টেট) একটি সংগ্রহ। একবার ডিপ্লয় করা হলে, একটি কন্ট্রাক্ট ইথেরিয়াম ব্লকচেইনের একটি নির্দিষ্ট ঠিকানায় অবস্থান করে। আরও জানুন: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
9contract HelloWorld {
10
11 // আপডেট ফাংশন কল করা হলে এমিট হয়
12 // স্মার্ট কন্ট্রাক্ট ইভেন্ট হলো আপনার কন্ট্রাক্টের জন্য ব্লকচেইনে কিছু ঘটার বিষয়ে আপনার অ্যাপের ফ্রন্ট-এন্ডের সাথে যোগাযোগ করার একটি উপায়, যা নির্দিষ্ট ইভেন্টগুলোর জন্য 'লিসেন' করতে পারে এবং সেগুলো ঘটলে ব্যবস্থা নিতে পারে।
13 event UpdatedMessages(string oldStr, string newStr);
14
15 // `string` টাইপের একটি স্টেট ভেরিয়েবল `message` ডিক্লেয়ার করে।
16 // স্টেট ভেরিয়েবল হলো এমন ভেরিয়েবল যার মান স্থায়ীভাবে কন্ট্রাক্ট স্টোরেজে সংরক্ষিত থাকে। `public` কিওয়ার্ড ভেরিয়েবলগুলোকে কন্ট্রাক্টের বাইরে থেকে অ্যাক্সেসযোগ্য করে তোলে এবং এমন একটি ফাংশন তৈরি করে যা অন্যান্য কন্ট্রাক্ট বা ক্লায়েন্টরা মান অ্যাক্সেস করতে কল করতে পারে।
17 string public message;
18
19 // অনেক ক্লাস-ভিত্তিক অবজেক্ট-ওরিয়েন্টেড ভাষার মতো, কনস্ট্রাক্টর হলো একটি বিশেষ ফাংশন যা শুধুমাত্র কন্ট্রাক্ট তৈরির সময় এক্সিকিউট হয়।
20 // কনস্ট্রাক্টরগুলো কন্ট্রাক্টের ডেটা ইনিশিয়ালাইজ করতে ব্যবহৃত হয়। আরও জানুন: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
21 constructor(string memory initMessage) {
22
23 // একটি স্ট্রিং আর্গুমেন্ট `initMessage` গ্রহণ করে এবং কন্ট্রাক্টের `message` স্টোরেজ ভেরিয়েবলে মান সেট করে)।
24 message = initMessage;
25 }
26
27 // একটি পাবলিক ফাংশন যা একটি স্ট্রিং আর্গুমেন্ট গ্রহণ করে এবং `message` স্টোরেজ ভেরিয়েবল আপডেট করে।
28 function update(string memory newMessage) public {
29 string memory oldMsg = message;
30 message = newMessage;
31 emit UpdatedMessages(oldMsg, newMessage);
32 }
33}

স্মার্ট কন্ট্রাক্ট ইভেন্টগুলো হলো আপনার কন্ট্রাক্টের জন্য ব্লকচেইন এ কিছু ঘটেছে (অর্থাৎ, একটি ইভেন্ট ছিল) তা আপনার ফ্রন্ট-এন্ড অ্যাপ্লিকেশনে জানানোর একটি উপায়, যা নির্দিষ্ট ইভেন্টগুলোর জন্য 'লিসেনিং' করতে পারে এবং সেগুলো ঘটলে ব্যবস্থা নিতে পারে।

addSmartContractListener ফাংশনটি বিশেষভাবে আমাদের Hello World স্মার্ট কন্ট্রাক্ট এর UpdatedMessages ইভেন্টের জন্য লিসেন করবে এবং নতুন মেসেজটি প্রদর্শন করতে আমাদের UI আপডেট করবে।

addSmartContractListener নিচের মতো মডিফাই করুন:

1// HelloWorld.js
2
3function addSmartContractListener() {
4 helloWorldContract.events.UpdatedMessages({}, (error, data) => {
5 if (error) {
6 setStatus("😥 " + error.message)
7 } else {
8 setMessage(data.returnValues[1])
9 setNewMessage("")
10 setStatus("🎉 Your message has been updated!")
11 }
12 })
13}

লিসেনার যখন কোনো ইভেন্ট শনাক্ত করে তখন কী ঘটে তা চলুন ভেঙে দেখি:

  • ইভেন্টটি এমিট হওয়ার সময় যদি কোনো ত্রুটি ঘটে, তবে এটি আমাদের status স্টেট ভেরিয়েবলের মাধ্যমে UI-তে প্রতিফলিত হবে।
  • অন্যথায়, আমরা রিটার্ন করা data অবজেক্টটি ব্যবহার করব। data.returnValues হলো শূন্যতে ইনডেক্স করা একটি অ্যারে যেখানে অ্যারের প্রথম উপাদানটি আগের মেসেজটি সংরক্ষণ করে এবং দ্বিতীয় উপাদানটি আপডেট করা মেসেজটি সংরক্ষণ করে। সব মিলিয়ে, একটি সফল ইভেন্টে আমরা আমাদের message স্ট্রিংটিকে আপডেট করা মেসেজে সেট করব, newMessage স্ট্রিংটি ক্লিয়ার করব এবং আমাদের স্মার্ট কন্ট্রাক্ট এ একটি নতুন মেসেজ পাবলিশ করা হয়েছে তা প্রতিফলিত করতে আমাদের status স্টেট ভেরিয়েবল আপডেট করব।

অবশেষে, চলুন আমাদের useEffect ফাংশনে আমাদের লিসেনারকে কল করি যাতে এটি HelloWorld.js কম্পোনেন্টের প্রথম রেন্ডারে ইনিশিয়ালাইজ হয়। সব মিলিয়ে, আপনার useEffect ফাংশনটি এরকম হওয়া উচিত:

1// HelloWorld.js
2
3useEffect(async () => {
4 const message = await loadCurrentMessage()
5 setMessage(message)
6 addSmartContractListener()
7}, [])

এখন যেহেতু আমরা আমাদের স্মার্ট কন্ট্রাক্ট থেকে রিড করতে সক্ষম, তাই এতে কীভাবে রাইট করতে হয় তা বের করা দারুণ হবে! তবে, আমাদের ডিএ্যাপ এ রাইট করতে, আমাদের প্রথমে এর সাথে একটি ইথিরিয়াম ওয়ালেট কানেক্ট থাকতে হবে।

সুতরাং, এরপর আমরা আমাদের ইথিরিয়াম ওয়ালেট (MetaMask) সেট আপ করা এবং তারপর এটিকে আমাদের ডিএ্যাপ এর সাথে কানেক্ট করার বিষয়টি সামলাব!

ধাপ 4: আপনার ইথিরিয়াম ওয়ালেট সেট আপ করুন

ইথিরিয়াম চেইনে কিছু রাইট করতে, ব্যবহারকারীদের অবশ্যই তাদের ভার্চুয়াল ওয়ালেট এর প্রাইভেট কি ব্যবহার করে লেনদেন সাইন করতে হবে। এই টিউটোরিয়ালের জন্য, আমরা MetaMask (opens in a new tab) ব্যবহার করব, যা ব্রাউজারে একটি ভার্চুয়াল ওয়ালেট যা আপনার ইথিরিয়াম একাউন্ট এডড্রেস পরিচালনা করতে ব্যবহৃত হয়, কারণ এটি শেষ-ব্যবহারকারীর জন্য এই লেনদেন সাইন করা অত্যন্ত সহজ করে তোলে।

ইথিরিয়াম এ লেনদেন কীভাবে কাজ করে সে সম্পর্কে আপনি যদি আরও বুঝতে চান, তবে ইথিরিয়াম ফাউন্ডেশনের এই পেজটি চেক করুন।

MetaMask ডাউনলোড করুন

আপনি বিনামূল্যে এখানে (opens in a new tab) একটি MetaMask একাউন্ট ডাউনলোড এবং তৈরি করতে পারেন। যখন আপনি একটি একাউন্ট তৈরি করছেন, বা যদি আপনার আগে থেকেই একটি একাউন্ট থাকে, তবে উপরের ডানদিকে "Goerli Test Network"-এ স্যুইচ করতে ভুলবেন না (যাতে আমরা আসল টাকা নিয়ে কাজ না করি)।

একটি ফাসেট থেকে ইথার যোগ করুন

ইথিরিয়াম ব্লকচেইন এ একটি লেনদেন সাইন করতে, আমাদের কিছু ফেক Eth প্রয়োজন হবে। Eth পেতে আপনি FaucETH (opens in a new tab)-এ যেতে পারেন এবং আপনার Goerli একাউন্ট এডড্রেস লিখতে পারেন, "Request funds"-এ ক্লিক করুন, তারপর ড্রপডাউনে "Ethereum Testnet Goerli" নির্বাচন করুন এবং অবশেষে আবার "Request funds" বোতামে ক্লিক করুন। এর পরপরই আপনার MetaMask একাউন্টে Eth দেখতে পাওয়া উচিত!

আপনার ব্যালেন্স চেক করুন

আমাদের ব্যালেন্স সেখানে আছে কিনা তা ডাবল চেক করতে, চলুন Alchemy’s composer tool (opens in a new tab) ব্যবহার করে একটি eth_getBalance (opens in a new tab) রিকোয়েস্ট করি। এটি আমাদের ওয়ালেট এ Eth এর পরিমাণ রিটার্ন করবে। আপনার MetaMask একাউন্ট এডড্রেস ইনপুট করার পর এবং "Send Request"-এ ক্লিক করার পর, আপনার এরকম একটি রেসপন্স দেখা উচিত:

1{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}

নোট: এই ফলাফলটি wei-তে, eth-এ নয়। Wei ইথারের ক্ষুদ্রতম একক হিসেবে ব্যবহৃত হয়। wei থেকে eth-এ রূপান্তর হলো: 1 eth = 10¹⁸ wei। তাই যদি আমরা 0xde0b6b3a7640000-কে ডেসিমালে রূপান্তর করি তবে আমরা 1*10¹⁸ পাই যা 1 eth এর সমান।

যাক! আমাদের ফেক টাকা সব সেখানেই আছে! 🤑

ধাপ 5: আপনার UI-এর সাথে MetaMask কানেক্ট করুন

এখন যেহেতু আমাদের MetaMask ওয়ালেট সেট আপ করা হয়েছে, চলুন আমাদের ডিএ্যাপ এর সাথে এটি কানেক্ট করি!

connectWallet ফাংশন

আমাদের interact.js ফাইলে, চলুন connectWallet ফাংশনটি ইমপ্লিমেন্ট করি, যা আমরা পরে আমাদের HelloWorld.js কম্পোনেন্টে কল করতে পারি।

চলুন connectWallet নিচের মতো মডিফাই করি:

1// interact.js
2
3export const connectWallet = async () => {
4 if (window.ethereum) {
5 try {
6 const addressArray = await window.ethereum.request({
7 method: "eth_requestAccounts",
8 })
9 const obj = {
10 status: "👆🏽 Write a message in the text-field above.",
11 address: addressArray[0],
12 }
13 return obj
14 } catch (err) {
15 return {
16 address: "",
17 status: "😥 " + err.message,
18 }
19 }
20 } else {
21 return {
22 address: "",
23 status: (
24 <span>
25 <p>
26 {" "}
27 🦊 <a target="_blank" href={`https://metamask.io/download`}>
28 You must install MetaMask, a virtual Ethereum wallet, in your
29 browser.
30 </a>
31 </p>
32 </span>
33 ),
34 }
35 }
36}

তাহলে কোডের এই বিশাল ব্লকটি আসলে কী করে?

প্রথমত, এটি চেক করে যে আপনার ব্রাউজারে window.ethereum এনাবল করা আছে কিনা।

window.ethereum হলো MetaMask এবং অন্যান্য ওয়ালেট প্রোভাইডারদের দ্বারা ইনজেক্ট করা একটি গ্লোবাল API যা ওয়েবসাইটগুলোকে ব্যবহারকারীদের ইথিরিয়াম একাউন্ট রিকোয়েস্ট করার অনুমতি দেয়। যদি অনুমোদিত হয়, তবে এটি ব্যবহারকারী যে ব্লকচেইন গুলোর সাথে কানেক্টেড আছে তা থেকে ডেটা রিড করতে পারে এবং ব্যবহারকারীকে মেসেজ এবং লেনদেন সাইন করার পরামর্শ দিতে পারে। আরও তথ্যের জন্য MetaMask docs (opens in a new tab) চেক করুন!

যদি window.ethereum উপস্থিত না থাকে, তবে এর মানে হলো MetaMask ইনস্টল করা নেই। এর ফলে একটি JSON অবজেক্ট রিটার্ন করা হয়, যেখানে রিটার্ন করা address হলো একটি খালি স্ট্রিং এবং status JSX অবজেক্টটি রিলে করে যে ব্যবহারকারীকে অবশ্যই MetaMask ইনস্টল করতে হবে।

এখন যদি window.ethereum উপস্থিত থাকে, তবে তখনই বিষয়গুলো আকর্ষণীয় হয়ে ওঠে।

একটি try/catch লুপ ব্যবহার করে, আমরা window.ethereum.request({ method: "eth_requestAccounts" }); (opens in a new tab) কল করে MetaMask-এর সাথে কানেক্ট করার চেষ্টা করব। এই ফাংশনটি কল করলে ব্রাউজারে MetaMask খুলবে, যার মাধ্যমে ব্যবহারকারীকে তাদের ওয়ালেট আপনার ডিএ্যাপ এর সাথে কানেক্ট করার জন্য প্রম্পট করা হবে।

  • যদি ব্যবহারকারী কানেক্ট করা বেছে নেন, method: "eth_requestAccounts" একটি অ্যারে রিটার্ন করবে যাতে ডিএ্যাপ এর সাথে কানেক্ট করা ব্যবহারকারীর সমস্ত একাউন্ট এডড্রেস থাকে। সব মিলিয়ে, আমাদের connectWallet ফাংশনটি একটি JSON অবজেক্ট রিটার্ন করবে যাতে এই অ্যারের প্রথম address (লাইন 9 দেখুন) এবং একটি status মেসেজ থাকে যা ব্যবহারকারীকে স্মার্ট কন্ট্রাক্ট এ একটি মেসেজ লিখতে প্রম্পট করে।
  • যদি ব্যবহারকারী কানেকশনটি প্রত্যাখ্যান করেন, তবে JSON অবজেক্টটিতে রিটার্ন করা address এর জন্য একটি খালি স্ট্রিং এবং একটি status মেসেজ থাকবে যা প্রতিফলিত করে যে ব্যবহারকারী কানেকশনটি প্রত্যাখ্যান করেছেন।

এখন যেহেতু আমরা এই connectWallet ফাংশনটি লিখেছি, পরবর্তী ধাপ হলো এটিকে আমাদের HelloWorld.js কম্পোনেন্টে কল করা।

আপনার HelloWorld.js UI কম্পোনেন্টে connectWallet ফাংশন যোগ করুন

HelloWorld.js-এ connectWalletPressed ফাংশনে নেভিগেট করুন এবং এটিকে নিচের মতো আপডেট করুন:

1// HelloWorld.js
2
3const connectWalletPressed = async () => {
4 const walletResponse = await connectWallet()
5 setStatus(walletResponse.status)
6 setWallet(walletResponse.address)
7}

লক্ষ্য করেছেন কীভাবে আমাদের বেশিরভাগ কার্যকারিতা interact.js ফাইল থেকে আমাদের HelloWorld.js কম্পোনেন্ট থেকে অ্যাবস্ট্রাক্ট করা হয়েছে? এটি করা হয়েছে যাতে আমরা M-V-C প্যারাডাইম মেনে চলি!

connectWalletPressed-এ, আমরা কেবল আমাদের ইমপোর্ট করা connectWallet ফাংশনে একটি await কল করি এবং এর রেসপন্স ব্যবহার করে, আমরা তাদের স্টেট হুকগুলোর মাধ্যমে আমাদের status এবং walletAddress ভেরিয়েবলগুলো আপডেট করি।

এখন, চলুন উভয় ফাইল (HelloWorld.js এবং interact.js) সেভ করি এবং এ পর্যন্ত আমাদের UI টেস্ট করি।

http://localhost:3000/ (opens in a new tab) পেজে আপনার ব্রাউজার খুলুন এবং পেজের উপরের ডানদিকে "Connect Wallet" বোতাম টিপুন।

আপনার যদি MetaMask ইনস্টল করা থাকে, তবে আপনাকে আপনার ডিএ্যাপ এর সাথে আপনার ওয়ালেট কানেক্ট করার জন্য প্রম্পট করা উচিত। কানেক্ট করার আমন্ত্রণ গ্রহণ করুন।

আপনার দেখা উচিত যে ওয়ালেট বোতামটি এখন প্রতিফলিত করে যে আপনার এডড্রেস কানেক্টেড! দারুণ 🔥

এরপর, পেজটি রিফ্রেশ করার চেষ্টা করুন... এটি অদ্ভুত। আমাদের ওয়ালেট বোতামটি আমাদের MetaMask কানেক্ট করতে প্রম্পট করছে, যদিও এটি আগে থেকেই কানেক্টেড...

তবে, ভয় পাবেন না! আমরা সহজেই getCurrentWalletConnected ইমপ্লিমেন্ট করে এর সমাধান করতে পারি, যা চেক করবে যে কোনো এডড্রেস আগে থেকেই আমাদের ডিএ্যাপ এর সাথে কানেক্টেড কিনা এবং সেই অনুযায়ী আমাদের UI আপডেট করবে!

getCurrentWalletConnected ফাংশন

interact.js ফাইলে আপনার getCurrentWalletConnected ফাংশনটি নিচের মতো আপডেট করুন:

1// interact.js
2
3export const getCurrentWalletConnected = async () => {
4 if (window.ethereum) {
5 try {
6 const addressArray = await window.ethereum.request({
7 method: "eth_accounts",
8 })
9 if (addressArray.length > 0) {
10 return {
11 address: addressArray[0],
12 status: "👆🏽 Write a message in the text-field above.",
13 }
14 } else {
15 return {
16 address: "",
17 status: "🦊 Connect to MetaMask using the top right button.",
18 }
19 }
20 } catch (err) {
21 return {
22 address: "",
23 status: "😥 " + err.message,
24 }
25 }
26 } else {
27 return {
28 address: "",
29 status: (
30 <span>
31 <p>
32 {" "}
33 🦊 <a target="_blank" href={`https://metamask.io/download`}>
34 You must install MetaMask, a virtual Ethereum wallet, in your
35 browser.
36 </a>
37 </p>
38 </span>
39 ),
40 }
41 }
42}

এই কোডটি আগের ধাপে আমাদের লেখা connectWallet ফাংশনের খুবই কাছাকাছি।

প্রধান পার্থক্য হলো eth_requestAccounts মেথড কল করার পরিবর্তে, যা ব্যবহারকারীর ওয়ালেট কানেক্ট করার জন্য MetaMask খোলে, এখানে আমরা eth_accounts মেথড কল করি, যা কেবল বর্তমানে আমাদের ডিএ্যাপ এর সাথে কানেক্টেড MetaMask এডড্রেস গুলো ধারণকারী একটি অ্যারে রিটার্ন করে।

এই ফাংশনটি কাজ করতে দেখতে, চলুন এটিকে আমাদের HelloWorld.js কম্পোনেন্টের useEffect ফাংশনে কল করি:

1// HelloWorld.js
2
3useEffect(async () => {
4 const message = await loadCurrentMessage()
5 setMessage(message)
6 addSmartContractListener()
7
8 const { address, status } = await getCurrentWalletConnected()
9 setWallet(address)
10 setStatus(status)
11}, [])

লক্ষ্য করুন, আমরা আমাদের walletAddress এবং status স্টেট ভেরিয়েবলগুলো আপডেট করতে getCurrentWalletConnected-এ আমাদের কলের রেসপন্স ব্যবহার করি।

এখন যেহেতু আপনি এই কোডটি যোগ করেছেন, চলুন আমাদের ব্রাউজার উইন্ডো রিফ্রেশ করার চেষ্টা করি।

চমৎকার! বোতামটির বলা উচিত যে আপনি কানেক্টেড, এবং আপনার কানেক্টেড ওয়ালেট এর এডড্রেস এর একটি প্রিভিউ দেখানো উচিত - এমনকি আপনি রিফ্রেশ করার পরেও!

addWalletListener ইমপ্লিমেন্ট করুন

আমাদের ডিএ্যাপ ওয়ালেট সেটআপের চূড়ান্ত ধাপ হলো ওয়ালেট লিসেনার ইমপ্লিমেন্ট করা যাতে আমাদের ওয়ালেট এর স্টেট পরিবর্তন হলে আমাদের UI আপডেট হয়, যেমন যখন ব্যবহারকারী ডিসকানেক্ট করে বা একাউন্ট পরিবর্তন করে।

আপনার HelloWorld.js ফাইলে, আপনার addWalletListener ফাংশনটি নিচের মতো মডিফাই করুন:

1// HelloWorld.js
2
3function addWalletListener() {
4 if (window.ethereum) {
5 window.ethereum.on("accountsChanged", (accounts) => {
6 if (accounts.length > 0) {
7 setWallet(accounts[0])
8 setStatus("👆🏽 Write a message in the text-field above.")
9 } else {
10 setWallet("")
11 setStatus("🦊 Connect to MetaMask using the top right button.")
12 }
13 })
14 } else {
15 setStatus(
16 <p>
17 {" "}
18 🦊 <a target="_blank" href={`https://metamask.io/download`}>
19 You must install MetaMask, a virtual Ethereum wallet, in your browser.
20 </a>
21 </p>
22 )
23 }
24}

আমি বাজি ধরে বলতে পারি এই পর্যায়ে এখানে কী ঘটছে তা বুঝতে আপনার আমাদের সাহায্যেরও প্রয়োজন নেই, তবে পুঙ্খানুপুঙ্খতার উদ্দেশ্যে, চলুন এটি দ্রুত ভেঙে দেখি:

  • প্রথমে, আমাদের ফাংশন চেক করে যে window.ethereum এনাবল করা আছে কিনা (অর্থাৎ, MetaMask ইনস্টল করা আছে কিনা)।
    • যদি না থাকে, তবে আমরা কেবল আমাদের status স্টেট ভেরিয়েবলটিকে একটি JSX স্ট্রিংয়ে সেট করি যা ব্যবহারকারীকে MetaMask ইনস্টল করতে প্রম্পট করে।
    • যদি এটি এনাবল করা থাকে, তবে আমরা 3 নম্বর লাইনে window.ethereum.on("accountsChanged") লিসেনার সেট আপ করি যা MetaMask ওয়ালেট এ স্টেট পরিবর্তনের জন্য লিসেন করে, যার মধ্যে রয়েছে যখন ব্যবহারকারী ডিএ্যাপ এ একটি অতিরিক্ত একাউন্ট কানেক্ট করে, একাউন্ট পরিবর্তন করে বা একটি একাউন্ট ডিসকানেক্ট করে। যদি অন্তত একটি একাউন্ট কানেক্টেড থাকে, তবে walletAddress স্টেট ভেরিয়েবলটি লিসেনার দ্বারা রিটার্ন করা accounts অ্যারের প্রথম একাউন্ট হিসেবে আপডেট করা হয়। অন্যথায়, walletAddress একটি খালি স্ট্রিং হিসেবে সেট করা হয়।

সবশেষে, আমাদের অবশ্যই এটিকে আমাদের useEffect ফাংশনে কল করতে হবে:

1// HelloWorld.js
2
3useEffect(async () => {
4 const message = await loadCurrentMessage()
5 setMessage(message)
6 addSmartContractListener()
7
8 const { address, status } = await getCurrentWalletConnected()
9 setWallet(address)
10 setStatus(status)
11
12 addWalletListener()
13}, [])

এবং এটাই! আমরা সফলভাবে আমাদের সমস্ত ওয়ালেট কার্যকারিতা প্রোগ্রামিং সম্পন্ন করেছি! এখন আমাদের শেষ কাজ: আমাদের স্মার্ট কন্ট্রাক্ট এ সংরক্ষিত মেসেজটি আপডেট করা!

ধাপ 6: updateMessage ফাংশন ইমপ্লিমেন্ট করুন

ঠিক আছে বন্ধুরা, আমরা শেষ পর্যায়ে পৌঁছে গেছি! আপনার interact.js ফাইলের updateMessage-এ, আমরা নিচের কাজগুলো করতে যাচ্ছি:

  1. নিশ্চিত করুন যে আমরা আমাদের স্মার্ট কন্ট্রাক্ট এ যে মেসেজটি পাবলিশ করতে চাই তা বৈধ
  2. MetaMask ব্যবহার করে আমাদের লেনদেন সাইন করুন
  3. আমাদের HelloWorld.js ফ্রন্টএন্ড কম্পোনেন্ট থেকে এই ফাংশনটি কল করুন

এতে খুব বেশি সময় লাগবে না; চলুন এই ডিএ্যাপ টি শেষ করি!

ইনপুট এরর হ্যান্ডলিং

স্বাভাবিকভাবেই, ফাংশনের শুরুতে কোনো ধরনের ইনপুট এরর হ্যান্ডলিং থাকাটা যৌক্তিক।

আমরা চাইব আমাদের ফাংশনটি তাড়াতাড়ি রিটার্ন করুক যদি কোনো MetaMask এক্সটেনশন ইনস্টল করা না থাকে, কোনো ওয়ালেট কানেক্টেড না থাকে (অর্থাৎ, পাস করা address একটি খালি স্ট্রিং), বা message একটি খালি স্ট্রিং হয়। চলুন updateMessage-এ নিচের এরর হ্যান্ডলিং যোগ করি:

1// interact.js
2
3export const updateMessage = async (address, message) => {
4 if (!window.ethereum || address === null) {
5 return {
6 status:
7 "💡 Connect your MetaMask wallet to update the message on the blockchain.",
8 }
9 }
10
11 if (message.trim() === "") {
12 return {
13 status: "❌ Your message cannot be an empty string.",
14 }
15 }
16}

এখন যেহেতু এতে সঠিক ইনপুট এরর হ্যান্ডলিং রয়েছে, তাই MetaMask-এর মাধ্যমে লেনদেন সাইন করার সময় এসেছে!

আমাদের লেনদেন সাইন করা

আপনি যদি আগে থেকেই প্রথাগত web3 ইথিরিয়াম লেনদেন এর সাথে স্বাচ্ছন্দ্যবোধ করেন, তবে আমরা পরবর্তীতে যে কোডটি লিখব তা খুব পরিচিত হবে। আপনার ইনপুট এরর হ্যান্ডলিং কোডের নিচে, updateMessage-এ নিচের কোডটি যোগ করুন:

1// interact.js
2
3// ট্রানজ্যাকশন প্যারামিটার সেট আপ করুন
4const transactionParameters = {
5 to: contractAddress, // কন্ট্রাক্ট পাবলিকেশন ছাড়া অন্যান্য সময় প্রয়োজনীয়।
6 from: address, // অবশ্যই ব্যবহারকারীর সক্রিয় ঠিকানার সাথে মিলতে হবে।
7 data: helloWorldContract.methods.update(message).encodeABI(),
8}
9
10// ট্রানজ্যাকশন সাইন করুন
11try {
12 const txHash = await window.ethereum.request({
13 method: "eth_sendTransaction",
14 params: [transactionParameters],
15 })
16 return {
17 status: (
18 <span>
19{" "}
20 <a target="_blank" href={`https://goerli.etherscan.io/tx/${txHash}`}>
21 View the status of your transaction on Etherscan!
22 </a>
23 <br />
24 ℹ️ Once the transaction is verified by the network, the message will be
25 updated automatically.
26 </span>
27 ),
28 }
29} catch (error) {
30 return {
31 status: "😥 " + error.message,
32 }
33}

চলুন ভেঙে দেখি কী ঘটছে। প্রথমে, আমরা আমাদের লেনদেন প্যারামিটারগুলো সেট আপ করি, যেখানে:

  • to প্রাপকের এডড্রেস (আমাদের স্মার্ট কন্ট্রাক্ট) নির্দিষ্ট করে
  • from লেনদেন এর সাইনার নির্দিষ্ট করে, address ভেরিয়েবল যা আমরা আমাদের ফাংশনে পাস করেছি
  • data আমাদের Hello World স্মার্ট কন্ট্রাক্ট এর update মেথডে কল ধারণ করে, যা ইনপুট হিসেবে আমাদের message স্ট্রিং ভেরিয়েবল গ্রহণ করে

তারপর, আমরা একটি await কল করি, window.ethereum.request, যেখানে আমরা MetaMask-কে লেনদেন সাইন করতে বলি। লক্ষ্য করুন, 11 এবং 12 লাইনে, আমরা আমাদের eth মেথড, eth_sendTransaction নির্দিষ্ট করছি এবং আমাদের transactionParameters পাস করছি।

এই পর্যায়ে, ব্রাউজারে MetaMask খুলবে এবং ব্যবহারকারীকে লেনদেন সাইন বা প্রত্যাখ্যান করতে প্রম্পট করবে।

  • যদি লেনদেন সফল হয়, তবে ফাংশনটি একটি JSON অবজেক্ট রিটার্ন করবে যেখানে status JSX স্ট্রিং ব্যবহারকারীকে তাদের লেনদেন সম্পর্কে আরও তথ্যের জন্য Etherscan চেক করতে প্রম্পট করে।
  • যদি লেনদেন ব্যর্থ হয়, তবে ফাংশনটি একটি JSON অবজেক্ট রিটার্ন করবে যেখানে status স্ট্রিং এরর মেসেজ রিলে করে।

সব মিলিয়ে, আমাদের updateMessage ফাংশনটি এরকম হওয়া উচিত:

1// interact.js
2
3export const updateMessage = async (address, message) => {
4 // ইনপুট এরর হ্যান্ডলিং
5 if (!window.ethereum || address === null) {
6 return {
7 status:
8 "💡 Connect your MetaMask wallet to update the message on the blockchain.",
9 }
10 }
11
12 if (message.trim() === "") {
13 return {
14 status: "❌ Your message cannot be an empty string.",
15 }
16 }
17
18 // ট্রানজ্যাকশন প্যারামিটার সেট আপ করুন
19 const transactionParameters = {
20 to: contractAddress, // কন্ট্রাক্ট পাবলিকেশন ছাড়া অন্যান্য সময় প্রয়োজনীয়।
21 from: address, // অবশ্যই ব্যবহারকারীর সক্রিয় ঠিকানার সাথে মিলতে হবে।
22 data: helloWorldContract.methods.update(message).encodeABI(),
23 }
24
25 // ট্রানজ্যাকশন সাইন করুন
26 try {
27 const txHash = await window.ethereum.request({
28 method: "eth_sendTransaction",
29 params: [transactionParameters],
30 })
31 return {
32 status: (
33 <span>
34{" "}
35 <a target="_blank" href={`https://goerli.etherscan.io/tx/${txHash}`}>
36 View the status of your transaction on Etherscan!
37 </a>
38 <br />
39 ℹ️ Once the transaction is verified by the network, the message will
40 be updated automatically.
41 </span>
42 ),
43 }
44 } catch (error) {
45 return {
46 status: "😥 " + error.message,
47 }
48 }
49}

সবশেষে, আমাদের updateMessage ফাংশনটিকে আমাদের HelloWorld.js কম্পোনেন্টের সাথে কানেক্ট করতে হবে।

HelloWorld.js ফ্রন্টএন্ডের সাথে updateMessage কানেক্ট করুন

আমাদের onUpdatePressed ফাংশনটির ইমপোর্ট করা updateMessage ফাংশনে একটি await কল করা উচিত এবং আমাদের লেনদেন সফল হয়েছে নাকি ব্যর্থ হয়েছে তা প্রতিফলিত করতে status স্টেট ভেরিয়েবল মডিফাই করা উচিত:

1// HelloWorld.js
2
3const onUpdatePressed = async () => {
4 const { status } = await updateMessage(walletAddress, newMessage)
5 setStatus(status)
6}

এটি অত্যন্ত পরিচ্ছন্ন এবং সহজ। এবং জানেন কি... আপনার ডিএ্যাপ সম্পূর্ণ!!!

এগিয়ে যান এবং Update বোতামটি টেস্ট করুন!

আপনার নিজস্ব কাস্টম ডিএ্যাপ তৈরি করুন

দারুণ, আপনি টিউটোরিয়ালের শেষে পৌঁছে গেছেন! সংক্ষেপে বলতে গেলে, আপনি শিখেছেন কীভাবে:

  • আপনার ডিএ্যাপ প্রজেক্টের সাথে একটি MetaMask ওয়ালেট কানেক্ট করতে হয়
  • Alchemy Web3 (opens in a new tab) API ব্যবহার করে আপনার স্মার্ট কন্ট্রাক্ট থেকে ডেটা রিড করতে হয়
  • MetaMask ব্যবহার করে ইথিরিয়াম লেনদেন সাইন করতে হয়

এখন আপনি আপনার নিজস্ব কাস্টম ডিএ্যাপ প্রজেক্ট তৈরি করতে এই টিউটোরিয়াল থেকে অর্জিত দক্ষতা প্রয়োগ করতে পুরোপুরি প্রস্তুত! বরাবরের মতো, আপনার যদি কোনো প্রশ্ন থাকে, তবে Alchemy Discord (opens in a new tab)-এ সাহায্যের জন্য আমাদের সাথে যোগাযোগ করতে দ্বিধা করবেন না। 🧙‍♂️

একবার আপনি এই টিউটোরিয়ালটি সম্পন্ন করার পর, আপনার অভিজ্ঞতা কেমন ছিল তা আমাদের জানান বা আপনার যদি কোনো মতামত থাকে তবে টুইটারে @alchemyplatform (opens in a new tab)-এ আমাদের ট্যাগ করে জানান!

পেজ সর্বশেষ আপডেট: 3 মার্চ, 2026

এই টিউটোরিয়ালটি কি সহায়ক ছিল?