پیشنیازها و ابزارهای لازم
برای شروع یادگیری سالیدیتی به این موارد نیاز دارید:
- آشنایی پایه با برنامهنویسی: متغیر، شرط، حلقه و تابع. دانستن JavaScript مزیت بزرگی است؛ اگر از صفر شروع میکنید، آموزش برنامه نویسی از صفر را ببینید.
- Remix IDE: محیط توسعه آنلاین و رایگان در مرورگر؛ بهترین گزینه برای شروع، بدون نیاز به نصب.
- کیف پول متامسک (MetaMask): برای امضای تراکنشها و اتصال به شبکه آزمایشی.
- اتر آزمایشی: از فاست (Faucet) شبکه تست مثل Sepolia دریافت میشود و ارزش واقعی ندارد.
- برای پروژههای جدی: فریمورکهای Hardhat یا Foundry برای تست و استقرار حرفهای.
ساختار یک قرارداد ساده
اولین قرارداد ما یک عدد را ذخیره و بازیابی میکند:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract SimpleStorage { uint256 private storedValue; function set(uint256 newValue) public { storedValue = newValue; } function get() public view returns (uint256) { return storedValue; } }
توضیح بخشها:
- خط SPDX: نوع مجوز کد را مشخص میکند و کامپایلر انتظار دارد وجود داشته باشد.
- pragma: نسخه کامپایلر را تعیین میکند. نسخههای 0.8 به بعد بررسی سرریز عددی را بهصورت خودکار انجام میدهند.
- contract: شبیه کلاس در زبانهای دیگر است.
- storedValue: یک متغیر وضعیت (State Variable) که بهطور دائمی روی بلاکچین ذخیره میشود.
- تابع set: وضعیت را تغییر میدهد، پس اجرای آن تراکنش و کارمزد (Gas) دارد.
- تابع get: با کلمه view فقط داده را میخواند و فراخوانی آن از بیرون رایگان است.
انواع داده و متغیرها در سالیدیتی
سالیدیتی زبانی با نوع ایستا (Statically Typed) است؛ یعنی نوع هر متغیر باید مشخص باشد. مهمترین انواع داده:
- uint256 و int256: اعداد صحیح بدون علامت و با علامت. سالیدیتی عدد اعشاری ندارد و مقادیر پولی معمولاً با کوچکترین واحد (مثل wei) ذخیره میشوند.
- bool: درست یا نادرست.
- address: آدرس کیف پول یا قرارداد. نوع address payable میتواند اتر دریافت کند.
- string و bytes: متن و داده باینری.
- آرایهها و struct: برای نگهداری مجموعهها و ساختارهای سفارشی.
متغیرهای سراسری مهم
- msg.sender: آدرسی که تابع را صدا زده است.
- msg.value: مقدار اتر ارسالشده همراه تراکنش.
- block.timestamp: زمان بلاک جاری.
یادتان باشد ذخیره داده روی بلاکچین گران است؛ فقط دادههای ضروری را در متغیرهای وضعیت نگه دارید.
توابع، سطح دسترسی و modifier
هر تابع یک سطح دسترسی (Visibility) دارد:
- public: از داخل و خارج قرارداد قابل فراخوانی است.
- external: فقط از بیرون قرارداد.
- internal: فقط داخل همین قرارداد و قراردادهای فرزند.
- private: فقط داخل همین قرارداد. توجه کنید private بودن به معنی مخفی بودن داده نیست؛ همه دادههای بلاکچین قابل خواندن هستند.
با modifier میتوانید شرطی را قبل از اجرای تابع بررسی کنید. مثلاً محدود کردن تابع به مالک قرارداد:
address public owner; error NotOwner(); constructor() { owner = msg.sender; } modifier onlyOwner() { if (msg.sender != owner) revert NotOwner(); _; }
حالا هر تابعی که onlyOwner را داشته باشد، فقط توسط مالک قابل اجراست. علامت _ جایی است که بدنه تابع اجرا میشود. در پروژههای واقعی بهجای نوشتن دستی، از قرارداد Ownable کتابخانه OpenZeppelin استفاده کنید.
mapping، رویدادها و دریافت اتر
mapping ساختاری شبیه دیکشنری است و برای نگهداری موجودی کاربران بسیار رایج است. در این مثال یک صندوق ساده میسازیم که کاربران در آن واریز و برداشت میکنند:
mapping(address => uint256) public balances;
event Deposited(address indexed user, uint256 amount);
error ZeroAmount();
function deposit() external payable { if (msg.value == 0) revert ZeroAmount(); balances[msg.sender] += msg.value; emit Deposited(msg.sender, msg.value); }
function withdraw() external { uint256 amount = balances[msg.sender]; if (amount == 0) revert ZeroAmount(); balances[msg.sender] = 0; (bool ok, ) = payable(msg.sender).call{value: amount}(""); require(ok); }
- payable: اجازه میدهد تابع اتر دریافت کند.
- event و emit: رویدادها در لاگ تراکنش ثبت میشوند و رابط کاربری (مثلاً با Ethers.js) میتواند آنها را دنبال کند.
- custom error: روش جدیدتر و کمهزینهتر برای برگرداندن خطا نسبت به پیام متنی.
به ترتیب خطوط در withdraw دقت کنید: ابتدا موجودی صفر میشود و بعد اتر ارسال میشود. این الگو در بخش بعد توضیح داده شده است.
نکات امنیتی که از روز اول باید بدانید
در سالیدیتی، یک اشتباه کوچک میتواند به از دست رفتن دارایی واقعی منجر شود. این اصول را جدی بگیرید:
- الگوی Checks-Effects-Interactions: اول شرطها را بررسی کنید، بعد وضعیت را بهروز کنید و در آخر با قراردادها یا آدرسهای بیرونی تعامل کنید. این کار جلوی حمله Reentrancy را میگیرد.
- کنترل دسترسی: مطمئن شوید توابع حساس مثل برداشت یا تغییر تنظیمات محافظت شدهاند.
- از کتابخانههای معتبر استفاده کنید: برای توکنها و کنترل دسترسی، OpenZeppelin را به نوشتن از صفر ترجیح دهید.
- tx.origin را برای احراز هویت به کار نبرید: از msg.sender استفاده کنید.
- تست بنویسید: هم سناریوهای عادی و هم سناریوهای مخرب.
- قبل از انتشار روی شبکه اصلی، ممیزی بگیرید.
کامپایل و انتشار روی شبکه آزمایشی
با Remix میتوانید در چند دقیقه اولین قرارداد را منتشر کنید:
- در Remix یک فایل جدید با پسوند sol بسازید و کد SimpleStorage را در آن قرار دهید.
- در تب Solidity Compiler نسخه مناسب را انتخاب و قرارداد را کامپایل کنید.
- ابتدا در تب Deploy محیط Remix VM را انتخاب کنید تا قرارداد را بدون هزینه در مرورگر تست کنید.
- سپس متامسک را روی شبکه Sepolia قرار دهید، از فاست اتر آزمایشی بگیرید و در Remix محیط Injected Provider را انتخاب کنید.
- روی Deploy بزنید، تراکنش را در متامسک تأیید کنید و با توابع set و get کار کنید.
- آدرس قرارداد را در مرورگر بلاکچین (Etherscan شبکه Sepolia) جستجو کنید و تراکنشها را ببینید.
قدم بعدی، یادگیری Hardhat یا Foundry برای تست خودکار و ساخت یک توکن ERC20 با OpenZeppelin است. مقاله ساخت توکن در این مسیر کمکتان میکند.
آموزش تخصصی و توسعه قرارداد هوشمند با ثابتسافت
اگر میخواهید سالیدیتی را عمیقتر و با بازبینی کد توسط یک برنامهنویس باتجربه یاد بگیرید، آموزش برنامه نویسی ثابتسافت شامل مسیر بلاکچین با Solidity و Ethers.js هم میشود.
اگر هم برای کسبوکار خود به قرارداد هوشمند، توکن، dApp یا ممیزی امنیتی نیاز دارید، صفحه برنامه نویسی بلاکچین و سرویس DotSol را ببینید یا از صفحه تماس برای مشاوره رایگان اقدام کنید.
پرسشهای پرتکرار
یادگیری سالیدیتی برای مبتدیها سخت است؟
مقدمات آن برای کسی که مبانی برنامهنویسی و ترجیحاً JavaScript را بلد است سخت نیست. بخش چالشبرانگیز، رعایت اصول امنیتی و بهینهسازی مصرف Gas است که با تمرین و مطالعه به دست میآید.
برای تمرین سالیدیتی باید ارز دیجیتال واقعی بخرم؟
خیر. میتوانید در Remix VM کاملاً رایگان تمرین کنید و برای شبکههای آزمایشی مثل Sepolia از فاست، اتر آزمایشی بدون ارزش واقعی بگیرید.
Remix بهتر است یا Hardhat و Foundry؟
Remix برای یادگیری و آزمایش سریع عالی است. برای پروژههای واقعی، Hardhat یا Foundry امکانات بهتری برای تست خودکار، مدیریت پروژه و استقرار دارند.
قرارداد سالیدیتی روی چه شبکههایی اجرا میشود؟
روی اتریوم و همه شبکههای سازگار با EVM مثل BNB Chain، Polygon، Arbitrum و Optimism. شبکه ترون هم از قراردادهای سالیدیتی با تفاوتهایی پشتیبانی میکند.
آیا ثابتسافت آموزش خصوصی سالیدیتی دارد؟
بله، آموزش آنلاین و پروژهمحور برنامهنویسی بلاکچین با Solidity ارائه میشود. برای تعیین مسیر متناسب با سطح خود، مشاوره رایگان بگیرید.