Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Далей мы разгледзім у дэталях асноўныя характарыстыкі мовы Move і ў чым яго ключавыя адрозненні з іншым, ужо папулярным мовай для смарт-кантрактаў - Solidity (на платформе Ethereum). Матэрыял заснаваны на вывучэнні даступнага он-лайн 26-старонкавага whitepaper-а.

Увядзенне

Move - гэта выкананая мова байт-кода, які выкарыстоўваецца для выканання карыстацкіх транзакцый і смарт-кантрактаў. Звярніце ўвагу на два моманты:

  1. У той час як Move з'яўляецца мовай байт-кода, які можа напрамую выконвацца на віртуальнай машыне Move, Solidity (мова смарт-кантрактаў у Ethereum) - мова больш высокага ўзроўню, які спачатку кампілюецца ў байт-код перад выкананнем у EVM (Ethereum Virtual Machine ).
  2. Move можна выкарыстоўваць не толькі для рэалізацыі смарт-кантрактаў, але і для карыстацкіх транзакцый (падрабязней пра гэта будзе далей), у той час як Solidity - гэта мова толькі для смарт-кантрактаў.


Пераклад выкананы камандай праекту INDEX Protocol. Раней мы ўжо пераводзілі вялікі матэрыял, які апісвае праект Libra, зараз надышла чарга крыху больш падрабязна зірнуць на мову Move. Пераклад выкананы сумесна з хабраюзерам coolsiu

Ключавой асаблівасцю Move з'яўляецца магчымасць вызначаць карыстацкія тыпы рэсурсаў з семантыкай, заснаванай на лінейнай логіцы: рэсурс ніколі не можа быць скапіяваны ці няяўна выдалены, толькі перамешчаны. Функцыянальна, гэта падобна з магчымасцямі мовы Rust. Значэнні ў Rust могуць быць прызначаны толькі аднаму імя за раз. Прысваенне значэння іншаму імені робіць яго недаступным пад папярэднім імем.

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Для прыкладу, наступны фрагмент кода выведзе памылку: Use of moved value 'x'. Гэта таму, што ў Rust няма зборкі смецця. Калі зменныя выходзяць з вобласці бачнасці, памяць, на якую яны спасылаюцца, таксама вызваляецца. Прасцей кажучы, можа быць толькі адзін «ўладальнік» дадзеных. У гэтым прыкладзе x з'яўляецца першапачатковым уладальнікам, а затым y становіцца новым уладальнікам. Больш падрабязна пра такія паводзіны тут.

Прадстаўленне лічбавых актываў ў адкрытых сістэмах

Існуе два ўласцівасці фізічных актываў, якія цяжка ўявіць у лічбавым выглядзе:

  • рэдкасць (Дэфіцытныя, у арыгінале - scarcity). Колькасць актываў (эмісія) у сістэме павінна быць кантраляванай. Неабходна забараніць дубляванне існуючых актываў, а стварэнне новых - гэта прывілеяваная аперацыя.
  • кантроль доступу. Удзельнік сістэмы павінен мець магчымасць абараніць актывы з дапамогай палітык кантролю доступу.

Гэтыя дзве характарыстыкі, якія натуральныя для фізічных актываў, трэба рэалізаваць і для лічбавых аб'ектаў, калі мы хочам лічыць іх актывамі. Напрыклад, рэдкі метал - мае натуральны дэфіцыт, і толькі ў вас ёсць да яго доступ (трымаючы ў руках, напрыклад) і вы можаце яго прадаць або выдаткаваць.

Каб праілюстраваць, як мы прыйшлі да двух гэтым уласцівасцям, давайце пачнем са наступных прапаноў:

Прапанова № 1: найпростае правіла без дэфіцыту і кантролю доступу

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

  • G [K]: = n пазначае абнаўленне колькасці, даступнага па ключы К ў глабальным стане блокчейна, новым значэннем n.
  • transaction ⟨Alice, 100⟩ азначае ўстаноўку балансу рахунку Алісы на 100.

Прыведзенае вышэй рашэнне мае некалькі сур'ёзных праблем:

  • Аліса можа атрымаць неабмежаваную колькасць манет, проста адпраўляючы transaction ⟨Alice, 100⟩.
  • Манеты, якія Аліса пасылае Бобу, бескарысныя, так як Боб мог адпраўляць сабе неабмежаваную колькасць манет, выкарыстоўваючы тую ж тэхніку.

Прапанова № 2: улічваць дэфіцыт

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Цяпер мы адсочваем сітуацыю, каб колькасць манет Ka было як мінімум, роўна n перад транзакцыяй перакладу. Тым не менш, хоць гэта вырашае праблему дэфіцыту, няма ніякай інфармацыі пра тое, хто можа адпраўляць манеты Алісы (пакуль што гэта можа зрабіць кожны, галоўнае не парушаць правіла абмежавання колькасці).

Прапанова № 3: Аб'ядноўвае дэфіцыт і кантроль доступу

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Мы вырашаем гэтую праблему з дапамогай механізму лічбавай подпісы verify_sig перад праверкай балансу, што азначае, што Аліса выкарыстоўвае свой закрыты ключ для падпісання транзакцыі і пацверджання таго, што яна з'яўляецца ўладальнікам сваіх манеты.

Мовы праграмавання блокчейна

Існуючыя мовы блокчейна сутыкаюцца з наступнымі праблемамі (усе яны былі вырашаны ў Move (заўв .: на жаль, аўтар артыкула апелюе толькі да Ethereum ў сваіх параўнаннях, таму варта ўспрымаць іх толькі ў такім кантэксце. Напрыклад, большасць з нижесказанного таксама вырашана і ў EOS)):

Непрамое ўяўленне актываў. Актыў кадуецца з выкарыстаннем цэлага ліку, але цэлалікае значэнне - гэта не тое ж самае, што актыў. На самай справе, няма тыпу або значэння, які прадстаўляе біткойн / эфір / <Любая Манета>! Гэта робіць цяжкім і схільным памылкам напісанне праграм, якія выкарыстоўваюць актывы. Патэрны, такія як перадача актываў у/з працэдур або захоўванне актываў у структурах патрабуюць спецыяльнай падтрымкі ад мовы.

дэфіцыт нерасширяем. Мова ўяўляе толькі адзін дэфіцытны актыў. Акрамя таго, сродкі абароны ад дэфіцыту жорстка зашытая непасрэдна ў самой семантыцы мовы. Распрацоўшчык, калі ён хоча стварыць карыстацкі актыў, павінен сам старанна кантраляваць усе аспекты рэсурсу. Гэта як раз праблемы смарт-кантрактаў Ethereum.

Карыстальнікі выпускаюць свае актывы, токены стандарту ERC-20, выкарыстоўваючы цэлыя лікі для вызначэння як кошту, так і агульнай эмісіі. Кожны раз, калі ствараюцца новыя токены, код смарт-кантракта павінен самастойна правяраць захавання правілаў эмісіі. Акрамя таго, непрамое ўяўленне актываў прыводзіць, у шэрагу выпадкаў, да сур'ёзных памылак - дублявання, падвойным марнаванняў ці нават поўнай страты актываў.

Адсутнасць гнуткага кантролю доступу. Адзіная палітыка кантролю доступу, якая ўжываецца цяпер - гэта схема подпісы з выкарыстаннем асіметрычнай крыптаграфіі. Як і абарона ад дэфіцыту, палітыка кантролю доступу глыбока закладзена ў семантыцы мовы. Але як пашырыць мова, каб дазволіць праграмістам вызначаць уласныя палітыкі кантролю доступу - гэта, часцяком, вельмі нетрывіяльная задача.

Гэта таксама дакладна для Ethereum, дзе смарт-кантракты не маюць роднай падтрымкі крыптаграфіі для кантролю доступу. Распрацоўнікі павінны ўручную прапісаць кантроль доступу, напрыклад, выкарыстоўваючы мадыфікатар onlyOwner.

Нягледзячы на ​​тое, што я вялікі прыхільнік Ethereum, я лічу, што ўласцівасці актываў павінны першапачаткова натыўна падтрымлівацца мовай у мэтах бяспекі. У прыватнасці, перадача Ether у смарт-кантракт уключае дынамічную дыспетчарызацыю, якая прывяла да з'яўлення новага класа памылак, вядомых як паўторны ўваходу (re-entrancy vulnerabilities). Дынамічная дыспетчарызацыя тут азначае, што логіка выканання кода будзе вызначацца падчас выканання (дынамічная), а не падчас кампіляцыі (статычная).

Такім чынам, у Solidity, калі кантракт A выклікае функцыю кантракта B, кантракт B можа запускаць код, які не быў прадугледжаны распрацоўшчыкам кантракта A, што можа прывесці да уразлівасцям паўторнага ўваходу (кантракт A выпадкова выконвае функцыю кантракта B, каб зняць грошы да фактычнага выліку рэшткаў з уліковага запісу).

Асновы дызайну мовы Move

Рэсурсы першага парадку

Калі казаць высокаўзроўневы, то ўзаемадзеянне паміж модулямі / рэсурсамі / працэдурамі ў мове Move вельмі нагадваюць адносіны паміж класамі / обьекта і метадамі ў ООП-мовах.
Модулі ў Move аналагічныя смарт-кантрактах у іншых блокчейнах. Модуль аб'яўляе тыпы рэсурсаў і працэдуры, якія задаюць правілы для стварэння, знішчэння і абнаўлення абвешчаных рэсурсаў. Але ўсё гэта - толькі ўмоўнасці ( "жаргон") У Move. Крыху пазней мы праілюструем гэты момант.

Гнуткасць

Move дадае гнуткасці Libra праз скрыпты. Кожная транзакцыя ў Libra уключае ў сябе скрыпт, які фактычна з'яўляецца асноўнай працэдурай транзакцыі. Скрыпт можа выконваць або адно зададзенае дзеянне, напрыклад, плацяжы па ўказаным спісе атрымальнікаў, або перавыкарыстоўваць іншыя рэсурсы - напрыклад, выклікаючы працэдуру, у якой зададзена агульная логіка. Вось чаму скрыпты транзакцый Move прапануюць вялікую гнуткасць. Скрыпт можа выкарыстоўваць як аднаразовыя, так і паўтараюцца варыянты паводзін, у той час як Ethereum можа выконваць толькі паўтараюцца сцэнары (выклікаючы адзін метад метад смарт-кантракту). Чыннік, па якой ён названы "шматразовым", складаецца ў тым, што функцыі смарт-кантракту могуць выконвацца некалькі разоў. (заўв.: тут момант вельмі тонкі. З аднаго боку, скрыпты транзакцый у выглядзе псеўда-байткода, ёсць і ў Bitcoin. З іншага, як я зразумеў - Move пашырае гэтую мову, па сутнасці, да ўзроўню паўнавартаснай мовы смарт-кантрактаў).

бяспеку

Выконваемы фармат Move - гэта байт-код, які, з аднаго боку, мова больш высокага ўзроўню, чым асэмблер, але нізкаўзроўневыя, чым зыходны код. Байт-код правяраецца ў ран-тайме (on-chain) на наяўнасць рэсурсаў, тыпы і бяспекі памяці з дапамогай верыфікатара байт-кода, а затым выконваецца інтэрпрэтатарам. Такі падыход дазваляе Move даваць бяспеку, характэрную для зыходнага кода, але без працэсу кампіляцыі і неабходнасці дадаваць кампілятар у сістэму. Зрабіць Move мовай байт-кода - гэта сапраўды добрае рашэнне. Яго няма патрэбы кампіляваць з зыходнікаў, як у выпадку з Solidity, не трэба турбавацца аб магчымых збоях ці нападах на інфраструктуру кампілятара.

Верифицируемость

Мы нацэлены на выкананне як мага лягчэйшых праверак, бо ўсё гэта ідзе on-chain (заўв.: он-лайн, у працэсе выканання кожнай транзакцыі, таму любая затрымка прыводзіць да запаволення ўсёй сеткі), аднак першапачаткова дызайн мовы гатовы да выкарыстання і off-chain сродкаў статычнай верыфікацыі. Хоць гэта і больш пераважна, але пакуль распрацоўка сродкаў верыфікацыі (як асобнага тулкіта) адкладзена на будучыню, і зараз падтрымліваецца толькі дынамічная верыфікацыя ў ран-тайме (on-chain).

модульнасць

Модулі Move забяспечваюць абстракцыю дадзеных і лакалізуюць крытычныя аперацыі над рэсурсамі. Інкапсуляцыя, якая забяспечваецца модулем, у спалучэнні з абаронай, якая забяспечваецца сістэмай тыпаў Move, гарантуе, што ўласцівасці, устаноўленыя для тыпаў модуля, не могуць быць парушаныя кодам па-за модуля. Гэта досыць прадуманы дызайн абстракцыі, які азначае, што дадзеныя ўнутры кантракту могуць змяняцца толькі ў рамках выкананне кантракту, але не звонку.

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Агляд Move

Прыклад скрыпту транзакцыі дэманструе, што зламысныя або неасцярожныя дзеянні праграміста па-за модуля не могуць парушыць бяспеку рэсурсаў модуля. Далей мы разгледзім прыклады таго, як модулі, рэсурсы і працэдуры выкарыстоўваюцца для праграмавання блокчейна Libra.

Peer-to-Peer плацяжы

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Зададзенае ў amount колькасць манет будзе пераведзена з балансу адпраўніка да атрымальніка.
Тут ёсць некалькі новых момантаў (вылучана чырвонымі надпісамі):

  • 0x0: Адрас ўліковага запісу, дзе захоўваецца модуль
  • Валюта: Назву модуля
  • Манета: Тып рэсурсу
  • Значэнне coin, якое вяртаецца працэдурай, з'яўляецца значэннем рэсурсу, тып якога 0x0.Currency.Coin
  • move (): Значэнне не можа быць выкарыстана зноў
  • капіяваць (): Значэнне можа быць выкарыстана пазней

Разбіраем код: на першым кроку адпраўнік выклікае працэдуру з імем withdraw_from_sender з модуля, які захоўваецца ў 0x0.Currency. На другім этапе адпраўнік пераводзіць сродкі атрымальніку, перамяшчаючы значэнне рэсурсу манеты ў працэдуру дэпазіту модуля. 0x0.Currency.

Вось тры прыклады памылак у кодзе, якія будуць адхіленыя праверкамі:
Дубляванне сродкаў шляхам змены выкліку move (coin) на copy (coin). Рэсурсы могуць быць толькі перамешчаныя. Спроба дубляваць колькасць рэсурсу (напрыклад, выклікаючы copy (coin) у прыведзеным вышэй прыкладзе) прывядзе да памылкі падчас праверкі байт-кода.

Переиспользование сродкаў, паказаўшы move (coin) двойчы . Даданне радка 0x0.Currency.deposit (copy (some_other_payee), move (coin)) Напрыклад вышэй дазволіць адпраўшчыку «выдаткаваць» манеты двойчы - першы раз з атрымальнікам плацяжу, а другі з some_other_payee. Гэта непажаданыя паводзіны, немагчымыя з фізічным актывам. На шчасце, Move адхіліць гэтую праграму.

Страта сродкаў з-за адмовы ў move (coin). Калі не перамясціць рэсурс (напрыклад, выдаліўшы радок, якая змяшчае move (coin)), будзе выклікана памылка праверкі байт-кода. Гэта абараняе праграмістаў Move ад выпадковай ці зламыснай страты сродкаў.

Модуль Currency

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Кожны акаўнт можа змяшчаць 0 або больш модуляў (намаляваных у выглядзе прамавугольнікаў) і адно або некалькі значэнняў рэсурсаў (намаляваных у выглядзе цыліндраў). Напрыклад, уліковы запіс па адрасе 0x0 змяшчае модуль 0x0.Currency і значэнне рэсурсу тыпу 0x0.Currency.Coin. Уліковы запіс па адрасе 0x1 мае два рэсурсы і адзін модуль; Уліковы запіс па адрасе 0x2 мае два модулі і адно значэнне рэсурсу.

Некаторыя моманты:

  • Скрыпт транзакцыі атамарны - ці цалкам выконвацца, ці ніяк.
  • Модуль - гэта доўгажывучы кавалак кода, глабальна даступны.
  • Глабальнае стан структуравана як хэш-табліца, дзе ключом будзе адрас акаўнта
  • Уліковыя запісы могуць змяшчаць не больш за адно значэнне рэсурсу дадзенага тыпу і не больш за адзін модуль з зададзеным імем (уліковы запіс па адрасе 0x0 не можа змяшчаць дадатковы рэсурс 0x0.Currency.Coin ці іншы модуль з імем Валюта)
  • Адрас дэкларуемага модуля з'яўляецца часткай тыпу (0x0.Currency.Coin и 0x1.Currency.Coin - гэта асобныя тыпы, якія нельга выкарыстоўваць узаемазаменна)
  • Праграмісты могуць захоўваць некалькі асобнікаў дадзенага тыпу рэсурсу ва ўліковым запісе, вызначаючы свой кастамны рэсурс.resource TwoCoins {c1: 0x0.Currency.Coin, c2: 0x0.Currency.Coin})
  • Вы можаце спасылацца на рэсурс па ім імя без канфліктаў, напрыклад, вы можаце спасылацца на два рэсурсы, выкарыстоўваючы TwoCoins.c1 и TwoCoins.c2.

Аб'ява рэсурсу Coin

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook
Модуль з імем Валюта і тыпам рэсурсу з імем Манета

Некаторыя моманты:

  • Манета - гэта структура з адным полем тыпу u64 (64-разраднае цэлае без знака)
  • Толькі працэдуры модуля Валюта могуць ствараць або знішчаць значэння тыпу Манета.
  • Іншыя модулі і скрыпты могуць запісваць або спасылацца на поле значэння толькі праз адкрытыя працэдуры, якія прадстаўляюцца модулем.

Рэалізацыя дэпазіту

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Гэтая працэдура прымае рэсурс Манета у якасці ўваходных дадзеных і аб'ядноўвае яго з рэсурсам Манета, якія захоўваюцца на рахунку атрымальніка:

  1. Знішчэнне ўваходнага рэсурсу Coin і запіс яе значэння.
  2. Атрыманне спасылкі на ўнікальны рэсурс Coin, які захоўваецца на акаўнце атрымальніка.
  3. Змяненне значэння колькасці Coin на велічыню, перададзеную ў параметры пры выкліку працэдуры.

Некаторыя моманты:

  • Unpack, BorrowGlobal - убудаваныя працэдуры
  • Unpack гэта адзіны спосаб выдаліць рэсурс тыпу T. Працэдура прымае рэсурс на ўваход, знішчае яго і вяртае значэнне, асацыяванае з палямі рэсурсу.
  • BorrowGlobal прымае адрас у якасці ўводу і вяртае спасылку на ўнікальны асобнік T, апублікаваны (які належыць) гэтаму адрасу
  • &mut Coin гэта спасылка на рэсурс Манета

Рэалізацыя withdraw_from_sender

Апусканне ў Move – мова праграмавання блокчейна Libra ад Facebook

Гэтая працэдура:

  1. Атрымлівае спасылку на ўнікальны рэсурс Манета, прывязаны да акаўнта адпраўніка
  2. Памяншае значэнне рэсурсу Манета па спасылцы на ўказаную суму
  3. Стварае і вяртае новы рэсурс Манета з абноўленым балансам.

Некаторыя моманты:

  • Дэпазіт можа быць выкліканы кім заўгодна, але withdraw_from_sender мае доступ толькі да манет выклікальнага акаўнта
  • GetTxnSenderAddress падобна з msg.sender у Solidity
  • RejectUnless падобна з патрабаваць у Solidity. Калі гэтая праверка няўдалая, выкананне транзакцыі спыняецца і ўсе змены адкочваюцца.
  • Pack гэта таксама ўбудаваная працэдура, якая стварае новы рэсурс тыпу Т.
  • Так жа як Unpack, Pack можа выклікацца толькі ўнутры модуля, дзе апісаны рэсурс T

Заключэнне

Мы разабралі асноўныя характарыстыкі мовы Move, параўналі яе з Ethereum, а таксама азнаёміліся з асноўным сінтаксісам скрыптоў. У завяршэнне, я настойліва рэкамендую пагартаць арыгінальны white paper. Ён уключае ў сябе мноства дэталяў, якія тычацца прынцыпаў праектавання мовы праграмавання, а таксама мноства карысных спасылак.

Крыніца: habr.com

Дадаць каментар