مکان داده در برنامه نویسی سالیدیتی
31 اردیبهشت 1401 1401-03-22 13:32مکان داده در برنامه نویسی سالیدیتی
مکان داده در برنامه نویسی سالیدیتی
هر متغیری که در سالیدیتی اعلان و در یک قرارداد بکار گرفته می شود یک یک مکان یا به عبارد دیگر یک Data Location دارد.مکان داده مشخص می کند که مقدار آن متغیر باید در کجا ذخیره شود.در این مقاله به بررسی مختصر مکان داده در برنامه نویسی سالیدیتی می پردازیم.جهت دریافت اطلاعات بیشتر توصیه می کنیم مقالات و محتواهای آموزش زبان سالیدیتی را هم مطالعه نمایید
- هر آنچه که باید در مورد اتریوم بدانید
- قرارداد هوشمند یا اسمارت کانترکت (Smart Contract) چیست؟
- انواع داده ها و متغیرها در زبان برنامه نویسی سالیدیتی
هر داده پیچیده، علاوه بر نوع، ویژگی دیگری بنام Data Location دارد که نشان میدهد آن داده در کجای حافظه ذخیره میشود. در زبان برنامه نویسی سالیدیتی چهار نوع Data Location داریم.
مکان داده در برنامه نویسی سالیدیتی (Storage)
حافظه همگانی و قابل دسترس برای همه توابع قرارداد.از Storage برای ذخیره سازی ثابت و دائمی و پایا استفاده می شود.متغیر های State (متغیرهای دائمی) همیشه در مکان حافظه Storage ذخیره می شوند.داده های Storage بطور دائمی در بلاکچین ذخیره می شوند.بنابراین Gas بیشتری مصرف می کنند.متغیر اگر در storage ذخیره شود به این معناست که دیتای آن برای همیشه در بلاکچین نگه داری می شود. (مثل نگه داری اطلاعات در disk کامپیوتر).
مکان داده در برنامه نویسی سالیدیتی (Memory)
دادههای این بخش از حافظه به صورت موقت ذخیره میشوند و زمان اجرای آنها محدود به زمان اجرای تابع است.این مکان داده حافظه محلی قابل دسترس برای هر تابع قرارداد می باشد هم چنین مکان داده در بخش memory حافظه کوتاه مدت و زودگذر می باشد که با تکمیل شدن اجرای تابع، به اتمامی می رسد.داده های این بخش حافظه به طور موقت ذخیره می شوند و زمان اجرای آن محدود به اجرای تابع است.هم چنین داده های memory در بلاکچین ذخیره نمی شوند.
اجرای هر تراکنش در شبکه اتریوم شامل هزینهای موسوم به گس است. هر چقدر کدی که نوشته میشود، گس کمتری مصرف کند، کد بهینهتری است. گسی که حافظه memory مصرف میکند، در مقابل گسی که حافظه storage مصرف میکند، بسیار ناچیز است. بنابراین، بهتر است محاسبات میانی روی حافظه memory صورت گیرد و فقط نتایج محاسبات در storage نوشته شود.متغیر اگر در memory ذخیره شود دیتای آن موقتی است و از بین می رود. ( مثل ذخیره سازی در RAM کامپیوتر).
خوشبختانه compiler زبان برنامه نویسی solidity قابلیت تشخیص این مورد را دارد.
در ورژنهای قبلی سالیدیتی ، پارامترهای توابع در memory ذخیره میشد (به جز توابع external که پارامترها در calldata ذخیره میشدند). در ورژنهای جدید سالیدیتی، برای دادههای پیچیده، در پارامتر ورودی و خروجی تابع باید نوع حافظه مشخص باشد.
در ورژنهای جدید برنامه نویسی سالیدیتی، برای پارامترهای ورودی و خروجی توابع اگر از نوع دادههای پیچیده باشند، باید مکان داده را صراحتا مشخص کنیم.وقتی قرار است پارامتر ورودی یک تابع، یک داده پیچیده از متغیرهای سراسری باشد باید مشخص کنیم که storage است.
مقایسه memory و storage
حافظه memory در سالیدیتی مکانی موقتی برای ذخیره دادههاست؛ در حالیکه حافظه storage دادهها را به صورت دائمی بین اجراهای توابع نگهداری میکند
مقدار Gas که حافظه memory مصرف میکند، در مقابل مقدار گس که حافظه storage مصرف میکند، بسیار ناچیز است. بنابراین، بهتر است محاسبات میانی روی حافظه memory صورت گیرد و فقط نتایج محاسبات در storage نوشته شود.
State variables ها همیشه در مکان داده storage ذخیره می شوند. مانند کد زیر
pragma solidity ^0.5.0;
contract DataLocation {
//storage
uint stateVariable;
uint[] stateArray;
}
Local variables ها همراه با نوع value در memory ذخیره می شوند.مانند کد زیر
pragma solidity ^0.5.0;
contract Locations {
/* these all are state variables */
//stored in the storage
bool flag;
uint number;
address account;
function doSomething() public {
/* these all are local variables */
//value types
//so they are stored in the memory
bool flag2;
uint number2;
address account2;
//reference type
uint[] memory localArray;
}
}
function visibility در سالیدیتی و کاربردآن
آشکار بودن یک کلاس، یک متد، یک متغیر یا یک ویژگی به ما می گوید که چگونه می توان به آن آیتم دسترسی پیدا کرد. متداول ترین نوع سطح دسترسی visibility ؛ public یا private بودن می باشد در بخش زیر به تعریف انواع function visibility در زبان برنامه نویسی سالیدیتی و توضیح در مورد هر مورد می پردازیم.
- private: فقط از داخل همین قرارداد به تابع دسترسی داریم.
- internal: فقط از داخل همین قرارداد و قراردادهای فرزند به تابع دسترسی داریم.
- external: فقط از خارج قرارداد به تابع دسترسی داریم.
- public: هم از داخل و هم از خارج قرارداد به تابع دسترسی داریم.
مکان داده در برنامه نویسی سالیدیتی (calldata)
مکانی از حافظه که برای ذخیره سازی پارامترهای توابع استفاده میشود. دادههای این بخش از حافظه Read-Only هستند. calldata بسیار شبیه memory عمل میکند.این مدل Data Location یک ذخیره سازی خاص است که برای استفاده آرگومان های تابع را ذخیره می کند.این فضا یک فضای فقط خواندنی است.calldata نسبت به Memory مقدار گس (Gas) کمتری مصرف می کند.اما این نوع مکان داده محدیدیت های دارد از جمله غیرقابل تغییر بودن آن و فقط خواندنی بودن آنوقتی تابعی، خارج از قرارداد فراخوانی میشود، پارامترهایی که فراخواننده ارسال میکند، در calldata ذخیره میشوند. از این حافظه فقط در پارامترهای ورودی و خروجی توابع استفاده میشود.برخلاف ورژنهای قبلی که استفاده از calldata محدود به توابع external بود، در ورژنهای جدید، محدودیتی در استفاده از کلمههای کلیدی private، internal، external و public وجود ندارد. گرچه استفاده از calldata در توابع private و internal در حال حاضر کاربردهای محدودتری دارد.
دقت کنید که زمانی پارامتر خروجی میتواند از نوع calldata باشد که بخواهیم یک پارامتر ورودی از نوع calldata را به همان صورت برگردانیم؛ زیرا، همانطور که گفته شد، calldata فقط خواندنی است، پس نمیتوان متغیری از نوع calldata را داخل توابع ایجاد کرد و فقط میتوان آرگومان ورودی تابع از نوع calldata را به همان صورت برگرداند که میتواند کاربرد خودش را داشته باش.
طبق داکیومنت سالیدیتی، تا جاییکه امکان دارد، بهتر است از calldata استفاده شود.
مکان داده Stack در سالیدیتی
Stack یک داده غیر پایدار است که توسط EVM (ماشین مجازی اتریوم) نگهداری می شود. EVM از محل داده پشته برای بارگذاری متغیرها در حین اجرا استفاده می کند. مکان پشته تا 1024 سطح محدودیت دارد.
EVM یک پشته برای بارگزاری متغیرها و مقادیر میانی نگهداری می کند.
پشته یک ساختار داده LIFO باشد. LIFO اختصاری برای عبارت Last-in-first-out است یعنی ورودی-آخر- خروجی-اول. در اصطلاحشناسی پشته عملیات درج به نام عملیات PUSH نامیده و عملیات حذف به نام POP خوانده میشود.
عملیاتهای ابتدایی ممکن است شامل راهاندازی اولیه پشته، استفاده و تخریب آن باشد. علاوه بر آن وقتی عنصری در پشته قرار میگیرد، معمولاً از این دو عملیات ابتدایی استفاده میشود:
- ()Push: فرایند قرار دادن یک عنصر جدید در پشته به نام عملیات push شناخته میشود
- ()Pop: دسترسی به محتوای پشته در هنگام حذف آن، به نام عملیات pop شناخته میشود.
در بخش زیر نمونه یک فایل سالیدیتی را مشاهده می کنید که دارای کدهای مکان داده در برنامه نویسی سالیدیتی متشکل شده است.
منبع: وب سایت c-sharpcorner