قرارداد Compound V3 دقیقاً مانند یک توکن ERC20 با موجودی متغیر خودکار عمل میکند. چنین توکن هایی، عرضه ثابتی ندارند و الگوریتمی، مقدار موجودی را تغییر میدهند. در این سیستم، توکن در واقع نشاندهنده ارزش فعلی موجودی مثبت USDC کاربران است. به زبان ساده، وام دهندگان میتوانند همانند یک توکن ERC20، ارزش فعلی سرمایه خود را به آدرسهای دیگر منتقل کنند.
از آنجایی که سرمایه اصلی معمولاً در طول زمان رشد میکند (به دلیل دریافت سود)، مقدار این توکن نیز بهصورت خودکار افزایش پیدا میکند.
توسعه دهندگان Compound V3 تصمیم گرفتند برای ردیابی سهم کاربران از استخر وام دهی، از استانداردهای رایج خزانه داری مانند استاندارد ERC-4626 استفاده نکنند.
همانطور که پیشتر توضیح دادیم، اگر کاربری 100 USDC واریز کرده باشد، ممکن است با گذشت زمان، اعتبارش به 110 USDC برسد. این اختلاف بهدلیل انباشته شدن سود بهوجود میآید. در واقع، مقدار 110 نشان دهنده ارزش فعلی است و سیستم ERC20 در Compound V3 نیز با همین عدد کار میکند.
پیشنیازها
برای درک بهتر این مقاله، کاربران باید با مفاهیم نرخ بهره در دیفای (interest indexes)، ارزش فعلی (present value) و ارزش سرمایه اولیه (principal value) در Compound V3 آشنایی داشته باشند. در این مقاله، اصطلاحات Compound V3 و Comet بهصورت مترادف بهکار رفتهاند، زیرا Comet نام قرارداد هوشمند اصلی در این پروتکل است که تمام توابع مورد بحث در این متن در آن پیاده سازی شدهاند.
ساختار مقاله
در هر بخش از این مقاله، به بررسی یکی از توابع ERC20 میپردازیم که در Compound V3 پیاده سازی شده است. همچنین توضیح میدهیم که این پروتکل چگونه آن تابع را اجرا میکند. برخی از توابع مورد بحث، جزو استاندارد رسمی ERC20 نیستند، اما برای درک عملکرد کلی سیستم، نقش مهمی دارند.
totalSupply و totalBorrow در فایل Comet.sol
تابع totalBorrow همانطور که از نامش پیداست، مجموع کل USDC وامگرفتهشده را نشان میدهد. به بیان دقیقتر، این عدد نمایانگر ارزش فعلی بدهی کاربران است. میتوانیم این مقدار را هم از خروجی قرارداد هوشمند و هم از اطلاعات نمایشدادهشده در رابط کاربری Compound تأیید کنیم. این عدد فقط نشاندهنده مقدار USDC برداشتشده نیست، بلکه شامل سودی نیز میشود که به مرور زمان بر روی وامها انباشته شده است.
در تصویر زیر، رابط کاربری Compound V3 مقدار totalBorrow را نمایش میدهد. همچنین میبینیم که خروجی تابع totalBorrow()
در Etherscan نیز همین مقدار را بازمیگرداند.
به همین صورت، مقدار خروجی تابع totalSupply()
نیز صرفاً نشان دهنده میزان USDC واریزشده توسط وام دهندگان در پلتفرم Compound نیست، بلکه نشان دهنده ارزش فعلی کل سپرده ها است.
در اسکرین شات کد زیر، میتوانید توابع totalSupply
و totalBorrow
را مشاهده کنید که بهروشنی ارتباط آن ها با مفهوم ارزش فعلی (Present Value) را نشان میدهند.
در تصویر زیر، دو بار اجرای تابع totalSupply()
را مشاهده میکنید. اگر به اسکرین شات سمت راست دقت کنید، میبینید که مقدار totalSupply
نسبت به تصویر سمت چپ افزایش یافته است. این تغییر، نشان میدهد که ارزش فعلی سپرده ها در حال رشد بوده که معمولاً بهدلیل انباشت سود اتفاق میافتد.
تابع totalSupply()
در Compound V3 دقیقاً مشابه همان تابع totalSupply()
در استاندارد ERC20 عمل میکند و مقدار کل توکن های در گردش را نمایش میدهد.
از سوی دیگر، وام گیرندگان نمیتوانند بدهی خود را به آدرس های دیگر منتقل کنند؛ بنابراین تابع totalBorrow
در هیچ رابط شبیه به توکن مورد استفاده قرار نمیگیرد و فقط برای محاسبه مجموع بدهی فعلی کاربرد دارد.
balanceOf در فایل Comet.sol
پیشتر در بخش مربوط به سرمایه اصلی (principal) و ارزش فعلی (present value) درباره تابع balanceOf
توضیح داده بودیم، بنابراین در این بخش نیازی به تکرار آن نیست.
transfer و transferFrom در فایل Comet.sol
توابع transfer
و transferFrom
، هر دو ارزش فعلی موجودی وام دهنده را منتقل میکنند. پارامتر amount
در این توابع، بر پایه ارزش فعلی (present value) سنجیده میشود؛ نه سرمایه اولیه. درک این تفاوت برای هر کسی که وارد برنامه نویسی قراردادهای هوشمند میشود مهم است.
هر دو تابع transfer
و transferFrom
در پشت صحنه، تابع داخلی transferInternal
را فراخوانی میکنند.
در Compound V3، روش صحیح برای انتقال کل موجودی این است که مقدار uint256
بیشینه (max value) را بهعنوان ورودی تابع وارد کنید. موجودی کاربران بهصورت لحظهای افزایش مییابد، چون سود بهطور مداوم به آن اضافه میشود. به همین دلیل، تعیین دقیق کل موجودی کار سادهای نیست.
توجه داشته باشید که وام گیرندگان نمیتوانند وثیقه (Collateral) خود را به آدرس های دیگر منتقل کنند، زیرا تابع transferCollateral
فقط بهصورت داخلی (internal) تعریف شده است. این تابع صرفاً در فرآیند لیکوییدیشن (Liquidation) مورد استفاده قرار میگیرد.
توابع تکمیلی ERC20 در فایل CometExt.sol
بهدلیل محدودیت ۲۴ کیلوبایتی برای استقرار قراردادهای هوشمند در اتریوم، قرارداد اصلی Comet بخشی از عملکرد خود را با استفاده از الگوی افزونه بازگشتی (fallback extension pattern) به فایل CometExt.sol منتقل کرده است. بیشتر توابعی که در CometExt پیاده سازی شدهاند، به عملکردهای مربوط به استاندارد ERC20 مربوط میشوند.
approve در فایل CometExt.sol
عملکرد تابع approve()
برای توکن cUSDCv3 غیراستاندارد است، چرا که فقط دو مقدار را میپذیرد: uint256.max
یا صفر.
از آنجایی که موجودی حساب کاربران بهصورت مداوم و خودکار در حال افزایش است (بهدلیل ساختار توکن با موجودی متغیر خودکار)، امکان اینکه دقیقاً برای کل موجودی فعلی به کسی مجوز (allowance) بدهید وجود ندارد. از آنجا که سود بهطور مداوم به موجودی افزوده میشود، هر عدد ثابت خیلی زود از مقدار واقعی موجودی عقب میماند.
تابع approve()
در پشتصحنه، تابع داخلی allowInternal
را فراخوانی میکند که بررسی آن بهصورت جداگانه ارزشمند است.
allow() و allowInternal()
تابع allow()
بخشی از استاندارد ERC20 نیست، اما عملکرد آن مشابه approve()
است و به یک آدرس، اجازه دسترسی کامل (maximum allowance) میدهد. هر دو تابع approve()
و allow()
، در پشتصحنه از تابع داخلی allowInternal()
برای تنظیم این سطح دسترسی استفاده میکنند.
از آنجا که تابع approve()
در cUSDCv3 فقط دو حالت دارد (یا صفر یا حداکثر مقدار)، تابع allow()
نیز رفتاری مشابه approve()
دارد، با این تفاوت که بهجای مقدار uint256
، یک آرگومان بولی (boolean) دریافت میکند. این آرگومان مشخص میکند که آیا باید اجازه کامل صادر شود یا خیر.
متغیر ذخیره سازی مربوط به “مقدار مجاز” (allowances) در فایل CometStorage.sol قرار دارد و با نام isAllowed
تعریف شده است.
در Compound V3، مقدار مجاز (Allowance) فقط بهصورت صفر یا کامل تعریف میشود و حالت میانهای وجود ندارد. به همین دلیل، تابع approve
تنها بیشینه مقدار uint256
را بهعنوان ورودی میپذیرد.
برخلاف توکن های استاندارد ERC20، این نسخه از Compound هیچ متغیر ذخیره سازی برای نگهداری عددی مقدار مجاز ندارد. در نتیجه، امکان تعیین مقدار مشخصی بهعنوان مجوز محدود وجود ندارد و تنها میتوان دسترسی کامل یا هیچ دسترسی را تعریف کرد.
allowance در فایل CometExt.sol
در Compound V3، مقدار مجاز (Allowance) حالتی دودویی دارد؛ یعنی یک آدرس فقط میتواند یا مجوز کامل (uint256.max
) داشته باشد یا هیچ مجوزی (صفر) نداشته باشد. اگر کاربر عددی غیر از این دو مقدار را وارد کند، تراکنش ریجکت (revert) میشود.
تابع hasPermission
نیز بهسادگی یک مقدار بولی (Boolean) برمیگرداند که مشخص میکند آیا یک آدرس، دسترسی کامل دارد یا هیچ دسترسی ندارد.
allowBySig() بهعنوان نسخه غیر استاندارد تابع permit() در ERC20
تابع allowBySig()
در Compound V3 جایگزین غیر استانداردی برای تابع permit()
در استاندارد ERC20 محسوب میشود. این تابع همان هدف را دنبال میکند، اما توسعه دهندگان آن را با ساختاری متفاوت پیاده سازی کردهاند.
در این نسخه، فایل CometStorage
بهجای استفاده از تابع nonces(address owner)
که در استاندارد EIP-2612 تعریف شده، متغیر userNonce
را بهصورت عمومی و از نوع mapping(address => uint256)
در دسترس قرار داده است.
توابع name() و symbol() در فایل CometExt.sol
توابع name()
و symbol()
جزو توابع اختیاری استاندارد ERC20 هستند که یک رشته (string) را بهعنوان خروجی برمیگردانند.
در فایل CometExt.sol
، این مقادیر بهجای آنکه بهصورت مستقیم در متغیرهای string
ذخیره شوند، در متغیرهای bytes32
تغییرناپذیر (immutable) نگهداری میشوند تا از نظر مصرف گس بهینهتر باشند.
از آنجایی که زبان سالیدیتی امکان تبدیل مستقیم bytes32
به string
را فراهم نمیکند، سیستم این مقادیر را بهصورت لحظهای و با استفاده از کد خاصی به رشته تبدیل میکند.
نکتهای که کمتر مورد توجه قرار میگیرد این است که در سالیدیتی، انواع bytes1
تا bytes32
را میتوان مانند آرایههای بایت، در سطح بایت (byte-level) ایندکسگذاری کرد. برای مثال:
1 2 3 4 5 6 7 |
contract Example { bytes32 immutable x = 0x3300000000000000000000000000000000000000000000000000000000000000; function main() external pure returns (bytes1) { return x[0]; // returns 0x33 } } |
CometExt
برای تبدیل نام و نماد توکن، ابتدا یک آرایه bytes
را در حافظه (memory) ایجاد میکند، سپس کاراکترهای ذخیره شده در متغیرهای تغییرناپذیر name32
و symbol32
(از نوع bytes32
) را به آن کپی میکند. در نهایت، این آرایه را بهصورت لحظهای به نوع string
تبدیل میکند.
فراخوانی توابع موجود در CometExt
رابط ABI که در Etherscan شناخته شده است، از وجود این توابع آگاهی ندارد؛ بنابراین توابع CometExt
در لیست عمومی توابع قرارداد Comet نمایش داده نمیشوند. با این حال، امکان فراخوانی آنها همچنان وجود دارد، زیرا این توابع از طریق مکانیسم fallback در قرارداد Comet شناسایی شده و بهصورت خودکار به قرارداد CometExt
ارجاع داده میشوند.
در ادامه، یک نمونه از فراخوانی توابع name()
و symbol()
با استفاده از ابزار cast
در فریم ورک Foundry آورده شده است.
نتیجه گیری
Comet V3 رفتاری شبیه به یک توکن ERC20 با موجودی متغیر خودکار دارد که نمایانگر موجودی مثبت وام دهندگان است. کاربران میتوانند این موجودی مثبت را همانند یک توکن معمولی ERC20 به آدرس های دیگر منتقل کنند.
تابع approve()
در این سیستم غیراستاندارد است و فقط دو حالت دارد: یا اجازه کامل (مقدار uint256.max
) صادر میکند یا هیچ دسترسی نمیدهد. بههمین صورت، تابع permit()
که برای صدور مجوز بدون پرداخت گس استفاده میشود نیز از استاندارد ERC20 تبعیت نمیکند و ساختار متفاوتی دارد.
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۲۷ تیر ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++C
- ADO.NET
- Adobe Flash
- Ajax
- AngularJS
- apache
- ARM
- Asp.Net
- ASP.NET MVC
- AVR
- Bootstrap
- CCNA
- CCNP
- CMD
- CSS
- Dreameaver
- EntityFramework
- HTML
- IOS
- jquery
- Linq
- Mysql
- Oracle
- PHP
- PHPMyAdmin
- Rational Rose
- silver light
- SQL Server
- Stimulsoft Reports
- Telerik
- UML
- VB.NET&VB6
- WPF
- Xml
- آموزش های پروژه محور
- اتوکد
- الگوریتم تقریبی
- امنیت
- اندروید
- اندروید استودیو
- بک ترک
- بیسیک فور اندروید
- پایتون
- جاوا
- جاوا اسکریپت
- جوملا
- دلفی
- دوره آموزش Go
- دوره های رایگان پیشنهادی
- زامارین
- سئو
- ساخت CMS
- سی شارپ
- شبکه و مجازی سازی
- طراحی الگوریتم
- طراحی بازی
- طراحی وب
- فتوشاپ
- فریم ورک codeigniter
- فلاتر
- کانستراکت
- کریستال ریپورت
- لاراول
- معماری کامپیوتر
- مهندسی اینترنت
- هوش مصنوعی
- یونیتی
- کتاب های آموزشی
- Android
- ASP.NET
- AVR
- LINQ
- php
- Workflow
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس