آموزش مپینگ ها (Mappings) در سالیدیتی
در زبان های برنامه نویسی مختلف، ساختارهایی مانند HashMap
، Associative Array
یا Map
وجود دارند که به شما اجازه میدهند یک مقدار را به یک کلید خاص اختصاص دهید. در سالیدیتی نیز ساختاری مشابه به نام mapping وجود دارد. ما هم از واژه “مپینگ” استفاده میکنیم چون این همان کلیدواژهای است که سالیدیتی از آن استفاده میکند.
تعریف اولیه mapping در سالیدیتی
1 2 3 4 5 6 7 8 9 10 11 12 |
contract ExampleContract { mapping(uint256 => uint256) public myMapping; function setMapping(uint256 key, uint256 value) public { myMapping[key] = value; } function getValue(uint256 key) public view returns (uint256) { return myMapping[key]; } } |
در مثال بالا، با استفاده از mapping
، یک عدد (کلید) را به عددی دیگر (مقدار) نگاشت میکنیم. از آنجایی که متغیر myMapping
عمومی (public) تعریف شده، کامپایلر بهصورت خودکار یک تابع دسترسی (getter) برای آن تولید میکند. بنابراین، میتوانید با وارد کردن کلید مورد نظر، مقدار متناظر را دریافت کنید.
اما اگر بخواهید از طریق تابع خاصی به مقدار دسترسی داشته باشید، میتوانید مانند تابع getValue
عمل کنید.
نکته شگفتانگیز اول: کلیدهای تنظیم نشده خطا ایجاد نمیکنند
اگر به mapping
با کلیدی که هنوز مقداردهی نشده دسترسی پیدا کنید، با خطا مواجه نمیشوید. در عوض، مقدار پیش فرض (zero value) نوع داده مربوطه برگردانده میشود.
در مثال زیر، اگر عددی را وارد کنید که هنوز تنظیم نشده باشد، مپینگ مقدار false را برمیگرداند.
1 2 3 4 5 6 7 8 9 10 11 |
contract ExampleContract { // returns false by default mapping(uint256 => bool) public mapToBool; // returns 0 by default mapping(uint256 => uint256) public mapToUint; // returns 0x0000000000000000000000000000000000000000 by default mapping(uint256 => address) public mapToAddress; } |
پیشنهاد میشود این قرارداد را در محیط Remix امتحان کرده و کلید های مختلف را بررسی کنید تا متوجه رفتار آن با کلید های ناموجود شوید.
مپینگ ها در توکن های ERC20
در قراردادهای ERC20 نیز از mapping
برای ذخیره تعداد توکن های هر کاربر استفاده میشود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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 reciever's balance } } |
البته این پیاده سازی امنیت ندارد چون هرکسی میتواند هر تراکنشی را انجام دهد، اما در آموزشهای بعدی این موضوع اصلاح خواهد شد.
بر خلاف تصور عموم، توکن های ERC20 در کیف پول ها ذخیره نمیشوند. آنها فقط یک عدد صحیح (uint256
) در یک قرارداد هوشمند هستند که به آدرس شما نسبت داده شدهاند.
برای نمونه، میتوانید قراردادهای زیر را ببینید:
-
قرارداد توکن USDC:
etherscan.io/token/USDC -
قرارداد توکن APE (ApeCoin):
etherscan.io/token/APE
نکته شگفتانگیز دوم: مپینگ ها فقط در فضای ذخیره سازی (Storage) تعریف میشوند
این ممکن است یک محدودیت بسیار عجیب به نظر برسد، اما مپینگ ها نمیتوانند درون یک تابع تعریف شوند و این به نحوه عملکرد ماشین مجازی اتریوم (EVM) مربوط میشود. بلاکچین ها به طور کلی HashMap
را به دلیل زمان اجرای غیرقابل پیشبینیشان دوست ندارند. کد زیر نامعتبر است:
1 2 3 4 5 6 7 8 9 |
contract BrokenContract { function wontWork() public view { mapping(uint256 => uint256) someMap; // This won't compile, mappings must be state variables } } |
نکته شگفتانگیز سوم: امکان پیمایش (iteration) روی مپینگ ها وجود ندارد
در سالیدیتی راهی برای پیمایش کلید های یک مپینگ وجود ندارد، زیرا هر مقدار کلیدی از نظر فنی معتبر تلقی میشود و فقط در صورت مقداردهی نشده بودن، مقدار پیشفرض را بازمیگرداند. به همین دلیل نمیتوان از حلقه for
روی مپینگ استفاده کرد.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
contract BrokenContract { mapping(uint256 => uint256) public someMap; function wontWork() public view { for (uint256 key in someMap) { // Corrected to valid Solidity syntax, though the logic still // won't compile in Solidity // do something } } } |
نکته شگفت انگیز چهارم: مپینگ ها را نمیتوان از توابع برگرداند
در سالیدیتی، نمیتوان مپینگ ها را مستقیماً از توابع بازگرداند، حتی اگر تابع view
باشد. کد زیر نامعتبر است:
1 2 3 4 5 6 7 8 9 10 |
contract BrokenContract { mapping(uint256 => uint256) public someMap; function wontWork() public view returns (mapping(uint256 => uint256)) { return someMap; // This will not compile, as mappings cannot be returned from public functions } } |
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۱۰ اردیبهشت ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++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
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس