📝 مقاله

توسعه قراردادهای هوشمند با Solidity و Web3: از صفر تا اتریوم ۲.۰ ارز های دیجیتال

۱۶ اوت ۲۰۲۶ بلاکچین | توسعه | برنامه‌نویسی ۵۰ دقیقه مطالعه

توسعه قراردادهای هوشمند با Solidity و Web3: از صفر تا اتریوم ۲.۰

بلاکچین اتریوم با معرفی ماشین مجازی اتریوم (EVM) و زبان قراردادهای هوشمند Solidity، انقلابی در صنعت فناوری مالی و غیرمتمرکز (DeFi) ایجاد کرد. در سال ۲۰۲۶، با اجرایی شدن کامل اتریوم ۲.۰ و کاهش چشمگیر هزینه‌های گس (Gas Fees)، توسعه قراردادهای هوشمند به یکی از داغ‌ترین حوزه‌های برنامه‌نویسی تبدیل شده است.

در این مقاله، از مفاهیم پایه بلاکچین تا پیاده‌سازی یک توکن ERC-20 استاندارد و تعامل با آن از طریق Web3.js را به صورت کاملاً عملی و پروژه‌محور یاد می‌گیرید.

۱. بلاکچین و اتریوم: فراتر از ارز دیجیتال

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

مفاهیم کلیدی که باید بدانید:

  • EVM (Ethereum Virtual Machine): محیط اجرای قراردادها در شبکه اتریوم.
  • Gas: واحد اندازه‌گیری هزینه محاسباتی. هر عملیات در EVM نیاز به Gas دارد که با اتر (ETH) پرداخت می‌شود. اتریوم ۲.۰ این هزینه‌ها را به شدت کاهش داده است.
  • ابزارهای توسعه: Remix IDE (محیط آنلاین برای شروع سریع)، Hardhat و Truffle (فریمورک‌های حرفه‌ای برای تست و استقرار).

۲. زبان Solidity: ساختار و سینتکس

Solidity یک زبان شیءگرا و سطح بالا است که تحت تأثیر C++، Python و JavaScript طراحی شده است.

ساختار پایه یک قرارداد:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract MyFirstContract {
    // متغیر وضعیت (State Variable)
    string public greeting = "Hello, Blockchain!";

    // تابع برای تغییر متغیر
    function setGreeting(string memory _newGreeting) public {
        greeting = _newGreeting;
    }

    // تابع View (فقط خواندنی، بدون هزینه Gas)
    function getGreeting() public view returns (string memory) {
        return greeting;
    }
}

انواع داده مهم:

  • uint256 / int256: اعداد صحیح ۲۵۶ بیتی (بدون علامت/با علامت).
  • address: نوع داده مخصوص آدرس کیف پول (۲۰ بایت).
  • mapping: معادل دیکشنری در پایتون. مانند mapping(address => uint256) public balances;
  • msg.sender: آدرس فراخوانی‌کننده تابع (مهم‌ترین متغیر برای احراز هویت در بلاکچین).

۳. پیاده‌سازی استاندارد توکن ERC-20

ERC-20 استاندارد طلایی برای توکن‌های قابل تعویض (مانند USDC، DAI و توکن‌های پروژه‌های مختلف) است. در زیر یک پیاده‌سازی ساده اما کامل از آن را مشاهده می‌کنید:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract MyToken {
    // متغیرهای عمومی
    string public name = "MyToken";
    string public symbol = "MTK";
    uint8 public decimals = 18;
    uint256 public totalSupply;

    // لیست موجودی‌ها و مجوزها
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    // رویدادها (Events) برای ثبت در بلاکچین
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    // سازنده (Constructor) - ۱۰۰۰ توکن به deployer اختصاص می‌دهد
    constructor() {
        totalSupply = 1000 * (10 ** uint256(decimals));
        balanceOf[msg.sender] = totalSupply;
    }

    // تابع انتقال
    function transfer(address recipient, uint256 amount) external returns (bool) {
        require(balanceOf[msg.sender] >= amount, "Insufficient balance");
        balanceOf[msg.sender] -= amount;
        balanceOf[recipient] += amount;
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }

    // تابع تایید هزینه (برای انتقال از طرف شخص دیگر)
    function approve(address spender, uint256 amount) external returns (bool) {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    // تابع انتقال از طرف شخص دیگر (TransferFrom)
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
        require(balanceOf[sender] >= amount, "Insufficient balance");
        require(allowance[sender][msg.sender] >= amount, "Allowance exceeded");
        balanceOf[sender] -= amount;
        balanceOf[recipient] += amount;
        allowance[sender][msg.sender] -= amount;
        emit Transfer(sender, recipient, amount);
        return true;
    }
}

۴. توکن‌های غیرقابل تعویض (NFT) با استاندارد ERC-721

اگر توکن‌ها منحصر‌به‌فرد باشند (مانند آثار هنری دیجیتال یا اشیاء در بازی‌ها)، از استاندارد ERC-721 استفاده می‌شود. ایده اصلی، نگاشت یک uint256 tokenId به یک address owner است.

یک قرارداد NFT ساده نیازمند تابع mint (ضرب) است:

function mint(address to, uint256 tokenId) public {
    require(_owners[tokenId] == address(0), "Token already minted");
    _owners[tokenId] = to;
    _balances[to] += 1;
    emit Transfer(address(0), to, tokenId);
}

برای تست NFT خود می‌توانید از شبکه‌های تستی مانند Sepolia استفاده کنید و از کیف پول متامسک (MetaMask) برای تعامل استفاده نمایید.

۵. تعامل با قرارداد با استفاده از Web3.js

پس از استقرار قرارداد روی شبکه (با استفاده از Hardhat یا Remix)، برای ارتباط برنامه‌های وب (React/Vue) با آن از کتابخانه Web3.js استفاده می‌کنیم.

اتصال به کیف پول متامسک و خواندن قرارداد:

import Web3 from "web3"؛

const connectToBlockchain = async () => {
    // درخواست اتصال به متامسک
    if (window.ethereum) {
        const web3 = new Web3(window.ethereum);
        await window.ethereum.request({ method: "eth_requestAccounts" });

        const accounts = await web3.eth.getAccounts();
        console.log("Connected to:", accounts[0]);

        // ABI (رابط قرارداد) و آدرس قرارداد مستقر شده
        const contractABI = [ ... ]؛ // ABI شما
        const contractAddress = "0x..."؛
        const contract = new web3.eth.Contract(contractABI, contractAddress);

        // فراخوانی تابع getName
        const name = await contract.methods.name().call();
        console.log("Token Name:", name);
    } else {
        alert("لطفاً متامسک نصب کنید!");
    }
}؛

ارسال تراکنش (مثلاً انتقال توکن):

// مقدار را به کوچکترین واحد (Wei) تبدیل کنید
const amount = web3.utils.toWei("10", "ether")؛

await contract.methods.transfer("0xRecipientAddress", amount).send({
    from: accounts[0],
    gas: 300000,
})؛

۶. امنیت در قراردادهای هوشمند (آسیب‌پذیری‌های رایج)

متاسفانه هک‌های میلیارد دلاری در دنیای DeFi زیاد رخ می‌دهد. مهم‌ترین آسیب‌پذیری‌ها عبارتند از:

  • Reentrancy Attack (حمله بازگشتی): معروف‌ترین حمله که در هک DAO (۲۰۱۶) منجر به سرقت ۶۰ میلیون دلار شد. امروزه با استفاده از ReentrancyGuard یا استفاده از transfer و send (که محدودیت گس دارند) از آن جلوگیری می‌شود.
  • Integer Overflow/Underflow: قبل از Solidity 0.8، عملگرها به صورت خودکار سرریز نمی‌شدند. اکنون به طور پیش‌فرض require انجام می‌شود، اما در نسخه‌های قدیمی باید از کتابخانه SafeMath استفاده کرد.
  • Front-running: مهاجمان با مشاهده تراکنش‌های در حال انتظار در Mempool، تراکنش خود را با Gas بالاتر ارسال می‌کنند تا جلوتر بیفتند. برای جلوگیری از این کار از الگوریتم‌های Commit-Reveal استفاده می‌شود.
  • خطا در منطق کنترل دسترسی (Access Control): فراموش کردن استفاده از onlyOwner یا بررسی msg.sender.

۷. بلاکچین لایه ۲ و آینده اتریوم

با وجود اتریوم ۲.۰ و راه‌حل‌های لایه ۲ مانند Arbitrum و Optimism، هزینه‌های تراکنش به شدت کاهش یافته و سرعت پردازش به بیش از ۱۰۰ هزار تراکنش در ثانیه رسیده است. این موضوع، بلاکچین را برای پذیرش گسترده در صنایع سنتی (حمل و نقل، بیمه، سلامت) آماده کرده است.

همچنین استاندارد جدید ERC-4337 (Account Abstraction) امکان استفاده از کیف پول‌های هوشمند را فراهم کرده که تجربه کاربری را به سطح برنامه‌های عادی وب نزدیک می‌کند.

جمع‌بندی

توسعه قراردادهای هوشمند یک مهارت فوق‌العاده ارزشمند در سال ۲۰۲۶ است. با یادگیری Solidity و Web3، شما به یک توسعه‌دهنده وب ۳.۰ تبدیل می‌شوید و می‌توانید در پروژه‌های غیرمتمرکز، بازی‌های بلاکچینی و سیستم‌های مالی شفاف مشارکت کنید.

پیشنهاد می‌کنم ابتدا با Remix IDE روی شبکه Sepolia تمرین کنید، سپس پروژه‌های خود را با Hardhat به صورت حرفه‌ای مدیریت کرده و در نهایت برنامه وب خود را به آن متصل کنید.


نویسنده: محمدمهدی محمودی

تاریخ انتشار: ۱۶ اوت ۲۰۲۶

منابع: مستندات Solidity (docs.soliditylang.org)، استاندارد EIP-20 و EIP-721، مستندات Hardhat و Web3.js، کتاب Mastering Ethereum (Andreas M. Antonopoulos).