گروه سام آرام
فصل 6

فصل ۵: استانداردهای توکن و طراحی قرارداد

۵.۱ استانداردهای اصلی و مقایسه فنی

استاندارد نوع مناسب برای محدودیت کلیدی
ERC-20 Fungible واحدهای قابل‌تعویض محدودیت حقوقی ذاتی ندارد
ERC-721 Non-fungible دارایی یکتا برای حجم بالای واحدهای مشابه بهینه نیست
ERC-1155 Multi-token چند نوع دارایی در یک قرارداد پیچیدگی بیشتر مدل داده
ERC-4626 Vault سهم از دارایی زیرین / pool مدل مشخص برای vault
ERC-3643 (T-REX) Permissioned Security دارایی تنظیم‌شده با KYC نیازمند زیرساخت identity/compliance

۵.۲ نکته امنیتی و انطباقی حیاتی

ERC-20 به‌تنهایی «قانون‌گذاری» را اجرا نمی‌کند. اگر انتقال فقط به سرمایه‌گذاران واجد شرایط مجاز است، باید قبل از هر transfer تابع eligibility فراخوانی شود. ERC-3643 دقیقاً با معماری permissioned طراحی شده و identity registry + compliance module را در چرخه انتقال وارد می‌کند.

۵.۳ قرارداد آموزشی کامل‌تر (غیر production)

// Educational example — NOT production-ready.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/**
 * @title SimpleAssetToken
 * @notice Demonstrates eligibility-gated mint and transfer.
 * @dev For learning only. Production requires AccessControl, pause,
 *      recovery, full events, upgrade strategy, key management and legal compliance.
 */
contract SimpleAssetToken {
    mapping(address => uint256) public balanceOf;
    mapping(address => bool) public eligible;
    uint256 public totalSupply;
    address public immutable issuer;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event EligibilityUpdated(address indexed account, bool value);
    event Mint(address indexed to, uint256 amount);

    constructor() {
        issuer = msg.sender;
    }

    modifier onlyEligible(address account) {
        require(eligible[account], "NOT_ELIGIBLE");
        _;
    }

    function setEligible(address account, bool value) external {
        require(msg.sender == issuer, "ONLY_ISSUER");
        eligible[account] = value;
        emit EligibilityUpdated(account, value);
    }

    function mint(address to, uint256 amount) external onlyEligible(to) {
        require(msg.sender == issuer, "ONLY_ISSUER");
        balanceOf[to] += amount;
        totalSupply += amount;
        emit Mint(to, amount);
        emit Transfer(address(0), to, amount);
    }

    function transfer(address to, uint256 amount)
        external
        onlyEligible(msg.sender)
        onlyEligible(to)
        returns (bool)
    {
        require(balanceOf[msg.sender] >= amount, "INSUFFICIENT");
        unchecked {
            balanceOf[msg.sender] -= amount;
            balanceOf[to] += amount;
        }
        emit Transfer(msg.sender, to, amount);
        return true;
    }
}
هشدار تولید: این کد فقط مفهوم eligibility را آموزش می‌دهد. برای محیط واقعی باید AccessControl (OpenZeppelin)، pause، recovery، event کامل، upgrade strategy (UUPS یا Transparent)، مدیریت کلید چندامضایی (multisig + HSM) و الزامات حقوقی/انطباق اضافه شود. هرگز کد آموزشی را بدون audit مستقل به production نبرید.
6 / 16