قرارداد شما کار می کند. فقط هر تراکنشش سه برابر رقیب هزینه دارد. اولین کاری که اکثر توسعه دهنده ها می کنند این است که اسم متغیرها را کوتاه می کنند.
این کار هیچ اثری ندارد. اسم متغیر بعد از کامپایل وجود خارجی ندارد. جای واقعی هزینه چند لایه بالاتر است و از آنجا شروع می کنیم.
گس چیست و کدام نصفش دست شماست
هزینه یک تراکنش از دو چیز ساخته می شود: مقدار کاری که قرارداد انجام می دهد، و قیمتی که در آن لحظه برای هر واحد کار پرداخت می شود.
دومی بازار است و شلوغی شبکه تعیینش می کند؛ شما هیچ کنترلی رویش ندارید. اولی کاملا دست شماست و تمام بحث بهینه سازی درباره همین است. کسی که می خواهد با «فرستادن تراکنش در ساعت خلوت» بهینه سازی کند، دارد نصف دوم را مدیریت می کند نه کد را.
ترتیب درست، از گران ترین به ارزان ترین
بیشتر آموزش ها فهرستی از ترفندها می دهند بدون اینکه بگویند کدام چقدر می ارزد. ترتیب اهمیت دارد، چون کل صرفه معمولا در دو بند اول است.
۱. هرچه را می شود ننوشت، ننویسید
نوشتن در حافظه دائمی قرارداد، گران ترین کاری است که یک قرارداد اتریومی انجام می دهد؛ با اختلاف زیاد نسبت به محاسبه، خواندن یا هر چیز دیگری.
پس اولین سوال هر بازبینی این است: این مقدار را باید ذخیره کنیم یا می شود هر بار حساب کرد؟ و سوال دوم: این داده را قرارداد لازم دارد یا فقط رابط کاربری لازمش دارد؟ اگر فقط بیرون قرارداد خوانده می شود، جایش رویداد است نه متغیر ذخیره شده. رویدادها به مراتب ارزان ترند و از بیرون کاملا قابل خواندن.
حذف یک نوشتن از یک تابع پرترافیک، معمولا بیشتر از تمام ترفندهای بعدی این فهرست صرفه دارد.
۲. حلقه های بی سقف را بردارید
حلقه ای که روی آرایه ای با طول نامعلوم می چرخد، فقط گران نیست؛ خطرناک است. با بزرگ شدن آرایه، هزینه بالا می رود تا جایی که تراکنش از سقف گس بلاک رد می شود و آن تابع برای همیشه از کار می افتد.
الگوی جایگزین همان است که پروتکل های جاافتاده استفاده می کنند: به جای اینکه قرارداد به همه پرداخت کند، هر کسی سهم خودش را برداشت کند. هزینه از دوش یک تراکنش برداشته می شود و بین کاربران پخش می شود.
۳. متغیرها را کنار هم بچینید
حافظه قرارداد به خانه های با اندازه ثابت تقسیم می شود. چند متغیر کوچک که پشت سر هم تعریف شده باشند در یک خانه جا می شوند و با یک بار نوشتن ذخیره می شوند؛ همان متغیرها اگر با یک متغیر بزرگ در میانشان تعریف شوند، هر کدام یک خانه می گیرند.
یعنی صرفا با عوض کردن ترتیب چند خط تعریف، هزینه پایین می آید. این ارزان ترین بهینه سازی این فهرست است و بیشترین نسبت نتیجه به زحمت را دارد.
۴. بهینه ساز کامپایلر و آن عددی که کسی تنظیمش نمی کند
کامپایلر سالیدیتی بهینه سازی دارد که خیلی ها فقط روشنش می کنند و رد می شوند. اما یک پارامتر کنارش هست که مشخص می کند قرار است چند بار اجرا شدن را بهینه کند.
عدد پایین یعنی برای هزینه انتشار بهینه کن؛ به درد قراردادی می خورد که یک بار مستقر می شود و کم استفاده می شود. عدد بالا یعنی برای اجرا بهینه کن؛ به درد قراردادی می خورد که میلیون ها بار صدا زده می شود. اگر این را تنظیم نکنید، روی مقدار پیش فرض می ماند که برای هیچ کدام از این دو حالت انتخاب نشده است.
۵. و بعد، ترفندهای کوچک
خطاهای سفارشی به جای متن های بلند خطا، استفاده از کال دیتا به جای حافظه در ورودی توابع، و برداشتن بررسی سرریز جایی که ریاضیاتش اجازه سرریز نمی دهد. این ها واقعی اند و کار می کنند، ولی در مقیاس بند اول نیستند. اگر از اینجا شروع کنید، وقت زیادی برای صرفه کوچکی گذاشته اید.
جایی که بهینه سازی به ضرر شما تمام می شود
باید صریح گفت: هر بهینه سازی، خوانایی را کم می کند و ریسک باگ را بالا می برد.
برداشتن بررسی سرریز دقیقا همان جایی است که ممیزی ها بیشترین ایراد را می گیرند، چون فرضی که امروز درست است ممکن است بعد از یک تغییر کوچک غلط شود. کدی که برای صرفه جویی چند درصدی غیرقابل خواندن شده، اولین جایی است که در نسخه بعدی اشتباه می شود.
و مهم تر از همه: قبل از اندازه گیری بهینه سازی نکنید. ابزارهای تست، گزارش گس هر تابع را می دهند. بدون آن گزارش، شما دارید حدس می زنید کدام تابع گران است و معمولا حدس اشتباه است. امنیت هم بحث جداگانه ای است که تست و دیپلوی قرارداد پیش از مین نت به آن پرداخته است.
بهینه سازی که از همه بزرگ تر است
انتخاب شبکه.
هر صرفه ای که با بازنویسی کد به دست می آورید، در بهترین حالت درصدی است. جابه جا شدن از شبکه اصلی اتریوم به یک لایه دوم، هزینه هر تراکنش را از مرتبه ای به مرتبه دیگر می برد. اگر کاربران شما پرداخت های کوچک انجام می دهند، این تصمیم از تمام این فهرست مهم تر است و گزینه های لایه دوم و محدودیت هایشان مقایسه شان کرده است.
این برای پروژه ای که کاربر ایرانی دارد اهمیت مضاعف دارد. کارمزد شبکه اصلی به دلار حساب می شود و به مقدار پول کاربر کاری ندارد؛ یعنی یک تعامل ساده می تواند از خود مبلغی که کاربر جابه جا می کند گران تر شود. و اگر انتظار داشتید ارتقای شبکه این را حل کرده باشد، دلیل ثابت ماندن کارمزد اتریوم پس از مرج توضیحش را دارد.
برای تامین اتر لازم برای انتشار قرارداد، تهیه اتر برای هزینه انتشار نرخ روز را نشان می دهد و اگر سرویس های ابری و ابزارهای توسعه هم باید شارژ شوند، ووچرهای دلاری برای ابزار توسعه مسیر متعارفش است.
سوال های پرتکرار
بهینه سازی گس چقدر می تواند هزینه را کم کند؟
بستگی دارد از کجا شروع کنید. روی قراردادی که بی حساب در حافظه دائمی می نویسد، حذف چند نوشتن می تواند تفاوت چشمگیری بسازد. روی قراردادی که یک بار بازبینی شده، ترفندهای باقی مانده معمولا در حد چند درصدند. هیچ عدد ثابتی وجود ندارد و هر کسی که عدد قطعی بدهد، قرارداد شما را ندیده است.
کسب درآمد از قرارداد هوشمند چه ربطی به گس دارد؟
ربط مستقیم. اگر مدل درآمدی شما کارمزد کوچک روی تعداد زیاد تراکنش است، هزینه گس مستقیما از حاشیه سود شما کم می شود و در شلوغی شبکه می تواند کل آن را ببلعد. پروژه هایی که این حساب را نکرده اند، معمولا در اولین دوره پرترافیک متوقف می شوند.
آیا کد بهینه تر یعنی کد امن تر؟
معمولا برعکس. بخش قابل توجهی از تکنیک های کاهش گس، بررسی هایی را حذف می کنند که برای ایمنی گذاشته شده بودند. هر بهینه سازی باید با آزمون همراه باشد و هر جایی که بررسی خودکار را برداشته اید، دلیلش باید در خود کد نوشته شده باشد.
کلاهبرداری با قرارداد هوشمند چطور تشخیص داده می شود؟
از روی اختیاراتی که در قرارداد باقی مانده، نه از روی ظاهر پروژه. اینکه چه کسی می تواند توکن بسازد، موجودی را مسدود کند یا قرارداد را ارتقا دهد، همه در کد قابل دیدن است. قراردادی که کدش روی کاوشگر تایید نشده باشد، از همان اول قابل بررسی نیست.
جمع بندی
بهینه سازی قرارداد هوشمند یک فهرست ترفند نیست، یک ترتیب اولویت است. اول معماری، بعد حافظه، بعد کامپایلر، و آخر از همه ترفندهای کوچک. و قبل از هر کدامشان یک گزارش گس که نشان بدهد پول واقعا کجا خرج می شود. بدون آن گزارش، هر ساعتی که صرف بهینه سازی کنید ممکن است روی تابعی باشد که ماهی دو بار صدا زده می شود.