آموزش msg.sender و address(this) در سالیدیتی
مثال قبلی مان از یک توکن ERC20 بد را به خاطر دارید؟
دوباره در این مورد صحبت میکنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
contract ERC20Token { mapping(address => uint256) public balances; function setSomeonesBalance( address owner, uint256 amount ) public { balances[owner] = amount; } function transferTokensBetweenAddresses( address sender, address receiver, uint256 amount ) public { balances[sender] -= amount; // deduct/debit the sender's balance balances[receiver] += amount; // credit the receiver's balance } } |
در این کد، هیچ راهی برای تشخیص اینکه چه کسی تابع را فراخوانی کرده وجود ندارد.
راهحل: استفاده از msg.sender
خوشبختانه سالیدیتی مکانیزمی برای تشخیص فراخواننده تابع ارائه میدهد: msg.sender
. این ویژگی، آدرس فرد یا قرارداد فراخواننده تابع را بازمیگرداند.
به مثال زیر در Remix توجه کنید:
1 2 3 4 5 6 7 8 9 |
contract ExampleContract { function whoami() public view returns (address) { address sender = msg.sender; return sender; } } |
این تابع آدرسی را بازمیگرداند که با آن در حال تست در Remix هستید.
حال آدرس تست را از منوی کشویی “ACCOUNT” تغییر دهید و دوباره تابع را اجرا کنید. خواهید دید که آدرس برگشتی تغییر میکند.
با ترکیب msg.sender
با یک شرط if
میتوانید به آدرس های خاصی دسترسی ویژه بدهید. مثلاً اگر بخواهید فقط آدرس پیشفرض در Remix بتواند تغییراتی ایجاد کند:
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 |
contract ERC20Token { address public banker = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4; mapping(address => uint256) public balances; function setSomeonesBalance( address owner, uint256 amount ) public { if (msg.sender == banker) { balances[owner] = amount; } // do nothing } function transferTokensBetweenAddresses( address sender, address receiver, uint256 amount ) public { if (msg.sender == banker) { balances[sender] -= amount; // deduct/debit the sender's balance balances[receiver] += amount; // credit the reciever's balance } // do nothing } } |
در کد بالا، کاربران میتوانند موجودی خود را ببینند (چون balances
عمومی است)، اما فقط بانکدار (banker) اجازه تغییر موجودیها را دارد.
بهبود: امکان انتقال توسط کاربر
با کمی خلاقیت، میتوانیم اجازه دهیم کاربران خودشان موجودیشان را به آدرس دیگری منتقل کنند، بدون اینکه بانکدار دخالتی داشته باشد:
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 |
contract ERC20 { address public banker = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4; mapping(address => uint256) public balances; function setSomeonesBalance( address owner, uint256 amount ) public { if (msg.sender == banker) { balances[owner] = amount; } // do nothing } function transfer( address receiver, uint256 amount ) public { balances[msg.sender] -= amount; balances[receiver] += amount; } } |
در این نسخه، هر فردی میتواند با فراخوانی transfer
، موجودی خود را به شخص دیگری منتقل کند. اما فقط میتواند از حساب خودش برداشت کند، نه از حساب دیگران. بهعنوان تمرین، فکر کنید که چرا امکان دزدی از حساب دیگران با این روش وجود ندارد.
اگر کاربر بیش از موجودی خود انتقال دهد چه میشود؟
اگر از سالیدیتی نسخه ۰.۸.۰ یا بالاتر استفاده میکنید، چنین تراکنشی شکست میخورد (revert میشود). زیرا امکان ندارد یک عدد بدون علامت (unsigned integer) را بهگونهای کم کنید که منفی شود.
tx.origin
؛ و چرا نباید از آن استفاده کنید
سالیدیتی یک ویژگی دیگر هم دارد به نام tx.origin
که مشابه msg.sender
عمل میکند. اما نباید از آن استفاده کنید، مگر در شرایط خاص. دلایل امنیتی آن را فعلاً مطرح نمیکنیم، اما نکته مهم این است:
بههیچوجه از tx.origin
در منطقهای احراز هویت استفاده نکنید.
address (this)؛ شناسایی آدرس خود قرارداد
هر قرارداد هوشمند میتواند آدرس خودش را بشناسد. بهسادگی از address(this)
استفاده میکنیم:
1 2 3 4 5 6 7 8 9 |
contract ExampleContract { function whoami() public view returns (address) { return address(this); } } |
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۹ اردیبهشت ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++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
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس