قرارداد میانه
مقدمه
این قرارداد، قیمت قابل اعتماد برای پروتکل را تامین میکند. به طور خلاصه، یک لیستی از مراجع معتبر 1 قراردادهای تغذیه قیمت را نگهداری میکند که مجاز به ارسال بهروزرسانیهای قیمت در زرگری هستند. هر زمان که یک لیست جدید از قیمتهای از این مراجع دریافت میشود، با استفاده از این قرارداد میانه آنها محاسبه شده و برای بهروزرسانی قیمت دارایی مرتبط استفاده میشود. این قرارداد دارای منطق مجوزدهی 2 است که حذف و اضافه کردن آدرسهای قرارداد تغذیه قیمت که مجاز هستند را فراهم میکند. این منطق مجوزدهی در سایر پارامترهای نیز برای کنترل شرایط استفاده میشود. برای مثال، در پارامتر bar موثر است که این پارامتر نشاندهنده حداقل تعداد قیمتها است که برای پذیرش یک مقدار میانه جدید لازم است .
جزئیات فنی
مکانیسم و مفاهیم کلیدی
متغیرهای کلیدی
متغیر | نوع داده | توضیح |
---|---|---|
wards | mapping(address => uint256) | نگاشت مدیریت دسترسی آدرسها |
val | uint128 | قیمت (به صورت خصوصی) باید با read یا peek خوانده شود |
orcl | mapping(address => uint256) | لیستی معتبر val / امضاکنندگان قیمتها |
bud | uint256 | مجوزدهی به لیستی معتبر از val |
age | uint32 | زمان آخرین بلوک برای بهروزرسانی قیمت val |
wat | bytes32 | نوع تغذیه قیمت (برای مثال: ETHUSD ) یا اینکه میگوید که دارایی از چه نوع است |
bar | uint256 | حداقل تعداد خوانش3های poke یا اینکه کمترین تعداد پیام معتبر که برای بهروزرسانی قیمت نیاز دارید |
توابع اصلی و عملکرد
به طور خلاصه برخی از عملکردهای توابع موجود در این قرارداد عبارتند از:
read
: یک قیمت غیر صفر را خروجی میدهد یا اینکه در صورت صفر بودن پیام خطای مرتبط را نشان میدهدpeek
: قیمت و اعتبار را خروجی میدهدpoke
: قیمت را از ارائهدهندگان مجاز به روزرسانی میکندlift
: یک آدرس را به لیست معتبر اضافه میکندdrop
: یک آدرس را از لیست معتبر حذف میکندsetBar
: نوار را تنظیم میکندkiss
: یک آدرس را به لیست معتبر اضافه میکندdiss
: یک آدرس را از لیست معتبر حذف میکند
نکات فنی عملکرد توابع
تابع
read
مقدار را برمیگرداند یا در صورت عدم معتبر بودن با شکست مواجه میشود وpeek
مقدارvalue
را برمیگرداند.قرارداد میانه قیمت مرجع و معتبر داراییها را در زرگری تهیه میکند. داشتن مجوز یکی از اجزای کلیدی در مکانیزم این قرارداد و تعاملات آن است. به عنوان مثال، قیمت (
val
) عمداً به صورت عمومی در دسترس نیست چرا که هدف این است که فقط از طریق دو تابعread
وpeek
که بررسی و مجاز شدهاند، خوانده شود. بنابراین شما برای خواندن قیمت، نیاز به مجوز دسترسی دارید که از طریق متغیرbud
این کار امکانپذیر میشود. عملکردbud
برای دریافت مجوز خواندن قیمت روی بلاکچین تعیین شده است. در حالی که همه فعالیتهای آن صرفا در خارج از بلاکچین عمومی است.برای فراخوانی تابع
poke
نیاز به هیچ گونه مجوزی نیست. بعبارت دیگر هر کسی میتواند آن را فراخوانی کند. با هدف تشویق حافظان به فراخوانی این تابع و ارتباط با حراجی ها طراحی شده است. تنها راه برای تغییر وضعیت آن این است که آن را فراخوانی کنید و دادههای معتبری را برای آن ارسال کنید. به عنوان مثال، فرض کنید این اوراکل به 15 منبع مختلف نیاز دارد. بنابراین نیاز دارید 15 امضاء مختلف ارسال کنید. سپس به ترتیب هرکدام را بررسی میکند و هر کسی که این دادهها را به صورت معتبر ارسال کرده باشد، مجاز است. در صورتی که اوراکلی مجاز باشد، بررسی میکند که آیا پیام را با زمانی که بیشتر از زمان آخرین پیام است، امضا شده است. این کار برای اطمینان از این است که یک پیام نامعتبر نباشد. مرحله بعدی بررسی مقادیر دستور است که برای این منظور نیاز است همه دادهها در یک آرایه و به ترتیب صعودی ارسال شود. اگر به درستی ارسال نشود (یعنی صعودی نباشد)، میانه به درستی محاسبه نمیشود. از طرفی اگر قیمتها مرتب شده باشند، به سادگی مقدار میانه محاسبه میشود.برای بررسی یکتا بودن این آرایه، از یک فیلتر بنام
bloom
استفاده میشود. به طور خلاصه، این فیلتر یک ساختار داده است که با سرعت مناسب و کارآیی زمان حافظه به ما بگوید که آیا یک عنصر در مجموعه وجود دارد یا خیر. استفاده از فیلترbloom
به بهینهسازی کمک میکند. برای وارد کردن امضاکنندگان به لیست معتبر، اولین دو حرف از آدرس آنها (اولین بایت) باید یکتا باشد. به عنوان مثال، فرض کنید 15 امضا کننده با قیمت مختلف دارید، هیچکدام از دو حرف اول آدرس آنها نمیتواند یکسان باشد. این کار کمک میکند که تمام 15 امضاکننده متفاوت باشند.تابع بعدی
lift
است. این تابع به ما میگوید که چه کسانی میتوانند پیامها را امضا کنند. میتوانید یک یا چندین پیام برای آن ارسال کنید. اما باید ورودی اوراکل مجاز شوند.به دلیل طراحی مکانیسم اوراکلها، حدنصاب امضاکنندگان باید یک عدد فرد باشد. اگر عدد زوج باشد، کار نخواهد کرد. پیادهسازی این قطعه کد نشان میدهد که چگونه کار میکند:
val = uint128(val_[val_.length >> 1]);
که در آن با گرفتن آرایهای از مقادیر (تمام قیمتهایی که هر یک از امضاکنندگان قیمت گذاری کردهاند، از 200 تا 215) و سپس انتخاب یکی از آنها است. این کار با گرفتن طول آرایه (15) و جابهجایی آن به سمت راست در یک گام(که همانند تقسیم بر 2 است) انجام میشود. در نهایت این مقدار 7.5 میشود و سپس EVM آن را به 7 تبدیل میکند. اگر قرار باشد اعداد زوج قابل قبول باشد، بهینگی پیادهسازی آن کمتر خواهد شد. این مسئله را نیز به وجود میآورد که باید تعادلی بین تعداد مورد نیاز و تعداد امضاکنندگان واقعی وجود داشته باشد. به عنوان مثال، فرض کنید اوراکل به 15 امضا نیاز دارد، باید حداقل 17-18 امضا کننده داشته باشید چرا که اگر 15 نفر مورد نیاز داشتید و فقط 15 نفر تایید کنند و یکی از آنها دچار مشکل شود، نمیتوانید قیمت را تغییر دهید، بنابراین همیشه باید تعداد مناسبی بیشتر داشته باشید. با این حال، نباید از حد زیادی استفاده شود، زیرا ممکن است این تعداد زیاد عملکرد را تحت تاثیر قرار دهند.
ریسکها و خطاهای احتمالی
اوراکلهای اضطراری
این اوراکلها میتوانند تغذیه قیمت را خاموش کنند. اما نمیتوانند آن را دوباره فعال کنند. برای فعال کردن دوباره آن، سیستم باید دخالت کند.
فریزشدن قیمت
اگر ماژول اوراکلها را از بین ببرید، نمیتوانید با هیچ یک از صندوقهایی که به آن
ilk
وابسته هستند، تعامل کنید. به عنوان مثال با خاموش کردن
ETH/USD
(میتوانید هنوز سرمایه اضافه کنید و بدهی پرداخت کنید ) اما نمیتوانید هیچ کاری دیگری انجام دهید که ریسک را افزایش دهد( حذف سرمایه، تولید زر و غیره). زیرا سیستم نمیتواند تشخیص دهد که آیا اکنون وثیقه کافی دارید یا خیر.
اوراکلها نیاز به اصلاح و نگهداری زیادی دارند
اوراکلها باید همه
relayer
ها را در حالت فعال نگه دارند. در فضای بلاکچین که غیرمتمرکز است، اگر نیاز به جایگزینی باشد، همه باید خودشان نظارت کنند (با توجه به هر امضاکننده قیمت و غیره). باید مطمئن شوند که هر ساعت یکبار و به موقع فراخوانی میشود (برای هر ساعت، یک تراکنش به
OSM
ارسال میشود)، بنابراین چندین تراکنش قبلاً به این قرارداد ارسال شده است تا بهروزرسانی شود، علاوه بر این، نیاز به ارسال یک تراکنش به
spotter
وجود دارد، زیرا سیستم زربان به روشی با نام از نوع استخراج4 اداره میشود (به عبارتی سیستم را به روز نمیکند، شما به آن میگویید که از
OSM
بخواند). چیزی وجود ندارد که از استفاده کردن دو امضاکننده قیمت با آدرس یکسان جلوگیری کند. تنها چیزی که باعث میشود این اتفاق بیفتد این است که نمیتوانید بیش از 256 اوراکل داشته باشید. اما در عمل هرگز انتظار نداریم که این تعداد زیاد را داشته باشیم، بنابراین این یک محدودیت است که در عمل مانع کاری نمیشود.
در طراحی حال حاضر، هیچ روشی برای خاموش کردن اوراکل (شکست یا برگشت به مقدار اشتباه) وجود ندارد. اگر تمام اوراکلها با هم تبانی کنند و قیمت صفر را امضا کنند، باعث میشود قیمت نامعتبر شود و در
peek
، مقداری را به ما میدهد که به این مقدار اعتماد نکنیم.
در حال حاضر (ماژول اوراکلها) برای لغو قیمت در حال بررسی است. اما هیچ راهی برای انجام این کار در این قرارداد وجود ندارد. در واقع به دلیل جداسازی مسئولیتها و امنیت است که سیستم توکن زر مستقیماً از این قرارداد قیمت را نمیخواند، بلکه از
OSM
میخواند .
1 Whitelist
2 Authorization
3 Reads
4 Pool-type