Dive into Move - limbajul de programare blockchain Libra al Facebook

În continuare, vom analiza în detaliu principalele caracteristici ale limbajului Move și care sunt diferențele sale cheie cu un alt limbaj, deja popular, pentru contractele inteligente - Solidity (pe platforma Ethereum). Materialul se bazează pe un studiu al unei cărți albe de 26 de pagini, disponibilă online.

Introducere

Move este un limbaj de bytecode executabil care este folosit pentru a executa tranzacții cu utilizatorul și contracte inteligente. Vă rugăm să rețineți două puncte:

  1. În timp ce Move este un limbaj de bytecode care poate fi executat direct pe Move Virtual Machine, Solidity (limbajul de contract inteligent în Ethereum) este un limbaj de nivel superior care este compilat mai întâi în bytecode înainte de execuție în EVM (Ethereum Virtual Machine).
  2. Move poate fi folosit nu numai pentru a implementa contracte inteligente, ci și pentru tranzacțiile utilizatorilor (mai multe despre asta mai târziu), în timp ce Solidity este un limbaj doar pentru contracte inteligente.


Traducerea a fost realizată de echipa de proiect INDEX Protocol. Am tradus deja material mare care descrie proiectul Libra, acum este timpul să ne uităm puțin mai detaliat la limba Mutare. Traducerea a fost realizată în comun cu Habrauser coolsiu

O caracteristică cheie a Move este capacitatea de a defini tipuri de resurse personalizate cu semantică bazată pe logica liniară: o resursă nu poate fi niciodată copiată sau ștearsă implicit, ci doar mutată. Din punct de vedere funcțional, acest lucru este similar cu capacitățile limbajului Rust. Valorile în Rust pot fi atribuite doar unui nume la un moment dat. Atribuirea unei valori unui nume diferit face ca aceasta să nu fie disponibilă sub numele anterior.

Dive into Move - limbajul de programare blockchain Libra al Facebook

De exemplu, următorul fragment de cod va genera o eroare: Utilizarea valorii mutate „x”. Acest lucru se datorează faptului că Rust nu are colectare de gunoi. Când variabilele ies din domeniul de aplicare, memoria la care se referă este, de asemenea, eliberată. Pur și simplu, poate exista un singur „proprietar” al datelor. În acest exemplu x este proprietarul inițial și apoi y devine noul proprietar. Citiți mai multe despre acest comportament aici.

Reprezentarea activelor digitale în sisteme deschise

Există două proprietăți ale activelor fizice care sunt dificil de reprezentat digital:

  • Raritate (Insuficiență, în original - deficit). Numărul de active (emisii) din sistem trebuie controlat. Duplicarea activelor existente trebuie interzisă, iar crearea altora noi este o operațiune privilegiată.
  • Controlul accesului. Participantul la sistem trebuie să poată proteja activele utilizând politici de control al accesului.

Aceste două caracteristici, care sunt naturale pentru bunurile fizice, trebuie implementate și pentru obiectele digitale dacă vrem să le considerăm active. De exemplu, un metal rar are o penurie naturală și doar tu ai acces la el (ținându-l în mâini, de exemplu) și îl poți vinde sau cheltui.

Pentru a ilustra cum am ajuns la aceste două proprietăți, să începem cu următoarele propoziții:

Propunerea #1: Cea mai simplă regulă fără deficit și controlul accesului

Dive into Move - limbajul de programare blockchain Libra al Facebook

  • G[K]:=n denotă actualizarea unui număr accesibil prin tastă К în starea globală a blockchain-ului, cu un nou sens n.
  • tranzacție ⟨Alice, 100⟩ înseamnă a seta soldul contului lui Alice la 100.

Soluția de mai sus are câteva probleme serioase:

  • Alice poate primi un număr nelimitat de monede prin simpla trimitere tranzacție ⟨Alice, 100⟩.
  • Monedele pe care Alice le trimite lui Bob sunt fără valoare, deoarece Bob și-ar putea trimite un număr nelimitat de monede folosind aceeași tehnică.

Sugestia nr. 2: Luați în considerare deficitul

Dive into Move - limbajul de programare blockchain Libra al Facebook

Acum monitorizăm situația astfel încât numărul de monede Ka a fost cel puțin egal n înainte de tranzacția de transfer. Cu toate acestea, deși acest lucru rezolvă problema deficitului, nu există informații despre cine poate trimite monede Alice (deocamdată, oricine poate face acest lucru, atâta timp cât nu încalci regula limită de cantitate).

Propunerea #3: Combinați deficitul și controlul accesului

Dive into Move - limbajul de programare blockchain Libra al Facebook

Rezolvăm această problemă folosind un mecanism de semnătură digitală verify_sig înainte de a verifica soldul, ceea ce înseamnă că Alice își folosește cheia privată pentru a semna tranzacția și a confirma că este proprietarul monedelor sale.

Limbaje de programare Blockchain

Limbile blockchain existente se confruntă cu următoarele probleme (toate au fost rezolvate în Move). Din păcate, autorul articolului se referă doar la Ethereum în comparațiile sale, așa că ar trebui luate doar în acest context. De exemplu, cele mai multe dintre următoarele sunt rezolvate și în EOS)):

Reprezentarea indirectă a activelor. Un activ este codificat folosind un număr întreg, dar un număr întreg nu este același cu un activ. De fapt, nu există niciun tip sau valoare care să reprezinte Bitcoin/Ether/<Orice monedă>! Acest lucru face scrierea programelor care utilizează active dificilă și predispusă la erori. Modele precum transmiterea activelor către/de la proceduri sau stocarea activelor în structuri necesită suport special din partea limbii.

Deficitul nu se extinde. Limba reprezintă doar un bun rar. În plus, mijloacele de protecție împotriva deficiențelor sunt conectate direct în însăși semantica limbii. Un dezvoltator, dacă dorește să creeze un activ personalizat, trebuie să controleze el însuși cu atenție toate aspectele resursei. Acestea sunt exact problemele cu contractele inteligente Ethereum.

Utilizatorii își emit activele, jetoane ERC-20, folosind numere întregi pentru a determina atât valoarea, cât și oferta totală. Ori de câte ori sunt create noi jetoane, codul de contract inteligent trebuie să verifice în mod independent respectarea regulilor de emisie. În plus, reprezentarea indirectă a activelor duce, în unele cazuri, la erori grave - dublare, dublare a cheltuielilor sau chiar pierderea totală a activelor.

Lipsa unui control flexibil al accesului. Singura politică de control al accesului aplicată în prezent este o schemă de semnătură care utilizează criptografia asimetrică. La fel ca și protecția deficitului, politica de control al accesului este profund încorporată în semantica limbii. Dar cum să extinzi limbajul pentru a permite programatorilor să-și definească propriile politici de control al accesului este adesea o sarcină foarte dificilă.

Acest lucru este valabil și pe Ethereum, unde contractele inteligente nu au suport de criptare nativă pentru controlul accesului. Dezvoltatorii trebuie să seteze manual controlul accesului, de exemplu, folosind modificatorul onlyOwner.

Chiar dacă sunt un mare fan al Ethereum, cred că proprietățile activelor ar trebui să fie susținute nativ de limbaj din motive de securitate. În special, transferul Ether într-un contract inteligent implică trimiterea dinamică, care a introdus o nouă clasă de erori cunoscute sub numele de vulnerabilități de reintrare. Expedierea dinamică înseamnă aici că logica de execuție a codului va fi determinată în timpul execuției (dinamic) mai degrabă decât în ​​timpul compilării (static).

Astfel, în Solidity, atunci când contractul A apelează o funcție din contractul B, contractul B poate rula cod care nu a fost intenționat de dezvoltatorul contractului A, ceea ce poate duce la vulnerabilități de reintrare (contractul A acționează accidental ca contractul B pentru a retrage bani înainte ca soldurile contului să fie efectiv deduse).

Move Language Design Fundamentals

Resurse de primă comandă

Vorbind la nivel înalt, interacțiunea dintre module/resurse/proceduri în limbajul Move este foarte asemănătoare cu relațiile dintre clase/obiecte și metode din limbajele OOP.
Modulele din Move sunt similare cu contractele inteligente din alte blockchain-uri. Modulul declară tipuri de resurse și proceduri care specifică reguli pentru crearea, distrugerea și actualizarea resurselor declarate. Dar toate acestea sunt doar convenții („jargon”) în Mutare. Vom ilustra acest punct puțin mai târziu.

flexibilitate

Move adaugă flexibilitate Libra prin scripting. Fiecare tranzacție în Balanță include un script, care este în esență procedura de bază a tranzacției. Scriptul poate efectua fie o acțiune specificată, de exemplu, plăți către o listă specificată de destinatari, fie reutiliza alte resurse - de exemplu, apelând o procedură în care este specificată logica generală. Acesta este motivul pentru care scripturile de tranzacție Move oferă o mai mare flexibilitate. Un script poate folosi atât comportamente unice, cât și comportamente repetate, în timp ce Ethereum poate executa doar scripturi repetabile (apelând o singură metodă pe o metodă de contract inteligent). Motivul pentru care se numește „reutilizabil” este că funcțiile unui contract inteligent pot fi executate de mai multe ori. (Notă: Ideea aici este foarte subtilă. Pe de o parte, scripturile de tranzacție sub formă de pseudo-bytecode există și în Bitcoin. Pe de altă parte, după cum am înțeles, Move extinde acest limbaj, de fapt, la nivelul unui limbaj cu drepturi depline pentru contracte inteligente.).

Безопасность

Formatul executabil Move este bytecode, care este, pe de o parte, un limbaj de nivel mai înalt decât limbajul de asamblare, dar un nivel mai scăzut decât codul sursă. Codul de octet este verificat în timpul rulării (în lanț) pentru resurse, tipuri și siguranța memoriei folosind un verificator de cod de octet și apoi executat de interpret. Această abordare permite Move să ofere securitatea codului sursă, dar fără procesul de compilare și necesitatea de a adăuga un compilator la sistem. A face Move un limbaj bytecode este o soluție foarte bună. Nu trebuie să fie compilat din sursă, așa cum este cazul Solidity, și nu este nevoie să vă faceți griji cu privire la posibile eșecuri sau atacuri asupra infrastructurii compilatorului.

Verificabilitate

Ne propunem să efectuăm verificări cât mai ușor posibil, deoarece toate acestea se fac în lanț (notă: online, în timpul executării fiecărei tranzacții, deci orice întârziere duce la o încetinire a întregii rețele), cu toate acestea, inițial proiectarea limbajului este pregătită pentru a utiliza instrumente de verificare statică în afara lanțului. Deși acest lucru este mai de preferat, deocamdată dezvoltarea instrumentelor de verificare (ca un set de instrumente separat) a fost amânată pentru viitor, iar acum este acceptată doar verificarea dinamică în timp de execuție (on-chain).

Modularitate

Modulele de mutare oferă extragerea datelor și localizează operațiunile critice ale resurselor. Încapsularea oferită de un modul, combinată cu protecția oferită de sistemul de tip Move, asigură că proprietățile setate pe tipuri de module nu pot fi încălcate de cod în afara modulului. Acesta este un design destul de inteligent al abstracției, ceea ce înseamnă că datele din interiorul contractului pot fi modificate numai în domeniul de aplicare al contractului, și nu din exterior.

Dive into Move - limbajul de programare blockchain Libra al Facebook

Mutați recenzia

Exemplul de script de tranzacție demonstrează că acțiunile rău intenționate sau neglijente ale unui programator din afara modulului nu pot compromite securitatea resurselor modulului. În continuare, vom analiza exemple despre modul în care modulele, resursele și procedurile sunt utilizate pentru a programa blockchain-ul Libra.

Plăți peer-to-Peer

Dive into Move - limbajul de programare blockchain Libra al Facebook

Numărul de monede specificat ca sumă va fi transferat din soldul expeditorului către destinatar.
Există câteva lucruri noi aici (evidențiate cu roșu):

  • 0x0: adresa contului în care este stocat modulul
  • Monedă: numele modulului
  • Monedă: tipul de resursă
  • Valoarea monedei returnată de procedură este o valoare a resursei al cărei tip este 0x0.Currency.Coin
  • mișcare(): valoarea nu poate fi folosită din nou
  • copie(): valoarea poate fi folosită ulterior

Să ne uităm la cod: în primul pas, expeditorul apelează o procedură numită retrage_de_expeditor dintr-un modul stocat în 0x0.Moneda. În al doilea pas, expeditorul transferă fonduri către destinatar prin mutarea valorii resursei de monede în procedura de depunere a modulului 0x0.Moneda.

Iată trei exemple de erori în cod care vor fi respinse prin verificări:
Duplicați fonduri schimbând apelul muta (moneda) pe copie (moneda). Resursele pot fi doar mutate. Încercarea de a duplica o cantitate dintr-o resursă (de exemplu, apelând copie (moneda) în exemplul de mai sus) va avea ca rezultat o eroare în timpul verificării bytecode.

Reutilizarea fondurilor prin specificare muta (moneda) de două ori . Adăugarea unei linii 0x0.Currency.deposit (copiere (un_altul_beneficiar), mutare (monedă)) de exemplu, cele de mai sus vor permite expeditorului să „cheltuiască” monedele de două ori - prima dată cu beneficiarul și a doua cu un_altul_beneficiar. Acesta este un comportament nedorit care nu este posibil cu un bun fizic. Din fericire, Move va respinge acest program.

Pierderea de fonduri din cauza refuzului muta (moneda). Dacă nu mutați resursa (de exemplu, ștergând linia care conține muta (moneda)), va fi generată o eroare de verificare a codului octet. Acest lucru îi protejează pe programatorii Move de pierderea accidentală sau rău intenționată de fonduri.

Modul valutar

Dive into Move - limbajul de programare blockchain Libra al Facebook

Fiecare cont poate conține 0 sau mai multe module (afișate ca dreptunghiuri) și una sau mai multe valori de resurse (afișate ca cilindri). De exemplu, un cont la 0x0 conţine modul 0x0.Moneda și valoarea tipului de resursă 0x0.Monedă.Monedă. Cont la adresa 0x1 are două resurse și un modul; Cont la adresa 0x2 are două module și o valoare de resursă.

Momente Nekotory:

  • Scriptul de tranzacție este atomic - fie este executat complet, fie deloc.
  • Un modul este o bucată de cod de lungă durată care este accesibilă la nivel global.
  • Starea globală este structurată ca un tabel hash, unde cheia este adresa contului
  • Conturile nu pot conține mai mult de o valoare de resursă de un anumit tip și nu mai mult de un modul cu un nume dat (contul la 0x0 nu poate conține o resursă suplimentară 0x0.Monedă.Monedă sau alt modul numit Monedă)
  • Adresa modulului declarat face parte din tipul (0x0.Monedă.Monedă и 0x1.Monedă.Monedă sunt tipuri separate care nu pot fi folosite interschimbabil)
  • Programatorii pot stoca mai multe instanțe ale acestui tip de resursă într-un cont prin definirea resursei lor personalizate - (resursă TwoCoins {c1: 0x0.Currency.Coin, c2: 0x0.Currency.Coin})
  • Puteți face referire la o resursă prin numele ei fără conflicte, de exemplu vă puteți referi la două resurse folosind DouăMonede.c1 и DouăMonede.c2.

Anunț privind resursele de monede

Dive into Move - limbajul de programare blockchain Libra al Facebook
Modulul numit Monedă și un tip de resursă numit Monedă

Momente Nekotory:

  • Monedă este o structură cu un câmp de tip u64 (întreg fără semn pe 64 de biți)
  • Numai procedurile modulului Monedă poate crea sau distruge valori de tip Monedă.
  • Alte module și scripturi pot scrie sau face referire la câmpul de valoare numai prin proceduri publice furnizate de modul.

Vânzarea depozitului

Dive into Move - limbajul de programare blockchain Libra al Facebook

Această procedură acceptă o resursă Monedă ca intrare și o combină cu resursa Monedăstocate în contul destinatarului:

  1. Distrugerea resursei de intrare Coin și înregistrarea valorii acesteia.
  2. Primirea unui link către o resursă unică de monede stocată în contul destinatarului.
  3. Modificarea valorii numărului de monede cu valoarea transmisă în parametru la apelarea procedurii.

Momente Nekotory:

  • Despachetați, BorrowGlobal - proceduri încorporate
  • Despacheta Acesta este singurul mod de a șterge o resursă de tip T. Procedura ia o resursă ca intrare, o distruge și returnează valoarea asociată câmpurilor resursei.
  • BorrowGlobal ia o adresă ca intrare și returnează o referință la o instanță unică de T publicată (deținută) de adresa respectivă
  • &mut Coin acesta este un link către resursă Monedă

Implementarea lui withdraw_from_sender

Dive into Move - limbajul de programare blockchain Libra al Facebook

Această procedură:

  1. Obține un link către o resursă unică Monedă, conectat la contul expeditorului
  2. Scade valoarea unei resurse Monedă prin link pentru suma specificată
  3. Creează și returnează o nouă resursă Monedă cu sold actualizat.

Momente Nekotory:

  • Depozit poate fi cauzat de oricine, dar retrage_de_expeditor are acces doar la monedele contului de apelare
  • GetTxnSenderAddress similar cu msg.sender în Soliditate
  • RespingeDacă similar cu necesita în Soliditate. Dacă această verificare eșuează, tranzacția este oprită și toate modificările sunt anulate.
  • Ambalaj este, de asemenea, o procedură încorporată care creează o nouă resursă de tip T.
  • Precum și Despacheta, Ambalaj poate fi apelat doar în interiorul modulului în care este descrisă resursa T

Concluzie

Am examinat principalele caracteristici ale limbajului Move, l-am comparat cu Ethereum și, de asemenea, ne-am familiarizat cu sintaxa de bază a scripturilor. În cele din urmă, vă recomand cu căldură să verificați hârtie albă originală. Include o mulțime de detalii cu privire la principiile de proiectare a limbajului de programare, precum și multe link-uri utile.

Sursa: www.habr.com

Adauga un comentariu