مکان داده در برنامه نویسی سالیدیتی
مکان داده در زبان سالیدیتی چیست؟
در زبان برنامهنویسی سالیدیتی تمام متغیرهای حالت state variables و متغیرهای محلی local variables دارای یک مکان داده data location in solidity هستند. این مکان داده در سالیدیتی یا به صورت پیشفرض مشخص شده است و یا میتوانید به صراحت، یک مکان داده انتخابی را برای آنها تعریف کنید. با این مکانهای داده با نام حافظه memory و ذخیره سازی storage تا حدی آشنایی دارید.
شما میتوانید مکان داده پیشفرض را همراه با اعلان متغیر و مشخص کردن آن به صراحت لغو کنید. در زمانی که از انواع دادههای پیچیده مانند آرایهها (arrays)، بایتها (bytes) و ساختارها (structs) استفاده میکنید باید یک مکان داده تعریف کنید. مکان داده موضوعی است که تا حد زیادی به معماری ماشین مجازی اتریوم یا همان Evm مربوط میشود. با این مقاله در توکن خان همراه باشید تا با مفهوم مکان داده در برنامه نویسی سالیدیتی و انواع آن بیشتر آشنا شوید.
قبل از مطالعه کامل مقاله “مکان داده در برنامه نویسی سالیدیتی” پیشنهاد میکنیم مقالات دیگر حوزه آموزش جامع سالیدیتی را هم مطالعه کنید.
آرایه ها (Array) در زبان برنامه نویسی Solidity
Struct در قراردادهای هوشمند سالیدیتی Solidity
Interface در قراردادهای هوشمند Solidity
مدیریت خطا در سالیدیتی Error Handling
Mapping در قرارداد هوشمند Solidity
کاربردهای برنامه نویسی سالیدیتی
اهمیت یادگیری و درک مکان داده در سالیدیتی
یادگیری چگونگی عملکرد هر مکان داده چند موضوع را در برمیگیرد، یکی ساختار و آرایش این مکانهای داده و دیگری اینکه چه چیزی را میتوانیم در کجا ذخیره کنیم. اما یک موضوع مهمتر در این میان یادگیری این است که هزینه مربوط به هر یک از آنها یا گس پرداختی برای هر مکان داده چقدر است.
در نتیجه میتوان مزایای یادگیری و درک مکان داده در سالیدیتی و در ماشین مجازی اتریوم (Evm) که به استفاده بهتر و مناسبتر از آن منجر میشود را شامل موارد زیر دانست:
- شما میتوانید عملکرد قرارداد هوشمند خود را بهبود ببخشید.
- هزینه اجرای آن قرارداد هوشمند را به حداقل برسانید. (منظور از این هزینه، گس مورد استفاده در زمان فراخوانی توابع داخلی یا عمومی است.)
- امنیت را بیشتر کنید و از بروز مشکلات و خطاهای بالقوه جلوگیری کنید.
انواع مکان داده در برنامه نویسی سالیدیتی
بررسی مکان داده در سالیدیتی به بررسی مکانی میپردازد که میتوان دادهها را در آن نوشت و یا از آن خواند. حال اینکه برخی از این مکانهای داده فقط خواندنی هستند و نمیتوان در آنها را نوشت، در حالی که برخی قابل تغییر هستند و مقادیر ذخیره شده در داخل آنها را میتوان ویرایش کرد.
به طور کلی 5 مکان داده اصلی وجود دارد که شامل موارد زیر است:
- ذخیره سازی (Storage)
- حافظه (Memory)
- Calldata
- پشته (Stack)
- کد (Code)
مکان داده ذخیره سازی
مکان داده ذخیره سازی جایی است که تمام متغیرهای حالت یک قرارداد در آن قرار دارند. هر قراردادی یک مکان داده ذخیره سازی storage مخصوص به خود دارد و این مکان داده بین فراخوانی توابع باقی میماند. متغیرهایی که در این storage ذخیره میشوند در واقع به طور دائم و همیشگی در بلاک چین ذخیره میشوند و باقی میمانند. استفاده از این مکان داده بسیار گران است و گس بیشتری مصرف میکند.
امکان خواندن دادهها از این مکان داده و همچنین نوشتن دادهها در این مکان داده وجود دارد. این مکان داده همگانی و قابل دسترس برای تمام توابع سالیدیتی است و از آن به عنوان مکان داده ثابت، دائمی و پایا استفاده میشود. در نتیجه متغیرهایی که در این مکان داده در سالیدیتی ذخیره میشوند متغیرهایی دائمی مانند متغیرهای حالت هستند.
مکان داده حافظه
مکان داده حافظه مکانی موقتی برای نگهداری دادهها است و بین فراخوانی توابع خارجی به قراردادهای دیگر پاک میشود. در واقع زمان اجرای دادههای این مکان داده به زمان اجرای تابع محدود شده است. استفاده از این مکان داده ارزانتر است و برای نگهداری مقادیر موقت استفاده میشود.
مکان داده Memory فرار است و این محیط به یک قرارداد خاص اختصاص دارد، بدین معنی که whiteboard/scratchpad پس از تغییر زمینه اجرا از یک قرارداد به قرارداد دیگر پاک میشود. در هر پیام فراخوانی جدید یک نمونه تازه پاک شده از مکان داده حافظه فراهم میشود.
امکان خواندن دادهها از این مکان داده و همچنین نوشتن دادهها در این مکان داده وجود دارد. این مکان داده محلی و قابل دسترس برای هر تابع در قرارداد هوشمند سالیدیتی است و از آن به عنوان مکان داده کوتاه مدت، موقتی و زودگذر استفاده میشود، مکان دادهای که با تکمیل اجرای تابع تمام میشود. در نتیجه دادههایی که در این مکان داده در سالیدیتی ذخیره میشوند متغیرهایی موقتی هستند که در بلاک چین ذخیره نمیشوند.
مکان داده Calldata
مکان داده calldata مکانی است که دادههای یک تراکنش یا پارامترهای فراخوانی تابع خارجی در آن قرار دارند. امکان خواندن دادهها از این مکان وجود دارد اما نوشتن دادهها در آن امکانپذیر نیست، به بیان دیگر دادههای این مکان داده Read-Only هستند.
این مکان داده بیشتر شبیه حافظه عمل میکند و یک فضای آدرس پذیر بایت byte-addressable است. استفاده از این مکان داده در مقایسه با مکان داده حافظه، گس مصرفی کمتری میخواهد اما نسبت به آن کاستیها و محدودیتهایی مانند تغییرناپذیر بودن و نبود امکان نوشتن در آن را دارد. از این مکان داده تنها برای پارامترهای ورودی و خارجی توابع سالیدیتی در قرارداد هوشمند استفاده میشود. طبق مستندات اعلام شده توسط سالیدیتی بهتر است تا جای ممکن از مکان داده calldata استفاده شود.
مکان داده پشته
از این مکان داده در برنامه نویسی سالیدیتی برای نگهداری متغیرهای محلی کوچک استفاده میشود و اغلب استفاده از آن رایگان است (مقدار گس بسیار کمی برای آن مصرف میشود). در عین حال مکان داده پشته اندازه محدودی دارد که تعداد آیتمهای محدودی را در خود جای میدهد.
این مکان داده مکانی است که اکثر متغیرهای محلی ایجاد شده در داخل یک تابع در آن مستقر هستند. Stack به عنوان یک بخش اساسی برای EVM در نظر گرفته میشود که از آن برای بارگذاری متغیرها در حین اجرای قرارداد هوشمند استفاده میکند.
مکان داده کد
مکان داده کد به بایتکد (bytecode) قرارداد اشاره دارد. شما تنها میتوانید از روی بایتکد قرارداد بخوانید اما نمیتوانید در آن بنویسید. این مکان داده، جایی است که میتوانید در آن متغیرهایی را پیدا کنید که در سالیدیتی به عنوان متغیرهای ثابت تعریف شده اند. بایتکد دارای منطق و اطلاعات زیادی درباره قرارداد هوشمند شامل توزیع کننده (dispatcher) و فراداده (metadata) قرارداد است.
جمع بندی
اینکه شما باید از کدام مکان داده در برنامه نویسی سالیدیتی که شامل ذخیره سازی (storage)، حافظه (memory) یا calldata است، استفاده کنید، به کاری بستگی دارد که شما سعی دارید در قرارداد هوشمند خود انجام دهید.
برای انواع دادههای خاص، اگر دادهها بزرگ باشند، کپی کردن آنها از ذخیره سازی به حافظه میتواند بسیار گران باشد. از طرفی در برخی موارد خاص، اگر شما بخواهید متغیر را در تابع لغو کنید و نتایج ذخیره سازی قرارداد را منتشر نکنید، ممکن است نیاز داشته باشید که آنها را از مکان داده ذخیره سازی به مکان داده حافظه منتقل کنید.
از طرف دیگر مکان داده calldata نسبت به حافظه مزایای زیادی دارد که موجب ترجیح دادن آن نسبت به حافظه میشود. این مزایا به ترتیب زیر هستند:
- صرفه جویی در گس با اجتناب از کپی کردن دادهها در حافظه
- امنیت بیشتر (در برخی موارد) با توجه به اینکه مکان داده calldata یک مکان داده فقط خواندنی است، تضمین میکند که دادهها در آن قابل تغییر نیستند. این ویژگی موجب افزایش امنیت میشود به خصوص در زمانی که آرگومان ارسال شده به تابع، دادههای “حساس (sensitive)” را نشان میدهد (برای نمونه میتوان به امضاهای 64 بایتی اشاره کرد).
منابع معتبر مرتبط:
https://medium.com/coinmonks/solidity-fundamentals-a71bf54c0b98
https://soliditytips.com/articles/solidity-data-location-storage-memory
مطالب زیر را حتما مطالعه کنید
بررسی رفتار توابع View و Pure در سالیدیتی Solidity
توابع Payable در قراردادهای هوشمند Solidity
سالیدیتی Solidity چیست؟
سطح دسترسی Visibility در سالیدیتی Solidity
توابع Function در سالیدیتی Solidity
انواع حافظه در قرارداد هوشمند سالیدیتی
8 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
مقالاتتون عالین واقعا!
خیلی محتوای خوبی بود مهندس
بسیار گویا و شفاف بیان کردید
موضوعات سالیدیتی یکی از موضوعات موردعلاقه منه
چه مطلب خوبی
شما پیج اینستا هم دارین؟
خیلی محتوای کامل و عالی بود
ایا مشاوره هم دارین برای خرید ارز؟ قیمت مشاورتون چقدره؟