নতুনদের জন্য হ্যালো ওয়ার্ল্ড স্মার্ট কন্ট্রাক্ট - ফুলস্ট্যাক
আপনি যদি ব্লকচেইন ডেভেলপমেন্টে নতুন হয়ে থাকেন এবং কোথা থেকে শুরু করবেন বা কীভাবে স্মার্ট কন্ট্রাক্ট ডিপ্লয় করবেন এবং এর সাথে ইন্টারঅ্যাক্ট করবেন তা না জানেন, তবে এই গাইডটি আপনার জন্য। আমরা মেটামাস্ক (একটি নতুন ট্যাবে খোলে), Solidity (একটি নতুন ট্যাবে খোলে), Hardhat (একটি নতুন ট্যাবে খোলে) এবং Alchemy (একটি নতুন ট্যাবে খোলে) ব্যবহার করে Goerli টেস্ট নেটওয়ার্কে একটি সাধারণ স্মার্ট কন্ট্রাক্ট তৈরি এবং ডিপ্লয় করার প্রক্রিয়া ধাপে ধাপে দেখব।
এই টিউটোরিয়ালটি সম্পূর্ণ করতে আপনার একটি Alchemy অ্যাকাউন্ট প্রয়োজন হবে। একটি বিনামূল্যের অ্যাকাউন্টের জন্য সাইন আপ করুন (একটি নতুন ট্যাবে খোলে)।
যেকোনো পর্যায়ে আপনার যদি কোনো প্রশ্ন থাকে, তবে নির্দ্বিধায় Alchemy ডিসকর্ড (একটি নতুন ট্যাবে খোলে)-এ যোগাযোগ করুন!
পর্ব 1 - Hardhat ব্যবহার করে আপনার স্মার্ট কন্ট্রাক্ট তৈরি এবং ডিপ্লয় করুন
ইথেরিয়াম নেটওয়ার্কের সাথে সংযুক্ত হোন
ইথেরিয়াম চেইনে রিকোয়েস্ট করার অনেক উপায় আছে। সহজে বোঝার জন্য, আমরা Alchemy-তে একটি বিনামূল্যের অ্যাকাউন্ট ব্যবহার করব, যা একটি ব্লকচেইন ডেভেলপার প্ল্যাটফর্ম এবং API। এটি আমাদের নিজেদের কোনো নোড না চালিয়েই ইথেরিয়াম চেইনের সাথে যোগাযোগ করতে দেয়। Alchemy-তে মনিটরিং এবং অ্যানালিটিক্সের জন্য ডেভেলপার টুলও রয়েছে; আমাদের স্মার্ট কন্ট্রাক্ট ডিপ্লয়মেন্টের ভেতরে আসলে কী ঘটছে তা বোঝার জন্য আমরা এই টিউটোরিয়ালে সেগুলোর সুবিধা নেব।
আপনার অ্যাপ এবং API কী তৈরি করুন
একবার আপনি একটি Alchemy অ্যাকাউন্ট তৈরি করার পর, আপনি একটি অ্যাপ তৈরি করে একটি API কী জেনারেট করতে পারেন। এটি আপনাকে Sepolia টেস্টনেট-এ রিকোয়েস্ট করার অনুমতি দেবে। আপনি যদি টেস্টনেটগুলোর সাথে পরিচিত না হন তবে আপনি নেটওয়ার্ক বেছে নেওয়ার বিষয়ে Alchemy-এর গাইডটি পড়তে পারেন (একটি নতুন ট্যাবে খোলে)।
Alchemy ড্যাশবোর্ডে, নেভিগেশন বারে Apps ড্রপডাউনটি খুঁজুন এবং Create App-এ ক্লিক করুন।
আপনার অ্যাপের নাম দিন 'Hello World' এবং একটি ছোট বিবরণ লিখুন। আপনার এনভায়রনমেন্ট হিসেবে Staging এবং আপনার নেটওয়ার্ক হিসেবে Sepolia নির্বাচন করুন।
দ্রষ্টব্য: অবশ্যই Sepolia নির্বাচন করবেন, অন্যথায় এই টিউটোরিয়ালটি কাজ করবে না।
Create app-এ ক্লিক করুন। আপনার অ্যাপটি নিচের টেবিলে দেখা যাবে।
একটি ইথেরিয়াম অ্যাকাউন্ট তৈরি করুন
ট্রানজ্যাকশন পাঠাতে এবং গ্রহণ করতে আপনার একটি ইথেরিয়াম অ্যাকাউন্ট প্রয়োজন। আমরা মেটামাস্ক ব্যবহার করব, যা ব্রাউজারে থাকা একটি ভার্চুয়াল ওয়ালেট এবং এটি ব্যবহারকারীদের তাদের ইথেরিয়াম অ্যাকাউন্ট ঠিকানা পরিচালনা করতে দেয়।
আপনি বিনামূল্যে এখানে (একটি নতুন ট্যাবে খোলে) একটি মেটামাস্ক অ্যাকাউন্ট ডাউনলোড এবং তৈরি করতে পারেন। আপনি যখন একটি অ্যাকাউন্ট তৈরি করছেন, বা আপনার যদি আগে থেকেই একটি অ্যাকাউন্ট থাকে, তবে উপরের ডানদিকে "Sepolia Test Network"-এ স্যুইচ করতে ভুলবেন না (যাতে আমরা আসল টাকা নিয়ে কাজ না করি)।
ধাপ 4: একটি ফসেট থেকে ইথার যোগ করুন
আপনার স্মার্ট কন্ট্রাক্টটি টেস্ট নেটওয়ার্কে ডিপ্লয় করতে, আপনার কিছু নকল ETH প্রয়োজন হবে। Sepolia নেটওয়ার্কে ETH পেতে, একটি Sepolia ফসেটে যান এবং আপনার Sepolia অ্যাকাউন্ট ঠিকানা লিখুন। চেষ্টা করার মতো বিকল্পগুলোর একটি তালিকার জন্য টেস্ট নেটওয়ার্ক পেজ দেখুন:
দ্রষ্টব্য: নেটওয়ার্কে ভিড়ের কারণে, এতে কিছুটা সময় লাগতে পারে। ``
ধাপ 5: আপনার ব্যালেন্স চেক করুন
আপনার ওয়ালেটে ETH আছে কিনা তা নিশ্চিত করতে, চলুন Alchemy-এর স্যান্ডবক্স টুল (একটি নতুন ট্যাবে খোলে) ব্যবহার করে একটি eth_getBalance (একটি নতুন ট্যাবে খোলে) রিকোয়েস্ট করি। এটি আমাদের ওয়ালেটে থাকা ETH-এর পরিমাণ রিটার্ন করবে। আরও জানতে কম্পোজার টুল কীভাবে ব্যবহার করতে হয় সে সম্পর্কে Alchemy-এর ছোট টিউটোরিয়ালটি (একটি নতুন ট্যাবে খোলে) দেখুন।
আপনার মেটামাস্ক অ্যাকাউন্ট ঠিকানা লিখুন এবং Send Request-এ ক্লিক করুন। আপনি নিচের কোড স্নিপেটের মতো একটি রেসপন্স দেখতে পাবেন।
{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" }
দ্রষ্টব্য: এই ফলাফলটি wei-তে দেওয়া হয়েছে, ETH-এ নয়। wei হলো ইথারের ক্ষুদ্রতম একক।
যাক! আমাদের সব নকল টাকা সেখানেই আছে।
ধাপ 6: আমাদের প্রজেক্ট ইনিশিয়ালাইজ করুন
প্রথমে, আমাদের প্রজেক্টের জন্য একটি ফোল্ডার তৈরি করতে হবে। আপনার কমান্ড লাইনে যান এবং নিচের কমান্ডগুলো ইনপুট দিন।
mkdir hello-world
cd hello-world
যেহেতু আমরা এখন আমাদের প্রজেক্ট ফোল্ডারের ভেতরে আছি, তাই প্রজেক্টটি ইনিশিয়ালাইজ করতে আমরা npm init ব্যবহার করব।
আপনার যদি এখনও npm ইনস্টল করা না থাকে, তবে Node.js এবং npm ইনস্টল করতে Node.js ইনস্টলেশন নির্দেশিকা (একটি নতুন ট্যাবে খোলে) অনুসরণ করুন।
এই টিউটোরিয়ালের জন্য, আপনি ইনিশিয়ালাইজেশনের প্রশ্নগুলোর উত্তর কীভাবে দিচ্ছেন তা কোনো ব্যাপার না। রেফারেন্সের জন্য আমরা এটি কীভাবে করেছি তা নিচে দেওয়া হলো:
package name: (hello-world)
version: (1.0.0)
description: hello world smart contract
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/.../.../.../hello-world/package.json:
{
"name": "hello-world",
"version": "1.0.0",
"description": "hello world smart contract",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
package.json অনুমোদন করুন এবং আমরা কাজ শুরু করার জন্য প্রস্তুত!
ধাপ 7: Hardhat ডাউনলোড করুন
Hardhat হলো আপনার ইথেরিয়াম সফটওয়্যার কম্পাইল, ডিপ্লয়, টেস্ট এবং ডিবাগ করার জন্য একটি ডেভেলপমেন্ট এনভায়রনমেন্ট। লাইভ চেইনে ডিপ্লয় করার আগে স্থানীয়ভাবে স্মার্ট কন্ট্রাক্ট এবং বিকেন্দ্রীকৃত অ্যাপ্লিকেশন (dapp) তৈরি করার সময় এটি ডেভেলপারদের সাহায্য করে।
আমাদের hello-world প্রজেক্টের ভেতরে রান করুন:
npm install --save-dev hardhat
ইনস্টলেশন নির্দেশিকা (একটি নতুন ট্যাবে খোলে) সম্পর্কে আরও বিস্তারিত জানতে এই পৃষ্ঠাটি দেখুন।
ধাপ 8: Hardhat প্রজেক্ট তৈরি করুন
আমাদের hello-world প্রজেক্ট ফোল্ডারের ভেতরে, রান করুন:
npx hardhat
এরপর আপনি একটি স্বাগত বার্তা এবং আপনি কী করতে চান তা নির্বাচন করার বিকল্প দেখতে পাবেন। "create an empty hardhat.config.js" নির্বাচন করুন:
888 888 888 888 888
888 888 888 888 888
888 888 888 888 888
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
888 888 "88b 888P" d88" 888 888 "88b "88b 888
888 888 .d888888 888 888 888 888 888 .d888888 888
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
👷 Welcome to Hardhat v2.0.11 👷
What do you want to do? …
Create a sample project
❯ Create an empty hardhat.config.js
Quit
এটি প্রজেক্টে একটি hardhat.config.js ফাইল তৈরি করবে। আমাদের প্রজেক্টের সেটআপ নির্দিষ্ট করার জন্য আমরা টিউটোরিয়ালের পরের অংশে এটি ব্যবহার করব।
ধাপ 9: প্রজেক্ট ফোল্ডার যোগ করুন
প্রজেক্টটি গুছিয়ে রাখতে, চলুন দুটি নতুন ফোল্ডার তৈরি করি। কমান্ড লাইনে, আপনার hello-world প্রজেক্টের রুট ডিরেক্টরিতে যান এবং টাইপ করুন:
mkdir contracts
mkdir scripts
contracts/হলো সেই জায়গা যেখানে আমরা আমাদের hello world স্মার্ট কন্ট্রাক্ট কোড ফাইলটি রাখবscripts/হলো সেই জায়গা যেখানে আমরা আমাদের কন্ট্রাক্ট ডিপ্লয় এবং এর সাথে ইন্টারঅ্যাক্ট করার স্ক্রিপ্টগুলো রাখব
ধাপ 10: আমাদের কন্ট্রাক্ট লিখুন
আপনি হয়তো নিজেকে জিজ্ঞাসা করছেন, আমরা কখন কোড লিখতে যাচ্ছি? এখনই সময়!
আপনার পছন্দের এডিটরে hello-world প্রজেক্টটি খুলুন। স্মার্ট কন্ট্রাক্টগুলো সাধারণত Solidity-তে লেখা হয়, যা আমরা আমাদের স্মার্ট কন্ট্রাক্ট লিখতে ব্যবহার করব।
contractsফোল্ডারে যান এবংHelloWorld.solনামে একটি নতুন ফাইল তৈরি করুন- নিচে একটি নমুনা Hello World স্মার্ট কন্ট্রাক্ট দেওয়া হলো যা আমরা এই টিউটোরিয়ালের জন্য ব্যবহার করব। নিচের বিষয়বস্তুগুলো
HelloWorld.solফাইলে কপি করুন।
দ্রষ্টব্য: এই কন্ট্রাক্টটি কী করে তা বুঝতে অবশ্যই কমেন্টগুলো পড়বেন।
// সিমেন্টিক ভার্সনিং ব্যবহার করে Solidity-এর ভার্সন নির্দিষ্ট করে।
// আরও জানুন: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
pragma solidity >=0.7.3;
// `HelloWorld` নামের একটি কন্ট্রাক্ট সংজ্ঞায়িত করে।
// একটি কন্ট্রাক্ট হলো ফাংশন এবং ডেটার (এর স্টেট) একটি সংগ্রহ। একবার ডিপ্লয় করা হলে, একটি কন্ট্রাক্ট ইথেরিয়াম ব্লকচেইনের একটি নির্দিষ্ট ঠিকানায় অবস্থান করে। আরও জানুন: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
contract HelloWorld {
//আপডেট ফাংশন কল করা হলে এমিট হয়
//স্মার্ট কন্ট্রাক্ট ইভেন্টগুলো হলো আপনার অ্যাপের ফ্রন্ট-এন্ডকে ব্লকচেইনে কিছু ঘটার বিষয়ে জানানোর একটি উপায়, যা নির্দিষ্ট ইভেন্টগুলোর জন্য 'লিসেন' করতে পারে এবং সেগুলো ঘটলে ব্যবস্থা নিতে পারে।
event UpdatedMessages(string oldStr, string newStr);
// `string` টাইপের একটি স্টেট ভেরিয়েবল `message` ঘোষণা করে।
// স্টেট ভেরিয়েবল হলো এমন ভেরিয়েবল যার মানগুলো স্থায়ীভাবে কন্ট্রাক্ট স্টোরেজে সংরক্ষিত থাকে। `public` কীওয়ার্ডটি ভেরিয়েবলগুলোকে কন্ট্রাক্টের বাইরে থেকে অ্যাক্সেসযোগ্য করে তোলে এবং এমন একটি ফাংশন তৈরি করে যা অন্য কন্ট্রাক্ট বা ক্লায়েন্টরা মানটি অ্যাক্সেস করতে কল করতে পারে।
string public message;
// অনেক ক্লাস-ভিত্তিক অবজেক্ট-ওরিয়েন্টেড ভাষার মতো, কনস্ট্রাক্টর হলো একটি বিশেষ ফাংশন যা শুধুমাত্র কন্ট্রাক্ট তৈরির সময় এক্সিকিউট হয়।
// কনস্ট্রাক্টরগুলো কন্ট্রাক্টের ডেটা ইনিশিয়ালাইজ করতে ব্যবহৃত হয়। আরও জানুন:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
constructor(string memory initMessage) {
// একটি স্ট্রিং আর্গুমেন্ট `initMessage` গ্রহণ করে এবং মানটিকে কন্ট্রাক্টের `message` স্টোরেজ ভেরিয়েবলে সেট করে)।
message = initMessage;
}
// একটি পাবলিক ফাংশন যা একটি স্ট্রিং আর্গুমেন্ট গ্রহণ করে এবং `message` স্টোরেজ ভেরিয়েবল আপডেট করে।
function update(string memory newMessage) public {
string memory oldMsg = message;
message = newMessage;
emit UpdatedMessages(oldMsg, newMessage);
}
}
এটি একটি সাধারণ স্মার্ট কন্ট্রাক্ট যা তৈরি করার সময় একটি বার্তা সংরক্ষণ করে। update ফাংশন কল করে এটি আপডেট করা যেতে পারে।
ধাপ 11: আপনার প্রজেক্টের সাথে মেটামাস্ক এবং Alchemy সংযুক্ত করুন
আমরা একটি মেটামাস্ক ওয়ালেট, Alchemy অ্যাকাউন্ট তৈরি করেছি এবং আমাদের স্মার্ট কন্ট্রাক্ট লিখেছি, এখন এই তিনটিকে সংযুক্ত করার সময়।
আপনার ওয়ালেট থেকে পাঠানো প্রতিটি ট্রানজ্যাকশনের জন্য আপনার অনন্য প্রাইভেট কী ব্যবহার করে একটি স্বাক্ষরের প্রয়োজন হয়। আমাদের প্রোগ্রামকে এই অনুমতি দেওয়ার জন্য, আমরা নিরাপদে আমাদের প্রাইভেট কী একটি এনভায়রনমেন্ট ফাইলে সংরক্ষণ করতে পারি। আমরা এখানে Alchemy-এর জন্য একটি API কী-ও সংরক্ষণ করব।
ট্রানজ্যাকশন পাঠানো সম্পর্কে আরও জানতে, Web3 ব্যবহার করে ট্রানজ্যাকশন পাঠানোর বিষয়ে এই টিউটোরিয়ালটি দেখুন।
প্রথমে, আপনার প্রজেক্ট ডিরেক্টরিতে dotenv প্যাকেজটি ইনস্টল করুন:
npm install dotenv --save
তারপর, প্রজেক্টের রুট ডিরেক্টরিতে একটি .env ফাইল তৈরি করুন। এতে আপনার মেটামাস্ক প্রাইভেট কী এবং HTTP Alchemy API URL যোগ করুন।
আপনার এনভায়রনমেন্ট ফাইলের নাম অবশ্যই .env হতে হবে, অন্যথায় এটি এনভায়রনমেন্ট ফাইল হিসেবে স্বীকৃত হবে না।
এর নাম process.env বা .env-custom বা অন্য কিছু দেবেন না।
- আপনার প্রাইভেট কী এক্সপোর্ট করতে এই নির্দেশিকাগুলো (একটি নতুন ট্যাবে খোলে) অনুসরণ করুন
- HTTP Alchemy API URL পেতে নিচে দেখুন
আপনার .env দেখতে এরকম হওয়া উচিত:
API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"
এগুলোকে আমাদের কোডের সাথে যুক্ত করতে, আমরা 13 নম্বর ধাপে আমাদের hardhat.config.js ফাইলে এই ভেরিয়েবলগুলোর রেফারেন্স দেব।
ধাপ 12: Ethers.js ইনস্টল করুন
Ethers.js হলো এমন একটি লাইব্রেরি যা স্ট্যান্ডার্ড JSON-RPC মেথডগুলোকে আরও ব্যবহারকারী-বান্ধব মেথড দিয়ে র্যাপ করে ইথেরিয়ামের সাথে ইন্টারঅ্যাক্ট করা এবং রিকোয়েস্ট করা সহজ করে তোলে।
Hardhat আমাদের অতিরিক্ত টুলিং এবং বর্ধিত কার্যকারিতার জন্য প্লাগইন (একটি নতুন ট্যাবে খোলে) ইন্টিগ্রেট করার অনুমতি দেয়। আমরা কন্ট্রাক্ট ডিপ্লয়মেন্টের জন্য Ethers প্লাগইন (একটি নতুন ট্যাবে খোলে)-এর সুবিধা নেব।
আপনার প্রজেক্ট ডিরেক্টরিতে টাইপ করুন:
npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"
ধাপ 13: hardhat.config.js আপডেট করুন
আমরা এ পর্যন্ত বেশ কয়েকটি ডিপেন্ডেন্সি এবং প্লাগইন যোগ করেছি, এখন আমাদের hardhat.config.js আপডেট করতে হবে যাতে আমাদের প্রজেক্ট সেগুলোর সব সম্পর্কে জানতে পারে।
আপনার hardhat.config.js আপডেট করুন যাতে এটি দেখতে এরকম হয়:
/**
* @type import('hardhat/config').HardhatUserConfig
*/
require("dotenv").config()
require("@nomiclabs/hardhat-ethers")
const { API_URL, PRIVATE_KEY } = process.env
module.exports = {
solidity: "0.7.3",
defaultNetwork: "goerli",
networks: {
hardhat: {},
goerli: {
url: API_URL,
accounts: [`0x${PRIVATE_KEY}`],
},
},
}
ধাপ 14: আমাদের কন্ট্রাক্ট কম্পাইল করুন
এ পর্যন্ত সবকিছু ঠিকঠাক কাজ করছে কিনা তা নিশ্চিত করতে, চলুন আমাদের কন্ট্রাক্ট কম্পাইল করি। compile টাস্কটি হলো বিল্ট-ইন Hardhat টাস্কগুলোর মধ্যে একটি।
কমান্ড লাইন থেকে রান করুন:
npx hardhat compile
আপনি SPDX license identifier not provided in source file সম্পর্কে একটি সতর্কতা পেতে পারেন, তবে এটি নিয়ে চিন্তা করার দরকার নেই — আশা করি অন্য সবকিছু ঠিক আছে! যদি তা না হয়, তবে আপনি সবসময় Alchemy ডিসকর্ড (একটি নতুন ট্যাবে খোলে)-এ মেসেজ করতে পারেন।
ধাপ 15: আমাদের ডিপ্লয় স্ক্রিপ্ট লিখুন
যেহেতু আমাদের কন্ট্রাক্ট লেখা হয়ে গেছে এবং আমাদের কনফিগারেশন ফাইল প্রস্তুত, তাই এখন আমাদের কন্ট্রাক্ট ডিপ্লয় স্ক্রিপ্ট লেখার সময়।
scripts/ ফোল্ডারে যান এবং deploy.js নামে একটি নতুন ফাইল তৈরি করুন, এতে নিচের বিষয়বস্তুগুলো যোগ করুন:
async function main() {
const HelloWorld = await ethers.getContractFactory("HelloWorld")
// ডিপ্লয়মেন্ট শুরু করুন, একটি প্রমিস রিটার্ন করে যা একটি কন্ট্রাক্ট অবজেক্টে রিজলভ হয়
const hello_world = await HelloWorld.deploy("Hello World!")
console.log("Contract deployed to address:", hello_world.address)
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error)
process.exit(1)
})
Hardhat তাদের কন্ট্রাক্ট টিউটোরিয়ালে (একটি নতুন ট্যাবে খোলে) কোডের এই প্রতিটি লাইন কী করে তা খুব ভালোভাবে ব্যাখ্যা করেছে, আমরা এখানে তাদের ব্যাখ্যাগুলো গ্রহণ করেছি।
const HelloWorld = await ethers.getContractFactory("HelloWorld")
ethers.js-এ একটি ContractFactory হলো নতুন স্মার্ট কন্ট্রাক্ট ডিপ্লয় করার জন্য ব্যবহৃত একটি অ্যাবস্ট্রাকশন, তাই এখানে HelloWorld হলো আমাদের hello world কন্ট্রাক্টের ইনস্ট্যান্সগুলোর জন্য একটি ফ্যাক্টরি (একটি নতুন ট্যাবে খোলে)। hardhat-ethers প্লাগইন ContractFactory এবং Contract ব্যবহার করার সময়, ইনস্ট্যান্সগুলো ডিফল্টভাবে প্রথম সাইনারের (মালিক) সাথে সংযুক্ত থাকে।
const hello_world = await HelloWorld.deploy()
একটি ContractFactory-এ deploy() কল করলে ডিপ্লয়মেন্ট শুরু হবে এবং একটি Promise রিটার্ন করবে যা একটি Contract অবজেক্টে রিজলভ হয়। এটি হলো সেই অবজেক্ট যার আমাদের প্রতিটি স্মার্ট কন্ট্রাক্ট ফাংশনের জন্য একটি মেথড রয়েছে।
ধাপ 16: আমাদের কন্ট্রাক্ট ডিপ্লয় করুন
আমরা অবশেষে আমাদের স্মার্ট কন্ট্রাক্ট ডিপ্লয় করার জন্য প্রস্তুত! কমান্ড লাইনে যান এবং রান করুন:
npx hardhat run scripts/deploy.js --network sepolia
এরপর আপনি এরকম কিছু দেখতে পাবেন:
Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570
অনুগ্রহ করে এই ঠিকানাটি সেভ করে রাখুন। আমরা টিউটোরিয়ালের পরের অংশে এটি ব্যবহার করব।
আমরা যদি Sepolia Etherscan (একটি নতুন ট্যাবে খোলে)-এ যাই এবং আমাদের কন্ট্রাক্ট ঠিকানাটি সার্চ করি, তবে আমরা দেখতে পাব যে এটি সফলভাবে ডিপ্লয় হয়েছে। ট্রানজ্যাকশনটি দেখতে অনেকটা এরকম হবে:
From ঠিকানাটি আপনার মেটামাস্ক অ্যাকাউন্ট ঠিকানার সাথে মিলে যাওয়া উচিত এবং To ঠিকানায় Contract Creation লেখা থাকবে। আমরা যদি ট্রানজ্যাকশনে ক্লিক করি, তবে আমরা To ফিল্ডে আমাদের কন্ট্রাক্ট ঠিকানাটি দেখতে পাব।
অভিনন্দন! আপনি এইমাত্র একটি ইথেরিয়াম টেস্টনেটে একটি স্মার্ট কন্ট্রাক্ট ডিপ্লয় করেছেন।
ভেতরে আসলে কী ঘটছে তা বুঝতে, চলুন আমাদের Alchemy ড্যাশবোর্ড (একটি নতুন ট্যাবে খোলে)-এর Explorer ট্যাবে নেভিগেট করি। আপনার যদি একাধিক Alchemy অ্যাপ থাকে, তবে অ্যাপ অনুযায়ী ফিল্টার করে Hello World নির্বাচন করতে ভুলবেন না।
এখানে আপনি বেশ কয়েকটি JSON-RPC মেথড দেখতে পাবেন যা আমরা .deploy() ফাংশন কল করার সময় Hardhat/Ethers আমাদের জন্য অভ্যন্তরীণভাবে তৈরি করেছে। এখানকার দুটি গুরুত্বপূর্ণ মেথড হলো eth_sendRawTransaction (একটি নতুন ট্যাবে খোলে), যা আমাদের কন্ট্রাক্টটিকে Sepolia চেইনে লেখার জন্য একটি রিকোয়েস্ট, এবং eth_getTransactionByHash (একটি নতুন ট্যাবে খোলে), যা হ্যাশ দেওয়া থাকলে আমাদের ট্রানজ্যাকশন সম্পর্কে তথ্য পড়ার জন্য একটি রিকোয়েস্ট। ট্রানজ্যাকশন পাঠানো সম্পর্কে আরও জানতে, Web3 ব্যবহার করে ট্রানজ্যাকশন পাঠানোর বিষয়ে আমাদের টিউটোরিয়ালটি দেখুন।
পর্ব 2: আপনার স্মার্ট কন্ট্রাক্টের সাথে ইন্টারঅ্যাক্ট করুন
যেহেতু আমরা সফলভাবে Goerli নেটওয়ার্কে একটি স্মার্ট কন্ট্রাক্ট ডিপ্লয় করেছি, তাই চলুন শিখে নিই কীভাবে এর সাথে ইন্টারঅ্যাক্ট করতে হয়।
একটি interact.js ফাইল তৈরি করুন
এটি সেই ফাইল যেখানে আমরা আমাদের ইন্টারঅ্যাকশন স্ক্রিপ্ট লিখব। আমরা Ethers.js লাইব্রেরি ব্যবহার করব যা আপনি আগে পর্ব 1-এ ইনস্টল করেছিলেন।
scripts/ ফোল্ডারের ভিতরে, interact.js নামে একটি নতুন ফাইল তৈরি করুন এবং নিচের কোডটি যোগ করুন:
// interact.js
const API_KEY = process.env.API_KEY
const PRIVATE_KEY = process.env.PRIVATE_KEY
const 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 ফাইলে নিচের কোডগুলো যোগ করে এর কন্টেন্ট পার্স করতে হবে:
// interact.js
const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")
আপনি যদি ABI দেখতে চান তবে আপনি এটি আপনার কনসোলে প্রিন্ট করতে পারেন:
console.log(JSON.stringify(contract.abi))
আপনার ABI কনসোলে প্রিন্ট করা দেখতে, আপনার টার্মিনালে যান এবং রান করুন:
npx hardhat run scripts/interact.js
আপনার কন্ট্রাক্টের একটি ইনস্ট্যান্স তৈরি করুন
আমাদের কন্ট্রাক্টের সাথে ইন্টারঅ্যাক্ট করার জন্য, আমাদের কোডে একটি কন্ট্রাক্ট ইনস্ট্যান্স তৈরি করতে হবে। Ethers.js এর সাথে এটি করার জন্য, আমাদের তিনটি কনসেপ্ট নিয়ে কাজ করতে হবে:
- প্রোভাইডার - একটি নোড প্রোভাইডার যা আপনাকে ব্লকচেইনে রিড এবং রাইট অ্যাক্সেস দেয়
- সাইনার - একটি ইথেরিয়াম অ্যাকাউন্টকে উপস্থাপন করে যা ট্রানজ্যাকশনে সাইন করতে পারে
- Contract - একটি Ethers.js অবজেক্ট যা অনচেইনে ডিপ্লয় করা একটি নির্দিষ্ট কন্ট্রাক্টকে উপস্থাপন করে
আমরা কন্ট্রাক্টের ইনস্ট্যান্স তৈরি করতে আগের ধাপ থেকে কন্ট্রাক্ট ABI ব্যবহার করব:
// interact.js
// Provider
const alchemyProvider = new ethers.providers.AlchemyProvider(
(network = "goerli"),
API_KEY
)
// Signer
const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider)
// Contract
const helloWorldContract = new ethers.Contract(
CONTRACT_ADDRESS,
contract.abi,
signer
)
Providers, Signers এবং Contracts সম্পর্কে আরও জানুন ethers.js ডকুমেন্টেশনে (একটি নতুন ট্যাবে খোলে)।
init বার্তাটি পড়ুন
মনে আছে যখন আমরা initMessage = "Hello world!" দিয়ে আমাদের কন্ট্রাক্ট ডিপ্লয় করেছিলাম? আমরা এখন আমাদের স্মার্ট কন্ট্রাক্টে সংরক্ষিত সেই বার্তাটি পড়ব এবং এটি কনসোলে প্রিন্ট করব।
জাভাস্ক্রিপ্টে, নেটওয়ার্কের সাথে ইন্টারঅ্যাক্ট করার সময় অ্যাসিনক্রোনাস ফাংশন ব্যবহার করা হয়। অ্যাসিনক্রোনাস ফাংশন সম্পর্কে আরও জানতে, এই মিডিয়াম আর্টিকেলটি পড়ুন (একটি নতুন ট্যাবে খোলে)।
আমাদের স্মার্ট কন্ট্রাক্টে message ফাংশন কল করতে এবং init বার্তাটি পড়তে নিচের কোডটি ব্যবহার করুন:
// interact.js
// ...
async function main() {
const message = await helloWorldContract.message()
console.log("The message is: " + message)
}
main()
টার্মিনালে npx hardhat run scripts/interact.js ব্যবহার করে ফাইলটি রান করার পর আমাদের এই রেসপন্সটি দেখা উচিত:
The message is: Hello world!
অভিনন্দন! আপনি এইমাত্র ইথেরিয়াম ব্লকচেইন থেকে সফলভাবে স্মার্ট কন্ট্রাক্ট ডেটা পড়েছেন, দারুণ কাজ!
বার্তাটি আপডেট করুন
শুধুমাত্র বার্তাটি পড়ার পরিবর্তে, আমরা update ফাংশন ব্যবহার করে আমাদের স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তাটি আপডেটও করতে পারি! বেশ দারুণ, তাই না?
বার্তাটি আপডেট করতে, আমরা সরাসরি আমাদের ইনস্ট্যান্সিয়েট করা Contract অবজেক্টে update ফাংশনটি কল করতে পারি:
// interact.js
// ...
async function main() {
const message = await helloWorldContract.message()
console.log("The message is: " + message)
console.log("Updating the message...")
const tx = await helloWorldContract.update("This is the new message.")
await tx.wait()
}
main()
লক্ষ্য করুন যে 11 নম্বর লাইনে, আমরা রিটার্ন করা ট্রানজ্যাকশন অবজেক্টে .wait() কল করেছি। এটি নিশ্চিত করে যে ফাংশন থেকে বের হওয়ার আগে আমাদের স্ক্রিপ্টটি ব্লকচেইনে ট্রানজ্যাকশন মাইন হওয়ার জন্য অপেক্ষা করবে। যদি .wait() কলটি অন্তর্ভুক্ত না করা হয়, তবে স্ক্রিপ্টটি কন্ট্রাক্টে আপডেট করা message ভ্যালু দেখতে নাও পারে।
নতুন বার্তাটি পড়ুন
আপডেট করা message ভ্যালু পড়তে আপনার আগের ধাপটির পুনরাবৃত্তি করতে পারা উচিত। একটু সময় নিন এবং দেখুন আপনি সেই নতুন ভ্যালুটি প্রিন্ট করার জন্য প্রয়োজনীয় পরিবর্তনগুলো করতে পারেন কিনা!
আপনার যদি কোনো হিন্ট বা সূত্রের প্রয়োজন হয়, তবে এই পর্যায়ে আপনার interact.js ফাইলটি দেখতে এরকম হওয়া উচিত:
// interact.js
const API_KEY = process.env.API_KEY
const PRIVATE_KEY = process.env.PRIVATE_KEY
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS
const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json")
// প্রোভাইডার - Alchemy
const alchemyProvider = new ethers.providers.AlchemyProvider(
(network = "sepolia"),
API_KEY
)
// সাইনার - আপনি
const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider)
// কন্ট্রাক্ট ইনস্ট্যান্স
const helloWorldContract = new ethers.Contract(
CONTRACT_ADDRESS,
contract.abi,
signer
)
async function main() {
const message = await helloWorldContract.message()
console.log("The message is: " + message)
console.log("Updating the message...")
const tx = await helloWorldContract.update("this is the new message")
await tx.wait()
const newMessage = await helloWorldContract.message()
console.log("The new message is: " + newMessage)
}
main()
এখন শুধু স্ক্রিপ্টটি রান করুন এবং আপনি আপনার টার্মিনালে প্রিন্ট করা পুরোনো বার্তা, আপডেটিং স্ট্যাটাস এবং নতুন বার্তাটি দেখতে পাবেন!
npx hardhat run scripts/interact.js --network sepolia
The message is: Hello World!
Updating the message...
The new message is: This is the new message.
সেই স্ক্রিপ্টটি রান করার সময়, আপনি লক্ষ্য করতে পারেন যে নতুন বার্তাটি লোড হওয়ার আগে Updating the message... ধাপটি লোড হতে কিছুটা সময় নেয়। এটি মাইনিং প্রক্রিয়ার কারণে হয়; মাইনিং হওয়ার সময় ট্রানজ্যাকশনগুলো ট্র্যাক করার বিষয়ে আপনার যদি কৌতূহল থাকে, তবে ট্রানজ্যাকশনের স্ট্যাটাস দেখতে Alchemy mempool (একটি নতুন ট্যাবে খোলে)-এ যান। যদি ট্রানজ্যাকশনটি ড্রপ হয়ে যায়, তবে Sepolia Etherscan (একটি নতুন ট্যাবে খোলে) চেক করা এবং আপনার ট্রানজ্যাকশন হ্যাশ অনুসন্ধান করাও সহায়ক।
পর্ব 3: Etherscan-এ আপনার স্মার্ট কন্ট্রাক্ট পাবলিশ করুন
আপনার স্মার্ট কন্ট্রাক্টকে বাস্তবে রূপ দিতে আপনি অনেক পরিশ্রম করেছেন; এখন এটি বিশ্বের সাথে শেয়ার করার সময়!
Etherscan-এ আপনার স্মার্ট কন্ট্রাক্ট ভেরিফাই করার মাধ্যমে, যে কেউ আপনার সোর্স কোড দেখতে পারবে এবং আপনার স্মার্ট কন্ট্রাক্টের সাথে ইন্টারঅ্যাক্ট করতে পারবে। চলুন শুরু করা যাক!
ধাপ 1: আপনার Etherscan অ্যাকাউন্টে একটি API কী তৈরি করুন
আপনি যে স্মার্ট কন্ট্রাক্টটি পাবলিশ করার চেষ্টা করছেন তার মালিক যে আপনিই, তা ভেরিফাই করার জন্য একটি Etherscan API কী প্রয়োজন।
আপনার যদি আগে থেকে কোনো Etherscan অ্যাকাউন্ট না থাকে, তাহলে একটি অ্যাকাউন্টের জন্য সাইন আপ করুন (একটি নতুন ট্যাবে খোলে)।
লগ ইন করার পর, নেভিগেশন বারে আপনার ইউজারনেম খুঁজুন, এর উপর হোভার করুন এবং My profile বোতামটি নির্বাচন করুন।
আপনার প্রোফাইল পেজে, আপনি একটি সাইড নেভিগেশন বার দেখতে পাবেন। সাইড নেভিগেশন বার থেকে, API Keys নির্বাচন করুন। এরপর, একটি নতুন API কী তৈরি করতে "Add" বোতাম টিপুন, আপনার অ্যাপের নাম দিন hello-world এবং Create New API Key বোতাম টিপুন।
আপনার নতুন API কী-টি API কী টেবিলে দেখা যাবে। API কী-টি আপনার ক্লিপবোর্ডে কপি করুন।
এরপর, আমাদের .env ফাইলে Etherscan API কী যোগ করতে হবে।
এটি যোগ করার পর, আপনার .env ফাইলটি দেখতে এরকম হবে:
API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
PUBLIC_KEY = "your-public-account-address"
PRIVATE_KEY = "your-private-account-address"
CONTRACT_ADDRESS = "your-contract-address"
ETHERSCAN_API_KEY = "your-etherscan-key"
Hardhat-এর মাধ্যমে ডিপ্লয় করা স্মার্ট কন্ট্রাক্ট
hardhat-etherscan ইনস্টল করুন
Hardhat ব্যবহার করে Etherscan-এ আপনার কন্ট্রাক্ট পাবলিশ করা বেশ সহজ। শুরু করার জন্য আপনাকে প্রথমে hardhat-etherscan প্লাগইনটি ইনস্টল করতে হবে। hardhat-etherscan স্বয়ংক্রিয়ভাবে Etherscan-এ স্মার্ট কন্ট্রাক্টের সোর্স কোড এবং ABI ভেরিফাই করবে। এটি যোগ করতে, hello-world ডিরেক্টরিতে রান করুন:
npm install --save-dev @nomiclabs/hardhat-etherscan
ইনস্টল হয়ে গেলে, আপনার hardhat.config.js-এর একেবারে উপরে নিচের স্টেটমেন্টটি অন্তর্ভুক্ত করুন এবং Etherscan কনফিগ অপশনগুলো যোগ করুন:
// hardhat.config.js
require("dotenv").config()
require("@nomiclabs/hardhat-ethers")
require("@nomiclabs/hardhat-etherscan")
const { API_URL, PRIVATE_KEY, ETHERSCAN_API_KEY } = process.env
module.exports = {
solidity: "0.7.3",
defaultNetwork: "goerli",
networks: {
hardhat: {},
goerli: {
url: API_URL,
accounts: [`0x${PRIVATE_KEY}`],
},
},
etherscan: {
// Etherscan এর জন্য আপনার API কী
// https://etherscan.io/ থেকে একটি সংগ্রহ করুন
apiKey: ETHERSCAN_API_KEY,
},
}
Etherscan-এ আপনার স্মার্ট কন্ট্রাক্ট ভেরিফাই করুন
নিশ্চিত করুন যে সমস্ত ফাইল সেভ করা হয়েছে এবং সমস্ত .env ভেরিয়েবল সঠিকভাবে কনফিগার করা হয়েছে।
কন্ট্রাক্ট ঠিকানা এবং এটি যেখানে ডিপ্লয় করা হয়েছে সেই নেটওয়ার্কটি পাস করে verify টাস্কটি রান করুন:
npx hardhat verify --network sepolia DEPLOYED_CONTRACT_ADDRESS 'Hello World!'
নিশ্চিত করুন যে DEPLOYED_CONTRACT_ADDRESS হলো Sepolia টেস্ট নেটওয়ার্কে আপনার ডিপ্লয় করা স্মার্ট কন্ট্রাক্টের ঠিকানা। এছাড়াও, চূড়ান্ত আর্গুমেন্ট ('Hello World!') অবশ্যই পর্ব 1-এ ডিপ্লয়মেন্ট ধাপের সময় ব্যবহৃত একই স্ট্রিং ভ্যালু হতে হবে।
সবকিছু ঠিকঠাক থাকলে, আপনি আপনার টার্মিনালে নিচের বার্তাটি দেখতে পাবেন:
Successfully submitted source code for contract
contracts/HelloWorld.sol:HelloWorld at 0xdeployed-contract-address
for verification on Etherscan. Waiting for verification result...
Successfully verified contract HelloWorld on Etherscan.
https://sepolia.etherscan.io/address/<contract-address>#contracts
অভিনন্দন! আপনার স্মার্ট কন্ট্রাক্ট কোড এখন Etherscan-এ আছে!
Etherscan-এ আপনার স্মার্ট কন্ট্রাক্টটি দেখে নিন!
আপনার টার্মিনালে দেওয়া লিঙ্কে গেলে, আপনি Etherscan-এ পাবলিশ করা আপনার স্মার্ট কন্ট্রাক্ট কোড এবং ABI দেখতে পাবেন!
দারুণ - আপনি পেরেছেন চ্যাম্প! এখন যে কেউ আপনার স্মার্ট কন্ট্রাক্টে কল করতে বা লিখতে পারবে! আপনি পরবর্তীতে কী তৈরি করেন তা দেখার জন্য আমরা অধীর আগ্রহে অপেক্ষা করছি!
পর্ব 4 - ফ্রন্টএন্ডের সাথে আপনার স্মার্ট কন্ট্রাক্ট ইন্টিগ্রেট করা
এই টিউটোরিয়ালের শেষে, আপনি জানতে পারবেন কীভাবে:
- আপনার বিকেন্দ্রীকৃত অ্যাপ্লিকেশন (dapp)-এর সাথে একটি মেটামাস্ক ওয়ালেট কানেক্ট করতে হয়
- Alchemy Web3 (একটি নতুন ট্যাবে খোলে) API ব্যবহার করে আপনার স্মার্ট কন্ট্রাক্ট থেকে ডেটা পড়তে হয়
- মেটামাস্ক ব্যবহার করে ইথেরিয়াম ট্রানজ্যাকশন সাইন করতে হয়
এই dapp-এর জন্য, আমরা আমাদের ফ্রন্টএন্ড ফ্রেমওয়ার্ক হিসেবে React (একটি নতুন ট্যাবে খোলে) ব্যবহার করব; তবে, এটি মনে রাখা গুরুত্বপূর্ণ যে আমরা এর মৌলিক বিষয়গুলো নিয়ে খুব বেশি সময় ব্যয় করব না, কারণ আমরা মূলত আমাদের প্রজেক্টে Web3 কার্যকারিতা আনার দিকেই বেশি মনোযোগ দেব।
পূর্বশর্ত হিসেবে, আপনার React সম্পর্কে প্রাথমিক স্তরের ধারণা থাকা উচিত। যদি না থাকে, তবে আমরা অফিসিয়াল Intro to React tutorial (একটি নতুন ট্যাবে খোলে) সম্পন্ন করার পরামর্শ দিচ্ছি।
স্টার্টার ফাইলগুলো ক্লোন করুন
প্রথমে, এই প্রজেক্টের স্টার্টার ফাইলগুলো পেতে hello-world-part-four GitHub repository (একটি নতুন ট্যাবে খোলে)-তে যান এবং এই রিপোজিটরিটি আপনার লোকাল মেশিনে ক্লোন করুন।
ক্লোন করা রিপোজিটরিটি লোকালি খুলুন। খেয়াল করুন যে এতে দুটি ফোল্ডার রয়েছে: starter-files এবং completed।
starter-files- আমরা এই ডিরেক্টরিতে কাজ করব, আমরা UI-কে আপনার ইথেরিয়াম ওয়ালেট এবং পর্ব 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/ (একটি নতুন ট্যাবে খোলে) খুলবে, যেখানে আপনি আমাদের প্রজেক্টের ফ্রন্টএন্ড দেখতে পাবেন। এতে একটি ফিল্ড (আপনার স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তা আপডেট করার জায়গা), একটি "Connect Wallet" বোতাম এবং একটি "Update" বোতাম থাকা উচিত।
আপনি যদি কোনো বোতামে ক্লিক করার চেষ্টা করেন, তবে আপনি লক্ষ্য করবেন যে সেগুলো কাজ করছে না—এর কারণ হলো আমাদের এখনও সেগুলোর কার্যকারিতা প্রোগ্রাম করতে হবে।
HelloWorld.js কম্পোনেন্ট
চলুন আমাদের এডিটরে src ফোল্ডারে ফিরে যাই এবং HelloWorld.js ফাইলটি খুলি। এই ফাইলের সবকিছু বোঝা আমাদের জন্য অত্যন্ত গুরুত্বপূর্ণ, কারণ এটিই প্রাথমিক React কম্পোনেন্ট যেখানে আমরা কাজ করব।
এই ফাইলের শীর্ষে, আপনি লক্ষ্য করবেন যে আমাদের প্রজেক্টটি রান করার জন্য প্রয়োজনীয় বেশ কয়েকটি ইমপোর্ট স্টেটমেন্ট রয়েছে, যার মধ্যে রয়েছে React লাইব্রেরি, useEffect এবং useState হুক, ./util/interact.js থেকে কিছু আইটেম (আমরা শীঘ্রই সেগুলোর বিস্তারিত বর্ণনা করব!), এবং Alchemy লোগো।
// HelloWorld.js
import React from "react"
import { useEffect, useState } from "react"
import {
helloWorldContract,
connectWallet,
updateMessage,
loadCurrentMessage,
getCurrentWalletConnected,
} from "./util/interact.js"
import alchemylogo from "./alchemylogo.svg"
এরপর, আমাদের স্টেট ভেরিয়েবলগুলো রয়েছে যা আমরা নির্দিষ্ট ইভেন্টের পরে আপডেট করব।
// HelloWorld.js
//স্টেট ভেরিয়েবল
const [walletAddress, setWallet] = useState("")
const [status, setStatus] = useState("")
const [message, setMessage] = useState("No connection to the network.")
const [newMessage, setNewMessage] = useState("")
এখানে প্রতিটি ভেরিয়েবল যা উপস্থাপন করে তা দেওয়া হলো:
walletAddress- একটি স্ট্রিং যা ব্যবহারকারীর ওয়ালেট ঠিকানা সংরক্ষণ করেstatus- একটি স্ট্রিং যা একটি সহায়ক বার্তা সংরক্ষণ করে যা ব্যবহারকারীকে dapp-এর সাথে কীভাবে ইন্টারঅ্যাক্ট করতে হয় সে সম্পর্কে গাইড করেmessage- একটি স্ট্রিং যা স্মার্ট কন্ট্রাক্টে বর্তমান বার্তা সংরক্ষণ করেnewMessage- একটি স্ট্রিং যা নতুন বার্তা সংরক্ষণ করে যা স্মার্ট কন্ট্রাক্টে লেখা হবে
স্টেট ভেরিয়েবলগুলোর পরে, আপনি পাঁচটি ইমপ্লিমেন্ট না করা ফাংশন দেখতে পাবেন: useEffect ,addSmartContractListener, addWalletListener , connectWalletPressed, এবং onUpdatePressed। আমরা নিচে ব্যাখ্যা করব এগুলো কী কাজ করে:
// HelloWorld.js
//শুধুমাত্র একবার কল করা হয়
useEffect(async () => {
//TODO: বাস্তবায়ন করুন
}, [])
function addSmartContractListener() {
//TODO: বাস্তবায়ন করুন
}
function addWalletListener() {
//TODO: বাস্তবায়ন করুন
}
const connectWalletPressed = async () => {
//TODO: বাস্তবায়ন করুন
}
const onUpdatePressed = async () => {
//TODO: বাস্তবায়ন করুন
}
useEffect(একটি নতুন ট্যাবে খোলে)- এটি একটি React হুক যা আপনার কম্পোনেন্ট রেন্ডার হওয়ার পরে কল করা হয়। যেহেতু এতে একটি খালি অ্যারে[]প্রপ পাস করা হয়েছে (লাইন 4 দেখুন), এটি শুধুমাত্র কম্পোনেন্টের প্রথম রেন্ডারে কল করা হবে। এখানে আমরা আমাদের স্মার্ট কন্ট্রাক্টে সংরক্ষিত বর্তমান বার্তা লোড করব, আমাদের স্মার্ট কন্ট্রাক্ট এবং ওয়ালেট লিসেনারদের কল করব এবং কোনো ওয়ালেট আগে থেকেই কানেক্ট করা আছে কিনা তা প্রতিফলিত করতে আমাদের UI আপডেট করব।addSmartContractListener- এই ফাংশনটি একটি লিসেনার সেট আপ করে যা আমাদের HelloWorld কন্ট্রাক্টেরUpdatedMessagesইভেন্টের জন্য নজর রাখবে এবং আমাদের স্মার্ট কন্ট্রাক্টে বার্তা পরিবর্তন হলে আমাদের UI আপডেট করবে।addWalletListener- এই ফাংশনটি একটি লিসেনার সেট আপ করে যা ব্যবহারকারীর মেটামাস্ক ওয়ালেট স্টেটের পরিবর্তনগুলো শনাক্ত করে, যেমন যখন ব্যবহারকারী তাদের ওয়ালেট ডিসকানেক্ট করে বা ঠিকানা পরিবর্তন করে।connectWalletPressed- ব্যবহারকারীর মেটামাস্ক ওয়ালেটকে আমাদের dapp-এর সাথে কানেক্ট করতে এই ফাংশনটি কল করা হবে।onUpdatePressed- যখন ব্যবহারকারী স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তা আপডেট করতে চাইবেন তখন এই ফাংশনটি কল করা হবে।
এই ফাইলের শেষের দিকে, আমাদের কম্পোনেন্টের UI রয়েছে।
// HelloWorld.js
//আমাদের কম্পোনেন্টের UI
return (
<div id="container">
<img id="logo" src={alchemylogo}></img>
<button id="walletButton" onClick={connectWalletPressed}>
{walletAddress.length > 0 ? (
"Connected: " +
String(walletAddress).substring(0, 6) +
"..." +
String(walletAddress).substring(38)
) : (
<span>Connect Wallet</span>
)}
</button>
<h2 style={{ paddingTop: "50px" }}>Current Message:</h2>
<p>{message}</p>
<h2 style={{ paddingTop: "18px" }}>New Message:</h2>
<div>
<input
type="text"
placeholder="Update the message in your smart contract."
onChange={(e) => setNewMessage(e.target.value)}
value={newMessage}
/>
<p id="status">{status}</p>
<button id="publishButton" onClick={onUpdatePressed}>
Update
</button>
</div>
</div>
)
আপনি যদি এই কোডটি মনোযোগ সহকারে দেখেন, তবে আপনি লক্ষ্য করবেন যে আমরা আমাদের UI-তে আমাদের বিভিন্ন স্টেট ভেরিয়েবলগুলো কোথায় ব্যবহার করি:
- 6-12 লাইনে, যদি ব্যবহারকারীর ওয়ালেট কানেক্ট করা থাকে (অর্থাৎ,
walletAddress.length > 0), আমরা "walletButton" আইডি সহ বোতামে ব্যবহারকারীরwalletAddress-এর একটি সংক্ষিপ্ত সংস্করণ প্রদর্শন করি; অন্যথায় এটি কেবল "Connect Wallet" বলে। - 17 লাইনে, আমরা স্মার্ট কন্ট্রাক্টে সংরক্ষিত বর্তমান বার্তা প্রদর্শন করি, যা
messageস্ট্রিংয়ে ক্যাপচার করা হয়েছে। - 23-26 লাইনে, টেক্সট ফিল্ডের ইনপুট পরিবর্তন হলে আমাদের
newMessageস্টেট ভেরিয়েবল আপডেট করতে আমরা একটি নিয়ন্ত্রিত কম্পোনেন্ট (একটি নতুন ট্যাবে খোলে) ব্যবহার করি।
আমাদের স্টেট ভেরিয়েবলগুলো ছাড়াও, আপনি দেখতে পাবেন যে publishButton এবং walletButton আইডি সহ বোতামগুলোতে ক্লিক করা হলে যথাক্রমে connectWalletPressed এবং onUpdatePressed ফাংশনগুলো কল করা হয়।
অবশেষে, চলুন দেখি এই HelloWorld.js কম্পোনেন্টটি কোথায় যোগ করা হয়েছে।
আপনি যদি App.js ফাইলে যান, যা React-এর প্রধান কম্পোনেন্ট এবং অন্যান্য সমস্ত কম্পোনেন্টের কন্টেইনার হিসেবে কাজ করে, আপনি দেখতে পাবেন যে আমাদের HelloWorld.js কম্পোনেন্টটি 7 লাইনে ইনজেক্ট করা হয়েছে।
সবশেষে, চলুন আপনার জন্য দেওয়া আরও একটি ফাইল দেখে নিই, interact.js ফাইল।
interact.js ফাইল
যেহেতু আমরা M-V-C (একটি নতুন ট্যাবে খোলে) প্যারাডাইম অনুসরণ করতে চাই, তাই আমরা একটি আলাদা ফাইল চাইব যাতে আমাদের dapp-এর লজিক, ডেটা এবং নিয়মগুলো পরিচালনা করার জন্য আমাদের সমস্ত ফাংশন থাকে এবং তারপর সেই ফাংশনগুলোকে আমাদের ফ্রন্টএন্ডে (আমাদের HelloWorld.js কম্পোনেন্ট) এক্সপোর্ট করতে সক্ষম হই।
👆🏽এটিই আমাদের interact.js ফাইলের আসল উদ্দেশ্য!
আপনার src ডিরেক্টরির util ফোল্ডারে নেভিগেট করুন, এবং আপনি লক্ষ্য করবেন যে আমরা interact.js নামের একটি ফাইল অন্তর্ভুক্ত করেছি যাতে আমাদের সমস্ত স্মার্ট কন্ট্রাক্ট ইন্টারঅ্যাকশন এবং ওয়ালেট ফাংশন এবং ভেরিয়েবলগুলো থাকবে।
// interact.js
//export const helloWorldContract;
export const loadCurrentMessage = async () => {}
export const connectWallet = async () => {}
const getCurrentWalletConnected = async () => {}
export const updateMessage = async (message) => {}
আপনি ফাইলের শীর্ষে লক্ষ্য করবেন যে আমরা helloWorldContract অবজেক্টটি কমেন্ট আউট করেছি। এই টিউটোরিয়ালের পরে, আমরা এই অবজেক্টটি আনকমেন্ট করব এবং এই ভেরিয়েবলে আমাদের স্মার্ট কন্ট্রাক্ট ইনস্ট্যানশিয়েট করব, যা আমরা পরে আমাদের HelloWorld.js কম্পোনেন্টে এক্সপোর্ট করব।
আমাদের helloWorldContract অবজেক্টের পরে চারটি ইমপ্লিমেন্ট না করা ফাংশন নিচের কাজগুলো করে:
loadCurrentMessage- এই ফাংশনটি স্মার্ট কন্ট্রাক্টে সংরক্ষিত বর্তমান বার্তা লোড করার লজিক পরিচালনা করে। এটি Alchemy Web3 API (একটি নতুন ট্যাবে খোলে) ব্যবহার করে Hello World স্মার্ট কন্ট্রাক্টে একটি read কল করবে।connectWallet- এই ফাংশনটি ব্যবহারকারীর মেটামাস্ককে আমাদের dapp-এর সাথে কানেক্ট করবে।getCurrentWalletConnected- এই ফাংশনটি পেজ লোড হওয়ার সময় চেক করবে যে কোনো ইথেরিয়াম অ্যাকাউন্ট আগে থেকেই আমাদের dapp-এর সাথে কানেক্ট করা আছে কিনা এবং সেই অনুযায়ী আমাদের UI আপডেট করবে।updateMessage- এই ফাংশনটি স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তা আপডেট করবে। এটি Hello World স্মার্ট কন্ট্রাক্টে একটি write কল করবে, তাই বার্তাটি আপডেট করতে ব্যবহারকারীর মেটামাস্ক ওয়ালেটকে একটি ইথেরিয়াম ট্রানজ্যাকশন সাইন করতে হবে।
এখন যেহেতু আমরা বুঝতে পেরেছি যে আমরা কী নিয়ে কাজ করছি, চলুন বের করি কীভাবে আমাদের স্মার্ট কন্ট্রাক্ট থেকে পড়তে হয়!
ধাপ 3: আপনার স্মার্ট কন্ট্রাক্ট থেকে পড়ুন
আপনার স্মার্ট কন্ট্রাক্ট থেকে পড়তে, আপনাকে সফলভাবে সেট আপ করতে হবে:
- ইথেরিয়াম চেইনের সাথে একটি API কানেকশন
- আপনার স্মার্ট কন্ট্রাক্টের একটি লোড করা ইনস্ট্যান্স
- আপনার স্মার্ট কন্ট্রাক্ট ফাংশনে কল করার জন্য একটি ফাংশন
- স্মার্ট কন্ট্রাক্ট থেকে আপনি যে ডেটা পড়ছেন তা পরিবর্তন হলে আপডেটের জন্য নজর রাখতে একটি লিসেনার
এটি অনেকগুলো ধাপ বলে মনে হতে পারে, তবে চিন্তা করবেন না! আমরা আপনাকে ধাপে ধাপে দেখাব কীভাবে এর প্রতিটি করতে হয়! :)
ইথেরিয়াম চেইনের সাথে একটি API কানেকশন স্থাপন করুন
মনে আছে এই টিউটোরিয়ালের পর্ব 2-এ আমরা কীভাবে আমাদের স্মার্ট কন্ট্রাক্ট থেকে পড়ার জন্য আমাদের Alchemy Web3 কী ব্যবহার করেছিলাম? চেইন থেকে পড়ার জন্য আপনার বিকেন্দ্রীকৃত অ্যাপ্লিকেশন (dapp)-এও একটি Alchemy Web3 কী প্রয়োজন হবে।
যদি আপনার কাছে এটি আগে থেকে না থাকে, তবে প্রথমে আপনার starter-files-এর রুট ডিরেক্টরিতে নেভিগেট করে এবং আপনার টার্মিনালে নিচের কমান্ডটি রান করে Alchemy Web3 (একটি নতুন ট্যাবে খোলে) ইনস্টল করুন:
npm install @alch/alchemy-web3
Alchemy Web3 (একটি নতুন ট্যাবে খোলে) হলো Web3.js (একটি নতুন ট্যাবে খোলে)-এর একটি র্যাপার, যা উন্নত API মেথড এবং অন্যান্য গুরুত্বপূর্ণ সুবিধা প্রদান করে যাতে একজন Web3 ডেভেলপার হিসেবে আপনার কাজ আরও সহজ হয়। এটি এমনভাবে ডিজাইন করা হয়েছে যাতে ন্যূনতম কনফিগারেশনের প্রয়োজন হয়, ফলে আপনি এখনই আপনার অ্যাপে এটি ব্যবহার করা শুরু করতে পারেন!
তারপর, আপনার প্রজেক্ট ডিরেক্টরিতে dotenv (একটি নতুন ট্যাবে খোলে) প্যাকেজটি ইনস্টল করুন, যাতে আমাদের API কী সংগ্রহ করার পর সেটি সংরক্ষণ করার জন্য একটি নিরাপদ জায়গা থাকে।
npm install dotenv --save
আমাদের dapp-এর জন্য, আমরা আমাদের HTTP API কী-এর পরিবর্তে আমাদের Websockets API কী ব্যবহার করব, কারণ এটি আমাদের এমন একটি লিসেনার সেট আপ করার অনুমতি দেবে যা স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তা পরিবর্তন হলে তা শনাক্ত করতে পারে।
একবার আপনি আপনার API কী পেয়ে গেলে, আপনার রুট ডিরেক্টরিতে একটি .env ফাইল তৈরি করুন এবং এতে আপনার Alchemy Websockets URL যোগ করুন। এরপর, আপনার .env ফাইলটি দেখতে এরকম হওয়া উচিত:
REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/<key>
এখন, আমরা আমাদের dapp-এ আমাদের Alchemy Web3 এন্ডপয়েন্ট সেট আপ করতে প্রস্তুত! চলুন আমাদের interact.js-এ ফিরে যাই, যা আমাদের util ফোল্ডারের ভেতরে রয়েছে এবং ফাইলের একেবারে উপরে নিচের কোডটি যোগ করি:
// interact.js
require("dotenv").config()
const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
const web3 = createAlchemyWeb3(alchemyKey)
//export const helloWorldContract;
উপরে, আমরা প্রথমে আমাদের .env ফাইল থেকে Alchemy কী ইমপোর্ট করেছি এবং তারপর আমাদের Alchemy Web3 এন্ডপয়েন্ট স্থাপন করতে createAlchemyWeb3-তে আমাদের alchemyKey পাস করেছি।
এই এন্ডপয়েন্টটি প্রস্তুত হওয়ার সাথে সাথে, এখন আমাদের স্মার্ট কন্ট্রাক্ট লোড করার সময়!
আপনার Hello World স্মার্ট কন্ট্রাক্ট লোড করা
আপনার Hello World স্মার্ট কন্ট্রাক্ট লোড করতে, আপনার এর কন্ট্রাক্ট ঠিকানা এবং ABI প্রয়োজন হবে, যার উভয়ই Etherscan-এ পাওয়া যাবে যদি আপনি এই টিউটোরিয়ালের পর্ব 3 সম্পন্ন করে থাকেন।
Etherscan থেকে কীভাবে আপনার কন্ট্রাক্ট ABI পাবেন
আপনি যদি এই টিউটোরিয়ালের পর্ব 3 এড়িয়ে গিয়ে থাকেন, তবে প্রথমে আপনার নিজস্ব HelloWorld কন্ট্রাক্ট ডিপ্লয় এবং ভেরিফাই করুন। তারপর এর ABI কপি করতে Sepolia Etherscan (একটি নতুন ট্যাবে খোলে)-এ আপনার কন্ট্রাক্ট পেজটি খুলুন।
একটি কন্ট্রাক্ট কোন ফাংশনটি ইনভোক করবে তা নির্দিষ্ট করার পাশাপাশি ফাংশনটি আপনার প্রত্যাশিত ফরম্যাটে ডেটা রিটার্ন করবে তা নিশ্চিত করার জন্য একটি কন্ট্রাক্ট ABI প্রয়োজনীয়। একবার আমরা আমাদের কন্ট্রাক্ট ABI কপি করার পর, চলুন এটিকে আপনার src ডিরেক্টরিতে contract-abi.json নামের একটি JSON ফাইল হিসেবে সেভ করি।
আপনার contract-abi.json ফাইলটি আপনার src ফোল্ডারে সংরক্ষণ করা উচিত।
আমাদের কন্ট্রাক্ট ঠিকানা, ABI এবং Alchemy Web3 এন্ডপয়েন্ট প্রস্তুত থাকার পর, আমরা আমাদের স্মার্ট কন্ট্রাক্টের একটি ইনস্ট্যান্স লোড করতে contract method (একটি নতুন ট্যাবে খোলে) ব্যবহার করতে পারি। interact.js ফাইলে আপনার কন্ট্রাক্ট ABI ইমপোর্ট করুন এবং আপনার কন্ট্রাক্ট ঠিকানা যোগ করুন।
// interact.js
const contractABI = require("../contract-abi.json")
// এখানে আপনার কন্ট্রাক্ট ঠিকানা ব্যবহার করুন
const contractAddress = "0x..."
আমরা এখন অবশেষে আমাদের helloWorldContract ভেরিয়েবলটি আনকমেন্ট করতে পারি এবং আমাদের AlchemyWeb3 এন্ডপয়েন্ট ব্যবহার করে স্মার্ট কন্ট্রাক্টটি লোড করতে পারি:
// interact.js
export const helloWorldContract = new web3.eth.Contract(
contractABI,
contractAddress
)
সংক্ষেপে বলতে গেলে, আপনার interact.js-এর প্রথম 12 লাইন এখন এরকম হওয়া উচিত:
// interact.js
require("dotenv").config()
const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY
const { createAlchemyWeb3 } = require("@alch/alchemy-web3")
const web3 = createAlchemyWeb3(alchemyKey)
const contractABI = require("../contract-abi.json")
const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A"
export const helloWorldContract = new web3.eth.Contract(
contractABI,
contractAddress
)
এখন যেহেতু আমাদের কন্ট্রাক্ট লোড করা হয়েছে, তাই আমরা আমাদের loadCurrentMessage ফাংশনটি ইমপ্লিমেন্ট করতে পারি!
আপনার interact.js ফাইলে loadCurrentMessage ইমপ্লিমেন্ট করা
এই ফাংশনটি খুবই সহজ। আমরা আমাদের কন্ট্রাক্ট থেকে পড়ার জন্য একটি সাধারণ async web3 কল করতে যাচ্ছি। আমাদের ফাংশনটি স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তাটি রিটার্ন করবে:
আপনার interact.js ফাইলে loadCurrentMessage-কে নিচের মতো আপডেট করুন:
// interact.js
export const loadCurrentMessage = async () => {
const message = await helloWorldContract.methods.message().call()
return message
}
যেহেতু আমরা আমাদের UI-তে এই স্মার্ট কন্ট্রাক্টটি প্রদর্শন করতে চাই, তাই চলুন আমাদের HelloWorld.js কম্পোনেন্টে useEffect ফাংশনটিকে নিচের মতো আপডেট করি:
// HelloWorld.js
//শুধুমাত্র একবার কল করা হয়
useEffect(async () => {
const message = await loadCurrentMessage()
setMessage(message)
}, [])
মনে রাখবেন, আমরা চাই আমাদের loadCurrentMessage শুধুমাত্র কম্পোনেন্টের প্রথম রেন্ডারের সময় একবার কল করা হোক। স্মার্ট কন্ট্রাক্টে বার্তা পরিবর্তন হওয়ার পরে স্বয়ংক্রিয়ভাবে UI আপডেট করতে আমরা শীঘ্রই addSmartContractListener ইমপ্লিমেন্ট করব।
আমাদের লিসেনারে প্রবেশ করার আগে, চলুন দেখে নিই এ পর্যন্ত আমাদের কী আছে! আপনার HelloWorld.js এবং interact.js ফাইলগুলো সেভ করুন এবং তারপর http://localhost:3000/ (একটি নতুন ট্যাবে খোলে)-এ যান
আপনি লক্ষ্য করবেন যে বর্তমান বার্তাটি আর "No connection to the network" বলছে না। এর পরিবর্তে এটি স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তাটি প্রতিফলিত করে। দারুণ!
আপনার UI এখন স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তাটি প্রতিফলিত করা উচিত
এখন সেই লিসেনারের কথা বলতে গেলে...
addSmartContractListener ইমপ্লিমেন্ট করুন
আপনি যদি এই টিউটোরিয়াল সিরিজের পর্ব 1-এ আমাদের লেখা HelloWorld.sol ফাইলটির কথা মনে করেন, তবে আপনার মনে পড়বে যে UpdatedMessages নামে একটি স্মার্ট কন্ট্রাক্ট ইভেন্ট রয়েছে যা আমাদের স্মার্ট কন্ট্রাক্টের update ফাংশন ইনভোক হওয়ার পরে এমিট হয় (লাইন 9 এবং 27 দেখুন):
// HelloWorld.sol
// সিম্যান্টিক ভার্সনিং ব্যবহার করে Solidity এর ভার্সন নির্দিষ্ট করে।
// আরও জানুন: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
pragma solidity ^0.7.3;
// `HelloWorld` নামের একটি কন্ট্রাক্ট ডিফাইন করে।
// একটি কন্ট্রাক্ট হলো ফাংশন এবং ডেটার (এর স্টেট) একটি সংগ্রহ। একবার ডিপ্লয় করা হলে, একটি কন্ট্রাক্ট ইথেরিয়াম ব্লকচেইন এর একটি নির্দিষ্ট ঠিকানায় অবস্থান করে। আরও জানুন: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
contract HelloWorld {
//আপডেট ফাংশন কল করা হলে এমিট হয়
//স্মার্ট কন্ট্রাক্ট ইভেন্টগুলি হলো আপনার কন্ট্রাক্ট এর জন্য ব্লকচেইন এ কিছু ঘটেছে তা আপনার অ্যাপ ফ্রন্ট-এন্ডকে জানানোর একটি উপায়, যা নির্দিষ্ট ইভেন্টগুলির জন্য 'লিসেন' করতে পারে এবং সেগুলি ঘটলে ব্যবস্থা নিতে পারে।
event UpdatedMessages(string oldStr, string newStr);
// `string` টাইপের একটি স্টেট ভেরিয়েবল `message` ডিক্লেয়ার করে।
// স্টেট ভেরিয়েবল হলো সেই ভেরিয়েবল যার মান স্থায়ীভাবে কন্ট্রাক্ট স্টোরেজে সংরক্ষিত থাকে। `public` কীওয়ার্ডটি ভেরিয়েবলগুলিকে একটি কন্ট্রাক্ট এর বাইরে থেকে অ্যাক্সেসযোগ্য করে তোলে এবং একটি ফাংশন তৈরি করে যা অন্যান্য কন্ট্রাক্ট বা ক্লায়েন্টরা মানটি অ্যাক্সেস করতে কল করতে পারে।
string public message;
// অনেক ক্লাস-ভিত্তিক অবজেক্ট-ওরিয়েন্টেড ভাষার মতো, কনস্ট্রাক্টর হলো একটি বিশেষ ফাংশন যা শুধুমাত্র কন্ট্রাক্ট তৈরির সময় এক্সিকিউট হয়।
// কনস্ট্রাক্টরগুলি কন্ট্রাক্ট এর ডেটা ইনিশিয়ালাইজ করতে ব্যবহৃত হয়। আরও জানুন:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
constructor(string memory initMessage) {
// একটি স্ট্রিং আর্গুমেন্ট `initMessage` গ্রহণ করে এবং মানটিকে কন্ট্রাক্ট এর `message` স্টোরেজ ভেরিয়েবলে সেট করে)।
message = initMessage;
}
// একটি পাবলিক ফাংশন যা একটি স্ট্রিং আর্গুমেন্ট গ্রহণ করে এবং `message` স্টোরেজ ভেরিয়েবল আপডেট করে।
function update(string memory newMessage) public {
string memory oldMsg = message;
message = newMessage;
emit UpdatedMessages(oldMsg, newMessage);
}
}
স্মার্ট কন্ট্রাক্ট ইভেন্টগুলো হলো আপনার কন্ট্রাক্টের জন্য ব্লকচেইনে কিছু ঘটেছে (অর্থাৎ, একটি ইভেন্ট ছিল) তা আপনার ফ্রন্ট-এন্ড অ্যাপ্লিকেশনে যোগাযোগ করার একটি উপায়, যা নির্দিষ্ট ইভেন্টগুলোর জন্য 'লিসেন' করতে পারে এবং সেগুলো ঘটলে ব্যবস্থা নিতে পারে।
আমাদের Hello World স্মার্ট কন্ট্রাক্টের UpdatedMessages ইভেন্টের জন্য addSmartContractListener ফাংশনটি বিশেষভাবে লিসেন করবে এবং নতুন বার্তাটি প্রদর্শন করতে আমাদের UI আপডেট করবে।
নিচের মতো করে addSmartContractListener পরিবর্তন করুন:
// HelloWorld.js
function addSmartContractListener() {
helloWorldContract.events.UpdatedMessages({}, (error, data) => {
if (error) {
setStatus("😥 " + error.message)
} else {
setMessage(data.returnValues[1])
setNewMessage("")
setStatus("🎉 Your message has been updated!")
}
})
}
লিসেনার যখন কোনো ইভেন্ট শনাক্ত করে তখন কী ঘটে তা চলুন ভেঙে দেখি:
- ইভেন্টটি এমিট হওয়ার সময় যদি কোনো ত্রুটি ঘটে, তবে এটি আমাদের
statusস্টেট ভেরিয়েবলের মাধ্যমে UI-তে প্রতিফলিত হবে। - অন্যথায়, আমরা রিটার্ন করা
dataঅবজেক্টটি ব্যবহার করব।data.returnValuesহলো শূন্যতে ইনডেক্স করা একটি অ্যারে যেখানে অ্যারের প্রথম উপাদানটি আগের বার্তাটি সংরক্ষণ করে এবং দ্বিতীয় উপাদানটি আপডেট করা বার্তাটি সংরক্ষণ করে। সব মিলিয়ে, একটি সফল ইভেন্টে আমরা আমাদেরmessageস্ট্রিংটিকে আপডেট করা বার্তায় সেট করব,newMessageস্ট্রিংটি ক্লিয়ার করব এবং আমাদের স্মার্ট কন্ট্রাক্টে একটি নতুন বার্তা পাবলিশ করা হয়েছে তা প্রতিফলিত করতে আমাদেরstatusস্টেট ভেরিয়েবল আপডেট করব।
অবশেষে, চলুন আমাদের useEffect ফাংশনে আমাদের লিসেনারকে কল করি যাতে এটি HelloWorld.js কম্পোনেন্টের প্রথম রেন্ডারে ইনিশিয়ালাইজ হয়। সব মিলিয়ে, আপনার useEffect ফাংশনটি দেখতে এরকম হওয়া উচিত:
// HelloWorld.js
useEffect(async () => {
const message = await loadCurrentMessage()
setMessage(message)
addSmartContractListener()
}, [])
এখন যেহেতু আমরা আমাদের স্মার্ট কন্ট্রাক্ট থেকে পড়তে সক্ষম, তাই কীভাবে এতে লিখতে হয় তা বের করতে পারলে দারুণ হবে! তবে, আমাদের dapp-এ লিখতে হলে, প্রথমে এর সাথে একটি ইথেরিয়াম ওয়ালেট কানেক্ট করা থাকতে হবে।
সুতরাং, এরপর আমরা আমাদের ইথেরিয়াম ওয়ালেট (মেটামাস্ক) সেট আপ করা এবং তারপর এটিকে আমাদের dapp-এর সাথে কানেক্ট করার বিষয়টি নিয়ে কাজ করব!
ধাপ 4: আপনার ইথেরিয়াম ওয়ালেট সেট আপ করুন
ইথেরিয়াম চেইনে কিছু লিখতে হলে, ব্যবহারকারীদের তাদের ভার্চুয়াল ওয়ালেটের প্রাইভেট কী ব্যবহার করে ট্রানজ্যাকশন সাইন করতে হবে। এই টিউটোরিয়ালের জন্য, আমরা মেটামাস্ক (একটি নতুন ট্যাবে খোলে) ব্যবহার করব, যা ব্রাউজারে একটি ভার্চুয়াল ওয়ালেট এবং আপনার ইথেরিয়াম অ্যাকাউন্ট ঠিকানা পরিচালনা করতে ব্যবহৃত হয়, কারণ এটি শেষ-ব্যবহারকারীর জন্য এই ট্রানজ্যাকশন সাইন করাকে খুব সহজ করে তোলে।
ইথেরিয়ামে ট্রানজ্যাকশন কীভাবে কাজ করে সে সম্পর্কে আপনি যদি আরও বুঝতে চান, তবে ইথেরিয়াম ফাউন্ডেশনের এই পেজটি দেখুন।
মেটামাস্ক ডাউনলোড করুন
আপনি এখান থেকে (একটি নতুন ট্যাবে খোলে) বিনামূল্যে মেটামাস্ক ডাউনলোড করে একটি অ্যাকাউন্ট তৈরি করতে পারেন। অ্যাকাউন্ট তৈরি করার সময়, অথবা আপনার যদি আগে থেকেই একটি অ্যাকাউন্ট থাকে, তবে উপরের ডানদিকের কোণায় “Sepolia টেস্ট নেটওয়ার্ক”-এ স্যুইচ করতে ভুলবেন না (যাতে আমাদের আসল টাকা নিয়ে কাজ করতে না হয়)।
একটি ফসেট থেকে ইথার যোগ করুন
ইথেরিয়াম ব্লকচেইনে একটি ট্রানজ্যাকশন সাইন করতে, আমাদের কিছু নকল ETH প্রয়োজন হবে। ETH পেতে আপনি টেস্ট নেটওয়ার্ক পেজে তালিকাভুক্ত একটি Sepolia ফসেটে যেতে পারেন এবং আপনার Sepolia অ্যাকাউন্ট ঠিকানা লিখতে পারেন। এর পরপরই আপনার মেটামাস্ক অ্যাকাউন্টে ETH দেখতে পাবেন!
আপনার ব্যালেন্স চেক করুন
আমাদের ব্যালেন্স সেখানে আছে কিনা তা নিশ্চিত করতে, চলুন Alchemy-এর স্যান্ডবক্স টুল (একটি নতুন ট্যাবে খোলে) ব্যবহার করে একটি eth_getBalance (একটি নতুন ট্যাবে খোলে) রিকোয়েস্ট করি। এটি আমাদের ওয়ালেটে থাকা ETH-এর পরিমাণ রিটার্ন করবে। আপনার মেটামাস্ক অ্যাকাউন্ট ঠিকানা ইনপুট করার পর এবং "Send Request"-এ ক্লিক করার পর, আপনার এরকম একটি রেসপন্স দেখা উচিত:
{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}
দ্রষ্টব্য: এই ফলাফলটি wei-তে আছে, ETH-এ নয়। Wei হলো ইথার-এর ক্ষুদ্রতম একক। wei থেকে ETH-এ রূপান্তর হলো: 1 ETH = 10¹⁸ wei। তাই আমরা যদি 0xde0b6b3a7640000-কে ডেসিমালে রূপান্তর করি তবে আমরা 1*10¹⁸ পাব যা 1 ETH-এর সমান।
যাক! আমাদের নকল টাকা সব সেখানেই আছে! 🤑
ধাপ 5: আপনার UI-এর সাথে মেটামাস্ক কানেক্ট করুন
এখন যেহেতু আমাদের মেটামাস্ক ওয়ালেট সেট আপ করা হয়েছে, চলুন আমাদের dapp-কে এর সাথে কানেক্ট করি!
connectWallet ফাংশন
আমাদের interact.js ফাইলে, চলুন connectWallet ফাংশনটি ইমপ্লিমেন্ট করি, যা আমরা পরে আমাদের HelloWorld.js কম্পোনেন্টে কল করতে পারি।
চলুন connectWallet-কে নিচের মতো পরিবর্তন করি:
// interact.js
export const connectWallet = async () => {
if (window.ethereum) {
try {
const addressArray = await window.ethereum.request({
method: "eth_requestAccounts",
})
const obj = {
status: "👆🏽 Write a message in the text-field above.",
address: addressArray[0],
}
return obj
} catch (err) {
return {
address: "",
status: "😥 " + err.message,
}
}
} else {
return {
address: "",
status: (
<span>
<p>
{" "}
🦊 <a target="_blank" href={`https://metamask.io/download`}>
You must install MetaMask, a virtual Ethereum wallet, in your
browser.
</a>
</p>
</span>
),
}
}
}
তাহলে কোডের এই বিশাল ব্লকটি আসলে কী করে?
প্রথমত, এটি চেক করে যে আপনার ব্রাউজারে window.ethereum এনাবল করা আছে কিনা।
window.ethereum হলো মেটামাস্ক এবং অন্যান্য ওয়ালেট প্রোভাইডারদের দ্বারা ইনজেক্ট করা একটি গ্লোবাল API যা ওয়েবসাইটগুলোকে ব্যবহারকারীদের ইথেরিয়াম অ্যাকাউন্টগুলোর জন্য রিকোয়েস্ট করার অনুমতি দেয়। যদি অনুমোদন করা হয়, তবে এটি ব্যবহারকারী যে ব্লকচেইনগুলোর সাথে কানেক্টেড আছে সেখান থেকে ডেটা পড়তে পারে এবং ব্যবহারকারীকে বার্তা ও ট্রানজ্যাকশন সাইন করার পরামর্শ দিতে পারে। আরও তথ্যের জন্য মেটামাস্ক ডক্স (একটি নতুন ট্যাবে খোলে) দেখুন!
যদি window.ethereum উপস্থিত না থাকে, তবে এর মানে হলো মেটামাস্ক ইনস্টল করা নেই। এর ফলে একটি JSON অবজেক্ট রিটার্ন করা হয়, যেখানে রিটার্ন করা address হলো একটি খালি স্ট্রিং, এবং status JSX অবজেক্টটি রিলে করে যে ব্যবহারকারীকে অবশ্যই মেটামাস্ক ইনস্টল করতে হবে।
এখন যদি window.ethereum উপস্থিত থাকে, তবে তখনই বিষয়টি আকর্ষণীয় হয়ে ওঠে।
একটি try/catch লুপ ব্যবহার করে, আমরা window.ethereum.request({ method: "eth_requestAccounts" }); (একটি নতুন ট্যাবে খোলে) কল করার মাধ্যমে মেটামাস্কের সাথে কানেক্ট করার চেষ্টা করব। এই ফাংশনটি কল করলে ব্রাউজারে মেটামাস্ক খুলবে, যার মাধ্যমে ব্যবহারকারীকে তাদের ওয়ালেট আপনার dapp-এর সাথে কানেক্ট করার জন্য প্রম্পট করা হবে।
- যদি ব্যবহারকারী কানেক্ট করা বেছে নেন, তবে
method: "eth_requestAccounts"একটি অ্যারে রিটার্ন করবে যাতে dapp-এর সাথে কানেক্ট করা ব্যবহারকারীর সমস্ত অ্যাকাউন্ট ঠিকানা থাকবে। সব মিলিয়ে, আমাদেরconnectWalletফাংশনটি একটি JSON অবজেক্ট রিটার্ন করবে যাতে এই অ্যারের প্রথমaddress(লাইন 9 দেখুন) এবং একটিstatusবার্তা থাকবে যা ব্যবহারকারীকে স্মার্ট কন্ট্রাক্টে একটি বার্তা লিখতে প্রম্পট করে। - যদি ব্যবহারকারী কানেকশনটি প্রত্যাখ্যান করেন, তবে JSON অবজেক্টটিতে রিটার্ন করা
address-এর জন্য একটি খালি স্ট্রিং এবং একটিstatusবার্তা থাকবে যা প্রতিফলিত করে যে ব্যবহারকারী কানেকশনটি প্রত্যাখ্যান করেছেন।
এখন যেহেতু আমরা এই connectWallet ফাংশনটি লিখেছি, পরবর্তী ধাপ হলো এটিকে আমাদের HelloWorld.js কম্পোনেন্টে কল করা।
আপনার HelloWorld.js UI কম্পোনেন্টে connectWallet ফাংশনটি যোগ করুন
HelloWorld.js-এ connectWalletPressed ফাংশনে নেভিগেট করুন এবং এটিকে নিচের মতো আপডেট করুন:
// HelloWorld.js
const connectWalletPressed = async () => {
const walletResponse = await connectWallet()
setStatus(walletResponse.status)
setWallet(walletResponse.address)
}
লক্ষ্য করেছেন কীভাবে আমাদের বেশিরভাগ কার্যকারিতা interact.js ফাইল থেকে আমাদের HelloWorld.js কম্পোনেন্ট থেকে অ্যাবস্ট্রাক্ট করা হয়েছে? এটি করা হয়েছে যাতে আমরা M-V-C প্যারাডাইম মেনে চলি!
connectWalletPressed-এ, আমরা কেবল আমাদের ইমপোর্ট করা connectWallet ফাংশনে একটি await কল করি এবং এর রেসপন্স ব্যবহার করে, আমরা তাদের স্টেট হুকগুলোর মাধ্যমে আমাদের status এবং walletAddress ভেরিয়েবলগুলো আপডেট করি।
এখন, চলুন উভয় ফাইল (HelloWorld.js এবং interact.js) সেভ করি এবং এ পর্যন্ত আমাদের UI পরীক্ষা করে দেখি।
http://localhost:3000/ (একটি নতুন ট্যাবে খোলে) পেজে আপনার ব্রাউজার খুলুন এবং পেজের উপরের ডানদিকে "Connect Wallet" বোতাম টিপুন।
যদি আপনার মেটামাস্ক ইনস্টল করা থাকে, তবে আপনাকে আপনার ওয়ালেটটি আপনার dapp-এর সাথে কানেক্ট করার জন্য প্রম্পট করা উচিত। কানেক্ট করার আমন্ত্রণটি গ্রহণ করুন।
আপনার দেখা উচিত যে ওয়ালেট বোতামটি এখন প্রতিফলিত করছে যে আপনার ঠিকানাটি কানেক্ট করা হয়েছে! দারুণ 🔥
এরপর, পেজটি রিফ্রেশ করার চেষ্টা করুন... এটি অদ্ভুত। আমাদের ওয়ালেট বোতামটি আমাদের মেটামাস্ক কানেক্ট করতে প্রম্পট করছে, যদিও এটি আগে থেকেই কানেক্ট করা আছে...
তবে, ভয় পাবেন না! আমরা সহজেই getCurrentWalletConnected ইমপ্লিমেন্ট করে এর সমাধান করতে পারি, যা চেক করবে যে কোনো ঠিকানা আগে থেকেই আমাদের dapp-এর সাথে কানেক্ট করা আছে কিনা এবং সেই অনুযায়ী আমাদের UI আপডেট করবে!
getCurrentWalletConnected ফাংশন
interact.js ফাইলে আপনার getCurrentWalletConnected ফাংশনটিকে নিচের মতো আপডেট করুন:
// interact.js
export const getCurrentWalletConnected = async () => {
if (window.ethereum) {
try {
const addressArray = await window.ethereum.request({
method: "eth_accounts",
})
if (addressArray.length > 0) {
return {
address: addressArray[0],
status: "👆🏽 Write a message in the text-field above.",
}
} else {
return {
address: "",
status: "🦊 Connect to MetaMask using the top right button.",
}
}
} catch (err) {
return {
address: "",
status: "😥 " + err.message,
}
}
} else {
return {
address: "",
status: (
<span>
<p>
{" "}
🦊 <a target="_blank" href={`https://metamask.io/download`}>
You must install MetaMask, a virtual Ethereum wallet, in your
browser.
</a>
</p>
</span>
),
}
}
}
এই কোডটি আগের ধাপে আমাদের লেখা connectWallet ফাংশনের খুবই কাছাকাছি।
প্রধান পার্থক্য হলো যে eth_requestAccounts মেথড কল করার পরিবর্তে, যা ব্যবহারকারীর ওয়ালেট কানেক্ট করার জন্য মেটামাস্ক খোলে, এখানে আমরা eth_accounts মেথড কল করি, যা কেবল বর্তমানে আমাদের dapp-এর সাথে কানেক্ট করা মেটামাস্ক ঠিকানাগুলো ধারণকারী একটি অ্যারে রিটার্ন করে।
এই ফাংশনটি কাজ করতে দেখতে, চলুন এটিকে আমাদের HelloWorld.js কম্পোনেন্টের useEffect ফাংশনে কল করি:
// HelloWorld.js
useEffect(async () => {
const message = await loadCurrentMessage()
setMessage(message)
addSmartContractListener()
const { address, status } = await getCurrentWalletConnected()
setWallet(address)
setStatus(status)
}, [])
লক্ষ্য করুন, আমরা আমাদের walletAddress এবং status স্টেট ভেরিয়েবলগুলো আপডেট করতে getCurrentWalletConnected-এ আমাদের কলের রেসপন্স ব্যবহার করি।
এখন যেহেতু আপনি এই কোডটি যোগ করেছেন, চলুন আমাদের ব্রাউজার উইন্ডোটি রিফ্রেশ করার চেষ্টা করি।
চমৎকার! বোতামটিতে বলা উচিত যে আপনি কানেক্টেড, এবং আপনার কানেক্ট করা ওয়ালেটের ঠিকানার একটি প্রিভিউ দেখানো উচিত - এমনকি আপনি রিফ্রেশ করার পরেও!
addWalletListener ইমপ্লিমেন্ট করুন
আমাদের dapp ওয়ালেট সেটআপের চূড়ান্ত ধাপ হলো ওয়ালেট লিসেনার ইমপ্লিমেন্ট করা যাতে আমাদের ওয়ালেটের স্টেট পরিবর্তন হলে আমাদের UI আপডেট হয়, যেমন যখন ব্যবহারকারী ডিসকানেক্ট করে বা অ্যাকাউন্ট পরিবর্তন করে।
আপনার HelloWorld.js ফাইলে, আপনার addWalletListener ফাংশনটিকে নিচের মতো পরিবর্তন করুন:
// HelloWorld.js
function addWalletListener() {
if (window.ethereum) {
window.ethereum.on("accountsChanged", (accounts) => {
if (accounts.length > 0) {
setWallet(accounts[0])
setStatus("👆🏽 Write a message in the text-field above.")
} else {
setWallet("")
setStatus("🦊 Connect to MetaMask using the top right button.")
}
})
} else {
setStatus(
<p>
{" "}
🦊 <a target="_blank" href={`https://metamask.io/download`}>
You must install MetaMask, a virtual Ethereum wallet, in your browser.
</a>
</p>
)
}
}
আমি নিশ্চিত যে এই পর্যায়ে এখানে কী ঘটছে তা বুঝতে আপনার আমাদের সাহায্যেরও প্রয়োজন নেই, তবে পুঙ্খানুপুঙ্খতার উদ্দেশ্যে, চলুন এটি দ্রুত ভেঙে দেখি:
- প্রথমে, আমাদের ফাংশন চেক করে যে
window.ethereumএনাবল করা আছে কিনা (অর্থাৎ, মেটামাস্ক ইনস্টল করা আছে কিনা)।- যদি না থাকে, তবে আমরা কেবল আমাদের
statusস্টেট ভেরিয়েবলটিকে একটি JSX স্ট্রিংয়ে সেট করি যা ব্যবহারকারীকে মেটামাস্ক ইনস্টল করতে প্রম্পট করে। - যদি এটি এনাবল করা থাকে, তবে আমরা 3 লাইনে
window.ethereum.on("accountsChanged")লিসেনার সেট আপ করি যা মেটামাস্ক ওয়ালেটে স্টেট পরিবর্তনের জন্য লিসেন করে, যার মধ্যে রয়েছে যখন ব্যবহারকারী dapp-এর সাথে একটি অতিরিক্ত অ্যাকাউন্ট কানেক্ট করে, অ্যাকাউন্ট পরিবর্তন করে বা একটি অ্যাকাউন্ট ডিসকানেক্ট করে। যদি অন্তত একটি অ্যাকাউন্ট কানেক্ট করা থাকে, তবেwalletAddressস্টেট ভেরিয়েবলটি লিসেনার দ্বারা রিটার্ন করাaccountsঅ্যারের প্রথম অ্যাকাউন্ট হিসেবে আপডেট করা হয়। অন্যথায়,walletAddressএকটি খালি স্ট্রিং হিসেবে সেট করা হয়।
- যদি না থাকে, তবে আমরা কেবল আমাদের
সবশেষে, আমাদের অবশ্যই এটিকে আমাদের useEffect ফাংশনে কল করতে হবে:
// HelloWorld.js
useEffect(async () => {
const message = await loadCurrentMessage()
setMessage(message)
addSmartContractListener()
const { address, status } = await getCurrentWalletConnected()
setWallet(address)
setStatus(status)
addWalletListener()
}, [])
এবং এটাই! আমরা সফলভাবে আমাদের সমস্ত ওয়ালেট কার্যকারিতা প্রোগ্রামিং সম্পন্ন করেছি! এখন আমাদের শেষ কাজ: আমাদের স্মার্ট কন্ট্রাক্টে সংরক্ষিত বার্তা আপডেট করা!
ধাপ 6: updateMessage ফাংশন ইমপ্লিমেন্ট করুন
ঠিক আছে বন্ধুরা, আমরা শেষ পর্যায়ে পৌঁছে গেছি! আপনার interact.js ফাইলের updateMessage-এ, আমরা নিচের কাজগুলো করতে যাচ্ছি:
- নিশ্চিত করুন যে আমরা আমাদের স্মার্ট কন্ট্রাক্টে যে বার্তাটি পাবলিশ করতে চাই তা বৈধ
- মেটামাস্ক ব্যবহার করে আমাদের ট্রানজ্যাকশন সাইন করুন
- আমাদের
HelloWorld.jsফ্রন্টএন্ড কম্পোনেন্ট থেকে এই ফাংশনটি কল করুন
এতে খুব বেশি সময় লাগবে না; চলুন এই dapp-টি শেষ করি!
ইনপুট এরর হ্যান্ডলিং
স্বাভাবিকভাবেই, ফাংশনের শুরুতে কোনো ধরনের ইনপুট এরর হ্যান্ডলিং থাকাটা যৌক্তিক।
আমরা চাইব আমাদের ফাংশনটি তাড়াতাড়ি রিটার্ন করুক যদি কোনো মেটামাস্ক এক্সটেনশন ইনস্টল করা না থাকে, কোনো ওয়ালেট কানেক্ট করা না থাকে (অর্থাৎ, পাস করা address একটি খালি স্ট্রিং), অথবা message একটি খালি স্ট্রিং হয়। চলুন updateMessage-এ নিচের এরর হ্যান্ডলিং যোগ করি:
// interact.js
export const updateMessage = async (address, message) => {
if (!window.ethereum || address === null) {
return {
status:
"💡 Connect your MetaMask wallet to update the message on the blockchain.",
}
}
if (message.trim() === "") {
return {
status: "❌ Your message cannot be an empty string.",
}
}
}
এখন যেহেতু এতে সঠিক ইনপুট এরর হ্যান্ডলিং রয়েছে, তাই মেটামাস্কের মাধ্যমে ট্রানজ্যাকশন সাইন করার সময় এসেছে!
আমাদের ট্রানজ্যাকশন সাইন করা
আপনি যদি আগে থেকেই প্রথাগত Web3 ইথেরিয়াম ট্রানজ্যাকশনগুলোর সাথে স্বাচ্ছন্দ্যবোধ করেন, তবে আমরা পরবর্তীতে যে কোডটি লিখব তা খুব পরিচিত হবে। আপনার ইনপুট এরর হ্যান্ডলিং কোডের নিচে, updateMessage-এ নিচের কোডটি যোগ করুন:
// interact.js
//ট্রানজ্যাকশন প্যারামিটার সেট আপ করুন
const transactionParameters = {
to: contractAddress, // কন্ট্রাক্ট পাবলিকেশনের সময় ছাড়া প্রয়োজনীয়।
from: address, // অবশ্যই ব্যবহারকারীর সক্রিয় ঠিকানার সাথে মিলতে হবে।
data: helloWorldContract.methods.update(message).encodeABI(),
}
//ট্রানজ্যাকশন সাইন করুন
try {
const txHash = await window.ethereum.request({
method: "eth_sendTransaction",
params: [transactionParameters],
})
return {
status: (
<span>
✅{" "}
<a target="_blank" href={`https://goerli.etherscan.io/tx/${txHash}`}>
View the status of your transaction on Etherscan!
</a>
<br />
ℹ️ Once the transaction is verified by the network, the message will be
updated automatically.
</span>
),
}
} catch (error) {
return {
status: "😥 " + error.message,
}
}
চলুন ভেঙে দেখি কী ঘটছে। প্রথমে, আমরা আমাদের ট্রানজ্যাকশন প্যারামিটারগুলো সেট আপ করি, যেখানে:
toপ্রাপকের ঠিকানা (আমাদের স্মার্ট কন্ট্রাক্ট) নির্দিষ্ট করেfromট্রানজ্যাকশনের সাইনার নির্দিষ্ট করে,addressভেরিয়েবল যা আমরা আমাদের ফাংশনে পাস করেছিdata-তে আমাদের Hello World স্মার্ট কন্ট্রাক্টেরupdateমেথডের কল রয়েছে, যা ইনপুট হিসেবে আমাদেরmessageস্ট্রিং ভেরিয়েবল গ্রহণ করে
তারপর, আমরা একটি await কল করি, window.ethereum.request, যেখানে আমরা মেটামাস্ককে ট্রানজ্যাকশনটি সাইন করতে বলি। লক্ষ্য করুন, 11 এবং 12 লাইনে, আমরা আমাদের eth মেথড, eth_sendTransaction নির্দিষ্ট করছি এবং আমাদের transactionParameters পাস করছি।
এই পর্যায়ে, ব্রাউজারে মেটামাস্ক খুলবে এবং ব্যবহারকারীকে ট্রানজ্যাকশনটি সাইন বা প্রত্যাখ্যান করতে প্রম্পট করবে।
- যদি ট্রানজ্যাকশনটি সফল হয়, তবে ফাংশনটি একটি JSON অবজেক্ট রিটার্ন করবে যেখানে
statusJSX স্ট্রিং ব্যবহারকারীকে তাদের ট্রানজ্যাকশন সম্পর্কে আরও তথ্যের জন্য Etherscan চেক করতে প্রম্পট করে। - যদি ট্রানজ্যাকশনটি ব্যর্থ হয়, তবে ফাংশনটি একটি JSON অবজেক্ট রিটার্ন করবে যেখানে
statusস্ট্রিংটি এরর মেসেজ রিলে করে।
সব মিলিয়ে, আমাদের updateMessage ফাংশনটি দেখতে এরকম হওয়া উচিত:
// interact.js
export const updateMessage = async (address, message) => {
//ইনপুট এরর হ্যান্ডলিং
if (!window.ethereum || address === null) {
return {
status:
"💡 Connect your MetaMask wallet to update the message on the blockchain.",
}
}
if (message.trim() === "") {
return {
status: "❌ Your message cannot be an empty string.",
}
}
//ট্রানজ্যাকশন প্যারামিটার সেট আপ করুন
const transactionParameters = {
to: contractAddress, // কন্ট্রাক্ট পাবলিকেশনের সময় ছাড়া প্রয়োজনীয়।
from: address, // অবশ্যই ব্যবহারকারীর সক্রিয় ঠিকানার সাথে মিলতে হবে।
data: helloWorldContract.methods.update(message).encodeABI(),
}
//ট্রানজ্যাকশন সাইন করুন
try {
const txHash = await window.ethereum.request({
method: "eth_sendTransaction",
params: [transactionParameters],
})
return {
status: (
<span>
✅{" "}
<a target="_blank" href={`https://goerli.etherscan.io/tx/${txHash}`}>
View the status of your transaction on Etherscan!
</a>
<br />
ℹ️ Once the transaction is verified by the network, the message will
be updated automatically.
</span>
),
}
} catch (error) {
return {
status: "😥 " + error.message,
}
}
}
সবশেষে, আমাদের updateMessage ফাংশনটিকে আমাদের HelloWorld.js কম্পোনেন্টের সাথে কানেক্ট করতে হবে।
HelloWorld.js ফ্রন্টএন্ডের সাথে updateMessage কানেক্ট করুন
আমাদের onUpdatePressed ফাংশনটির ইমপোর্ট করা updateMessage ফাংশনে একটি await কল করা উচিত এবং আমাদের ট্রানজ্যাকশন সফল হয়েছে নাকি ব্যর্থ হয়েছে তা প্রতিফলিত করতে status স্টেট ভেরিয়েবল পরিবর্তন করা উচিত:
// HelloWorld.js
const onUpdatePressed = async () => {
const { status } = await updateMessage(walletAddress, newMessage)
setStatus(status)
}
এটি অত্যন্ত পরিচ্ছন্ন এবং সহজ। এবং জানেন কি... আপনার DAPP সম্পূর্ণ!!!
এগিয়ে যান এবং Update বোতামটি পরীক্ষা করে দেখুন!
আপনার নিজস্ব কাস্টম dapp তৈরি করুন
দারুণ, আপনি টিউটোরিয়ালের শেষে পৌঁছে গেছেন! সংক্ষেপে বলতে গেলে, আপনি শিখেছেন কীভাবে:
- আপনার dapp প্রজেক্টের সাথে একটি মেটামাস্ক ওয়ালেট কানেক্ট করতে হয়
- Alchemy Web3 (একটি নতুন ট্যাবে খোলে) API ব্যবহার করে আপনার স্মার্ট কন্ট্রাক্ট থেকে ডেটা পড়তে হয়
- মেটামাস্ক ব্যবহার করে ইথেরিয়াম ট্রানজ্যাকশন সাইন করতে হয়
এখন আপনি আপনার নিজস্ব কাস্টম dapp প্রজেক্ট তৈরি করতে এই টিউটোরিয়াল থেকে শেখা দক্ষতাগুলো প্রয়োগ করতে পুরোপুরি প্রস্তুত! বরাবরের মতো, আপনার যদি কোনো প্রশ্ন থাকে, তবে সাহায্যের জন্য Alchemy ডিসকর্ড (একটি নতুন ট্যাবে খোলে)-এ আমাদের সাথে যোগাযোগ করতে দ্বিধা করবেন না। 🧙♂️
একবার আপনি এই টিউটোরিয়ালটি সম্পন্ন করার পর, টুইটারে @alchemyplatform (একটি নতুন ট্যাবে খোলে)-এ আমাদের ট্যাগ করে আপনার অভিজ্ঞতা কেমন ছিল বা আপনার কোনো মতামত থাকলে তা আমাদের জানান!




