Mapping در قرارداد هوشمند Solidity
Mapping در سالیدیتی چیست؟
Mapping در سالیدیتی یا solidity mapping یا همان را میتوان معادل همان dictionary در زبان برنامهنویسی پایتون یا hash table و map در زبان برنامهنویسی جاوا اسکریپت دانست. پایتون امکان تکرار را از طریق یک dictionary و جاوا اسکریپت امکان تکرار را از طریق یک map برای کاربر فراهم میکند. با این وجود در زبان برنامهنویسی سالیدیتی شما نمیتوانید از طریق mapping تکرار کنید.
به طور کلی به هر نوع متغیری در قرارداد هوشمند که یک نوع کلید و یک نوع ارزش داشته باشد، mapping در قرارداد هوشمند سالیدیتی میگویند. mapping در قرارداد هوشمند بیشتر به منظور برقراری ارتباط بین یک آدرس اتریومی با مقداری مرتبط مورد استفاده قرار میگیرد و برای ما امکان ذخیره دادههایمان را در یک تابع و از طریق رابطه بین جفت کلید به ارزش فراهم میکند.
واژه mapping در فارسی نقشهبرداری یا نگاشت هم ترجمه میشود و به منظور برقراری ارتباط بین انواعی از دادههای مختلف به عنوان نمونه بین address و amount یا بین uint و bool بسیار سودمند است. اگر اطلاعات بیشتری در مورد استفاده از mapping در قرارداد هوشمند سالیدیتی نیاز دارید، با این مقاله در توکن خان همراه باشید.
قبل از مطالعه کامل مقاله “Mapping در سالیدیتی” پشنهاد میکنیم مقالات دیگر حوزه آموزش زبان سالیدیتی را هم مطالعه کنید.
رویدادها Events در برنامه نویسی Solidity
تابع بازگشتی Fallback Function در سالیدیتی
توسعه قرارداد هوشمند در محیط ریمیکس Remix
توابع modifiers در سالیدیتی solidity
حلقه های تکرار در سالیدیتی Solidity Loop
دستور Enums در برنامه نویسی سالیدیتی
معرفی زبان برنامهنویسی سالیدیتی Solidity
زبان برنامهنویسی سالیدیتی زبانی شیگرا و سطح بالا است که در سال 2014 توسط ویتالیک بوترین(که خالق اتریوم میشناسندش)، گاوین وود یکی از بنیانگذاران اتریوم و چند نفر دیگر برای بلاک چین اتریوم معرفی شد. سالیدیتی بسیار پرکاربرد است و از آن برای نوشتن قراردادهای هوشمند در بلاک چین اتریوم و پس از آن دیگر بلاک چینها استفاده میشود. منابع فارسی زیادی برای یادگیری این زبان برنامهنویسی موجود نمیباشد اما یادگیری آن با توجه به گسترش ارزهای دیجیتال و کاربرد قراردادهای هوشمند بسیار ارزشمند است.
نکاتی در مورد Mapping در سالیدیتی
نکات قابل توجه در مورد mapping به ترتیب زیر است:
- Mappingها برای سرعت بخشیدن به جستجو بسیار مناسب هستند.
- Mappingها طول ندارند.
- یکmapping را به صورت پیشفرض نمیتوانید تکرار کنید.
- برای تکرار یک mapping نیاز دارید تا از ترکیب آنها استفاده کنید و کلیدهای آن را در یک آرایه (array) ذخیره کنید.
- اندازه یک mapping را نمیتوان مشخص یا محاسبه کرد.
- از mappingها عموماً برای state variableها که مرجع ذخیرهسازی داده در حافظه ی اسمارت کانترکت هستند، استفاده میشود.
سینتکس mapping به صورت “mapping(_KeyType => _ValueType) public mappingName” اجرا میشود و مانند انواع متغیرهای دیگر سالیدیتی تعریف میشود. keyType هر نوع مقدار داخلی شناخته شده توسط ماشین مجازی اتریوم، مانند bytes یا string میتواند باشد که به شکل uint، bool یا address ترجمه خواهد شد اما نمیتواند struct ، array، enum و یا Mapping باشد. ValueType هم میتواند از هر نوع متغیری مانند mappings ، arrays و structs باشد که این تنوع موجب انعطافپذیری و راحتی بسیار زیادی در mapping خواهد شد.
mapping تودرتو در قرارداد هوشمند سالیدیتی چیست؟
امکان استفاده از mapping تودرتو یا nested mapping نیز در برنامهنویسی سالیدیتی وجود دارد که سینتکس آن به ترتیب زیر است:
1 |
mapping(_KeyType => mapping(_KeyType => _ValueType)) public mappingName; |
همانطور که در سینتکس mapping بالا مشاهده میکنید، در mapping تودرتو یک کلید با یک نوع مقدار از mapping دیگری ارتباط برقرار میکند. این نوع از mapping در برخی موارد به کار میآید، اجازه بدهید برای درک بهتر mapping تودرتو در سالیدیتی از یک مثال استفاده کنیم.
فرض کنید شخصی با نام اکبر در والت کریپتویی خودش 20 اتریوم دارد، او قصد دارد از این حساب یک کمک هزینه allowance به میزان 5 اتریوم به اصغر و یک کمک هزینه به میزان 3 اتریوم به عباس بدهد. برای اینکه این قصد خود را پیاده کند او به یک mapping تودرتو احتیاج دارد. در معماری پایگاه داده رابطهای، به این رابطه یک به چند گفته میشود. به این معنی که یک مالک به بیشتر از یک مصرف کننده امکان خرج کردن توکنهایش را از طرف مالک میدهد.
نمونه این نوع از mapping تودرتو را در قرارداد استاندارد ERC20 در تابع کمک هزینه میتوان مشاهده کرد که یک کاربرد بسیار گسترده دارد. در تصویر زیر mapping تودرتو در قرارداد کمک هزینه contract allowance را مشاهده میکنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
pragma solidity ^0.8.0; contract allowance { //mapping an address to another mapping. This is a one to many relationship mapping(address => mapping(address => uint)) public allowance; //this function returns the allowance/amount that the owner permissioned to the spender function get(address _addrOwner, address _addrSpender) public view returns (uint) { return allowance[_addrOwner][_addrSpender]; } //this function sets the amount of allowance the owner gives to the spender function set(address _addrOwner, address _addrSpender, uint _amt) public { allowance[_addrOwner][_addrSpender] = _amt; } //this function removes the spenders allowance function remove(address _addrOwner, address _addrSpender) public { delete allowance[_addrOwner][_addrSpender]; } } |
یک مثال برای Mapping در سالیدیتی
حال بیائید با هم نحوه عملکرد mapping را با یک مثال بررسی کنیم. جدول زیر مربوط به شماره اتاقهای یک هتل است که نام مهمان هر اتاق نیز در مقابل آن مشخص شده است. با نگاه کردن به این جدول میتوانید بهتر به رابطه جفت کلید – مقدار پی ببرید. به این ترتیب خواهید دید که مجموعهای منحصربهفرد از کلیدها با یک مقدار منحصربهفرد تطابق دارد. مثلا برای کلید “102” شما مقدار “Sara” را دریافت میکنید. (به بیانی ساده تر، شما مقدار 102 را به عنوان ورودی به mapping میدهید و در ازای آن، mapping به شما مقدار موجود در values را(که همان sara است) را بر میگرداند.)
شما میتوانید نحوه ایجاد یک mapping در قرارداد هوشمند را در کد زیر مشاهده کنید:
1 2 3 4 5 6 |
pragma solidity ^0.8.0; contract MyContract { mapping(uint => string) public names; } |
ابتدای این دستور را باید با کلمه کلیدی mapping اعلام کرده و در ادامه نوع داده را برای کلید و مقدار مشخص کنید. در این مورد هر کلید در mapping یک uint خواهد بود و هر مقدار مربوط به آن یک string خواهد بود. قبل از اینکه این قرارداد هوشمند را اجرا کنیم تا به چگونگی عملکرد mapping برسیم، مقداری داده را اضافه میکنیم. برای این کار از تابع constructor استفاده خواهیم کرد.
1 2 3 4 5 6 |
constructor() public { names[101] = "Jon"; names[102] = "Sara"; names[103] = "Paul"; } } |
حال میتوانید قرارداد هوشمند نمونه خود را در Remix دیپلوی کنید تا ببینید چگونه کار میکند. پس بر روی Deploy کلیک کنید.
وقتی قرارداد دیپلوی شد، میتوانید Mapping در سالیدیتی را در عمل مشاهده کنید به این منظور یک ورودی به آن بدهید و بر روی call کلیک کنید. همانطور که در تصویر زیر میبینید، در این مثال مقدار برای کلید “101” خواسته شده است و در پاسخ “Jon” دریافت شده است.
خواندن یک آیتم در Mapping
برای خواندن یک آیتم از Mapping در سالیدیتی میتوان تابعی مثلاً به نام function get تعریف کرد که این تابع به نحوه دسترسی به دادهها در یک آرایه array شباهت دارد.
حذف یک آیتم در Mapping
برای حذف کردن یک داده از Mapping در سالیدیتی نیز میتوان تابعی مثلاً به نام function remove تعریف کرد. حال در تصویر زیر یک قرارداد را داریم که به ترتیب شامل موارد زیر است:
- یک Mapping که تحت عنوان myMap تعریف شده است که یک state variable(جهت یادآوری: state variable ها در بلاکچین ذخیره میشوند)
- یک تابع تحت عنوان function set که برای تنظیم یک مقدار به یک آدرس خاص آورده شده است.
- یک تابع تحت عنوان function get که برای دریافت مقدار ذخیره شده برای یک آدرس آورده شده است.
- و در انتها یک تابع تحت عنوان function remove که برای حذف کردن مقداری که قبلا برای یک آدرس تعریف شده بود، آورده شده است.
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 |
pragma solidity ^0.8.0; //Sample contract contract SampleContract { //state variables //added a map that takes an address "key" and a number "value" //the name of the map is called myMap mapping (address => bool) public myMap; //this function sets a value to a specific address //the data is saved to myMap on the block chain function set(address _addr, bool _i) public { myMap[_addr] = _i; } //this function gets a value from a specific address from the map //If a value was not set the function will return the default value of 0. function get(address _addr) public view returns (bool) { return myMap[_addr]; } //this function deletes a value from the map and sets it to the default value of 0 function remove(address _addr) public { delete myMap[_addr]; } } |
سخن آخر
در زبان برنامه نویسی سالیدیتی هر زمان که بخواهید مجموعهای از دادهها را ذخیره کنید میتوانید از آرایه array و یا mapping استفاده کنید. Array ها به نوعی با mappingها قابل مقایسه هستند، در زبان برنامهنویسی سالیدیتی، mapping شباهت بسیاری به جدول هش یا همان hash table یا dictionary در زبانهای برنامهنویسی دیگر دارد و تقریباً به همان صورت عمل میکند. این توابع به منظور ذخیره کردن دادهها به شکل جفتهای کلید – مقدار (key – value) کاربرد دارند و کلید میتواند هر یک از انواع دادههای داخلی به جز reference type باشد و مقدار نیز میتواند از هر نوعی باشد.
به طور معمول یکی از عمده کارایی های mapping در قرارداد هوشمند سالیدیتی برای جفت کردن یک آدرس اتریومی منحصربهفرد به یک نوع مقدار مرتبط با آن استفاده میشود. mapping در حقیقت انواعی از دادهها در زبان برنامهنویسی سالیدیتی هستند که طول ندارند. Iterable mapping یا پیمایش کردن در mapping ها بهصورت پیشفرض قابل انجام نیست و اگر بخواهیم این کار را بکنیم، باید از طریق library هایی که طراحی شده اند، این کار را انجام داد. mapping ها مانند آرایهها قابل دسترسی هستند اما یک مزیت عمده دارند، همه جفتهای کلید – مقدار با مقدار پیشفرض خود مقداردهی اولیه میشوند.
منابع معتبر مرتبط:
مطالب زیر را حتما مطالعه کنید
بررسی رفتار توابع View و Pure در سالیدیتی Solidity
توابع Payable در قراردادهای هوشمند Solidity
سالیدیتی Solidity چیست؟
سطح دسترسی Visibility در سالیدیتی Solidity
توابع Function در سالیدیتی Solidity
انواع حافظه در قرارداد هوشمند سالیدیتی
7 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
واقعا ارزش وقت گذاشتن داشت
حرف نداشت👌🏻
موضوعات کریپتو یکی از موضوعات موردعلاقه منه
سلام عالی بود
من یکی از کاربران دائمی سایت شما هستم
خیلی محتوای خوبی بود مهندس
احسنت عالی بود