تابع Receive در سالیدیتی چیست؟
در دنیای قراردادهای هوشمند اتریوم، گاهی اوقات نیاز داریم یک قرارداد تنها برای دریافت مستقیم اتر (Ether) مورد استفاده قرار گیرد، بدون اینکه داده ای همراه تراکنش ارسال شود یا تابع مشخصی صدا زده شود. در چنین شرایطی، زبان برنامه نویسی سالیدیتی تابعی ویژه به نام receive
ارائه میدهد. این تابع زمانی اجرا میشود که تراکنشی بدون دیتا به آدرس قرارداد ارسال شود.
نکته مهمی که باید به آن توجه داشت این است که اگر تابع receive
در قراردادی تعریف نشده باشد، و کسی بخواهد بدون فراخوانی تابع خاصی اتر به قرارداد ارسال کند، تراکنش با خطا مواجه شده و برگشت خواهد خورد. از اینرو، پیاده سازی تابع Receive در سالیدیتی در بسیاری از قراردادهای مالی و غیرمتمرکز، بهویژه آنهایی که قرار است وجوه مستقیم دریافت کنند، ضروری است.
آموزش تابع Receive در سالیدیتی
در بسیاری از مواقع، تنها هدف از ارسال تراکنش به یک قرارداد هوشمند، انتقال اتر است نه فراخوانی یک تابع خاص. در چنین شرایطی استفاده از تابع receive
بهترین گزینه است. این تابع یکی از توابع خاص در سالیدیتی محسوب میشود که به قرارداد امکان میدهد هنگام دریافت اتر، بدون نیاز به اطلاعات اضافی یا کدگذاری پیچیده، واکنش نشان دهد.
1 2 3 4 5 6 |
contract TakeMoney { receive() external payable { } } |
نکات مهم درباره تابع receive:
-
برخلاف توابع معمول، تابع receive بدون کلیدواژه
function
تعریف میشود، زیرا یکی از توابع خاص سالیدیتی مانندconstructor
است. -
این تابع فقط با سطح دسترسی
external
قابل تعریف است، به این معنا که تنها از بیرون از قرارداد قابل فراخوانی است.
تا اینجای آموزش، برای قابل فراخوانی بودن توابع از بیرون قرارداد، از public
استفاده میکردیم. اما external
به این معنی است که تابع فقط از بیرون قرارداد قابل صدا زدن است، نه از داخل خودش.
برای سادگی در آموزش، فعلاً از public
استفاده میکنیم ولی در ادامه تفاوت دقیق بین public
و external
را بررسی خواهیم کرد.
با این حال، زبان Solidity فقط اجازه میدهد تابع receive
از نوع external
باشد.
این تابع باید حتماً payable
باشد. اگر کلمه کلیدی payable
را حذف کنید و قرارداد را کامپایل کنید، با خطا مواجه میشوید. چرا؟ چون تابع receive
وظیفه دریافت مستقیم اتر را دارد و برای این کار باید payable
باشد.
حالا سوال اینجاست: چطور یک تابع دیگر میتواند اتر به این تابع بفرستد؟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
contract TakeMoney { receive() external payable { } function viewBalance() public view returns (uint256) { return address(this).balance; } } contract ForwardMoney { function payMe() public payable { } function sendMoney(address luckyAddress) public payable { uint256 myBalance = viewBalance(); luckyAddress.call{value: myBalance}(""); } function viewBalance() public view returns (uint256) { return address(this).balance; } } |
حالا این کد را در Remix وارد کنید تا عملکردش را بررسی کنید.
میبینید که این روش خیلی تمیزتر است — خبری از abi.encode
یا موارد پیچیده دیگر نیست.
این ساختار، همان روشی است که برای ارسال اتر به کیف پول ها هم استفاده میکنیم. در ادامه، یک قرارداد را میبینید که فقط اجازه برداشت اتر را به یک آدرس خاص میدهد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
contract SaveMoney { function withdrawMoney() public payable { require(msg.sender == 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, "not the first remix address"); msg.sender.call{value: viewBalance()}(""); } function viewBalance() public view returns (uint256) { return address(this).balance; } // anyone can send receive() external payable { } } |
ممکن است این موضوع کمی عجیب به نظر برسد که یک «فراخوانی تابع» به یک کیف پول انجام میشود، در حالی که کیف پول هیچ تابعی ندارد. این رفتار ناشی از conventions (روال های قراردادی) در شبکه اتریوم است که در ابتدا ممکن است گیجکننده به نظر برسد.
آنچه باید به خاطر داشته باشید این است که:
در اتریوم، تمامی فراخوانی های call
میتوانند اتر منتقل کنند، حتی اگر مقدار مشخصی تعیین نشده باشد.
در واقع، انتقال مقدار صفر اتر نیز کاملاً معتبر است و در بسیاری از مواقع، زمانی که نیازی به انتقال وجه نیست اما نیاز به تعامل با یک آدرس وجود دارد، مورد استفاده قرار میگیرد.
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۱۵ اردیبهشت ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++C
- ADO.NET
- Adobe Flash
- Ajax
- AngularJS
- apache
- ARM
- Asp.Net
- ASP.NET MVC
- AVR
- Bootstrap
- CCNA
- CCNP
- CMD
- CSS
- Dreameaver
- EntityFramework
- HTML
- IOS
- jquery
- Linq
- Mysql
- Oracle
- PHP
- PHPMyAdmin
- Rational Rose
- silver light
- SQL Server
- Stimulsoft Reports
- Telerik
- UML
- VB.NET&VB6
- WPF
- Xml
- آموزش های پروژه محور
- اتوکد
- الگوریتم تقریبی
- امنیت
- اندروید
- اندروید استودیو
- بک ترک
- بیسیک فور اندروید
- پایتون
- جاوا
- جاوا اسکریپت
- جوملا
- دلفی
- دوره آموزش Go
- دوره های رایگان پیشنهادی
- زامارین
- سئو
- ساخت CMS
- سی شارپ
- شبکه و مجازی سازی
- طراحی الگوریتم
- طراحی بازی
- طراحی وب
- فتوشاپ
- فریم ورک codeigniter
- فلاتر
- کانستراکت
- کریستال ریپورت
- لاراول
- معماری کامپیوتر
- مهندسی اینترنت
- هوش مصنوعی
- یونیتی
- کتاب های آموزشی
- Android
- ASP.NET
- AVR
- LINQ
- php
- Workflow
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس