چالش‌های مربوط به قراردادهای هوشمند شی‌ گرا

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

0 98

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

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

از بحث سوئیچ‌های مرگ به مصالحه‌ی بسیار مهمی در زمینه‌ی رایانش غیرمتمرکز می‌رسیم: ارتقاپذیری در برابر اعتماد.

ارتقاپذیری

ارتقاپذیری را می‌توان به عنوان توانایی برنامه‌نویسان برای تغییر رفتار نرم‌افزار در آینده تعریف کرد.

سوئیچ مرگ به طور واضح در همین دسته‌بندی قرار می‌گیرد. این سوئیچ‌ها در حالت عادی باید از قبل در قرارداد برنامه‌ریزی شود، به همین خاطر کاربران هشیار از وجود آن‌ها خبر خواهند داشت (ولی کاربران عادی احتمالا نه). دسته‌ی گسترده‌ترِ ارتقاپذیری می‌تواند شامل توانایی انتشار کد اضافه یا اصلاح‌شده‌ای باشد که تغییرات یا پیشرفت‌های سیستم را نشان می‌دهد.

توانایی ارتقای قراردادهای هوشمند در یک دید کلی‌تر به چند دلیل منطقی است:

  • اصلاح نقایص کد در صورت پیدا کردن آن‌ها
  • ارتقای پایگاه داده وقتی استانداردها یا روش‌های کارآمدتر در دسترس قرار می‌گیرد
  • تغییر رفتار کدی که برای تکامل برنامه ضروری است

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

شی گرایی قراردادهای هوشمند

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

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

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

قرارداد هوشمند

علاوه بر این، تقسیم فضای ذخیره‌سازی اطلاعات و منطق تجاری به ما اجازه می‌دهد برای موضوعات خاص رابط‌هایی پایدار تعریف و در عین حال انعطاف‌پذیری فرآیندهای اجرایی را حفظ کنیم.

این روش به دلایل مختلفی مفید است.

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

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

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

اگر ما منطق‌مان را در چند قرارداد تقسیم کنیم، لازم نیست CarRep چیزی را تغییر دهد.

ثانیاً، اگر رابط سطح بالایی تعریف کنیم که به شکل پیاده‌سازی منطق تجاری اشاره داشته باشد، CarRep فقط در صورتی باید کدش را تغییر دهد که ما API عمومی سطح بالا (قرارداد پروکسی) را عوض کنیم. اگر از همان ابتدا حواسمان به تعاریف و نام‌گذاری‌ها باشد، این تغییرات به ندرت رخ می‌دهد. از API-های بزرگ و عمومی مثل Stripe یا Twitter هم انتظار داریم به همین صورت عمل کنند.

نهایتاً، با دنبال کردن الگویی که از ابتدا آن را در نظر داشتیم می‌توانیم پیرو اصل باز-بسته باشیم؛ یعنی می‌توانیم بدون نیاز به تغییر کد منبع عملکردهای جدیدی را به سیستم اضافه کنیم. ما به راحتی می‌توانیم اجزای جدید مورد نظر خود را پیاده‌سازی کرده و آن‌ها را در لیست مجاز قرار دهیم تا در صورت نیاز امکان برقراری تعامل با سیستم ما وجود داشته باشد.

اعتماد

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

این ویژگی در مقابل ویژگی قبلی قرار می‌گیرد که برای ارتقای قراردادها بود. اگر من بتوانم به تنهایی قرارداد را ارتقا دهم، می‌توانم هر کار مخرب یا جهت‌داری که بخواهم انجام دهم، در نتیجه افراد باید به من اعتماد کنند.

این اتفاق تضادی اساسی را به وجود می‌آورد. همان طور که رابرت مارتین در کتاب «معماری تمیز» می‌گوید:

نرم‌افزار باید نرم باشد، باید به راحتی بتوان آن را تغییر داد.

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

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

این مشکل فاصله‌ی زیادی تا حل شدن دارد. ولی دیدگاه من از این قرار است:

  • اول، به نظرم تعداد بسیار کمی از کاربران واقعا کد را می‌خوانند و متوجه می‌شوند که عملا می‌خواهند چه چیزی را امضا کنند. بنابراین آن‌ها در اغلب اوقات مجبورند به شرکت، وبسایت، پلتفرم و غیره اعتماد داشته باشند.
  • دوم، این مشکل در خیلی از موضوعات با درخواست کردن از چند توسعه‌دهنده برای تایید تغییرات اعمالی قابل حل است. با این کار احتمال این که توسعه‌دهنده دست به کار مخرب یا نادرستی بزند بسیار کم می‌شود.
  • سوم، در سیستم‌های خیلی حساس، می‌توان از حسابرس‌های خارجی درخواست کرد تا در کنار توسعه‌دهندگان تغییرات اعمالی را تایید کنند. همچنین، در شرایطی که لازم است سیستم کاملا غیرمتمرکز باشد، می‌توانیم از TCR-ها بخواهیم فهرست توسعه‌دهندگان و حسابرس‌های مورد تایید خود را به ما بدهند.

شاید از این مطالب هم خوشتان بیاید.

ارسال پاسخ

آدرس ایمیل شما منتشر نخواهد شد.