آموزش ایجاد توکن روی پلتفرم اتریوم
پلتفرم اتریوم با ارائه قراردادهای هوشمند امکان ایجاد توکن را در اختیار توسعهدهندگان ارزهای دیجیتال قرار داده است. توکنها در اصل قراردادهای هوشمندی هستند که روی بلاک چین اتریوم فعالیت کرده و میتوانند چندین هدف یا کاربرد داشته باشند. توکنها میتوانند به عنوان ارز دیجیتال عرضه شوند و تنها تفاوتی که با ارزهای دیجیتال معمول دارند این است که بهجای یک بلاک چین خصوصی، روی بلاک چینهای دیگر قرار میگیرند.
یکی از امکانات اتریوم قرارداد هوشمند استاندارد ERC-20 است. این قرارداد هوشمند یک قطعه کد کامپیوتری به زبان «سالیدیتی» (Solidity)، زبان برنامهنویسی پلتفرم اتریوم، است که چند متغیر یا تابع اجباری و اختیاری دارد.
توسعهدهندگان با وارد کردن این متغیرها میتوانند توکن خاص خود را ایجاد کنند. این توکنها برای مجموعهای از کاربردهای مختلف مورد استفاده قرار میگیرند. در ادامهی این مطلب، نحوهی ایجاد توکن روی پلتفرم اتریوم آموزش داده میشود، پس با ما همراه باشید.
توکن چیست؟
بعضی از معروفترین ارزهای دیجیتال، از جمله بایننس کوین، تا قبل از اینکه روی بلاک چین اختصاصی خود قرار بگیرند با استاندارد ERC-20 و روی بلاک چین اتریوم عرضه میشدند.
توکنها میتوانند مجموعهای از نقشها را به خود بگیرند. توکنها به یک نقش محدود نیستند و میتوانند در یک اکوسیستم بومی چندین نقش داشته باشند. برخی از مهمترین نقشهای توکنها در ادامه معرفی میشود.
- ورودی: توکنها میتوانند به عنوان دروازهای به روی اپلیکیشنهای غیرمتمرکز در نظر گرفته شوند. در اصل برای دسترسی به اپلیکیشنهای غیرمتمرکز لازم است که توکن داشته باشید.
- حق رأی: از توکن همچنین میتوان برای مشخص ساختن حق رأیِ دارنده استفاده کرد. برای مثال «ایاواس» (EOS) را در نظر بگیرید، دارندگان توکن ایاواس میتوانند در مورد رویههای بلاک چین رای بدهند.
- تبادل ارزش: این یکی از نقشهای عمومیتر توکنها در اکوسیستم است.
- بهبود تجربه کاربری: از بعضی از توکنها برای اختیاری کردن تبلیغات و تجربه کاربری در پلتفرمهای مختلف استفاده میشود.
- ارز: میتواند به عنوان یک ذخیره ارزش قابل تراکنش هم داخل و هم خارج یک اکوسیستم مشخص مورد استفاده قرار بگیرد.
با در نظر گرفتن این نقشها میتوانیم متوجه اهمیت توکن شویم. از انواع هدایای وفاداری و ایجاد شبکه مشتریان گرفته تا ایجاد ارزهای دیجیتال، توکنها مجموعهای از امکانات را در اختیار توسعهدهندگان ارزهای دیجیتال قرار میدهند.
سالیدیتی چیست؟
سالیدیتی زبان برنامهنویسی قراردادهای هوشمند است. در حالیکه زبانهای جایگزین نیز وجود دارند، کمتر توسعهدهندهای از آنها برای این منظور استفاده میکند. توسعهدهندگان میتوانند از بیت کوین یا بلاک چینهای دیگر نیز برای توسعه اپلیکیشنهای غیرمتمرکز استفاده کنند، اما این کار چندان متداول نیست.
دلیل این موضوع سختی و پیچیدگی بیش از حد این کار است. این در حالی است که اتریوم با ارائه زبان سالیدیتی راهکاری بسیار ساده برای این مشکل عرضه میکند. سالیدیتی شبیه جاوااسکریپت است، برای همین اگر با جاوااسکریپت آشنایی داشته باشید، یا به جاوا و زبانهای مشابه C تسلط داشته باشید، نباید چندان با کدی که در سالیدیتی نوشته میشود غریبه باشید. در ادامه این مطلب با مثالهایی از کد این زبان آشنا خواهیم شد.
استاندارد ERC-20 چیست؟
بیشتر توکنهایی که روی بلاک چین اتریوم قرار دارند از استاندارد ERC-20 استفاده میکنند. ERC-20 یک استاندارد پروتکل است که قواعد و استانداردهای خاصی برای صدور توکنها در شبکه اتریوم عرضه میکند. برای اینکه موضوع را ساده نگه داریم، میتوانیم بگوییم ERC-20 یک راهنمای قواعد و قوانین است که قالبی کلی از قراردادهای هوشمند مبتنی بر اتریوم به منظور ایجاد توکن ارائه میدهد.
به این ترتیب یک توکن روی اتریوم در اصل فقط یک قرارداد هوشمند است که از برخی قواعد عمومی پیروی میکند؛ یعنی مجموعه استانداردی از توابع دارد که در تمام قراردادهای توکن مشترک هستند، مثل توابع transferFrom و balanceOf که در تمام آنها مشترک است.
استاندارد ERC-20 شامل ۶ قاعده اجباری و ۳ قاعده اختیاری یا سلیقهای است. قواعد اجباری که بهصورت تابع در این استاندارد معرفی شدهاند شامل موارد زیر میشود:
- ظرفیت کلی (totalSupply)
- ماندهاز (balanceOf)
- انتقال (transfer)
- انتقالاز (transferFrom)
- تایید (approve)
- پذیرش (allowance)
قواعد اختیاری هم شامل موارد زیر میشود:
- نام توکن (Token Name)
- نماد (Symbol)
- اعشار (Decimal) (تا ۱۸ رقم)
پس در کل توکن فقط یک قرارداد است که پیگیری میکند چه کسی چه مقدار از توکن را داشته و توابعی هم دارد که به کاربران امکان میدهد آن را به آدرسهای دیگر منتقل کنند. در مجموع توابع اصلی در استاندارد ERC-20 شامل موارد زیر میشود.
function totalSupply() public view returns (uint256); function balanceOf(address tokenOwner) public view returns (uint); function allowance(address tokenOwner, address spender) public view returns (uint); function transfer(address to, uint tokens) public returns (bool); function approve(address spender, uint tokens) public returns (bool); function transferFrom(address from, address to, uint tokens) public returns (bool); |
این توابع به یک کاربر بیرونی، برای مثال یک کیف پول ارز دیجیتال، اجازه میدهند تا مانده کاربر را به دست آورده و مبالغ را از یک کاربر به کاربر دیگر با تشخیص هویت مناسب منتقل کنند. در این نوع قراردادهای هوشمند دو ایونت تعریف میشود:
event Approval(address indexed tokenOwner, address indexed spender, uint tokens); event Transfer(address indexed from, address indexed to, uint tokens); |
هنگامی که به یک کاربر اجازه داده میشود توکن را از یک حساب برداشت کند، این ایونتها مشخصات و اطلاعات را بررسی میکنند.
نوشتن یک توکن ERC-20 در زبان سالیدیتی
حالا که با اصول و قواعد این استاندارد آشنا شدهایم، میتوانیم منطق ساخت توکن را بهتر درک کرده و اجرایی کنیم. قبل از هر چیز لازم است که دو mapping objects تعریف کنیم. سالیدیتی برای یک آرایه کلید/ارزش چنین انگارهای ارائه میدهد:
mapping(address => uint256) balances; mapping(address => mapping (address => uint256)) allowed; |
در اینجا عبارت mapping (address => uint256) یک آرایه متناظر را تعریف میکند که کلیدهای آن از نوع address هستند (عددی که یک آدرس حساب را مشخص میکند و ارزش آن uint256 است که یک اینتیجر ۲۵۶ رقمی است که معمولا برای ذخیره مانده توکن مورد استفاده قرار میگیرد.)
اولین mapping object، یعنی balances، مانده توکن هر صاحب حساب را نگه میدارد. دومین mapping object، یعنی allowed، به تمام حسابهای مورد تایید اجازه میدهد از یک حساب مشخص با جمع برداشت مورد تایید برای هر یک از آنها، برداشت انجام دهند. این مپینگها با هم در کنار تمام ستونهای قرارداد دیگر روی بلاک چین ذخیره میشوند و در ادامه تغییرات در نودهای کاربری شبکه ماین یا استخراج میشوند.
ذخیره بلاک چین گران است و کاربران قرارداد هوشمند شما لازم است که برای استفاده از آن به هر شکلی شده پرداخت انجام دهند. برای همین همواره باید سعی کنید فضای ذخیره را به حداقل برسانید.
حالا که ساختارهای داده مورد نیاز را داریم، میتوانیم جاگذاری استاندارد ERC-20 در تابعهای مناسب را شروع کنیم.
تنظیم تعداد توکن های عرضه اولیه کوین
چطور باید تعداد توکنهای «عرضه اولیه کوین» (ICO) را مشخص کنیم؟ در حقیقت چند راه برای تعیین حداکثر تعداد توکنها در عرضه اولیه کوین وجود دارد و این موضوعی است که خودش ارزش یک بحث طولانی را دارد. برای این آموزش، ما از سادهترین روش استفاده میکنیم: تعیین مجموع توکنها در زمان ساخت قرارداد و تخصیص اولیه تمام آنها به «مالک قرارداد»، یعنی حسابی که قرارداد هوشمند را به کار برده است:
uint256 totalSupply_; constructor(uint256 total) public {totalSupply_ = total; balances[msg.sender] = _totalSupply;} |
کانستراکتور یک تابع ویژه است که بهصورت خودکار درست بعد از راهاندازی قرارداد توسط اتریوم فراخوانی میشود. معمولا از آن برای ثبت وضعیت توکن با استفاده از پارامترهایی استفاده میشود که توسط حساب بهکارگیرنده قرارداد ارائه میشود.
در اینجا msg یک متغیر سراسری (global) است که توسط خود اتریوم اعلام شده و مورد استفاده قرار میگیرد. این متغیر حاوی دادههای مهم در مورد اجرای قرارداد است. ستونی که در اینجا مورد استفاده قرار دادهایم، msg.sender حاوی حساب اتریوم است که تابع قرارداد فعلی را اجرا میکند.
فقط حساب تعیینشده میتواند وارد کانستراکتور قرارداد شود. هنگامی که قرارداد شروع شود، این تابع توکنهای موجود را به «مالک قرارداد» (contract owner) منتقل میکند.
وارد کردن عرضه کلی توکن
function totalSupply() public view returns (uint256) {return totalSupply_;} |
این تابع تعداد تمام توکنهای اختصاص یافته توسط قرارداد را فارغ از مالک آن ارائه میدهد.
مانده توکن مالک
function balanceOf(address tokenOwner) public view returns (uint) {return balances[tokenOwner]; } |
در اینجا balanceOf مانده فعلی توکن یک حساب را که توسط آدرس مالک شناسایی شده بر میگرداند.
انتقال توکن به یک حساب دیگر
function transfer(address receiver, uint numTokens) public returns (bool) {require(numTokens <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender] — numTokens; balances[receiver] = balances[receiver] + numTokens; emit Transfer(msg.sender, receiver, numTokens); return true;} |
همان طور که از نام آن مشخص است، تابع transfer برای انتقال مبلغ numTokens از مانده حساب مالک به یک حساب دیگر، یا receiver، استفاده میکند. مالک انتقالدهنده msg.sender است، یعنی کسی است که تابع را اجرا میکند؛ به این معناست که فقط مالک توکنها میتواند آنها را به دیگران منتقل کند.
روش سالیدیتی برای اعمال یک پیشبینی استفاده از require است. در این مورد حساب فرستنده برای اجرا انتقال مانده کافی دارد. اگر یک گزاره require جور نباشد، تراکنش بلافاصله بدون هیچ تغییر مکتوبی در بلاک چین مرجوع میشود.
تایید انتقال برای برداشت توکنها
این تابع بیشتر برای سناریوی توکن مورد استفاده در بازار کاربرد دارد.
function approve(address delegate, uint numTokens) public returns (bool) {allowed[msg.sender][delegate] = numTokens; emit Approval(msg.sender, delegate, numTokens); return true;} |
در اینجا approve به مالک (فرستنده) یا msg.sender اجازه میدهد تا یک حساب انتقالی را تایید کند (احتمالا حساب خود بازار) تا توکنها از حساب او برداشتشده و وارد حسابهای دیگر شود. همانطور که میبینید، این تابع در سناریوهایی کاربرد دارد که در آنها مالکان توکنهای خود را در یک بازار عرضه میکنند. بهعلاوه، این تابع به بازار اجازه میدهد تراکنش را بدون انتظار برای تایید نهایی بسازد. در پایان اجرای این تابع، یک ایونت Approval انجام میشود.
تعداد توکنهای تایید شده برای برداشت
function allowance(address owner, address delegate) public view returns (uint) {return allowed[owner][delegate];} |
این تابع تعداد مورد تایید فعلی توکنهای یک مالک را به یک حساب انتقالی، همانطور که در تابع approve مشخص شده است، بر میگرداند.
فرستادن توکنها از طریق انتقال
تابع transferFrom جفت تابع approve است، که پیشتر در مورد آن بحث کردیم. این تابع به یک انتقال تاییدشده برای برداشت اجازه میدهد مبالغ پولی مالک را به یک حساب شخص-ثالث منتقل کند.
function transferFrom(address owner, address buyer, uint numTokens) public returns (bool) {require(numTokens <= balances[owner]); require(numTokens <= allowed[owner][msg.sender]); balances[owner] = balances[owner] — numTokens; allowed[owner][msg.sender] = allowed[from][msg.sender] — numTokens; balances[buyer] = balances[buyer] + numTokens; Transfer(owner, buyer, numTokens); return true;} |
دو گزاره require در شروع تابع برای شناسایی تراکنش قانونی مورد استفاده قرار میگیرند. تراکنش قانونی تراکنشی است که مالک آن توکن کافی برای ارسال داشته و گیرنده نیز تایید numTokens را داشته باشد. علاوه بر انتقال مبلغ numTokens از مالک به خریدار، این تابع میزان numTokens را نیز از پذیرش گیرنده کم میکند. این در مجموع به گیرنده اجازه میدهد با یک پذیرش چندین برداشت انجام دهد، که یک رفتار معمول در یک بازار است.
میتوانیم در همینجا که یک کارگزاری معتبر ERC-20 داریم متوقف شویم. اما بههرحال، مایل هستیم یک قدم جلوتر برویم، چرا که میخواهیم یک توکن با توان صنعتی داشته باشیم. برای همین لازم است کد امنتری داشته باشیم، اگر چه همچنان میتوانیم توکنها را به نسبت ساده، نه ابتدایی، نگه داریم.
لایبرری سیفمت سالیدیتی
سیفمت (SafeMath) یک لایبرری سالیدیتی است که با هدف فائق آمدن بر هکرهای یک طرفه که به قراردادها نفوذ میکنند ایجاد شده است؛ یعنی مقابله با حملات اینتیجری. در چنین حملهای، هکر قرارداد را مجبور به استفاده از ارزهای عددی با انتقال پارامترهایی میکند که باعث میشوند اینتیجرهای مرتبط از ارزش نهایی خود خارج شوند.
سیفمت با تست کردن سرریز اینتیجرها قبل از اجرای عملیات حساب در مقابل این نوع حملات از قرارداد محافظت میکند. این لایبرری به قدری کوچک است که تاثیر بسیار کمی روی اندازه قرارداد دارد؛ نه کارکرد آن را تحت تاثیر قرار میدهد و نه فضای ذخیره زیادی اشغال میکند.
حالا اجازه بدهید سیفمت را به کد خود اضافه کنیم:
library SafeMath { // Only relevant functions function sub(uint256 a, uint256 b) internal pure returns (uint256) {assert(b <= a); return a — b;} function add(uint256 a, uint256 b) internal pure returns (uint256) {uint256 c = a + b; assert(c >= a); return c;} |
سیفمت از گزارههای assert برای معتبر ساختن صحت پارامترهای انتقالی استفاده میکند. در صورتی که این گزاره جور نباشد، اجرای تابع بلافاصله متوقف شده و تمام تغییرات بلاک چین به عقب بر میگردد.
حالا باید از گزاره زیر برای معرفی لایبرری به کامپایلر سالیدیتی استفاده کنیم:
using SafeMath for uint256; |
سپس محاسبات بومی که در آغاز مورد استفاده قرار دادیم را با توابع سیفمت جایگزین کنیم:
balances[msg.sender] = balances[msg.sender].sub(numTokens); balances[receiver] = balances[receiver].add(numTokens); balances[buyer] = balances[buyer].add(numTokens); balances[owner] = balances[owner].sub(numTokens); |
جمع کردن تمام اجزا
در سالیدیتی، تابعها و ایونتهای یک قرارداد هوشمند در داخل چیزی به نام «قرارداد» قرار میگیرند که میتوانیم آن را به «کلاس بلاک چین» ترجمه کنیم. در ادامه قرارداد هماهنگ با ERC-20 که نوشتیم را برایتان قرار دادهایم. ستونهای نام و نماد میتوانند مطابق میل شما تغییر کنند. بیشتر توکنها اعشار را تا ۱۸ رقم نگه میدارد، ما هم همین کار را میکنیم.
استقرار قرار هوشمند اتریوم
حالا زمان مستقر کردن قرارداد هوشمندی که نوشتیم بر روی بلاک چین فرا رسیده است. در این فرایند، قرارداد ما برای تمام نودهای مشارکتکننده در شبکه منتقل میشود. به این ترتیب هر تغییری که در قرارداد ایجاد شود برای تمام نودها یا کاربران مشارکتکننده ارسال میشود.
معمولا توسعهدهندگان اتریوم از ابزارهای استقرار مثل «ترافل» (Truffle) استفاده میکنند. این ابزار برای نیازهای محدود این مقاله زیادی گسترده است و ابزار آنلاین سادهای مثل «رمیکس» (Remix) کفایت میکند. برای استفاده از آن لازم است پلاگین متاماسک را روی مرورگر خود نصب کرده و همچنین یک حساب «رینکبی» (Rinkeby) (شبکه تست اتریوم) و مقداری اتر در آن داشته باشید. اینها کارهای سادهای هستند، برای همین درگیر جزئیات آنها نمیشویم.
اگر هیچ کدام را ندارید، یک سر به سایتهای متاماسک و رینکبی بزنید تا لینک دانلود، راه نصب و استفاده را دریافت کنید. حالا که تمام موارد لازم را در اختیار داریم، وارد رمیکس شده و کد بالا را همراه خط معرفی و لایبرری سیفمت در ادیتور آنلاین آن قرار میدهیم.
سپس وارد زبانه دوم در سمت راست با نام «Run» شده و روی «Deploy» کلیک کنید. یک پاپآپ متاماسک ظاهر میشود که از شما میخواهد تراکنش را تایید کنید.
- باکس سبز: مطمئن شوید که روی رینکبی هستید.
- باکس آبی: ظرفیت کل توکن را مشخص کنید.
- باکس قرمز: استقرار!
Gist: https://gist.github.com/giladHaimov/8e81dbde10c9aeff69a1d683ed6870be#file-basicerc20-sol |
خسته نباشید! حالا اولین توکن ERC-20 خود را درست مثل یک متخصص اتریوم مستقر کردهاید. همانطور که وعده داده بودیم، این توکن ساده و سبک، اما کاملا کاربردی است و با استاندارد ERC-20 مطابقت دارد و با لایبرری سیفمت امنیت آن تامین شده است. این توکن برای خرید، پرداخت و انتقال روی بلاک چین آماده است.
سخن پایانی
از توکنها میتوان استفادههای گوناگونی کرد. از آنجا که توکنها روی بلاک چین ذخیره شده و درست مانند ارزهای دیجیتال عمل میکنند، ابزارهای بسیار مناسبی برای پیگیری توزیع محصولات و اطمینان از توزیع متناسب محسوب میشوند. علاوه بر این، از توکنها برای ارائه هدایای وفاداری، ایجاد واحدهای ارزش برای تبادل و موارد بیشتری استفاده میشود.
همانطور که در این مطلب دیدیم، اتریوم روشی بسیار ساده برای ایجاد توکن ارائه میدهد. توسعهدهندگان با وارد کردن مقادیر برای تابعهای اجباری قرارداد ERC-20 میتوانند بهسادگی توکن خود را ایجاد کنند. این توکنها هنگامی که در کنار ابزارهای مخصوص امنیتی اتریوم مورد استفاده قرار بگیرند، درست مثل ارزهای دیجیتال رسمی عمل خواهند کرد.
برای دریافت مشاوره تخصصی رایگان از کارشناسان ما، اطلاعات خواسته شده رو تکمیل فرمایید.