Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Tjetra, ne do të shqyrtojmë në detaje karakteristikat kryesore të gjuhës Move dhe cilat janë ndryshimet kryesore të saj me një gjuhë tjetër, tashmë popullore për kontratat inteligjente - Soliditeti (në platformën Ethereum). Materiali bazohet në një studim të letrës së bardhë të disponueshme në internet me 26 faqe.

Paraqitje

Move është një gjuhë bajtkodi e ekzekutueshme që përdoret për të ekzekutuar transaksionet e përdoruesit dhe kontratat inteligjente. Ju lutemi vini re dy pika:

  1. Ndërsa Move është një gjuhë bytekode që mund të ekzekutohet drejtpërdrejt në makinën virtuale Move, Soliditeti (gjuha e kontratës inteligjente të Ethereum) është një gjuhë e nivelit më të lartë që së pari përpilohet për të koduar para se të ekzekutohet në një EVM (Makinë Virtuale Ethereum).
  2. Move mund të përdoret jo vetëm për të zbatuar kontrata të zgjuara, por edhe për transaksione me porosi (më shumë për këtë më vonë), ndërsa Soliditeti është një gjuhë e zgjuar vetëm për kontrata.


Përkthimi u krye nga ekipi i projektit INDEX Protocol. Ne kemi përkthyer tashmë material i madh që përshkruan projektin Libra, tani është koha për të parë gjuhën Move me pak më shumë detaje. Përkthimi u krye së bashku me Habrauser coolsiu

Një tipar kyç i Move është aftësia për të përcaktuar llojet e burimeve të personalizuara me semantikë bazuar në logjikën lineare: një burim nuk mund të kopjohet kurrë ose të fshihet në mënyrë implicite, vetëm të zhvendoset. Funksionalisht, kjo është e ngjashme me aftësitë e gjuhës Rust. Vlerat në Rust mund t'i caktohen vetëm një emri në të njëjtën kohë. Caktimi i një vlere për një emër tjetër e bën atë të padisponueshëm nën emrin e mëparshëm.

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Për shembull, fragmenti i mëposhtëm i kodit do të japë një gabim: Përdorimi i vlerës së zhvendosur 'x'. Kjo ndodh sepse nuk ka grumbullim plehrash në Rust. Kur variablat dalin jashtë fushëveprimit, kujtesa të cilës i referohen lirohet gjithashtu. E thënë thjesht, mund të ketë vetëm një "pronar" të të dhënave. Në këtë shembull x është pronari origjinal dhe pastaj y bëhet pronar i ri. Lexoni më shumë rreth kësaj sjelljeje këtu.

Përfaqësimi i aseteve dixhitale në sisteme të hapura

Ekzistojnë dy veti të aktiveve fizike që janë të vështira për t'u paraqitur në mënyrë dixhitale:

  • gjë e rrallë (Mungesa, fillimisht mungesa). Numri i aseteve (emisioneve) në sistem duhet të kontrollohet. Dyfishimi i pasurive ekzistuese duhet të ndalohet, dhe krijimi i atyre të reja është një operacion i privilegjuar.
  • Kontrolli i hyrjes... Pjesëmarrësi i sistemit duhet të jetë në gjendje të mbrojë asetet duke përdorur politikat e kontrollit të aksesit.

Këto dy karakteristika, të cilat janë të natyrshme për pasuritë fizike, duhet të zbatohen për objektet dixhitale nëse duam t'i konsiderojmë ato si asete. Për shembull, një metal i rrallë ka një mungesë natyrore, dhe vetëm ju keni qasje në të (duke e mbajtur atë në duart tuaja, për shembull) dhe mund ta shisni ose shpenzoni.

Për të ilustruar se si arritëm në këto dy prona, le të fillojmë me fjalitë e mëposhtme:

Sugjerimi # 1: Rregulli më i thjeshtë pa mungesë dhe kontroll të aksesit

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

  • G [K]: = n tregon një përditësim të një numri të arritshëm me një çelës К në gjendjen globale të blockchain, me një kuptim të ri n.
  • transaksioni lAlice, 100⟩ nënkupton vendosjen e gjendjes së llogarisë së Alice në 100.

Zgjidhja e mësipërme ka disa probleme kryesore:

  • Alice mund të marrë një numër të pakufizuar monedhash thjesht duke dërguar transaksioni ⟨Alice, 100⟩.
  • Monedhat që Alice i dërgon Bobit janë të padobishme, pasi Bob mund t'i dërgojë vetes një numër të pakufizuar monedhash duke përdorur të njëjtën teknikë.

Sugjerimi # 2: Duke marrë parasysh deficitin

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Tani ne jemi duke monitoruar situatën në mënyrë që numri i monedhave Ka ishte të paktën e barabartë n para transaksionit të transferimit. Sidoqoftë, ndërsa kjo zgjidh problemin e mungesës, nuk ka informacion se kush mund të dërgojë monedhat e Alice (tani për tani, çdokush mund ta bëjë këtë, gjëja kryesore nuk është të thyejë rregullin e kufizimit të sasisë).

Propozimi # 3: Kombinimi i mungesës dhe kontrollit të aksesit

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Ne e zgjidhim këtë problem me një mekanizëm nënshkrimi dixhital verifiko_sig para se të kontrolloni bilancin, që do të thotë se Alice përdor çelësin e saj privat për të nënshkruar transaksionin dhe për të konfirmuar se ajo është pronare e monedhave të saj.

Gjuhët e programimit Blockchain

Gjuhët ekzistuese të blockchain përballen me problemet e mëposhtme (të gjitha ato u zgjidhën në Move (shënim: për fat të keq, autori i artikullit i bën thirrje vetëm Ethereum në krahasimet e tij, kështu që ia vlen t'i marrësh ato vetëm në këtë kontekst. Për shembull, shumica e mëposhtme është zgjidhur edhe në EOS.)):

Përfaqësimi indirekt i aseteve. Një aktiv është i koduar duke përdorur një numër të plotë, por një numër i plotë nuk është i njëjtë me një aktiv. Në fakt, nuk ka asnjë lloj apo vlerë që përfaqëson Bitcoin/Ether/<Any Coin>! Kjo e bën të vështirë shkrimin e programeve që përdorin asete dhe të prirur ndaj gabimeve. Modele të tilla si kalimi i aktiveve në/nga procedura ose ruajtja e aseteve në struktura kërkojnë mbështetje të veçantë nga gjuha.

Deficiti nuk është i zgjerueshëm... Gjuha përfaqëson vetëm një pasuri të pakët. Për më tepër, mjetet e mbrojtjes nga mungesa janë të lidhura drejtpërdrejt në semantikën e vetë gjuhës. Zhvilluesi, nëse dëshiron të krijojë një aktiv të personalizuar, duhet të kontrollojë me kujdes të gjitha aspektet e burimit vetë. Këto janë pikërisht problemet e kontratave inteligjente Ethereum.

Përdoruesit lëshojnë aktivet e tyre, shenjat ERC-20, duke përdorur numra të plotë për të përcaktuar si vlerën ashtu edhe furnizimin total. Sa herë që krijohen shenja të reja, kodi i kontratës së zgjuar duhet të verifikojë në mënyrë të pavarur pajtueshmërinë me rregullat e emetimit. Për më tepër, paraqitja indirekte e aktiveve çon, në disa raste, në gabime serioze - dyfishim, shpenzime të dyfishta apo edhe humbje të plotë të pasurive.

Mungesa e kontrollit fleksibël të qasjes... Politika e vetme e kontrollit të aksesit që përdoret sot është një skemë nënshkrimi duke përdorur kriptografi asimetrike. Ashtu si mbrojtja nga mungesa, politikat e kontrollit të aksesit janë ngulitur thellë në semantikën e gjuhës. Por mënyra se si të zgjerohet gjuha për të lejuar programuesit të përcaktojnë politikat e tyre të kontrollit të aksesit është shpesh një detyrë shumë e ndërlikuar.

Kjo është gjithashtu e vërtetë për Ethereum, ku kontratat inteligjente nuk kanë mbështetje të kriptografisë vendase për kontrollin e aksesit. Zhvilluesit duhet të vendosin manualisht kontrollin e aksesit, për shembull, duke përdorur modifikuesin onlyOwner.

Edhe pse unë jam një adhurues i madh i Ethereum, besoj se pronat e aseteve duhet të mbështeten nga gjuha për qëllime sigurie. Në veçanti, transferimi i Etherit në një kontratë inteligjente përfshin dërgimin dinamik, i cili ka prezantuar një klasë të re gabimesh të njohura si dobësitë e rihyrjes. Dërgimi dinamik këtu do të thotë që logjika e ekzekutimit të kodit do të përcaktohet në kohën e ekzekutimit (dinamike) dhe jo në kohën e përpilimit (statike).

Kështu, në Solidity, kur kontrata A thërret një funksion në kontratën B, kontrata B mund të ekzekutojë kodin që nuk ishte menduar nga zhvilluesi i kontratës A, gjë që mund të rezultojë në dobësitë e rihyrjes (kontrata A vepron aksidentalisht si kontratë B për tërheqjen e parave përpara se të zbriten realisht tepricat e llogarisë).

Zhvendos bazat e dizajnit të gjuhës

Burimet e rendit të parë

Në një nivel të lartë, ndërveprimi midis moduleve / burimeve / procedurave në gjuhën Move është shumë i ngjashëm me marrëdhënien midis klasave / objekteve dhe metodave në gjuhët OOP.
Modulet e lëvizjes janë të ngjashme me kontratat inteligjente në blockchains të tjerë. Moduli deklaron llojet dhe procedurat e burimeve që përcaktojnë rregullat për krijimin, shkatërrimin dhe azhurnimin e burimeve të deklaruara. Por të gjitha këto janë vetëm konventa ("zhargon”) Në lëvizje. Ne do ta ilustrojmë këtë pikë pak më vonë.

Lakueshmëri

Lëvizja i shton fleksibilitet Peshores përmes skriptimit. Çdo transaksion në Libra përfshin një skenar, i cili është në thelb procedura thelbësore e transaksionit. Skripti mund të kryejë ose një veprim të specifikuar, për shembull, pagesa për një listë të caktuar marrësish, ose të ripërdor burime të tjera - për shembull, duke thirrur një procedurë në të cilën specifikohet logjika e përgjithshme. Kjo është arsyeja pse skriptet e transaksioneve Move ofrojnë fleksibilitet më të madh. Një skript mund të përdorë sjellje të njëhershme dhe të përsëritura, ndërsa Ethereum mund të ekzekutojë vetëm skriptet e përsëritshme (duke thirrur një metodë në një metodë të kontratës inteligjente). Arsyeja pse quhet "i ripërdorshëm" është sepse funksionet e një kontrate inteligjente mund të ekzekutohen shumë herë. (shënim: Pika këtu është shumë delikate. Nga njëra anë, skriptet e transaksioneve në formën e pseudo-bytecode ekzistojnë gjithashtu në Bitcoin. Nga ana tjetër, siç e kuptoj unë, Move e zgjeron këtë gjuhë, në fakt, në nivelin e një gjuhe të plotë të kontratës inteligjente.).

siguri

Formati i ekzekutueshëm Move është bytecode, i cili është, nga njëra anë, një gjuhë e nivelit më të lartë se gjuha e asamblesë, por nivel më i ulët se kodi burimor. Bajtkodi kontrollohet në kohën e ekzekutimit (në zinxhir) për burimet, llojet dhe sigurinë e memories duke përdorur një verifikues të bajtkodit dhe më pas ekzekutohet nga interpretuesi. Kjo qasje lejon Move të sigurojë sigurinë e kodit burimor, por pa procesin e përpilimit dhe nevojën për të shtuar një përpilues në sistem. Bërja e Move një gjuhë bajtkodi është një zgjidhje vërtet e mirë. Nuk ka nevojë të kompilohet nga burimi, siç është rasti me Solidity, dhe nuk ka nevojë të shqetësoheni për dështime ose sulme të mundshme në infrastrukturën e përpiluesit.

Verifikueshmëria

Ne synojmë të kryejmë kontrolle sa më të lehta që të jetë e mundur, pasi e gjithë kjo bëhet në zinxhir (shënim: online, gjatë ekzekutimit të secilit transaksion, kështu që çdo vonesë çon në një ngadalësim të të gjithë rrjetit), megjithatë, fillimisht dizajni i gjuhës është gati për të përdorur mjete verifikimi statike jashtë zinxhirit. Edhe pse kjo është më e preferueshme, tani për tani zhvillimi i mjeteve të verifikimit (si një paketë vegla e veçantë) është shtyrë për të ardhmen dhe tani mbështetet vetëm verifikimi dinamik në kohën e ekzekutimit (në zinxhir).

Modulariteti

Modulet e lëvizjes sigurojnë abstraksion të të dhënave dhe lokalizojnë operacionet kritike në burime. Kapsulimi i ofruar nga moduli, i kombinuar me mbrojtjen e ofruar nga sistemi i tipit Move, siguron që vetitë e vendosura në llojet e modulit nuk mund të shkelen me kod jashtë modulit. Ky është një model abstraksioni i menduar mjaft mirë, që do të thotë se të dhënat brenda një kontrate mund të ndryshojnë vetëm brenda fushës së kontratës, por jo nga jashtë.

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Zhvendos pasqyrën

Shembulli i skenarit të transaksionit tregon se veprimet me qëllim të keq ose të pakujdesshëm nga një programues jashtë një moduli nuk mund të komprometojnë sigurinë e burimeve të një moduli. Tjetra, ne do të shikojmë shembuj se si modulet, burimet dhe procedurat përdoren për të programuar blockchain Libra.

Pagesat nga kolegët

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Numri i monedhave të specifikuara në shumë do të transferohet nga bilanci i dërguesit te marrësi.
Këtu ka disa gjëra të reja (të theksuara me të kuqe):

  • 0x0: adresa e llogarisë ku është ruajtur moduli
  • Monedhë: emri i modulit
  • Monedhë: lloji i burimeve
  • Vlera e monedhës e kthyer nga procedura është një vlerë burimi e llojit 0x0. Monedha. Monedhë
  • lëviz (): vlera nuk mund të përdoret përsëri
  • kopje (): vlera mund të përdoret më vonë

Analizoni kodin: në hapin e parë, dërguesi thërret një procedurë të quajtur tërheq_ nga dërguesi nga një modul i ruajtur në 0x0. Monedha. Në hapin e dytë, dërguesi transferon fonde te marrësi duke lëvizur vlerën e burimit të monedhës në procedurën e depozitimit të modulit 0x0. Monedha.

Këtu janë tre shembuj të gabimeve në kod që do të refuzohen nga kontrollet:
Kopjoni fonde duke ndryshuar thirrjen lëviz (monedhë) mbi kopje (monedhë). Burimet mund të zhvendosen vetëm. Përpjekja për të dyfishuar një sasi të një burimi (për shembull, duke telefonuar kopje (monedhë) në shembullin e mësipërm) do të rezultojë në një gabim gjatë vërtetimit të kodit byte.

Ripërdorimi i fondeve duke specifikuar lëviz (monedhë) дважды . Shtimi i një rreshti 0x0. Monedha.depozitë (kopje (disa_tjetër_pagues), lëviz (monedhë)) për shembull, sa më sipër do t'i lejojë dërguesit të "shpenzojë" monedhat dy herë - herën e parë me marrësin dhe të dytën me disa_të_paguesit. Kjo është një sjellje e padëshirueshme që nuk është e mundur me një aktiv fizik. Për fat të mirë, Move do ta refuzojë këtë program.

Humbja e fondeve për shkak të refuzimit lëviz (monedhë). Nëse nuk e zhvendosni burimin (për shembull, duke fshirë rreshtin që përmban lëviz (monedhë)), do të hidhet një gabim i verifikimit të bajtkodit. Kjo mbron programuesit e Move nga humbja aksidentale ose me qëllim të keq të fondeve.

Moduli i monedhës

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Çdo llogari mund të përmbajë 0 ose më shumë module (të paraqitura si drejtkëndësha) dhe një ose më shumë vlera burimesh (të paraqitura si cilindra). Për shembull, një llogari në 0x0 përmban modul 0x0. Monedha dhe vlerën e llojit të burimit 0x0.Manedha.Monedhë. Llogaria në adresë 0x1 ka dy burime dhe një modul; Llogaria në adresë 0x2 ka dy module dhe një vlerë burimi.

Momentet e fundit:

  • Skripti i transaksionit është atomike - ose është ekzekutuar plotësisht ose aspak.
  • Një modul është një pjesë e kodit jetëgjatë që është e aksesueshme globalisht.
  • Gjendja globale është e strukturuar si një tabelë hash, ku çelësi është adresa e llogarisë
  • Llogaritë mund të përmbajnë jo më shumë se një vlerë burimi të një lloji të caktuar dhe jo më shumë se një modul me një emër të caktuar (llogaria në 0x0 nuk mund të përmbajë një burim shtesë 0x0.Manedha.Monedhë ose një modul tjetër me emër Monedhë)
  • Adresa e modulit të deklaruar është pjesë e tipit (0x0.Manedha.Monedhë и 0x1.Manedha.Monedhë janë lloje të veçanta që nuk mund të përdoren në mënyrë të ndërsjellë)
  • Programuesit mund të ruajnë shembuj të shumtë të këtij lloji burimi në një llogari duke përcaktuar burimin e tyre të personalizuar - (burimi TwoCoins {c1: 0x0.Currency.Coin, c2: 0x0.Currency.Coin})
  • Ju mund t'i referoheni një burimi me emrin e tij pa konflikte, për shembull mund t'i referoheni dy burimeve duke përdorur Dy monedha.c1 и Dy monedha.c2.

Njoftimi i burimit të monedhës

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook
Emri i modulit Monedhë dhe një lloj burimi të emërtuar Monedhë

Momentet e fundit:

  • Monedhë është një strukturë me një fushë të tipit u64 (numër i plotë 64-bit i panënshkruar)
  • Vetëm procedurat e modulit Monedhë mund të krijojë ose shkatërrojë vlera të llojit Monedhë.
  • Modulet dhe skriptet e tjera mund të shkruajnë ose referojnë fushën e vlerës vetëm përmes procedurave publike të ofruara nga moduli.

Shitja e depozitës

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Kjo procedurë pranon një burim Monedhë si hyrje dhe e kombinon atë me burimin Monedhëtë ruajtura në llogarinë e marrësit:

  1. Shkatërrimi i monedhës së burimit hyrës dhe regjistrimi i vlerës së tij.
  2. Marrja e një lidhjeje me një burim unik të monedhës së ruajtur në llogarinë e marrësit.
  3. Ndryshimi i vlerës së numrit të monedhave me vlerën e kaluar në parametrin gjatë thirrjes së procedurës.

Momentet e fundit:

  • Shpaketo, BorrowGlobal - procedurat e integruara
  • Shpaketojeni Kjo është mënyra e vetme për të fshirë një burim të tipit T. Procedura merr një burim si hyrje, e shkatërron atë dhe kthen vlerën e lidhur me fushat e burimit.
  • BorrowGlobal merr një adresë si hyrje dhe kthen një referencë në një shembull unik të T të publikuar (në pronësi) nga ajo adresë
  • &Mut monedhë kjo është një lidhje me burimin Monedhë

Zbatimi i tërheqjes_nga_dërguesi

Dive into Move - gjuha e programimit të rrjetit bllokues Libra të Facebook

Kjo procedurë:

  1. Merr një lidhje me një burim unik Monedhë, e lidhur me llogarinë e dërguesit
  2. Zvogëlon vlerën e një burimi Monedhë nëpërmjet lidhjes për shumën e specifikuar
  3. Krijon dhe kthen një burim të ri Monedhë me bilanc të përditësuar.

Momentet e fundit:

  • Depozitë mund të shkaktohet nga kushdo, por tërheq_ nga dërguesi ka qasje vetëm në monedhat e llogarisë thirrëse
  • Adresa GetTxnSender të ngjashme me mesazh.dërguesi në Soliditet
  • Refuzo nëse të ngjashme me kërkojnë në Soliditet. Nëse ky kontroll dështon, transaksioni ndalet dhe të gjitha ndryshimet rikthehen.
  • Paketoni është gjithashtu një procedurë e integruar që krijon një burim të ri të tipit T.
  • Si dhe Shpaketojeni, Paketoni mund të thirret vetëm brenda modulit ku përshkruhet burimi T

Përfundim

Ne ekzaminuam karakteristikat kryesore të gjuhës Move, e krahasuam atë me Ethereum dhe gjithashtu u njohëm me sintaksën bazë të skripteve. Së fundi, unë rekomandoj shumë të kontrolloni letër e bardhë origjinale. Ai përfshin shumë detaje në lidhje me parimet e dizajnit të gjuhës së programimit, si dhe shumë lidhje të dobishme.

Burimi: www.habr.com

Shto një koment