Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

Deretter vil vi i detalj vurdere hovedtrekkene til Move -språket og hva som er hovedforskjellene med et annet, allerede populært språk for smarte kontrakter - Solidity (på Ethereum -plattformen). Materialet er basert på en studie av det tilgjengelige 26-siders whitepaper.

Innledning

Move er et kjørbart bytekodespråk som brukes til å utføre brukertransaksjoner og smarte kontrakter. Vær oppmerksom på to punkter:

  1. Mens Move er et bytekodespråk som kan kjøres direkte på den virtuelle Move-maskinen, er Solidity (Ethereums smarte kontraktspråk) et språk på et høyere nivå som først kompileres til bytekode før det kjøres på en EVM (Ethereum Virtual Machine).
  2. Move kan brukes ikke bare for å implementere smarte kontrakter, men også for tilpassede transaksjoner (mer om dette senere), mens Solidity er et smart kontrakt som bare er avtale.


Oversettelsen ble utført av INDEX Protocol-prosjektteamet. Vi har allerede oversatt stort materiale som beskriver Libra-prosjektet, nå er det på tide å se på Move-språket litt mer detaljert. Oversettelsen ble utført i fellesskap med Habrauser coolsiu

En nøkkelfunksjon ved Move er muligheten til å definere egendefinerte ressurstyper med semantikk basert på lineær logikk: en ressurs kan aldri kopieres eller implisitt slettes, kun flyttes. Funksjonelt ligner dette på egenskapene til Rust-språket. Verdier i Rust kan bare tildeles ett navn om gangen. Hvis du tilordner en verdi til et annet navn, blir det utilgjengelig under det forrige navnet.

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

For eksempel gir følgende kodebit en feilmelding: Bruk av flyttet verdi 'x'. Dette er fordi det ikke er noen søppelsamling i Rust. Når variabler går utenfor omfanget, frigjøres også minnet de refererer til. Enkelt sagt kan det bare være en "eier" av dataene. I dette eksemplet x er den opprinnelige eieren og deretter y blir ny eier. Les mer om denne oppførselen her.

Representasjon av digitale eiendeler i åpne systemer

Det er to egenskaper ved fysiske eiendeler som er vanskelig å representere digitalt:

  • Sjeldenhet (Knapphet, opprinnelig knapphet). Antall eiendeler (utslipp) i systemet må kontrolleres. Duplisering av eksisterende eiendeler må være forbudt, og å opprette nye er en privilegert operasjon.
  • Adgangskontroll... Systemdeltakeren må kunne beskytte eiendeler ved hjelp av tilgangskontrollpolicyer.

Disse to egenskapene, som er naturlige for fysiske eiendeler, må implementeres for digitale objekter hvis vi vil betrakte dem som eiendeler. For eksempel et sjeldent metall - har en naturlig knapphet, og bare du har tilgang til det (for eksempel å holde det i hendene), og du kan selge eller bruke det.

For å illustrere hvordan vi kom frem til disse to egenskapene, la oss starte med følgende setninger:

Forslag nr. 1: Den enkleste regelen uten knapphet og tilgangskontroll

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

  • G [K]: = n betegner en oppdatering av et nummer som er tilgjengelig med en nøkkel К i den globale tilstanden til blockchain, med en ny mening n.
  • transaksjon lAlice, 100⟩ betyr å sette Alices kontosaldo til 100.

Løsningen ovenfor har flere store problemer:

  • Alice kan motta et ubegrenset antall mynter ved ganske enkelt å sende transaksjon ⟨Alice, 100⟩.
  • Myntene Alice sender til Bob er ubrukelige, ettersom Bob kunne sende seg et ubegrenset antall mynter med samme teknikk.

Forslag nr. 2: Tar hensyn til underskuddet

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

Nå overvåker vi situasjonen slik at antall mynter Ka var minst like n før overføringstransaksjonen. Selv om dette løser problemet med knapphet, er det ingen informasjon om hvem som kan sende Alices mynter (foreløpig kan hvem som helst gjøre dette, det viktigste er ikke å bryte regelen om begrensning av beløpet).

Forslag nr. 3: Kombinere knapphet og tilgangskontroll

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

Vi løser dette problemet med en digital signaturmekanisme verifisere_sig før du sjekker saldoen, noe som betyr at Alice bruker sin private nøkkel for å signere transaksjonen og bekrefte at hun er eieren av myntene hennes.

Blockchain programmeringsspråk

De eksisterende blockchain -språkene står overfor følgende problemer (alle ble løst i Move (merk: Dessverre appellerer forfatteren av artikkelen bare til Ethereum i sine sammenligninger, så det er verdt å ta dem bare i denne sammenhengen. For eksempel er det meste av det følgende også løst i EOS.))):

Indirekte representasjon av eiendeler. En eiendel er kodet med et heltall, men et heltall er ikke det samme som en eiendel. Faktisk er det ingen type eller verdi som representerer Bitcoin/Ether/<Enhver mynt>! Dette gjør skriving av programmer som bruker eiendeler vanskelig og utsatt for feil. Mønstre som å overføre eiendeler til/fra prosedyrer eller lagring av eiendeler i strukturer krever spesiell støtte fra språket.

Underskuddet kan ikke utvides... Språk representerer bare en knapp ressurs. I tillegg er midlene for beskyttelse mot knapphet koblet direkte til semantikken i selve språket. Utvikleren, hvis han ønsker å lage en tilpasset eiendel, må nøye kontrollere alle aspekter av ressursen selv. Dette er nøyaktig problemene med Ethereum smarte kontrakter.

Brukere utsteder sine eiendeler, ERC-20-tokens, ved hjelp av heltall for å bestemme både verdien og den totale forsyningen. Når nye tokens opprettes, må smartkontrakoden uavhengig verifisere samsvar med utslippsreglene. I tillegg fører den indirekte presentasjonen av eiendeler i noen tilfeller til alvorlige feil - duplisering, doble utgifter eller til og med fullstendig tap av eiendeler.

Mangel på fleksibel tilgangskontroll... Den eneste tilgangskontrollpolitikken som brukes i dag er et signaturoppsett som bruker asymmetrisk kryptografi. I likhet med knapphetsbeskyttelse er tilgangskontrollpolitikk dypt innebygd i språkets semantikk. Men hvordan man utvider språket slik at programmerere kan definere sine egne tilgangskontrollpolicyer, er ofte en veldig vanskelig oppgave.

Dette gjelder også på Ethereum, der smarte kontrakter ikke har innfødt kryptografistøtte for tilgangskontroll. Utviklere må angi tilgangskontroll manuelt, for eksempel ved å bruke onlyOwner-modifikatoren.

Selv om jeg er en stor fan av Ethereum, tror jeg at eiendeler bør støttes av språket av sikkerhetshensyn. Spesielt involverer overføring av Ether til en smart kontrakt dynamisk sending, som har introdusert en ny klasse av feil kjent som gjeninntredenssårbarheter. Dynamisk utsendelse betyr her at utførelseslogikken til koden vil bli bestemt ved kjøretid (dynamisk) i stedet for ved kompilering (statisk).

I Solidity, når kontrakt A kaller en funksjon i kontrakt B, kan kontrakt B kjøre kode som ikke var tiltenkt av kontrakt A sin utvikler, noe som kan resultere i gjeninntredenssårbarheter (kontrakt A fungerer ved et uhell som kontrakt B for å ta ut penger før kontosaldoene faktisk trekkes fra).

Move Language Design Fundamentals

Førsteordensressurser

På et høyt nivå er samspillet mellom moduler / ressurser / prosedyrer på Move -språket veldig likt forholdet mellom klasser / objekter og metoder på OOP -språk.
Move -moduler ligner smarte kontrakter i andre blokker. Modulen deklarerer ressurstyper og prosedyrer som definerer reglene for å opprette, ødelegge og oppdatere deklarerte ressurser. Men alt dette er bare konvensjoner ("sjargong”) I bevegelse. Vi vil illustrere dette punktet litt senere.

Fleksibilitet

Move legger til fleksibilitet til Libra gjennom skripting. Hver transaksjon i Libra inkluderer et skript, som i hovedsak er kjerneprosedyren for transaksjonen. Skriptet kan utføre enten én spesifisert handling, for eksempel betalinger til en spesifisert liste over mottakere, eller gjenbruke andre ressurser – for eksempel ved å kalle en prosedyre der den generelle logikken er spesifisert. Dette er grunnen til at Move-transaksjonsskript gir større fleksibilitet. Et skript kan bruke både engangs- og repeterende atferd, mens Ethereum bare kan kjøre repeterbare skript (kaller én metode på en smart kontraktsmetode). Grunnen til at den kalles "gjenbrukbar" er fordi funksjonene til en smart kontrakt kan utføres flere ganger. (Merk: Poenget her er veldig subtilt. På den ene siden eksisterer transaksjonsskript i form av pseudo-bytekode også i Bitcoin. På den annen side, slik jeg forstår det, utvider Move dette språket, faktisk til nivået til et fullverdig smart kontraktsspråk).

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

Det kjørbare formatet Move er bytecode, som på den ene siden er et språk på høyere nivå enn assemblyspråk, men lavere nivå enn kildekode. Bytekoden sjekkes i løpetid (på kjeden) for ressurser, typer og minnesikkerhet ved hjelp av en bytekodebekreftelse, og utføres deretter av tolken. Denne tilnærmingen lar Move sørge for sikkerheten til kildekoden, men uten kompileringsprosessen og behovet for å legge til en kompilator til systemet. Å lage Move til et bytekodespråk er en veldig god løsning. Det trenger ikke å være kompilert fra kilden, slik tilfellet er med Solidity, og det er ikke nødvendig å bekymre seg for mulige feil eller angrep på kompilatorinfrastrukturen.

Verifiserbarhet

Vi tar sikte på å utføre kontroller så enkelt som mulig, siden alt dette gjøres på kjeden (merk: online, under gjennomføringen av hver transaksjon, så enhver forsinkelse fører til en nedgang i hele nettverket), men i utgangspunktet er språkdesignet klart til å bruke statiske verifiseringsverktøy utenfor kjeden. Selv om dette er mer å foretrekke, er utviklingen av verifiseringsverktøy (som et eget verktøysett) foreløpig utsatt for fremtiden, og nå støttes kun dynamisk verifisering i kjøretid (on-chain).

Modularitet

Move -moduler gir dataabstraksjon og lokaliserer kritiske operasjoner på ressurser. Innkapslingen som tilbys av modulen, kombinert med beskyttelsen fra Move -typesystemet, sikrer at egenskaper som er angitt på modulens typer, ikke kan krenkes med kode utenfor modulen. Dette er en ganske gjennomtenkt abstraksjonsdesign, noe som betyr at dataene i kontrakten bare kan endres innenfor rammen av kontrakten, men ikke utenfor.

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

Flytt oversikt

Transaksjonskripteksemplet viser at ondsinnede eller uforsiktige handlinger fra en programmerer utenfor en modul ikke kan kompromittere sikkerheten til modulens ressurser. Deretter ser vi på eksempler på hvordan moduler, ressurser og prosedyrer brukes til å programmere Libra blockchain.

Peer-to-Peer-betalinger

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

Antall mynter spesifisert i beløp vil bli overført fra avsenderens saldo til mottakeren.
Det er noen nye ting her (uthevet i rødt):

  • 0x0: adressen til kontoen der modulen er lagret
  • valuta: modulnavn
  • Coin: ressurstype
  • Myntverdien som returneres av prosedyren er en ressursverdi av typen 0x0.Currency.Coin
  • bevege seg (): verdi kan ikke brukes igjen
  • kopiere(): verdi kan brukes senere

Parse koden: i det første trinnet kaller avsenderen en prosedyre som heter trekke_fra_sender fra en modul lagret i 0x0.Valuta. I det andre trinnet overfører avsenderen midler til mottakeren ved å flytte myntressursverdien inn i modulens innskuddsprosedyre 0x0.Valuta.

Her er tre eksempler på feil i kode som vil bli avvist ved kontroller:
Dupliser midler ved å endre samtalen flytte (mynt)kopi (mynt). Ressurser kan bare flyttes. Prøver å duplisere en mengde av en ressurs (for eksempel ved å ringe kopi (mynt) i eksemplet ovenfor) vil resultere i en feil under validering av bykode.

Gjenbruk av midler ved å spesifisere flytte (mynt) to ganger . Legger til en linje 0x0.Currency.deposit (kopi (noen_andre_betalingsmottaker), flytt (mynt)) for eksempel vil ovenstående tillate avsenderen å "bruke" myntene to ganger - den første gangen med betalingsmottakeren, og den andre med noen_annet_betalingsmottaker. Dette er en uønsket oppførsel som ikke er mulig med en fysisk eiendel. Heldigvis vil Move avvise dette programmet.

Tap av midler på grunn av avslag flytte (mynt). Hvis du ikke flytter ressursen (for eksempel ved å slette linjen som inneholder flytte (mynt)), vil en bytekodebekreftelsesfeil bli kastet. Dette beskytter Move-programmerere mot utilsiktet eller ondsinnet tap av midler.

Valutamodul

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

Hver konto kan inneholde 0 eller flere moduler (vist som rektangler) og en eller flere ressursverdier (vist som sylindre). For eksempel en konto på 0x0 inneholder modul 0x0.Valuta og verdien av ressurstypen 0x0.Currency.Coin. Konto på adresse 0x1 har to ressurser og en modul; Konto på adresse 0x2 har to moduler og en ressursverdi.

Nekotory-øyeblikk:

  • Transaksjonsskriptet er atomisk - enten blir det utført fullstendig eller ikke i det hele tatt.
  • En modul er en langvarig kodebit som er globalt tilgjengelig.
  • Den globale tilstanden er strukturert som en hashtabell, der nøkkelen er kontoadressen
  • Kontoer kan ikke inneholde mer enn én ressursverdi av en gitt type og ikke mer enn én modul med gitt navn (konto på 0x0 kan ikke inneholde en ekstra ressurs 0x0.Currency.Coin eller en annen modul kalt valuta)
  • Adressen til den deklarerte modulen er en del av typen (0x0.Currency.Coin и 0x1.Currency.Coin er separate typer som ikke kan brukes om hverandre)
  • Programmerere kan lagre flere forekomster av denne typen ressurs i en konto ved å definere deres egendefinerte ressurs - (ressurs TwoCoins {c1: 0x0.Currency.Coin, c2: 0x0.Currency.Coin})
  • Du kan referere til en ressurs ved navn uten konflikter, for eksempel kan du referere til to ressurser ved å bruke TwoCoins.c1 и TwoCoins.c2.

Myntressurserklæring

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk
Modul navngitt valuta og en ressurstype kalt Coin

Nekotory-øyeblikk:

  • Coin er en struktur med ett typefelt u64 (64-bits usignert heltall)
  • Kun modulprosedyrer valuta kan skape eller ødelegge verdier av typen Coin.
  • Andre moduler og skript kan bare skrive eller referere til verdifeltet gjennom offentlige prosedyrer gitt av modulen.

Salg av depositum

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

Denne prosedyren godtar en ressurs Coin som input og kombinerer det med ressursen Coinlagret på mottakerens konto:

  1. Ødelegge inngangsressursen Coin og registrerer verdien.
  2. Motta en lenke til en unik myntressurs lagret på mottakerens konto.
  3. Endring av verdien på antall mynter med verdien som sendes i parameteren når prosedyren kalles.

Nekotory-øyeblikk:

  • Pakk ut, BorrowGlobal - innebygde prosedyrer
  • Pakke ut Dette er den eneste måten å slette en ressurs av type T. Prosedyren tar en ressurs som input, ødelegger den og returnerer verdien knyttet til ressursens felt.
  • BorrowGlobal tar en adresse som input og returnerer en referanse til en unik forekomst av T publisert (eid) av den adressen
  • &mut Mynt dette er en lenke til ressursen Coin

Implementering av trekke_fra_avsender

Dykk inn i Move - Facebooks Libra blockchain-programmeringsspråk

Denne prosedyren:

  1. Får en lenke til en unik ressurs Coin, knyttet til avsenderens konto
  2. Reduserer verdien av en ressurs Coin via lenken for det angitte beløpet
  3. Oppretter og returnerer en ny ressurs Coin med oppdatert saldo.

Nekotory-øyeblikk:

  • Innskudd kan være forårsaket av hvem som helst, men trekke_fra_sender har kun tilgang til myntene på den oppringende kontoen
  • GetTxnSenderAddress lik msg.sender i soliditet
  • Avvis Med mindre lik krever i soliditet. Hvis denne kontrollen mislykkes, stoppes transaksjonen og alle endringer rulles tilbake.
  • Pakke det er også en innebygd prosedyre som oppretter en ny ressurs av type T.
  • I tillegg til Pakke ut, Pakke kan kun kalles inne i modulen der ressursen er beskrevet T

Konklusjon

Vi undersøkte hovedegenskapene til Move-språket, sammenlignet det med Ethereum, og ble også kjent med den grunnleggende syntaksen til skript. Til slutt anbefaler jeg å sjekke ut originalt hvitt papir. Den inneholder mange detaljer angående designprinsipper for programmeringsspråk, samt mange nyttige lenker.

Kilde: www.habr.com

Legg til en kommentar