Web3 ব্যবহার করে ট্রানজ্যাকশন পাঠানো
এটি Web3 ব্যবহার করে ইথেরিয়াম ট্রানজ্যাকশন পাঠানোর জন্য একটি শিক্ষানবিস-বান্ধব গাইড। ইথেরিয়াম ব্লকচেইনে একটি ট্রানজ্যাকশন পাঠানোর জন্য তিনটি প্রধান ধাপ রয়েছে: তৈরি করা, স্বাক্ষরকরণ এবং সম্প্রচার করা। আমরা এই তিনটি ধাপ নিয়েই আলোচনা করব, আশা করি আপনার যেকোনো প্রশ্নের উত্তর দিতে পারব! এই টিউটোরিয়ালে, আমরা ইথেরিয়াম চেইনে আমাদের ট্রানজ্যাকশন পাঠাতে Alchemy (একটি নতুন ট্যাবে খোলে) ব্যবহার করব। আপনি এখানে একটি বিনামূল্যের Alchemy অ্যাকাউন্ট তৈরি করতে পারেন (একটি নতুন ট্যাবে খোলে)।
নোট: এই গাইডটি আপনার অ্যাপের ব্যাকএন্ডে আপনার ট্রানজ্যাকশন স্বাক্ষরকরণের জন্য। আপনি যদি ফ্রন্টএন্ডে আপনার ট্রানজ্যাকশন স্বাক্ষরকরণ ইন্টিগ্রেট করতে চান, তবে ব্রাউজার প্রোভাইডারের সাথে Web3 (একটি নতুন ট্যাবে খোলে) ইন্টিগ্রেট করার বিষয়টি দেখুন।
বেসিক বিষয়গুলো
বেশিরভাগ ব্লকচেইন ডেভেলপারদের মতো যখন তারা প্রথম শুরু করে, আপনি হয়তো কীভাবে একটি ট্রানজ্যাকশন পাঠাতে হয় (যা বেশ সহজ হওয়া উচিত) তা নিয়ে কিছু গবেষণা করেছেন এবং প্রচুর গাইডের সম্মুখীন হয়েছেন, যার প্রতিটি ভিন্ন ভিন্ন কথা বলছে এবং আপনাকে কিছুটা অভিভূত ও বিভ্রান্ত করে তুলেছে। আপনি যদি সেই পরিস্থিতিতে থাকেন, তবে চিন্তা করবেন না; আমরা সবাই কোনো না কোনো সময় সেখানে ছিলাম! তাই, শুরু করার আগে, আসুন কয়েকটি বিষয় পরিষ্কার করে নিই:
1. Alchemy আপনার প্রাইভেট কী সংরক্ষণ করে না
- এর মানে হলো Alchemy আপনার পক্ষে ট্রানজ্যাকশন স্বাক্ষরকরণ এবং পাঠাতে পারে না। এর কারণ হলো নিরাপত্তার উদ্দেশ্য। Alchemy কখনোই আপনাকে আপনার প্রাইভেট কী শেয়ার করতে বলবে না, এবং আপনার কখনোই কোনো হোস্টেড নোড (বা সেই ক্ষেত্রে অন্য কারো) সাথে আপনার প্রাইভেট কী শেয়ার করা উচিত নয়।
- আপনি Alchemy-এর কোর API ব্যবহার করে ব্লকচেইন থেকে পড়তে পারেন, কিন্তু এতে লিখতে হলে Alchemy-এর মাধ্যমে পাঠানোর আগে আপনার ট্রানজ্যাকশন স্বাক্ষরকরণের জন্য অন্য কিছু ব্যবহার করতে হবে (এটি অন্য যেকোনো নোড সার্ভিসের ক্ষেত্রেও একই)।
2. "সাইনার" (signer) কী?
- সাইনার আপনার প্রাইভেট কী ব্যবহার করে আপনার জন্য ট্রানজ্যাকশন স্বাক্ষরকরণ করবে। এই টিউটোরিয়ালে আমরা আমাদের ট্রানজ্যাকশন স্বাক্ষরকরণ করতে Alchemy Web3 (একটি নতুন ট্যাবে খোলে) ব্যবহার করব, তবে আপনি অন্য যেকোনো Web3 লাইব্রেরিও ব্যবহার করতে পারেন।
- ফ্রন্টএন্ডে, সাইনারের একটি ভালো উদাহরণ হতে পারে মেটামাস্ক (একটি নতুন ট্যাবে খোলে), যা আপনার পক্ষে ট্রানজ্যাকশন স্বাক্ষরকরণ করবে এবং পাঠাবে।
3. কেন আমার ট্রানজ্যাকশন স্বাক্ষরকরণ করতে হবে?
- ইথেরিয়াম নেটওয়ার্কে ট্রানজ্যাকশন পাঠাতে চাওয়া প্রত্যেক ব্যবহারকারীকে অবশ্যই ট্রানজ্যাকশনটি স্বাক্ষরকরণ করতে হবে (তাদের প্রাইভেট কী ব্যবহার করে), যাতে ট্রানজ্যাকশনের উৎসটি যা দাবি করছে তা যাচাই করা যায়।
- এই প্রাইভেট কী সুরক্ষিত রাখা অত্যন্ত গুরুত্বপূর্ণ, কারণ এতে অ্যাক্সেস থাকলে আপনার ইথেরিয়াম অ্যাকাউন্টের ওপর সম্পূর্ণ নিয়ন্ত্রণ পাওয়া যায়, যা আপনাকে (বা অ্যাক্সেস থাকা যে কাউকে) আপনার পক্ষে ট্রানজ্যাকশন করার অনুমতি দেয়।
4. আমি কীভাবে আমার প্রাইভেট কী সুরক্ষিত রাখব?
- আপনার প্রাইভেট কী সুরক্ষিত রাখার এবং ট্রানজ্যাকশন পাঠানোর জন্য এটি ব্যবহার করার অনেক উপায় রয়েছে। এই টিউটোরিয়ালে আমরা একটি
.envফাইল ব্যবহার করব। তবে, আপনি প্রাইভেট কী সংরক্ষণ করে এমন একটি আলাদা প্রোভাইডার ব্যবহার করতে পারেন, একটি কীস্টোর ফাইল ব্যবহার করতে পারেন, বা অন্যান্য বিকল্পও ব্যবহার করতে পারেন।
5. eth_sendTransaction এবং eth_sendRawTransaction এর মধ্যে পার্থক্য কী?
eth_sendTransaction এবং eth_sendRawTransaction উভয়ই ইথেরিয়াম API ফাংশন যা ইথেরিয়াম নেটওয়ার্কে একটি ট্রানজ্যাকশন সম্প্রচার করে যাতে এটি ভবিষ্যতের কোনো ব্লকে যুক্ত হয়। ট্রানজ্যাকশন স্বাক্ষরকরণ কীভাবে পরিচালনা করে তার ওপর ভিত্তি করে এদের মধ্যে পার্থক্য রয়েছে।
eth_sendTransaction(একটি নতুন ট্যাবে খোলে) স্বাক্ষরবিহীন ট্রানজ্যাকশন পাঠানোর জন্য ব্যবহৃত হয়, যার মানে হলো আপনি যে নোডে পাঠাচ্ছেন তাকে অবশ্যই আপনার প্রাইভেট কী পরিচালনা করতে হবে যাতে এটি চেইনে সম্প্রচার করার আগে ট্রানজ্যাকশনটি স্বাক্ষরকরণ করতে পারে। যেহেতু Alchemy ব্যবহারকারীর প্রাইভেট কী রাখে না, তাই তারা এই পদ্ধতি সমর্থন করে না।eth_sendRawTransaction(একটি নতুন ট্যাবে খোলে) এমন ট্রানজ্যাকশন সম্প্রচার করতে ব্যবহৃত হয় যা ইতিমধ্যে স্বাক্ষর করা হয়েছে। এর মানে হলো আপনাকে প্রথমেsignTransaction(tx, private_key)(একটি নতুন ট্যাবে খোলে) ব্যবহার করতে হবে, তারপর ফলাফলটিeth_sendRawTransaction-এ পাস করতে হবে।
Web3 ব্যবহার করার সময়, web3.eth.sendSignedTransaction (একটি নতুন ট্যাবে খোলে) ফাংশন কল করে eth_sendRawTransaction অ্যাক্সেস করা হয়।
এই টিউটোরিয়ালে আমরা এটিই ব্যবহার করব।
6. Web3 লাইব্রেরি কী?
- Web3.js হলো স্ট্যান্ডার্ড জেসন-আরপিসি কলগুলোর চারপাশে একটি র্যাপার লাইব্রেরি যা ইথেরিয়াম ডেভেলপমেন্টে ব্যবহার করা বেশ সাধারণ।
- বিভিন্ন ভাষার জন্য অনেক Web3 লাইব্রেরি রয়েছে। এই টিউটোরিয়ালে আমরা Alchemy Web3 (একটি নতুন ট্যাবে খোলে) ব্যবহার করব যা JavaScript-এ লেখা। আপনি এখানে অন্যান্য বিকল্পগুলো দেখতে পারেন যেমন Ethers.js (একটি নতুন ট্যাবে খোলে)।
ঠিক আছে, এখন যেহেতু আমরা এই কয়েকটি প্রশ্নের উত্তর পেয়ে গেছি, আসুন টিউটোরিয়ালে এগিয়ে যাই। Alchemy ডিসকর্ড (একটি নতুন ট্যাবে খোলে)-এ যেকোনো সময় প্রশ্ন করতে দ্বিধা করবেন না!
7. কীভাবে সুরক্ষিত, গ্যাস-অপ্টিমাইজড এবং প্রাইভেট ট্রানজ্যাকশন পাঠাবেন?
- Alchemy-এর ট্রানজ্যাকশন রিসোর্সের একটি সেট রয়েছে (একটি নতুন ট্যাবে খোলে)। আপনি এগুলো ব্যবহার করে ট্রানজ্যাকশন পাঠাতে, ট্রানজ্যাকশন ঘটার আগে সিমুলেট করতে, প্রাইভেট ট্রানজ্যাকশন পাঠাতে এবং গ্যাস-অপ্টিমাইজড ট্রানজ্যাকশন পাঠাতে পারেন।
- আপনার ট্রানজ্যাকশন মেমপুল থেকে টেনে নিয়ে চেইনে যুক্ত করার সময় সতর্ক হতে আপনি Alchemy ওয়েবহুক (একটি নতুন ট্যাবে খোলে) ব্যবহার করতে পারেন।
নোট: এই গাইডের জন্য একটি Alchemy অ্যাকাউন্ট, একটি ইথেরিয়াম ঠিকানা বা মেটামাস্ক ওয়ালেট, Node.js এবং npm ইনস্টল করা প্রয়োজন। যদি না থাকে, তবে এই ধাপগুলো অনুসরণ করুন:
- একটি বিনামূল্যের Alchemy অ্যাকাউন্ট তৈরি করুন (একটি নতুন ট্যাবে খোলে)
- মেটামাস্ক অ্যাকাউন্ট তৈরি করুন (একটি নতুন ট্যাবে খোলে) (বা একটি ইথেরিয়াম ঠিকানা পান)
- Node.js এবং npm ইনস্টল করুন (একটি নতুন ট্যাবে খোলে)
আপনার ট্রানজ্যাকশন পাঠানোর ধাপসমূহ
1. Sepolia টেস্টনেটে একটি Alchemy অ্যাপ তৈরি করুন
আপনার Alchemy ড্যাশবোর্ডে (একটি নতুন ট্যাবে খোলে) যান এবং আপনার নেটওয়ার্কের জন্য Sepolia (বা অন্য কোনো টেস্টনেট) বেছে নিয়ে একটি নতুন অ্যাপ তৈরি করুন।
2. Sepolia ফসেট থেকে ETH-এর অনুরোধ করুন
ETH পেতে Alchemy Sepolia ফসেট (একটি নতুন ট্যাবে খোলে)-এর নির্দেশাবলী অনুসরণ করুন। নিশ্চিত করুন যে আপনি আপনার Sepolia ইথেরিয়াম ঠিকানা (মেটামাস্ক থেকে) অন্তর্ভুক্ত করেছেন এবং অন্য কোনো নেটওয়ার্ক নয়। নির্দেশাবলী অনুসরণ করার পর, আপনার ওয়ালেটে ETH পেয়েছেন কিনা তা দুবার চেক করুন।
3. একটি নতুন প্রজেক্ট ডিরেক্টরি তৈরি করুন এবং এতে cd করুন
কমান্ড লাইন (ম্যাকের জন্য টার্মিনাল) থেকে একটি নতুন প্রজেক্ট ডিরেক্টরি তৈরি করুন এবং এতে নেভিগেট করুন:
mkdir sendtx-example
cd sendtx-example
4. Alchemy Web3 (বা যেকোনো Web3 লাইব্রেরি) ইনস্টল করুন
Alchemy Web3 (একটি নতুন ট্যাবে খোলে) ইনস্টল করতে আপনার প্রজেক্ট ডিরেক্টরিতে নিচের কমান্ডটি রান করুন:
মনে রাখবেন, আপনি যদি Ethers.js লাইব্রেরি ব্যবহার করতে চান, তবে এখানকার নির্দেশাবলী অনুসরণ করুন (একটি নতুন ট্যাবে খোলে)।
npm install @alch/alchemy-web3
5. dotenv ইনস্টল করুন
আমরা আমাদের API কী এবং প্রাইভেট কী নিরাপদে সংরক্ষণ করতে একটি .env ফাইল ব্যবহার করব।
npm install dotenv --save
6. .env ফাইল তৈরি করুন
আপনার প্রজেক্ট ডিরেক্টরিতে একটি .env ফাইল তৈরি করুন এবং নিচের অংশটি যোগ করুন ("your-api-url" এবং "your-private-key" প্রতিস্থাপন করে)
- আপনার Alchemy API URL খুঁজে পেতে, আপনার ড্যাশবোর্ডে সদ্য তৈরি করা অ্যাপের অ্যাপ ডিটেইলস পেজে যান, উপরের ডানদিকের কোণায় "View Key"-এ ক্লিক করুন এবং HTTP URL-টি সংগ্রহ করুন।
- মেটামাস্ক ব্যবহার করে আপনার প্রাইভেট কী খুঁজে পেতে, এই গাইডটি (একটি নতুন ট্যাবে খোলে) দেখুন।
API_URL = "your-api-url"
PRIVATE_KEY = "your-private-key"
.env কমিট করবেন না! অনুগ্রহ করে নিশ্চিত করুন যে আপনি কখনোই আপনার .env ফাইলটি কারো সাথে শেয়ার বা প্রকাশ করবেন না, কারণ এমনটি করলে আপনি আপনার গোপনীয়তা বিপন্ন করছেন। আপনি যদি ভার্সন কন্ট্রোল ব্যবহার করেন, তবে আপনার .env-কে একটি gitignore ফাইলে যুক্ত করুন।7. sendTx.js ফাইল তৈরি করুন
চমৎকার, এখন যেহেতু আমাদের সংবেদনশীল ডেটা একটি .env ফাইলে সুরক্ষিত আছে, আসুন কোডিং শুরু করি। আমাদের ট্রানজ্যাকশন পাঠানোর উদাহরণের জন্য, আমরা Sepolia ফসেটে ETH ফেরত পাঠাব।
একটি sendTx.js ফাইল তৈরি করুন, যেখানে আমরা আমাদের উদাহরণ ট্রানজ্যাকশনটি কনফিগার করব এবং পাঠাব, এবং এতে নিচের কোডগুলো যোগ করুন:
async function main() {
require('dotenv').config();
const { API_URL, PRIVATE_KEY } = process.env;
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(API_URL);
const myAddress = '0x610Ae88399fc1687FA7530Aac28eC2539c7d6d63' //TODO: এই ঠিকানাটি আপনার নিজস্ব পাবলিক ঠিকানা দিয়ে প্রতিস্থাপন করুন
const nonce = await web3.eth.getTransactionCount(myAddress, 'latest'); // নন্স 0 থেকে গণনা শুরু করে
const transaction = {
'to': '0x31B98D14007bDEe637298086988A0bBd31184523', // ETH ফেরত দেওয়ার জন্য ফসেট ঠিকানা
'value': 1000000000000000000, // 1 ETH
'gas': 30000,
'nonce': nonce,
// বার্তা পাঠাতে বা স্মার্ট কন্ট্রাক্ট এক্সিকিউট করতে ঐচ্ছিক ডেটা ফিল্ড
};
const signedTx = await web3.eth.accounts.signTransaction(transaction, PRIVATE_KEY);
web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(error, hash) {
if (!error) {
console.log("🎉 The hash of your transaction is: ", hash, "\n Check Alchemy's Mempool to view the status of your transaction!");
} else {
console.log("❗Something went wrong while submitting your transaction:", error)
}
});
}
main();
6 নম্বর লাইনে থাকা ঠিকানাটি আপনার নিজস্ব পাবলিক ঠিকানা দিয়ে প্রতিস্থাপন করতে ভুলবেন না।
এখন, এই কোডটি রান করার আগে, আসুন এখানকার কিছু উপাদান নিয়ে আলোচনা করি।
nonce: আপনার ঠিকানা থেকে পাঠানো ট্রানজ্যাকশনের সংখ্যার হিসাব রাখতে নন্স স্পেসিফিকেশন ব্যবহার করা হয়। নিরাপত্তার উদ্দেশ্যে এবং রিপ্লে অ্যাটাক প্রতিরোধ করতে আমাদের এটি প্রয়োজন। আপনার ঠিকানা থেকে পাঠানো ট্রানজ্যাকশনের সংখ্যা পেতে আমরা getTransactionCount (একটি নতুন ট্যাবে খোলে) ব্যবহার করি।transaction: ট্রানজ্যাকশন অবজেক্টের কয়েকটি দিক রয়েছে যা আমাদের নির্দিষ্ট করতে হবেto: এটি হলো সেই ঠিকানা যেখানে আমরা ETH পাঠাতে চাই। এই ক্ষেত্রে, আমরা Sepolia ফসেটে (একটি নতুন ট্যাবে খোলে) ETH ফেরত পাঠাচ্ছি যেখান থেকে আমরা প্রাথমিকভাবে অনুরোধ করেছিলাম।value: এটি হলো সেই পরিমাণ যা আমরা পাঠাতে চাই, যা Wei-তে নির্দিষ্ট করা হয় যেখানে 10^18 Wei = 1 ETHgas: আপনার ট্রানজ্যাকশনের সাথে অন্তর্ভুক্ত করার জন্য সঠিক পরিমাণ গ্যাস নির্ধারণ করার অনেক উপায় রয়েছে। Alchemy ওয়েবহুক (একটি নতুন ট্যাবে খোলে) সমর্থন করে যা আপনাকে অনচেইন কার্যকলাপ সম্পর্কে অবহিত করতে পারে। Mainnet ট্রানজ্যাকশনের জন্য, সঠিক পরিমাণ গ্যাস নির্ধারণ করতে বর্তমান গ্যাস পরিস্থিতি পরীক্ষা করা একটি ভালো অভ্যাস। ইথেরিয়ামে একটি অপারেশনে ন্যূনতম 21000 গ্যাস ব্যবহার করা হয়, তাই আমাদের ট্রানজ্যাকশনটি কার্যকর হবে তা নিশ্চিত করতে আমরা এখানে 30000 দিয়েছি।nonce: উপরের নন্স সংজ্ঞাটি দেখুন। নন্স 0 থেকে গণনা শুরু করে।- [ঐচ্ছিক] data: আপনার হস্তান্তরের সাথে অতিরিক্ত তথ্য পাঠাতে বা একটি স্মার্ট কন্ট্রাক্ট কল করতে ব্যবহৃত হয়, ব্যালেন্স হস্তান্তরের জন্য এটি প্রয়োজনীয় নয়, নিচের নোটটি দেখুন।
signedTx: আমাদের ট্রানজ্যাকশন অবজেক্ট স্বাক্ষরকরণ করতে আমরা আমাদেরPRIVATE_KEY-এর সাথেsignTransactionমেথড ব্যবহার করব।sendSignedTransaction: একবার আমাদের কাছে একটি স্বাক্ষরিত ট্রানজ্যাকশন থাকলে, আমরাsendSignedTransactionব্যবহার করে এটিকে পরবর্তী ব্লকে অন্তর্ভুক্ত করার জন্য পাঠাতে পারি।
ডেটা সম্পর্কিত একটি নোট ইথেরিয়ামে পাঠানো যায় এমন দুটি প্রধান ধরনের ট্রানজ্যাকশন রয়েছে।
- ব্যালেন্স হস্তান্তর: এক ঠিকানা থেকে অন্য ঠিকানায় ETH পাঠান। কোনো ডেটা ফিল্ডের প্রয়োজন নেই, তবে, আপনি যদি আপনার ট্রানজ্যাকশনের পাশাপাশি অতিরিক্ত তথ্য পাঠাতে চান, তবে আপনি এই ফিল্ডে HEX ফর্ম্যাটে সেই তথ্য অন্তর্ভুক্ত করতে পারেন।
- উদাহরণস্বরূপ, ধরুন আমরা একটি IPFS ডকুমেন্টের হ্যাশ ইথেরিয়াম চেইনে লিখতে চাই যাতে এটিকে একটি অপরিবর্তনীয় টাইমস্ট্যাম্প দেওয়া যায়। তখন আমাদের ডেটা ফিল্ডটি দেখতে এমন হওয়া উচিত: data:
web3.utils.toHex(‘IPFS hash‘)। এবং এখন যে কেউ চেইনে কোয়েরি করে দেখতে পারে কখন সেই ডকুমেন্টটি যোগ করা হয়েছিল।
- উদাহরণস্বরূপ, ধরুন আমরা একটি IPFS ডকুমেন্টের হ্যাশ ইথেরিয়াম চেইনে লিখতে চাই যাতে এটিকে একটি অপরিবর্তনীয় টাইমস্ট্যাম্প দেওয়া যায়। তখন আমাদের ডেটা ফিল্ডটি দেখতে এমন হওয়া উচিত: data:
- স্মার্ট কন্ট্রাক্ট ট্রানজ্যাকশন: চেইনে কিছু স্মার্ট কন্ট্রাক্ট কোড এক্সিকিউট করুন। এই ক্ষেত্রে, ডেটা ফিল্ডে আপনার এক্সিকিউট করতে চাওয়া স্মার্ট ফাংশন এবং যেকোনো প্যারামিটার থাকা উচিত।
- একটি ব্যবহারিক উদাহরণের জন্য, হ্যালো ওয়ার্ল্ড স্মার্ট কন্ট্রাক্ট টিউটোরিয়াল দেখুন।
8. node sendTx.js ব্যবহার করে কোডটি রান করুন
আপনার টার্মিনাল বা কমান্ড লাইনে ফিরে যান এবং রান করুন:
node sendTx.js
9. মেমপুলে আপনার ট্রানজ্যাকশন দেখুন
আপনার Alchemy ড্যাশবোর্ডে মেমপুল পেজটি (একটি নতুন ট্যাবে খোলে) খুলুন এবং আপনার ট্রানজ্যাকশনটি খুঁজে পেতে আপনার তৈরি করা অ্যাপ দ্বারা ফিল্টার করুন। এখানেই আমরা আমাদের ট্রানজ্যাকশনটিকে পেন্ডিং স্টেট থেকে মাইন্ড স্টেটে (যদি সফল হয়) বা ব্যর্থ হলে ড্রপড স্টেটে রূপান্তরিত হতে দেখতে পারি। এটি "All"-এ রাখতে ভুলবেন না যাতে আপনি "mined", "pending" এবং "dropped" ট্রানজ্যাকশনগুলো ক্যাপচার করতে পারেন। আপনি 0x31b98d14007bdee637298086988a0bbd31184523 ঠিকানায় পাঠানো ট্রানজ্যাকশনগুলো খুঁজে বের করেও আপনার ট্রানজ্যাকশনটি অনুসন্ধান করতে পারেন।
একবার আপনি আপনার ট্রানজ্যাকশনটি খুঁজে পেলে এর বিস্তারিত দেখতে, tx হ্যাশ নির্বাচন করুন, যা আপনাকে এমন একটি ভিউতে নিয়ে যাবে:
সেখান থেকে আপনি লাল বৃত্তাকার আইকনে ক্লিক করে Etherscan-এ আপনার ট্রানজ্যাকশন দেখতে পারেন!
ইয়িপ্পি! আপনি এইমাত্র Alchemy ব্যবহার করে আপনার প্রথম ইথেরিয়াম ট্রানজ্যাকশন পাঠিয়েছেন 🎉
এই গাইড সম্পর্কে মতামত এবং পরামর্শের জন্য, অনুগ্রহ করে Alchemy-এর ডিসকর্ডে (একটি নতুন ট্যাবে খোলে) Elan-কে মেসেজ করুন!
মূলত Alchemy দ্বারা প্রকাশিত।
