در سالیدیتی، Emitting Events به معنای ثبت رویدادهایی در بلاکچین است که هنگام تغییر وضعیت قرارداد اتفاق میافتند و امکان پیگیری و مانیتورینگ آن تغییرات را برای محیط خارج از زنجیره فراهم میکنند. این رویدادها ابزار مهمی برای شفافیت و تعامل اپلیکیشن ها با قرارداد هوشمند هستند.
آموزش انتشار رویدادها (Emitting Events) در سالیدتی
از نظر فنی، توکن “ERC20” ما هنوز بهطور کامل مطابق با استاندارد ERC20 نیست. چون یک ویژگی مهم در آن وجود ندارد: رویدادها (Events).
یک قانون کلی: اگر تابعی باعث تغییر وضعیت (State Change) شود، باید آن را ثبت (Log) کرد.
چرا چیزی را ثبت کنیم؟ مگر نه اینکه بلاکچین هر تراکنش را بهصورت تغییرناپذیر ذخیره میکند؟
این درست است؛ رویدادها از نظر فنی الزامی نیستند. اما آنها فرآیند ممیزی (Auditing) گذشته را بسیار آسانتر میکنند. به جای جستجو در میان مجموعهای از تراکنش ها، کاربر میتواند براساس لاگی که به آن علاقه دارد، فیلتر کند و بهسرعت رویدادهایی (تراکنش هایی) را پیدا کند که اهمیت دارند.
به همین روش، کیف پول رمزارزی شما بهسرعت میتواند موجودی توکن ERC20 شما را شناسایی کند. در غیر این صورت باید تمام تراکنش های تاریخچه یک توکن را بررسی کند تا بفهمد شما مالک آن هستید یا نه. اما لاگ ها طوری ذخیره میشوند که بازیابی آنها کارآمد باشد.
نکته مهم: رویدادها توسط قراردادهای هوشمند دیگر قابل مشاهده نیستند. آنها بهگونهای طراحی شدهاند که برای پردازشهای خارج از زنجیره (Off-chain) بهینه باشند.
بیایید یک مثال ببینیم.
1 2 3 4 5 6 7 8 9 10 |
contract ExampleContract { event Deposit(address indexed depositor, uint256 amount); receive() external payable { emit Deposit(msg.sender, msg.value); } } |
یک رویداد (event) میتواند حداکثر تا ۳ پارامتر index شده داشته باشد، اما برای تعداد پارامترهای غیر index شده محدودیتی وجود ندارد.
اگر با پایگاه داده (database) آشنایی دارید، میتوانید index در رویدادها را دقیقاً مانند ایندکس های یک پایگاه داده تصور کنید.
ضمناً، نوشتن نام آرگومان ها بعد از نوع داده اختیاری است. برای مثال، میتوانستیم رویداد بالا را به صورت زیر بنویسیم:
1 |
event Deposit(address indexed, uint256); |
و هیچ مشکلی هم ایجاد نمیشد، البته ممکن است خوانایی کد کمی کمتر شود.
چه زمانی یک متغیر باید index شود و چه زمانی نه؟
اگر فکر میکنید ممکن است بخواهید آن مقدار را سریع پیدا کنید—مثل اینکه “آیا یک آدرس خاص با این قرارداد توکن تعامل داشته؟”—در آن صورت باید آن را index کنید.
اما احتمالاً برای شما مهم نیست که “آیا کسی دقیقاً ۱٬۳۷۰٬۹۰۴ توکن در این قرارداد انتقال داده؟”، پس نیازی نیست مقدار مبلغ را index کنید.
در ادامه، نسخه کامل قرارداد ERC20 با رویدادهای اضافهشده را داریم. توجه داشته باشید که این رویدادها طبق استاندارد ERC20 اجباری هستند.
با دقت ببینید رویدادها کجا اضافه شدهاند، مخصوصاً در تابع mint! استفاده از address(0)
بهعنوان منبع به این معناست که توکن ها از هیچ به وجود آمدهاند، نه از آدرسی دیگر.
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
contract ERC20 { string public name; string public symbol; mapping(address => uint256) public balanceOf; address public owner; uint8 public decimals; uint256 public totalSupply; // owner -> spender -> allowance // this enables an owner to give allowance to multiple addresses mapping(address => mapping(address => uint256)) public allowance; event Transfer( address indexed _from, address indexed _to, uint256 _value ); event Approval( address indexed _owner, address indexed _spender, uint256 _value ); constructor( string memory _name, string memory _symbol ) { name = _name; symbol = _symbol; decimals = 18; owner = msg.sender; } function mint( address to, uint256 amount ) public { require(msg.sender == owner, "only owner can create tokens"); totalSupply += amount; balanceOf[owner] += amount; emit Transfer(address(0), owner, amount); } function transfer( address to, uint256 amount ) public returns (bool) { return helperTransfer(msg.sender, to, amount); } function approve( address spender, uint256 amount ) public returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public returns (bool) { if (msg.sender != from) { require( allowance[from][msg.sender] >= amount, "not enough allowance" ); allowance[from][msg.sender] -= amount; } return helperTransfer(from, to, amount); } function helperTransfer( address from, address to, uint256 amount ) internal returns (bool) { require(balanceOf[from] >= amount, "not enough money"); require(to != address(0), "cannot send to address(0)"); balanceOf[from] -= amount; balanceOf[to] += amount; emit Transfer(from, to, amount); return true; } } |
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۱۶ اردیبهشت ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++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
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس