Duik in Move - Facebook's Libra blockchain-programmeertaal

Vervolgens zullen we in detail kijken naar de belangrijkste kenmerken van de Move-taal en wat de belangrijkste verschillen zijn met een andere, al populaire taal voor slimme contracten: Solidity (op het Ethereum-platform). Het materiaal is gebaseerd op een studie van een whitepaper van 26 pagina's die online beschikbaar is.

Introductie

Move is een uitvoerbare bytecodetaal die wordt gebruikt om gebruikerstransacties en slimme contracten uit te voeren. Let op twee punten:

  1. Terwijl Move een bytecodetaal is die rechtstreeks kan worden uitgevoerd op de Move Virtual Machine, is Solidity (de slimme contracttaal in Ethereum) een taal van een hoger niveau die eerst wordt gecompileerd in bytecode voordat deze wordt uitgevoerd in de EVM (Ethereum Virtual Machine).
  2. Move kan niet alleen worden gebruikt om slimme contracten te implementeren, maar ook voor gebruikerstransacties (hierover later meer), terwijl Solidity een taal is die alleen voor slimme contracten geldt.


De vertaling werd uitgevoerd door het INDEX Protocol-projectteam. Wij hebben het al vertaald groot materiaal dat het Libra-project beschrijft, nu is het tijd om de Move-taal wat gedetailleerder te bekijken. De vertaling werd samen met Habrauser uitgevoerd koelsiu

Een belangrijk kenmerk van Move is de mogelijkheid om aangepaste resourcetypen te definiëren met semantiek gebaseerd op lineaire logica: een resource kan nooit worden gekopieerd of impliciet verwijderd, maar alleen worden verplaatst. Functioneel is dit vergelijkbaar met de mogelijkheden van de Rust-taal. Waarden in Rust kunnen slechts aan één naam tegelijk worden toegewezen. Als u een waarde aan een andere naam toewijst, is deze niet meer beschikbaar onder de vorige naam.

Duik in Move - Facebook's Libra blockchain-programmeertaal

Het volgende codefragment genereert bijvoorbeeld een fout: Gebruik van verplaatste waarde 'x'. Dit komt omdat Rust geen afvalinzameling heeft. Wanneer variabelen buiten het bereik vallen, wordt ook het geheugen waarnaar ze verwijzen vrijgegeven. Simpel gezegd kan er maar één ‘eigenaar’ van de gegevens zijn. In dit voorbeeld x is de oorspronkelijke eigenaar en dan y wordt de nieuwe eigenaar. Lees hier meer over dit gedrag.

Vertegenwoordigen van digitale assets in open systemen

Er zijn twee eigenschappen van fysieke activa die moeilijk digitaal weer te geven zijn:

  • Zeldzaamheid (Schaarste, in het origineel: schaarste). Het aantal assets (emissies) in het systeem moet beheerst worden. Het dupliceren van bestaande activa moet worden verboden, en het creëren van nieuwe is een bevoorrechte operatie.
  • Toegangscontrole. De systeemdeelnemer moet activa kunnen beschermen met behulp van toegangscontrolebeleid.

Deze twee kenmerken, die natuurlijk zijn voor fysieke activa, moeten ook worden geïmplementeerd voor digitale objecten als we ze als activa willen beschouwen. Een zeldzaam metaal heeft bijvoorbeeld een natuurlijke schaarste, en alleen jij hebt er toegang toe (als je het in je handen houdt bijvoorbeeld) en je kunt het verkopen of uitgeven.

Om te illustreren hoe we tot deze twee eigenschappen zijn gekomen, beginnen we met de volgende zinnen:

Stelling #1: De eenvoudigste regel zonder schaarste en toegangscontrole

Duik in Move - Facebook's Libra blockchain-programmeertaal

  • G[K]:=n geeft het bijwerken van een nummer aan dat toegankelijk is met een sleutel К in de mondiale staat van de blockchain, met een nieuwe betekenis n.
  • transactie ⟨Alice, 100⟩ betekent dat het rekeningsaldo van Alice op 100 wordt gezet.

De bovenstaande oplossing heeft verschillende ernstige problemen:

  • Alice kan een onbeperkt aantal munten ontvangen door simpelweg te verzenden transactie ⟨Alice, 100⟩.
  • De munten die Alice naar Bob stuurt zijn waardeloos, aangezien Bob zichzelf met dezelfde techniek een onbeperkt aantal munten kan sturen.

Suggestie nr. 2: Houd rekening met het tekort

Duik in Move - Facebook's Libra blockchain-programmeertaal

Nu houden we de situatie in de gaten, zodat het aantal munten toeneemt Ka was minimaal gelijk n vóór de overdrachtstransactie. Hoewel dit het schaarsteprobleem oplost, is er echter geen informatie over wie Alice-munten kan sturen (voorlopig kan iedereen dit doen, zolang je de regel voor de hoeveelheidslimiet niet overtreedt).

Voorstel #3: Combineer schaarste en toegangscontrole

Duik in Move - Facebook's Libra blockchain-programmeertaal

We lossen dit probleem op met behulp van een digitaal handtekeningmechanisme verifieer_sig voordat ze het saldo controleert, wat betekent dat Alice haar privésleutel gebruikt om de transactie te ondertekenen en te bevestigen dat zij de eigenaar van haar munten is.

Blockchain-programmeertalen

Bestaande blockchain-talen kampen met de volgende problemen (die allemaal zijn opgelost in Move). Helaas verwijst de auteur van het artikel in zijn vergelijkingen alleen naar Ethereum, dus ze moeten alleen in deze context worden genomen. Het meeste van het volgende is bijvoorbeeld ook opgelost in EOS)):

Indirecte vertegenwoordiging van activa. Een asset wordt gecodeerd met een geheel getal, maar een geheel getal is niet hetzelfde als een asset. In feite is er geen type of waarde die Bitcoin/Ether/<Any Coin> vertegenwoordigt! Dit maakt het schrijven van programma's die middelen gebruiken lastig en foutgevoelig. Patronen zoals het doorgeven van middelen aan/van procedures of het opslaan van middelen in structuren vereisen speciale ondersteuning van de taal.

Het tekort groeit niet. Taal vertegenwoordigt slechts één schaars bezit. Bovendien zijn de middelen ter bescherming tegen tekortkomingen rechtstreeks verankerd in de semantiek van de taal. Als een ontwikkelaar een aangepast asset wil maken, moet hij alle aspecten van de resource zelf zorgvuldig controleren. Dit zijn precies de problemen met slimme contracten van Ethereum.

Gebruikers geven hun activa, ERC-20-tokens, uit met behulp van gehele getallen om zowel de waarde als het totale aanbod te bepalen. Telkens wanneer er nieuwe tokens worden aangemaakt, moet de slimme contractcode onafhankelijk de naleving van de emissieregels verifiëren. Bovendien leidt de indirecte vertegenwoordiging van activa in sommige gevallen tot ernstige fouten: dubbel werk, dubbele uitgaven of zelfs volledig verlies van activa.

Gebrek aan flexibele toegangscontrole. Het enige toegangscontrolebeleid dat momenteel wordt toegepast, is een handtekeningschema dat gebruik maakt van asymmetrische cryptografie. Net als de bescherming tegen schaarste is het toegangscontrolebeleid diep verankerd in de semantiek van de taal. Maar hoe je de taal kunt uitbreiden zodat programmeurs hun eigen toegangscontrolebeleid kunnen definiëren, is vaak een zeer uitdagende taak.

Dit geldt ook voor Ethereum, waar slimme contracten geen native cryptografie-ondersteuning bieden voor toegangscontrole. Ontwikkelaars moeten de toegangscontrole handmatig instellen, bijvoorbeeld met behulp van de onlyOwner-modifier.

Ook al ben ik een grote fan van Ethereum, ik ben van mening dat activa-eigenschappen om veiligheidsredenen native door de taal moeten worden ondersteund. In het bijzonder gaat het bij het overbrengen van Ether naar een slim contract om dynamische verzending, waardoor een nieuwe klasse bugs is geïntroduceerd die bekend staan ​​als re-entry-kwetsbaarheden. Dynamische verzending betekent hier dat de uitvoeringslogica van de code wordt bepaald tijdens runtime (dynamisch) in plaats van tijdens het compileren (statisch).

Dus wanneer contract A in Solidity een functie in contract B aanroept, kan contract B code uitvoeren die niet bedoeld was door de ontwikkelaar van contract A, wat kan resulteren in kwetsbaarheden bij herintreding (contract A fungeert per ongeluk als contract B om geld op te nemen voordat het rekeningsaldo daadwerkelijk wordt afgeschreven).

Verplaats de basisprincipes van taalontwerp

Hulpmiddelen van de eerste orde

Op een hoog niveau gesproken: de interactie tussen modules/bronnen/procedures in de Move-taal lijkt sterk op de relaties tussen klassen/objecten en methoden in OOP-talen.
Modules in Move zijn vergelijkbaar met slimme contracten in andere blockchains. De module declareert resourcetypen en -procedures die regels specificeren voor het maken, vernietigen en bijwerken van gedeclareerde bronnen. Maar dit zijn allemaal slechts conventies (“jargon”) in Verplaatsen. We zullen dit punt iets later illustreren.

flexibiliteit

Move voegt flexibiliteit toe aan Libra via scripting. Elke transactie in Libra bevat een script, dat in wezen de kernprocedure van de transactie vormt. Het script kan één gespecificeerde actie uitvoeren, bijvoorbeeld betalingen aan een gespecificeerde lijst met ontvangers, of andere bronnen hergebruiken, bijvoorbeeld door een procedure aan te roepen waarin de algemene logica is gespecificeerd. Dit is de reden waarom Move-transactiescripts meer flexibiliteit bieden. Een script kan zowel eenmalig als herhalend gedrag gebruiken, terwijl Ethereum alleen herhaalbare scripts kan uitvoeren (één methode aanroepen op een slimme contractmethode). De reden dat het ‘herbruikbaar’ wordt genoemd, is omdat de functies van een slim contract meerdere keren kunnen worden uitgevoerd. (opmerking: Het punt hier is heel subtiel. Enerzijds bestaan ​​er in Bitcoin ook transactiescripts in de vorm van pseudo-bytecode. Aan de andere kant, zoals ik het begrijp, breidt Move deze taal feitelijk uit tot het niveau van een volwaardige slimme contracttaal).

veiligheid

Het uitvoerbare formaat van Move is bytecode, wat enerzijds een taal op een hoger niveau is dan de assembleertaal, maar op een lager niveau dan de broncode. De bytecode wordt tijdens runtime (on-chain) gecontroleerd op bronnen, typen en geheugenveiligheid met behulp van een bytecodeverifier, en vervolgens uitgevoerd door de tolk. Dankzij deze aanpak kan Move de beveiliging van de broncode bieden, maar zonder het compilatieproces en de noodzaak om een ​​compiler aan het systeem toe te voegen. Van Move een bytecodetaal maken is een hele goede oplossing. Het hoeft niet vanuit de broncode te worden gecompileerd, zoals het geval is bij Solidity, en u hoeft zich geen zorgen te maken over mogelijke fouten of aanvallen op de compilerinfrastructuur.

Controleerbaarheid

Wij zijn erop gericht om controles zo eenvoudig mogelijk uit te voeren, omdat dit allemaal on-chain gebeurt (let op: online, tijdens de uitvoering van elke transactie, dus elke vertraging leidt tot een vertraging van het hele netwerk), maar in eerste instantie is het taalontwerp klaar om off-chain statische verificatietools te gebruiken. Hoewel dit meer de voorkeur verdient, is de ontwikkeling van verificatietools (als een aparte toolkit) voorlopig uitgesteld naar de toekomst en wordt nu alleen dynamische verificatie in runtime (on-chain) ondersteund.

Modulariteit

Move-modules bieden gegevensabstractie en lokaliseren kritieke resourcebewerkingen. De inkapseling die door een module wordt geboden, gecombineerd met de bescherming die wordt geboden door het Move-type systeem, zorgt ervoor dat de eigenschappen die zijn ingesteld op moduletypen niet kunnen worden geschonden door code buiten de module. Dit is een vrij slim ontwerp van abstractie, wat betekent dat de gegevens binnen het contract alleen binnen de reikwijdte van het contract kunnen worden gewijzigd, en niet van buitenaf.

Duik in Move - Facebook's Libra blockchain-programmeertaal

Beoordeling verplaatsen

Het voorbeeld van een transactiescript laat zien dat kwaadaardige of onzorgvuldige acties door een programmeur buiten de module de veiligheid van de bronnen van de module niet in gevaar kunnen brengen. Vervolgens bekijken we voorbeelden van hoe modules, bronnen en procedures worden gebruikt om de Libra-blockchain te programmeren.

Peer-to-peer-betalingen

Duik in Move - Facebook's Libra blockchain-programmeertaal

Het bij bedrag opgegeven aantal munten wordt van het saldo van de afzender naar de ontvanger overgedragen.
Er zijn een paar nieuwe dingen hier (rood gemarkeerd):

  • 0x0: adres van het account waar de module is opgeslagen
  • Valuta: module naam
  • Munt: brontype
  • De muntwaarde die door de procedure wordt geretourneerd, is een resourcewaarde waarvan het type 0x0.Currency.Coin is
  • beweging(): waarde kan niet opnieuw worden gebruikt
  • kopiëren(): waarde kan later worden gebruikt

Laten we naar de code kijken: in de eerste stap roept de afzender een procedure aan met de naam terugtrekken_van_afzender van een module die is opgeslagen in 0x0.Valuta. In de tweede stap maakt de afzender geld over naar de ontvanger door de waarde van de muntbron naar de stortingsprocedure van de module te verplaatsen 0x0.Valuta.

Hier zijn drie voorbeelden van codefouten die door controles worden afgewezen:
Dupliceer het geld door de oproep te wijzigen bewegen (munt) op kopie(munt). Grondstoffen kunnen alleen worden verplaatst. Proberen een hoeveelheid van een hulpbron te dupliceren (bijvoorbeeld door te bellen kopie(munt) in het bovenstaande voorbeeld) zal resulteren in een fout tijdens de bytecodeverificatie.

Hergebruik van middelen door op te geven bewegen (munt) tweemaal . Een lijn toevoegen 0x0.Valuta.storting (kopie (een_andere_begunstigde), verplaatsing (munt)) Met het bovenstaande kan de afzender de munten bijvoorbeeld twee keer ‘uitgeven’: de eerste keer bij de begunstigde en de tweede keer bij een_andere_begunstigde. Dit is ongewenst gedrag dat niet mogelijk is met een fysiek bezit. Gelukkig zal Move dit programma afwijzen.

Verlies van geld als gevolg van weigering bewegen (munt). Als u de bron niet verplaatst (bijvoorbeeld door de regel te verwijderen die bewegen (munt)), zal er een bytecode-verificatiefout optreden. Dit beschermt Move-programmeurs tegen onbedoeld of kwaadwillig verlies van geld.

Valutamodule

Duik in Move - Facebook's Libra blockchain-programmeertaal

Elk account kan 0 of meer modules bevatten (weergegeven als rechthoeken) en een of meer bronwaarden (weergegeven als cilinders). Bijvoorbeeld een rekening op 0x0 bevat module 0x0.Valuta en de waarde van het resourcetype 0x0.Valuta.Munt. Rekening op adres 0x1 heeft twee bronnen en één module; Rekening op adres 0x2 heeft twee modules en één resourcewaarde.

Enkele momenten:

  • Het transactiescript is atomair: het wordt volledig of helemaal niet uitgevoerd.
  • Een module is een stuk code met een lange levensduur dat wereldwijd toegankelijk is.
  • De globale status is gestructureerd als een hashtabel, waarbij de sleutel het accountadres is
  • Accounts kunnen niet meer dan één resourcewaarde van een bepaald type bevatten en niet meer dan één module met een bepaalde naam (account op 0x0 kan geen extra bron bevatten 0x0.Valuta.Munt of een andere module met de naam Valuta)
  • Het adres van de gedeclareerde module maakt deel uit van het type (0x0.Valuta.Munt и 0x1.Valuta.Munt zijn afzonderlijke typen die niet door elkaar kunnen worden gebruikt)
  • Programmeurs kunnen meerdere exemplaren van dit type bron in een account opslaan door hun aangepaste bron te definiëren - (bron TwoCoins {c1: 0x0.Currency.Coin, c2: 0x0.Currency.Coin})
  • U kunt zonder conflicten naar een bron verwijzen met de naam. U kunt bijvoorbeeld naar twee bronnen verwijzen met behulp van Twee Munten.c1 и Twee Munten.c2.

Verklaring van de muntbronnen

Duik in Move - Facebook's Libra blockchain-programmeertaal
Module genoemd Valuta en een resourcetype met de naam Munt

Enkele momenten:

  • Munt is een structuur met één typeveld u64 (64-bit geheel getal zonder teken)
  • Alleen moduleprocedures Valuta kan waarden van het type creëren of vernietigen Munt.
  • Andere modules en scripts kunnen het waardeveld alleen schrijven of ernaar verwijzen via openbare procedures die door de module worden geleverd.

Verkoop van deposito

Duik in Move - Facebook's Libra blockchain-programmeertaal

Deze procedure accepteert een bron Munt als input en combineert deze met de bron Muntopgeslagen in het account van de ontvanger:

  1. Het vernietigen van de invoerbron Coin en het vastleggen van de waarde ervan.
  2. Het ontvangen van een link naar een unieke Coin-bron die is opgeslagen in het account van de ontvanger.
  3. Het wijzigen van de waarde van het aantal munten met de waarde die in de parameter is doorgegeven bij het aanroepen van de procedure.

Enkele momenten:

  • Uitpakken, lenenGlobal - ingebouwde procedures
  • Uitpakken Dit is de enige manier om een ​​resource van het type T te verwijderen. De procedure neemt een resource als invoer, vernietigt deze en retourneert de waarde die is gekoppeld aan de velden van de resource.
  • LenenGlobaal neemt een adres als invoer en retourneert een verwijzing naar een uniek exemplaar van T dat door dat adres is gepubliceerd (eigendom).
  • &mut Munt dit is een link naar de bron Munt

Implementatie van pull_from_sender

Duik in Move - Facebook's Libra blockchain-programmeertaal

Deze procedure:

  1. Krijgt een link naar een unieke bron Munt, gekoppeld aan het account van de afzender
  2. Verlaagt de waarde van een hulpbron Munt via de link voor het opgegeven bedrag
  3. Creëert en retourneert een nieuwe bron Munt met bijgewerkt saldo.

Enkele momenten:

  • Statiegeld kan door iedereen veroorzaakt worden, maar terugtrekken_van_afzender heeft alleen toegang tot de munten van de belrekening
  • GetTxnSenderAddress gelijkwaardig aan bericht.afzender in stevigheid
  • AfwijzenTenzij gelijkwaardig aan vereisen in stevigheid. Als deze controle mislukt, wordt de transactie gestopt en worden alle wijzigingen teruggedraaid.
  • Pak het is ook een ingebouwde procedure die een nieuwe bron van het type T creëert.
  • Net zoals Uitpakken, Pak kan alleen worden aangeroepen binnen de module waar de bron wordt beschreven T

Conclusie

We onderzochten de belangrijkste kenmerken van de Move-taal, vergeleken deze met Ethereum en raakten ook vertrouwd met de basissyntaxis van scripts. Tot slot raad ik je ten zeerste aan om eens uit te checken origineel wit papier. Het bevat veel details over de ontwerpprincipes van programmeertalen, evenals veel nuttige links.

Bron: www.habr.com

Voeg een reactie