sepisoltani
sepisoltani
خواندن ۳ دقیقه·۳ سال پیش

بهینه سازی مصرف gas در قرارداد های هوشمند اتریوم


مفهوم gas چیست ؟

در Solidity ، کاربران شما هر بار که تابع یا فانکشنی را در DApp شما فراخوانی می کنند باید gas پرداخت کنند. کاربران gas را با Ether (ارز اتریوم) خریداری می کنند ، بنابراین کاربران شما باید Ether را برای اجرای فانکشن های DApp شما هزینه کنند.


میزان gas مورد نیاز برای اجرای یک تابع بستگی به پیچیدگی منطق آن تابع دارد. هر عملیاتی هزینه gas دارد که بستگی به میزان منابع محاسباتی برای انجام آن عملیات دارد (به عنوان مثال نوشتن در storage بسیار گرانتر از افزودن دو عدد صحیح است و هزینه gas بیشتری دارد). در نهایت مجموع کل gas یک تابع برابر است با مجموع هزینه gas تمام عملیات های آن تابع.

از آنجا که اجرای توابع و فانکشن ها برای کاربران شما هزینه واقعی دارد، بهینه سازی کد در اتریوم بسیار مهم تر از سایر زبان های برنامه نویسی است. اگر کد شما بهینه نباشد، کاربران شما مجبور به پرداخت gas بالا برای انجام توابع شما هستند و این می تواند تا میلیون ها دلار هزینه غیر ضروری برای هزاران کاربر به همراه داشته باشد.

چرا باید برای هر بار فراخوانی توابع در قرارداد هوشمند باید gas پرداخت کنیم؟

اتریوم مانند یک کامپیوتر بزرگ اما کند و بسیار امن است. وقتی یک تابع را اجرا می کنید، هر node در شبکه باید همان تابع را برای تأیید خروجی خود اجرا کند. هزاران node که هر تابع را تأیید می کنند، اتریوم را غیر متمرکز می کنند و داده های آن را تغییر ناپذیر می کنند.

سازندگان اتریوم می خواستند مطمئن شوند که کسی نمی تواند شبکه را با یک حلقه بی نهایت مسدود کند یا تمام منابع شبکه را با محاسبات بسیار زیاد مصرف کند. بنابراین آنها این کار را انجام دادند تا معاملات رایگان نباشند و کاربران باید هزینه زمان محاسبه و همچنین ذخیره را بپردازند.

چطور کد بنویسیم تا هزینه gas پایین بیاید ؟

در زبان برنامه نویسی Solidity هنگام تعریف متغیر ها باید برای آن ها دیتا تایپ خاصی را مشخص کنیم. مثلا string یا uint256 یا uint8 و یا uint32.

فرض کنید در قرارداد زیر ما متغیر های زیر را تعریف کرده ایم :

https://gist.github.com/31263b26e7c30d7deff94e662cac4e22.git


بر خلاف باور شما هیچ فرقی نمیکند که ما یک متغیر را از کدام نوع uint تعریف کنیم . تمام uint ها در زمان تعریف مقدار ۲۵۶ بیت از فضا را اشغال می کنند در نتیجه تعریف کردن uint8 به جای uint256 فرقی در هزینه gas نمی کند . پس کجا می توانیم هزینه gas را بهبود ببخشیم ؟ در هنگام تعریف struct ها .

هنگامی که  uint های مختلفی را داخل یک struct تعریف میکنیم میتوانیم با تعریف uint های کوچک تر این هزینه را کاهش بدهیم . به مثال زیر توجه کنید. فرض کنید ما ۲ عدد struct تعریف کرده ایم :

https://gist.github.com/6b5e7998e2441c02d43704524418ee61.git

در این Contract  دو تا struct تعریف شده . One و Two

زمانی که استراک Two اجرا میشود هزینه gas کمتری نسبت به استراک One دارد . دلیل این مورد این است که در صورتی که در یک استراک تایپ های مختلفی داشته باشیم اگر تایپ های مشابه را کنار همدیکر تعریف کنیم کد از لحاظ هزینه gas  هزینه کمتری را در میطلبد. در استراک Two دو تایپ uint32 داریم که در کنار هم تعریف شده اند. اگر تایپ سوم یعنی uint256 را در بین ان ها قرار میدادیم معادله به هم میخورد و هزینه gas افزایش پیدا میکرد. پس برای بهبود هزینه gas باید در تعریف struct ها دقت به خرج داد. همچنین چون از نوع uint32 نیز استفاده کرده ایم اجرای این struct هزینه gas کمتری را در برمیگیرد.در مقاله های بعدی موارد بیشتری را برای بهبود دادن هزینه gas بیان میکنم.

امیدوارم مفید واقع شده باشه.

اگر به آموزش های برنامه نویسی علاقه دارید آموزش های من رو از کانال یوتوبم دنبال کنید. ممنون

لینک کانال یوتوب من


بلاک‌چیناتریومگسقرارداد هوشمندسالیدیتی
Senior backend developer
شاید از این پست‌ها خوشتان بیاید