شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

در مرحله بعد ، ما ویژگی های اصلی زبان Move و تفاوتهای اصلی آن را با زبان دیگری که قبلاً برای قراردادهای هوشمند رایج است - Solidity (در بستر Ethereum) ، به تفصیل در نظر خواهیم گرفت. این مطالب بر اساس مطالعه کاغذ سفید آنلاین 26 صفحه ای موجود تهیه شده است.

معرفی

Move یک زبان بایت کد اجرایی است که برای اجرای تراکنش های کاربر و قراردادهای هوشمند استفاده می شود. لطفا به دو نکته توجه کنید:

  1. در حالی که Move یک زبان بایت کد است که می تواند مستقیماً در ماشین مجازی Move اجرا شود ، Solidity (زبان قرارداد هوشمند اتریوم) یک زبان سطح بالاتر است که ابتدا قبل از اجرا بر روی EVM (ماشین مجازی اتریوم) برای کد بایتی کامپایل می شود.
  2. Move می تواند نه تنها برای اجرای قراردادهای هوشمند ، بلکه برای معاملات سفارشی (در ادامه بعداً) مورد استفاده قرار گیرد ، در حالی که Solidity یک زبان هوشمند فقط برای قرارداد است.


ترجمه توسط تیم پروژه پروتکل INDEX انجام شده است. ما قبلا ترجمه کرده ایم مطالب بزرگی که پروژه لیبرا را توصیف می کند، اکنون زمان آن رسیده است که زبان Move را با جزئیات بیشتری بررسی کنیم. ترجمه به طور مشترک با هابراوزر انجام شد کولسیو

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

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

به عنوان مثال ، قطعه کد زیر خطایی ایجاد می کند: استفاده از مقدار منتقل شده "x". این به این دلیل است که در زنگ جمع آوری زباله وجود ندارد. وقتی متغیرها از محدوده خارج می شوند ، حافظه ای که به آن اشاره می کنند نیز آزاد می شود. به زبان ساده ، فقط یک "مالک" داده می تواند وجود داشته باشد. در این مثال x مالک اصلی است و سپس y مالک جدید می شود. اطلاعات بیشتر در مورد این رفتار را اینجا بخوانید.

نمایش دارایی های دیجیتالی در سیستم های باز

دو ویژگی دارایی های فیزیکی وجود دارد که ارائه آنها به صورت دیجیتالی مشکل است:

  • نادر بودن (کمیابی ، در اصل کمیابی). تعداد دارایی ها (انتشار) در سیستم باید کنترل شود. تکثیر دارایی های موجود باید ممنوع باشد و ایجاد دارایی های جدید یک عملیات ممتاز است.
  • کنترل دسترسی... شرکت کننده در سیستم باید بتواند از دارایی ها با خط مشی های کنترل دسترسی محافظت کند.

این دو ویژگی که برای دارایی های فیزیکی طبیعی است ، اگر بخواهیم آنها را به عنوان دارایی در نظر بگیریم ، باید برای اشیاء دیجیتالی پیاده سازی شوند. به عنوان مثال ، یک فلز کمیاب دارای کمیابی طبیعی است و فقط شما به آن دسترسی دارید (برای مثال ، آن را در دستان خود بگیرید) و می توانید آن را بفروشید یا خرج کنید.

برای توضیح نحوه رسیدن به این دو ویژگی ، بیایید با جملات زیر شروع کنیم:

پیشنهاد شماره 1: ساده ترین قانون بدون کمیابی و کنترل دسترسی

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

  • G [K]: = n نشان دهنده به روزرسانی شماره ای است که توسط یک کلید قابل دسترسی است К در وضعیت جهانی بلاک چین ، با معنای جدید n.
  • تراکنش lآلیس ، 100⟩ به این معنی که مانده حساب آلیس را روی 100 تنظیم کنید.

راه حل فوق چندین مشکل عمده دارد:

  • آلیس می تواند با ارسال ساده تعداد نامحدودی سکه دریافت کند معامله lآلیس ، 100⟩.
  • سکه هایی که آلیس برای باب می فرستد بی فایده است ، زیرا باب می تواند با استفاده از تکنیک مشابه تعداد نامحدودی سکه برای خود ارسال کند.

پیشنهاد شماره 2: با احتساب کسری بودجه

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

اکنون ما وضعیت را زیر نظر داریم به طوری که تعداد سکه ها Ka حداقل برابر بود n قبل از معامله انتقال با این حال ، در حالی که این مشکل کمیابی را حل می کند ، هیچ اطلاعاتی در مورد اینکه چه کسی می تواند سکه های آلیس را ارسال کند وجود ندارد (در حال حاضر ، هر کسی می تواند این کار را انجام دهد ، نکته اصلی این است که از قانون محدود کردن مبلغ تخطی نکنید).

پیشنهاد شماره 3: ترکیب کمیابی و کنترل دسترسی

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

ما این مشکل را با مکانیسم امضای دیجیتال حل می کنیم verify_sig قبل از بررسی موجودی ، به این معنی است که آلیس از کلید خصوصی خود برای امضای معامله و تأیید مالک سکه های خود استفاده می کند.

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

زبان های بلاک چین موجود با مشکلات زیر روبرو هستند (همه آنها در Move حل شده اند) توجه داشته باشید: متأسفانه نویسنده مقاله در مقایسه های خود فقط به اتریوم متوسل می شود ، بنابراین ارزش دارد که آنها را فقط در این زمینه در نظر بگیریم. به عنوان مثال ، اکثر موارد زیر نیز در EOS حل شده است.)):

نمایش غیر مستقیم دارایی ها. یک دارایی با استفاده از یک عدد صحیح کدگذاری می شود، اما یک عدد صحیح با یک دارایی یکسان نیست. در واقع، هیچ نوع یا مقداری وجود ندارد که نشان دهنده بیت کوین/اتر/<هر کوین> باشد! این امر نوشتن برنامه هایی را که از دارایی ها استفاده می کنند دشوار و مستعد خطا می کند. الگوهایی مانند انتقال دارایی ها به/از رویه ها یا ذخیره دارایی ها در ساختارها نیاز به پشتیبانی ویژه از زبان دارند.

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

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

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

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

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

بنابراین، در Solidity، وقتی قرارداد A تابعی را در قرارداد B فراخوانی می‌کند، قرارداد B ممکن است کدی را اجرا کند که توسط توسعه‌دهنده قرارداد A در نظر گرفته نشده است، که ممکن است منجر به ورود مجدد آسیب پذیری ها (قرارداد A به طور تصادفی به عنوان قرارداد B برای برداشت پول قبل از کسر واقعی موجودی حساب عمل می کند).

مبانی طراحی زبان را حرکت دهید

منابع درجه یک

در سطح بالا ، تعامل بین ماژول ها / منابع / رویه ها در زبان Move بسیار شبیه به رابطه بین کلاس ها / اشیاء و روش ها در زبان های OOP است.
ماژول های Move مشابه قراردادهای هوشمند در سایر بلاک چین ها هستند. این ماژول انواع منابع و رویه هایی را تعریف می کند که قوانین ایجاد ، تخریب و به روز رسانی منابع اعلام شده را تعیین می کند. اما همه اینها فقط یک قرارداد است ("اصطلاحات اصطلاحات”) در حال حرکت ما این نکته را کمی بعد توضیح خواهیم داد.

انعطاف پذیری

Move از طریق اسکریپت به Libra انعطاف‌پذیری می‌افزاید. هر تراکنش در Libra شامل یک اسکریپت است که اساسا رویه اصلی تراکنش است. اسکریپت می تواند یک عمل مشخص را انجام دهد، به عنوان مثال، پرداخت به یک لیست مشخص از گیرندگان، یا استفاده مجدد از منابع دیگر - به عنوان مثال، با فراخوانی رویه ای که در آن منطق کلی مشخص شده است. به همین دلیل است که اسکریپت های تراکنش Move انعطاف پذیری بیشتری را ارائه می دهند. یک اسکریپت می‌تواند از رفتارهای یک‌باره و تکراری استفاده کند، در حالی که اتریوم فقط می‌تواند اسکریپت‌های تکرارپذیر را اجرا کند (یک روش را در روش قرارداد هوشمند فراخوانی می‌کند). دلیل اینکه آن را "قابل استفاده مجدد" می نامند این است که عملکردهای یک قرارداد هوشمند را می توان چندین بار اجرا کرد. (توجه داشته باشید: نکته در اینجا بسیار ظریف است. از یک طرف، اسکریپت های تراکنش به شکل شبه بایت کد نیز در بیت کوین وجود دارد. از طرف دیگر، همانطور که من متوجه شدم، Move این زبان را در واقع تا سطح یک زبان قرارداد هوشمند تمام عیار گسترش می دهد.).

امنیت

فرمت اجرایی Move بایت کد است که از یک طرف زبان سطح بالاتری نسبت به زبان اسمبلی است، اما سطح پایین تری نسبت به کد منبع است. بایت کد در زمان اجرا (روی زنجیره) برای منابع، انواع و ایمنی حافظه با استفاده از تأییدکننده بایت کد بررسی می شود و سپس توسط مفسر اجرا می شود. این رویکرد به Move اجازه می دهد تا امنیت کد منبع را فراهم کند، اما بدون فرآیند کامپایل و نیاز به افزودن کامپایلر به سیستم. ساخت Move یک زبان بایت کد راه حل واقعا خوبی است. مانند Solidity نیازی به کامپایل از منبع ندارد و نیازی به نگرانی در مورد خرابی ها یا حملات احتمالی به زیرساخت کامپایلر نیست.

صحت سنجی

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

مدولار بودن

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

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

انتقال نمای کلی

مثال اسکریپت تراکنش نشان می دهد که اقدامات مخرب یا بی دقتی توسط یک برنامه نویس خارج از یک ماژول نمی تواند امنیت منابع ماژول را به خطر بیندازد. در مرحله بعد ، ما نمونه هایی از نحوه استفاده از ماژول ها ، منابع و رویه ها برای برنامه ریزی بلاک چین Libra را بررسی می کنیم.

پرداخت های همتا به همتا

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

تعداد سکه های مشخص شده به مبلغ از موجودی فرستنده به گیرنده منتقل می شود.
چند چیز جدید در اینجا وجود دارد (با رنگ قرمز مشخص شده است):

  • 0x0: آدرس حسابی که ماژول در آن ذخیره شده است
  • واحد پول: نام ماژول
  • سکه: نوع منبع
  • مقدار سکه ای که با روش بازگشت داده می شود ، یک منبع منبع از نوع 0x0.Currency.Coin است
  • حرکت (): مقدار را نمی توان دوباره استفاده کرد
  • کپی 🀄 (): مقدار می تواند بعداً مورد استفاده قرار گیرد

تجزیه کد: در اولین مرحله ، فرستنده روشی به نام فراخوانی می کند برداشتن از فرستنده از یک ماژول ذخیره شده در 0x0. ارز. در مرحله دوم، فرستنده با انتقال ارزش منبع سکه به رویه سپرده ماژول، وجوه را به گیرنده منتقل می کند. 0x0. ارز.

در اینجا سه ​​نمونه از خطاهای کد وجود دارد که با بررسی رد می شوند:
با تغییر تماس ، وجوه را کپی کنید حرکت (سکه) بر کپی (سکه). منابع فقط قابل جابجایی هستند. تلاش برای کپی کردن مقداری از یک منبع (مثلاً با تماس کپی (سکه) در مثال بالا) هنگام بررسی کد بایتی منجر به خطا می شود.

استفاده مجدد از وجوه با تعیین حرکت (سکه) دوبار . اضافه کردن یک خط 0x0.Currency.Deposit (کپی (کسی_دیگر_پرداخت کننده)، انتقال (سکه)) به عنوان مثال، موارد فوق به فرستنده این امکان را می دهد که سکه ها را دو بار خرج کند - بار اول با گیرنده و بار دوم با دریافت کننده پرداخت. گیرنده_دیگر. این یک رفتار نامطلوب است که با یک دارایی فیزیکی امکان پذیر نیست. خوشبختانه، Move این برنامه را رد خواهد کرد.

از دست دادن وجوه به دلیل امتناع حرکت (سکه). اگر منبع را جابه جا نکنید (مثلاً با حذف خط حاوی حرکت (سکه)، یک خطای تأیید بایت کد پرتاب می شود. این از برنامه نویسان Move در برابر از دست دادن تصادفی یا مخرب سرمایه محافظت می کند.

ماژول ارز

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

هر حساب می تواند شامل 0 یا چند ماژول (به صورت مستطیل نشان داده شده است) و یک یا چند مقدار منبع (نشان داده شده به صورت سیلندر) باشد. به عنوان مثال، یک حساب کاربری در 0x0 شامل ماژول 0x0. ارز و مقدار نوع منبع 0x0.ارز.سکه. حساب در آدرس 0x1 دارای دو منبع و یک ماژول. حساب در آدرس 0x2 دارای دو ماژول و یک مقدار منبع است.

لحظات نکوتوری:

  • اسکریپت تراکنش اتمی است - یا به طور کامل اجرا می شود یا اصلاً اجرا نمی شود.
  • ماژول یک قطعه کد با عمر طولانی است که در سطح جهانی قابل دسترسی است.
  • حالت جهانی به صورت یک جدول هش ساخته شده است که کلید آن آدرس حساب است
  • حساب‌ها نمی‌توانند بیش از یک مقدار منبع از یک نوع معین و بیش از یک ماژول با نام معین (حساب در 0x0 نمی تواند حاوی یک منبع اضافی باشد 0x0.ارز.سکه یا ماژول دیگری به نام واحد پول)
  • آدرس ماژول اعلام شده بخشی از نوع (0x0.ارز.سکه и 0x1.ارز.سکه انواع جداگانه ای هستند که نمی توانند به جای یکدیگر استفاده شوند)
  • برنامه نویسان می توانند چندین نمونه از این نوع منبع را با تعریف منبع سفارشی خود در یک حساب ذخیره کنند - (منبع TwoCoins {c1: 0x0.Currency.Coin، c2: 0x0.Currency.Coin})
  • شما می توانید بدون تداخل به یک منبع با نام آن اشاره کنید، برای مثال می توانید با استفاده از دو منبع به آن مراجعه کنید TwoCoins.c1 и TwoCoins.c2.

اطلاعیه منابع سکه

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک
ماژول نامگذاری شد واحد پول و یک نوع منبع به نام سکه

لحظات نکوتوری:

  • سکه ساختاری با یک فیلد از نوع است u64 (عدد صحیح بدون علامت 64 بیتی)
  • فقط رویه های ماژول واحد پول می تواند مقادیر نوع را ایجاد یا از بین ببرد سکه.
  • سایر ماژول ها و اسکریپت ها فقط می توانند فیلد مقدار را از طریق رویه های عمومی ارائه شده توسط ماژول بنویسند یا ارجاع دهند.

فروش سپرده

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

این روش یک منبع را می پذیرد سکه به عنوان ورودی و آن را با منبع ترکیب می کند سکهذخیره شده در حساب گیرنده:

  1. از بین بردن منبع ورودی Coin و ثبت ارزش آن.
  2. دریافت پیوند به یک منبع کوین منحصر به فرد ذخیره شده در حساب گیرنده.
  3. تغییر مقدار تعداد Coins با مقدار ارسال شده در پارامتر هنگام فراخوانی رویه.

لحظات نکوتوری:

  • باز کردن بسته، BorrowGlobal - رویه های داخلی
  • بسته بندی را باز کنید این تنها راه برای حذف یک منبع از نوع T است. این روش یک منبع را به عنوان ورودی می گیرد، آن را از بین می برد و مقدار مربوط به فیلدهای منبع را برمی گرداند.
  • BorrowGlobal یک آدرس را به عنوان ورودی می گیرد و یک مرجع به یک نمونه منحصر به فرد از T منتشر شده (مالک) توسط آن آدرس برمی گرداند
  • سکه &mut این یک لینک به منبع است سکه

پیاده سازی remove_from_sender

شیرجه به حرکت - زبان برنامه نویسی بلاک چین لیبرا فیس بوک

این رویه:

  1. پیوندی به یک منبع منحصر به فرد دریافت می کند سکه، به حساب فرستنده پیوند داده شده است
  2. ارزش یک منبع را کاهش می دهد سکه از طریق لینک مبلغ مشخص شده
  3. یک منبع جدید ایجاد و برمی گرداند سکه با موجودی به روز شده

لحظات نکوتوری:

  • سپرده می تواند توسط هر کسی ایجاد شود، اما برداشتن از فرستنده فقط به سکه های حساب تماس دسترسی دارد
  • GetTxnSenderAddress شبیه به msg.sender در Solidity
  • رد کردن مگر اینکه شبیه به نیاز در Solidity. اگر این چک ناموفق باشد، تراکنش متوقف می شود و همه تغییرات برگشت داده می شود.
  • بسته همچنین یک رویه داخلی است که منبع جدیدی از نوع T ایجاد می کند.
  • همچنین بسته بندی را باز کنید, بسته فقط در داخل ماژول که منبع توضیح داده شده است فراخوانی می شود T

نتیجه

ویژگی های اصلی زبان Move را بررسی کردیم، آن را با اتریوم مقایسه کردیم و همچنین با سینتکس اولیه اسکریپت ها آشنا شدیم. در نهایت، من به شدت توصیه می کنم بررسی کنید کاغذ سفید اصلی. این شامل جزئیات زیادی در مورد اصول طراحی زبان برنامه نویسی و همچنین بسیاری از لینک های مفید است.

منبع: www.habr.com

اضافه کردن نظر