رابط(Interface) در سالیدیتی و قراردادهای هوشمند solidity
اگر با Interface در زبان های برنامه نویسی شی گرا آشنایی داشته باشید باید بدانید که interface در سالیدیتی نیز دقیقا مانند رابط Interface در دیگر زبان های برنامه نویسی شی گرا عمل می کند. اگر بخواهیم با یک مثال اینترفیس در سالیدیتی را بیان کنیم می توان گفت : فرض کنید در قصد دارید چراغ های خودرو را روشن کنید، شما با زدن کلید داخل خودرو این کار را انجام می دهید اما در واقع زمانی که شما کلید را فشار می دهید چندین عمل دیگر اتفاق می افتد تا در نهایت چراغ خودرو روشن شود پس در تعریف Interface می توان گفت :
هدف یک Interface اعمال مجموعه ای از ویژگی های تعریف شده و اجرای توابع خاص در یک شی دیگر است.
رابط(Interface) در Solidity چیست؟
Interface در solidity معمولا در بالای قرارداد هوشمند اضافه می شوند. شما با کلمه کلیدی “Interface” می توانید آنها را به قرارداد اضافه کنید. شما می توانید از اینترفیس در سالیدیتی برای فراخوانی تابع ها در قرارداد دیگر استفاده کنید. Interface شامل امضاهای تابع بدون اجرای تعریف تابع است.
لطفا به مثال زیر توجه کنید
در این مثال یک قرارداد هوشمند با رابط IERC20 را مشاهده می کنید. امضاهای تابع این رابط به صورت لیست مشخص شده اند و با نقطه ویرگول از یکدیگر جدا شده اند. شما با افزودن این رابط می توانید توابع IERC20 را در قرارداد هوشمند استفاده کنید. همچنین در نظر داشته باشید Interface ها در سالیدیتی نیازی به جزئیات پیاده سازی هر تابع ندارند.
رابط ها از تکرار کد ها و ایجاد پیچیدگی در قرارداد هوشمند شما جلوگیری می کنند. Interface در solidity دارای ویژگی هایی است که در ادامه بررسی می کنیم
ویژگی های Interface در سالیدیتی :
- برای اضافه کردن رابط باید از کلمه کلیدی Interface استفاده کنید
- برخی از نام های Interface با یک “I” شروع می شوند تا شناسایی آنها در کد آسان تر شود.
- تمام توابع Interface به طور ضمنی مجازی هستند.
- می توانید یک تابع Interface را لغو کنید.
- قراردادها می توانند Interface ها را به ارث ببرند همانطور که قراردادهای دیگر را به ارث می برند.
- همه توابعی که از Interface به ارث میبرند باید override modifier را روی هر تابعی که یک تابع Interface را overrides میکند تنظیم کنند. در غیر این صورت کامپایلر یک خطا ایجاد می کند.
- انواع داده های تعریف شده در داخل Interface ها را می توان از قراردادهای دیگر دسترسی داشت. برای مثال، قراردادی که از Interface نمونه زیر استفاده میکند، میتواند به Iauto.carType و Iauto.vehicle دسترسی داشته باشد.
چه محدودیت هایی در رابط وجود دارد؟
- آنها نمی توانند از قراردادهای دیگر ارث ببرند، اما می توانند از Interface های دیگر ارث ببرند.
- توابع یک Interface فقط می توانند از نوع external باشند.
- آنها نمی توانند سازنده (Constructor) را اعلام کنند.
- آنها نمی توانند متغیرهای حالت (State Variable) را اعلام کنند.
چگونه یک Interface در solidity ایجاد کنیم ؟
در ادامه با ذکر یک مثال با ایجاد Interface در سالیدیتی آشنا می شویم. در این مثال از دو قرارداد استفاده می کنیم که در قرارداد اول تابع هایی وجود دارد که داده ها را برمی گرداند و در قرارداد دوم با استفاده از Interface ها به تمامی عملکرد های قرارداد اول دسترسی خواهیم داشت. برای درک بهتر این مثال شما هم کد زیر را در remix کپی و اجرا کنید.
pragma solidity ^0.8.6;
contract dataContract {
function getAge() external pure returns(uint) {
return 25;
}
function getHeight() external pure returns(uint) {
return 6;
}
function getName() external pure returns(string memory) {
return ‘Bob’;
}
function getCar() external pure returns(string memory) {
return ‘truck’;
}
}
در مرحله بعد قرارداد زیر را نیز در remix کپی کنید. این قرارداد در واقع شامل یک رابط برای قرارداد اول است. شما باید آدرس قرارداد بالا را در متغیر حالت در قرارداد زیر وارد کنید.
pragma solidity ^0.8.6;
//defined interface with functions that do not contain an implementation
//declared as type external
interface IDataContractInterface {
function getAge() external pure returns(uint);
function getHeight() external pure returns(uint);
function getName() external pure returns(string memory);
function getCar() external pure returns(string memory);
}
contract MainContract {
// state variable called DataContractAddress that represents the address of the data contract
address private constant DataContractAddress = PASTEFIRSTCONTRACTADDRESSHERE;
// to access the functions in the data contract
// use the interface declared above and wrap the data contract address in ()
// example interfaceName(address).functionName
function getAge() external pure returns(uint) {
return IDataContractInterface(DataContractAddress).getAge();
}
function getHeight() external pure returns(uint) {
return IDataContractInterface(DataContractAddress).getHeight();
}
function getName() external pure returns(string memory) {
return IDataContractInterface(DataContractAddress).getName();
}
function getCar() external pure returns(string memory) {
return IDataContractInterface(DataContractAddress).getCar();
}
}
و در آخر توابع موجود در قرارداد را اجرا کنید. توابع از طریق Interface ها با ارتباط گرفتن با قرارداد اول داده ها را می گیرند.
تفاوت بین
تفاوت بین یک Interface و یک abstract contracts
Interface ها و abstract contracts از بسیاری جهات مشابه هستند. Interface نسبت به abstract contracts بیشتر انتزاعی هستند. همه توابع Interface فاقد پیاده سازی هستند و در abstract contracts حداقل یک تابع فاقد پیاده سازی است. در نتیجه شما نمی توانید یک Interface یا یک abstract contracts را به دلیل عدم اجرای آن کامپایل کنید.
Abstract Contracts:
به القای الگوهای کدنویسی در برنامه خود کمک کنید.
ساختار برنامه خود را تعریف و مستند کنید.
انواع دیگر قراردادها می توانند از abstract contracts ارث ببرند.
برعکس، در یک قرارداد هوشمند از Interface ها به عنوان نمایش استفاده می شود.
تفاوت بین Interfaces و Libraries
Interfaceها و Libraryها از این جهت مشابه هستند که یک قرارداد انتزاعی را برای ارتقاء پذیری ارائه میکنند که میتواند به روشهای مختلف برای ارتقای قرارداد هوشمند Solidity استفاده شود. با این حال آنها متفاوت هستند و موارد استفاده متفاوت را حل می کنند.
رابط ها:
نمی تواند شامل منطق فقط تعریف رابط باشد
عمدتاً به عنوان imports برای تعامل با سایر قراردادها مفید است
رابط ها برای استقرار/وارد کردن کوچکتر هستند
کتابخانه ها:
حاوی منطق هستند
برای اهداف نگهداری و استفاده مجدد، کد را از قرارداد خارج می کنند.
یک بار دپلوی شده و سپس در قراردادها استفاده می شود.
Bytecode به طور جداگانه مستقر می شود و بخشی از قراردادهایی نیست که به آنها ارجاع می دهد.
دیدگاهتان را بنویسید