پرش به مطلب اصلی

قرارداد ماژول امنیتی اوراکل

مقدمه

قرارداد ماژول امنیتی اوراکل 1 یا OSM این اطمینان را می‌دهد که مقادیر جدید قیمت‌های منتشرشده در زرگری توسط سیستم پذیرفته نمی‌شوند تا زمانی که یک زمان مشخص گذشته باشد. مقادیر از قرارداد DSValue یا هر قرارداد دیگری که رابط‌های read و peek را داشته باشد از طریق روش poke خوانده می‌شوند؛ روش‌های read و peek مقدار فعلی تغذیه قیمت را می‌دهند، قراردادهایی که این توابع را فراخوانی می‌کنند باید در لیست معتبر قرار داشته باشند. یک قرارداد osm می‌تواند تنها از یک مرجع قیمت بخواند، بنابراین در عمل باید برای هر وثیقه یک قرارداد ماژول امنیتی اوراکل توسعه داده شود.

جزئیات فنی

مکانیسم‌ و مفاهیم کلیدی

متغیرهای کلیدی

متغیرنوع دادهتوضیح
stoppeduint256یک باینری که در صورت غیر صفر بودن، به روزرسانی‌های تغذیه قیمت را غیر فعال می‌کند
srcaddressآدرس DSValue
ONE_HOURuint16معادل 3600 ثانیه از نوع داده
hopuint16تاخیر زمانی بین فراخوانی‌های poke
zzzuint64زمان آخرین به‌روزرسانی (گرد شده به نزدیک‌ترین مضرب و کوچکتر از hop)
curuint16ساختار Feed که مقدار فعلی تغذیه را نگه می‌دارد
nxtuint16ساختار Feed که مقدار بعدی تغذیه را نگه می‌دارد
budmapping(address => uint256)یک نگاشت که خوانش‌های تغذیه را در لیست معتبر قرار می‌دهد

همچنین در این قرارداد از یک نوع داده بنام Feed نیز استفاده می‌شود که دو عضو از نوع uint128 شامل val و has دارد. این متغیرها برای ذخیره داده‌ تغذیه استفاده می‌شوند.

مدیریت امنیت اوراکل به طور دوره‌ای یک قیمت به تعویق افتاده را برای نوع خاصی از وثیقه به سیستم زرگری تأمین می‌کند. برای اینکه این کار به خوبی انجام شود، یک فعال خارجی باید به طور منظم تابع poke را فراخوانی، قیمت فعلی را به‌روزرسانی کرده و قیمت بعدی را می‌خواند. این قرارداد زمان آخرین فراخوانی poke را در متغیر zzz ( به نزدیکترین مضرب از hop به پایین گرد شده است) پیگیری می‌کند و اجازه نمی‌دهد تابع poke فراخوانی شود تا وقتی که مقدار block.timestamp حداقل برابر zzz+hop باشد. این مقادیر از قرارداد DSValue (آدرس آن در src ذخیره می‌شود) خوانده می‌شوند. این مکانیسم یک به‌روزرسانی به تأخیر افتاده است، و هدفش این است که زمان کافی برای شناسایی و واکنش به یک حمله اوراکل (مانند تنظیم قیمت وثیقه به صفر) فراهم شود. واکنش‌ها به این موضوع شامل فراخوانی stop یا void یا فعال‌سازی خاموشی اضطراری است.

اگر قرارداد‌ هوشمند دیگری در لیست معتبر قرار داده شود، می‌تواند مقدار cur را از طریق توابع peek و read چک کنند. تابع peek یک مقدار دودویی برمی‌گرداند که نشان می‌دهد آیا مقداری برای آن تنظیم شده است یا خیر. اگر مقدار تنظیم نشده باشد، read وظیفه ‍revert را دارد. همچنین مقدار nxt می‌تواند از طریق peep چک شود.

قرارداد ماژول امنیتی اوراکل از یک ساختار مجوزدهی دولایه‌ای استفاده می‌کند. ابتدا در لایه اول، آدرس‌هایی که در wards به 1 نگاشت می‌شوند، می‌توانند

  • اجرا و متوقف شوند،
  • src را تنظیم کنند،
  • مقدار void را فراخوانی کنند،
  • و خوانش‌های جدید را اضافه کنند.

همچنین در لایه دوم مجوزدهی، آدرس‌هایی که در ‍buds به مقدار 1 نگاشت می‌شوند، می‌توانند peek، peep و read را فراخوانی کنند.

در این قرارداد مجموعه‌ای از توابع و عملکردها وجود دارد که کارکرد آنها را در دو بخش عمومی و تغذیه قیمت به طور خلاصه بیان می‌کنیم.

عملکرد توابع عمومی
  • stop /start : هدف این توابع تغییر مجوز به‌روزرسانی تغذیه قیمت است
  • change : تغییر داده قیمت‌ها (با تنظیم src)
  • step : تغییر فاصله بین به‌روزرسانی‌های قیمت (با تنظیم hop)
  • void : مشابه stop است، اما همچنین cur و nxt را به یک ساختار Feed با مقادیر صفر می‌رساند
  • kiss/diss : اضافه کردن/حذف مصرف‌کنندگان feed مجاز (با تغییرات در نگاشت buds)
عملکرد توابع فراخوانی تغذیه قیمت

این‌ توابع همچنین قادر هستند توسط آدرس‌هایی که در لیست معتبر قرار داده شده فراخوانی شوند

  • peek : مقدار تغذیه فعلی و یک باینری که نشان دهنده اعتبار است را برمی‌گرداند
  • peep : مقدار تغذیه بعدی را نشان می‌دهد (به عبارت دیگر چیزی که در فراخوانی poke بعدی به مقدار فعلی تبدیل می شود) و یک باینری را برمی‌گرداند که نشان می‌دهد معتبر است یا خیر
  • read : مقدار تغذیه فعلی را برمی‌گرداند؛ اگر توسط یک مکانیزم معتبر تنظیم نشده باشد، متدهای به‌روزرسانی تغذیه را برمی‌گرداند
  • poke : مقدار تغذیه فعلی را به‌روزرسانی می‌کند و مقدار بعدی خوانده می‌شود

ریسک‌ها و خطاهای احتمالی

خطاهای برنامه نویسی

❌ اشتباه در فراخوانی peek به‌عنوان peep (یا برعکس) در توسعه و استفاده از این توابع می‌تواند موجب اشتباهاتی شود. نام این توابع تنها یک حرف اختلاف دارد و در استفاده حال حاضر، هر دو "peek" و "peep" مفهوم مشابهی را دارند. این امر ممکن است باعث شود یک توسعه‌دهنده این دو را با هم اشتباه بگیرد و متد اشتباه را فراخوانی کند. اثرات چنین اشتباهاتی به‌طور طبیعی به متن وابسته هستند، اما ممکن است برای مثال هدف اصلی ماژول امنیتی اوراکل نادیده گرفته شود. یک روش برای کمک به بخاطرسپاری آنها این است که چون 'k' در زبان انگلیسی قبل از 'p' می‌آید، مقداری که توسط peek برمی‌گرداند، قبل از مقداری است که توسط peep برمی‌گردد.

❌ در استفاده از این توابع برنامه نویسان باید دقت کنند که اگر poke به موقع فراخوانی نمی‌شود، قیمت‌های مخرب به سرعت وارد الگوریتم می‌شوند. به دلایل مختلفی، poke همواره و تا زمانی که block.timestamp/hop در حال افزایش است و بدون توجه به اینکه اخرین بار چه وقتی poke فراخوانی می‌شود، قابل فراخوانی است (زیرا zzz به نزدیک‌ترین مضرب از hop به پایین گرد می‌شود). در واقع قرارداد تضمینی ندارد که یک بازه زمانی حداقلی hop ثانیه از زمان آخرین فراخوانی گذشته است. فقط این ضمانت را دارد که آخرین فراخوانی poke بلافاصله پس از افزایش قبلی block.timestamp/hop رخ داده باشد. بنابراین، مقدار قیمت مخرب ممکن است در زمانی کمتر از hop توسط سیستم تأیید شود.

❌ مورد بعدی در واقع یک تصمیم عمدی در طراحی الگوریتم است. دلیلی که در حمایت از آن آورده می‌شود این است که امکان اجرای کامل ماژول امنیتی اوراکل را به‌طور قابل اعتمادی در همان زمان و در یک تراکنش تضمین می‌کند. اینکه poke عمومی است و بنابراین توسط هر کسی قابل فراخوانی است، به کاهش نگرانی‌ها کمک می‌کند، اگرچه آنها را از بین نمی‌برد. به عنوان مثال، شلوغی شبکه می‌تواند جلوی هر کسی را از فراخوانی موفق poke بگیرد.

اگر مشاهده شود که poke به‌موقع فراخوانی نشده است، اقداماتی که میشود انجام داد عبارتند از:

  • فراخوانی poke به‌ صورت شخصی و تصمیم‌گیری در مورد اینکه آیا مقدار بعدی مخرب است یا نه.
  • فراخوانی stop یا void (اولی اگر تنها nxt مخرب باشد؛ دومی اگر مقدار مخرب از قبل در cur باشد).
  • فعال‌سازی خاموشی اضطراری (اگر سلامتی سیستم به‌طور کلی آسیب دیده باشد یا اگر باور بر این باشد که اوراکل‌های شرور در زمان معقولی قابل اصلاح نیستند). در آینده، منطق قرارداد ممکن است برای کاهش این چالش (به‌طور مثال با تنظیم فقط اجازه فراخوانی poke در یک بازه زمانی کوتاه در هر دوره hop ) تنظیم شود.

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

  • لغو مجوز انجام عملکردهای قراردادهای اصلی در توابعی که نیاز به این دسترسی‌ها دارند، باعث عدم موفقیت در به‌روزرسانی قیمت صحیح می‌شود
  • تغییر آدرس src به یک قرارداد مخرب یا به چیزی که دارای رابط کاربری peek نباشد، باعث می‌شود کارکردهایی اتفاق بیفتد که ماژول امنیتی اوراکل آنها را در اجرای poke برگرداند.
  • در فراخوانی توابع مختلفی مانند stop و void به‌صورت نامناسب، تنها راه حل برای مراقبت از انجام امن عملکردها دقت در مورد دسترسی wards از ماژول امنیتی اوراکل است.

1 Oracle Security Module