در این راهنما ساخت یک توکن قابل تعویض بر پایه استاندارد erc20 در سالیدیتی را گام به گام می آموزید؛ از انتخاب ابزار تا نوشتن قرارداد، استقرار روی شبکه آزمایشی و بررسی انتقال و مجوزها.

چرا توکن قابل تعویض و این استاندارد اهمیت دارد

توکن های قابل تعویض واحدهایی با ارزش برابر هستند و برای ارزهای دیجیتال، توکن های کاربردی و دارایی های درون برنامه ای استفاده می شوند. ERC20 قراردادی مشترک بین همه پیاده سازی ها می سازد تا کیف پول ها و صرافی ها بتوانند با آن تعامل کنند.

اگر همه توکن ها از یک قرارداد رابط پیروی کنند، فراخوانی هایی مثل استعلام موجودی، انتقال و اعطای مجوز همیشه یکسان عمل می کند. این سازگاری بیشترین نقش را در پذیرش گسترده و سهولت ادغام ایفا می کند.

آموزش سالیدیتی + 5 پروژه عملی

پیش نیازها و ابزارهای لازم

برای شروع نیازی به محیط پیچیده ندارید. Remix یک محیط آنلاین برای نوشتن، کامپایل و استقرار قراردادها است و برای آموزش بسیار مناسب است. کیف پولی مانند MetaMask هم برای اتصال به شبکه آزمایشی کافی خواهد بود.

  • Remix IDE برای کدنویسی و دیپلوی مستقیم در مرورگر
  • نسخه سالیدیتی 0.8.20 یا بالاتر برای ایمنی محاسبات و بهینه سازی
  • کتابخانه OpenZeppelin برای استفاده از پیاده سازی های استاندارد و امن
  • MetaMask برای مدیریت حساب و امضای تراکنش ها
  • توکن تست از فاست شبکه آزمایشی مثل Sepolia برای پرداخت هزینه گس

ساختار استاندارد و توابع کلیدی

رابط ERC20 مجموعه ای از توابع و رویدادها را تعریف می کند که پیاده سازی های مختلف باید آن را رعایت کنند. درک هر کدام کمک می کند رفتار توکن خود را درست ارزیابی کنید.

تابع یا رویداد کارکرد
totalSupply برگشت کل عرضه در گردش
balanceOf نمایش مانده حساب یک آدرس
transfer انتقال مستقیم توکن به آدرس دیگر
approve اعطای مجوز خرج به یک آدرس ثالث
allowance نمایش میزان مجاز خرج برای نماینده
transferFrom انتقال توسط نماینده تا سقف مجاز
رویداد Transfer ثبت هر انتقال یا مینت یا سوزاندن
رویداد Approval ثبت تغییرات مجوز خرج

پیاده سازی گام به گام یک توکن پایه

در این بخش یک توکن ساده با نام و نماد دلخواه می سازیم، عرضه اولیه را در سازنده مینت می کنیم و سپس آن را روی شبکه آزمایشی مستقر می کنیم.

  1. ورود به Remix و ساخت فایل جدید با پسوند .sol. از بخش Solidity Compiler نسخه 0.8.20 یا جدیدتر را انتخاب کنید.
  2. افزودن کتابخانه OpenZeppelin از طریق وارد کردن مسیر npm. Remix به صورت خودکار نسخه مناسب را واکشی می کند.
  3. نوشتن قرارداد با ارث بری از ERC20 و مینت عرضه اولیه برای سازنده قرارداد.
  4. کامپایل قرارداد و رفع خطاها. سپس از Deploy and Run استفاده و محیط Injected Provider را برای اتصال به MetaMask برگزینید.
  5. شبکه آزمایشی را در MetaMask روی Sepolia بگذارید، مقداری اتر تست بگیرید و قرارداد را دیپلوی کنید.
  6. پس از استقرار، با فراخوانی transfer، approve و transferFrom عملکرد را بررسی کنید.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    // نام و نماد را تنظیم می کنیم و عرضه اولیه را به سازنده می دهیم
    constructor(uint256 initialSupply) ERC20("My Token", "MYT") {
        _mint(msg.sender, initialSupply * 10 ** decimals());
    }
}

در مثال بالا پارامتر initialSupply تعداد واحدهای توکن قبل از اعمال اعشار است. تابع decimals به صورت پیش فرض 18 است، بنابراین 1000 به معنای 1000 ضرب در 10 به توان 18 واحد پایه خواهد بود.

تعامل با قرارداد در Remix

پس از استقرار، رابط کاربری Remix توابع قرارداد را نمایش می دهد. برای انتقال، آدرس مقصد و مقدار را وارد کنید و تراکنش را تایید کنید. رویداد Transfer در لاگ ها قابل مشاهده است.

برای کار با مجوزها، ابتدا approve را با آدرس نماینده و سقف دلخواه فراخوانی کنید. سپس از حساب نماینده تابع transferFrom را صدا بزنید تا توکن از حساب شما به گیرنده منتقل شود. مقدار allowance بعد از هر انتقال کاهش می یابد.

بهترین شیوه ها در طراحی توکن

حتی اگر از پیاده سازی استاندارد کتابخانه استفاده می کنید، چند اصل ساده باعث می شود نگهداری و امنیت کد شما بهتر شود و هزینه های تراکنش منطقی بماند.

  • نام، نماد و تعداد اعشار را ثابت نگه دارید و از تغییر آن ها پس از استقرار خودداری کنید.
  • عرضه اولیه و منطق مینت یا سوزاندن را شفاف و قابل پیش بینی طراحی کنید. اگر قابلیت مینت ندارید، آن را اضافه نکنید.
  • از رویدادها برای ردیابی عملیات خارج از زنجیره استفاده کنید و اندیس گذاری مناسب برای پارامترها در نظر بگیرید.
  • با مستندسازی واضح در توضیحات مخزن کد، نحوه توزیع و برنامه تخصیص را بیان کنید.

نکات امنیتی و خطاهای رایج

بخش عمده ای از ریسک ها ناشی از تعامل توکن با قراردادهای دیگر است، اما در خود توکن نیز باید به چند نکته توجه کرد تا از باگ های شناخته شده دور بمانید.

  • مساله کاهش مجوز: به جای بازنویسی مستقیم approve از مقدار غیر صفر به غیر صفر، ابتدا مجوز را صفر کنید یا از الگوهای increaseAllowance و decreaseAllowance استفاده کنید.
  • اصلاح دسترسی: اگر قابلیت مینت یا سوزاندن دارید، نقش ها و دسترسی ها را به صورت محدود و قابل تغییر با مکانیزم چند امضایی مدیریت کنید.
  • واحدها و اعشار: مقادیر ورودی رابط کاربری را به واحد پایه تبدیل کنید و از بروز خطای اعشاری جلوگیری کنید.
  • نسخه بندی کتابخانه: نسخه OpenZeppelin را ثابت نگه دارید و پس از ارتقا، تست های رگرسیونی اجرا کنید.
  • عدم اعتماد به ورودی: هر فراخوانی خارجی را اعتبارسنجی کنید و فرضیات مربوط به msg.sender را شفاف بنویسید.

آزمایش، شبیه سازی و اعتبارسنجی

پیش از دیپلوی روی شبکه اصلی، رفتار قرارداد را با ابزارهای تست خودکار بررسی کنید. Hardhat یا Foundry برای نوشتن تست های واحد، پوشش رویدادها و اندازه گیری مصرف گس مفید هستند.

  • تست سناریوهای خوش بینانه: انتقال های ساده، اعطای مجوز و استفاده از نماینده.
  • تست سناریوهای بدبینانه: کمبود موجودی، تلاش برای انتقال از طریق نماینده بیش از سقف مجوز، مقادیر صفر.
  • تست لبه ها: مقادیر بسیار بزرگ نزدیک به totalSupply، آدرس صفر به عنوان گیرنده یا فرستنده که باید رد شود.

گسترش قابلیت ها بر اساس نیاز محصول

بسته به کاربرد می توانید قابلیت های بیشتری اضافه کنید، مشروط به آنکه با رابط استاندارد تداخل ایجاد نکند. افزونه ها باید به شکلی طراحی شوند که کیف پول ها همچنان بتوانند توابع اصلی را اجرا کنند.

  • سوزاندن داوطلبانه توسط کاربر برای مدیریت عرضه.
  • تخصیص نقش های مدیریتی برای مینت کنترل شده یا توقف اضطراری انتقال ها در شرایط خاص.
  • صدور رسیدهای خارج از زنجیره با تکیه بر رویدادها برای سامانه های حسابداری.

بهینه سازی مصرف گس

بهینه سازی های کوچک در پیمایش حالت و نوشتن داده ها می تواند هزینه تراکنش را کاهش دهد، خصوصا در سناریوهای پرکاربرد. با این حال اولویت با خوانایی و امنیت کد است.

  • از ذخیره سازی غیر ضروری خودداری کنید و تا حد امکان از حافظه موقت استفاده کنید.
  • منطق پیچیده را در توابع داخلی کوچک کنید تا بهینه سازی کامپایلر موثرتر باشد.
  • از نسخه های جدید کامپایلر با بهینه سازی روشن استفاده کنید و تنظیمات بهینه ساز را مطابق نیاز پروژه بررسی کنید.

عیب یابی استقرار و استفاده

اگر تراکنش ها رد می شوند یا مقادیر نادرست به نظر می رسند، چند محل را بررسی کنید. بسیاری از خطاها ناشی از مقیاس بندی اعشار یا اشتباه در پارامترها است.

  • گس ناکافی یا شبکه اشتباه در MetaMask می تواند باعث شکست دیپلوی شود.
  • مقدار ورودی توابع را به واحد پایه تبدیل کنید. مثلا برای 10 توکن با 18 اعشار باید 10 ضرب در 10 به توان 18 ارسال کنید.
  • در صورت استفاده از transferFrom، پیش از آن approve را با مقدار کافی صدا بزنید و آدرس نماینده درست باشد.

کاربرد عملی در یک پروژه ساده

برای یک پروژه نمونه، می توانید توکن را به عنوان ارز درون برنامه ای بازی یا پلتفرم پاداش دهی به کار بگیرید. کافی است کیف پول کاربر به اپ متصل شود و عملیات انتقال و مجوزدهی از طریق قرارداد انجام گیرد.

به کمک جدول توابع و مثال کد، پیاده سازی بک اند یا اسکریپت های فرانت اند با کتابخانه هایی مثل ethers به سادگی انجام می شود و محدود به سرویس دهنده خاصی نیست.

نکته مهم درباره تطابق با استاندارد

در صورتی که بخواهید رفتار را تغییر دهید، از شکستن الزامات رابط خودداری کنید. افزودن رویداد یا تابع جدید مجاز است، اما حذف یا تغییر معنای توابع اصلی باعث ناسازگاری می شود. رعایت اصول استاندارد erc20 تضمین می کند کیف پول ها و سرویس ها بدون نیاز به تنظیمات اضافی از توکن شما پشتیبانی کنند.

کجا از این استاندارد استفاده نکنیم

اگر دارایی شما ویژگی های غیر قابل تعویض دارد، مانند یک اثر هنری یکتا، بهتر است از استانداردهای دیگر مانند ERC721 استفاده کنید. انتخاب نادرست استاندارد باعث پیچیدگی غیر ضروری و تجربه کاربری ضعیف می شود.

جمع بندی

با انتخاب ابزارهای مناسب، استفاده از پیاده سازی آزموده مانند OpenZeppelin و رعایت الگوهای امنیتی، ساخت یک توکن منطبق با استاندارد erc20 فرایندی سریع و قابل اتکا است. کد نمونه را بر اساس نیاز محصول گسترش دهید، اما سازگاری رابط و شفافیت رفتار را حفظ کنید تا ادغام با کیف پول ها و سرویس ها بدون دردسر انجام شود.