آموزش فراخوانی سایر قراردادها در سالیدیتی

آموزش فراخوانی سایر قراردادها در سالیدیتی

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

یک مثال ساده:

در ادامه، نحوه اجرای این فرآیند را به‌صورت عملی بررسی می‌کنیم.

از آنجایی که قبلاً در مورد «تاپل‌ها»، «رمزنگاری ABI» و «نوع داده bytes memory» صحبت کرده‌ایم، تنها نکات جدید در این بخش استفاده از تابع call و این است که چرا تابع askTheMeaningOfLife() یک تابع view نیست.

اما چرا askTheMeaningOfLife() نمی‌تواند view باشد؟ اگر سعی کنید آن را با مشخصه view تعریف و کامپایل کنید، با خطا مواجه خواهید شد.

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

همچنین، اگرچه در این مثال مشخص است که تابع meaningOfLifeAndAllExistence در قرارداد AnotherContract یک uint256 برمی‌گرداند، اما در حالت کلی نمی‌توان نوع بازگشتی را از قبل دانست. ممکن است مقدار بازگشتی یک رشته (string) باشد.

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

ابزار Remix این عملیات رمزگشایی را در پشت صحنه انجام می‌دهد تا داده ها را به فرمتی قابل فهم برای ما نمایش دهد (عدد، رشته و غیره).

بخش bool ok در تاپل چه کاربردی دارد؟ فراخوانی توابع سایر قراردادهای هوشمند ممکن است با شکست مواجه شوند؛ برای مثال، اگر تابع مقصد با خطای revert متوقف شود. برای تشخیص اینکه آیا این فراخوانی خارجی با موفقیت انجام شده یا نه، یک مقدار بولی (true یا false) به عنوان نتیجه برگردانده می‌شود.

در این پیاده‌سازی خاص، تابع فراخواننده یعنی askTheMeaningOfLifeAndAllExistence نیز در صورت شکست فراخوانی، عملیات را revert می‌کند. اما این رفتار یک الزام عمومی نیست و بستگی به طراحی قرارداد دارد.

اینجا یک نکته جالب وجود دارد: اگر یک قرارداد هوشمند غیر‌موجود را فراخوانی کنیم، چه اتفاقی می‌افتد؟

تابع askTheMeaningOfLife(address source) را با مقدار 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db به‌عنوان آرگومان امتحان کنید.

تنبل نباشید! حتماً آن را در کد بالا امتحان کنید!

این فراخوانی با خطا (revert) مواجه می‌شود، اما نه به این دلیل که آدرس وجود ندارد، بلکه به این خاطر که شما تلاش کرده‌اید داده خالی (empty data) را رمزگشایی (decode) کنید. اگر بخش رمزگشایی را از کد حذف کنیم، دیگر در هنگام فراخوانی یک آدرس غیر‌موجود، تابع با خطا مواجه نمی‌شود.

وقتی منوی کشویی تراکنش‌ها را در Remix باز می‌کنید، توضیح مربوط به خطا را آنجا مشاهده خواهید کرد.

5/5 - (1 امتیاز)

راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.

پکیج صفر تا صد آموزش سئو و بهینه سازی بصورت عملی
  • انتشار: ۱۴ اردیبهشت ۱۴۰۴

دسته بندی موضوعات

آخرین محصولات فروشگاه

مشاهده همه

نظرات

بازخوردهای خود را برای ما ارسال کنید