FunC FunCtional bihurtzea Haskell-ekin: Serokellek nola irabazi zuen Telegram Blockchain Lehiaketa

Seguruenik Telegram hori entzun duzu Ton blockchain plataforma abiarazteko zorian dago. Baina baliteke duela gutxi Telegramen albistea galdu izana lehiaketa iragarri zuen plataforma honetarako kontratu adimendun bat edo gehiago ezartzeko.

Serokell taldeak, blockchain proiektu handiak garatzen esperientzia handia duena, ezin izan zuen alde batera utzi. Lehiaketan bost langile eskuordetu genituen, eta bi aste beranduago bertan lehen postua lortu zuten Sexy Chameleon ausazko ezizen (ez) apalarekin. Artikulu honetan nola egin zuten buruz hitz egingo dut. Espero dugu hurrengo hamar minutuetan gutxienez istorio interesgarri bat irakurriko duzula eta, gehienez ere, zure lanean aplikatzeko moduko zerbait aurkituko duzula.

Baina has gaitezen testuinguru txiki batekin.

Lehia eta bere baldintzak

Beraz, parte-hartzaileen zeregin nagusiak proposatutako kontratu adimentsuetako bat edo gehiago ezartzea izan dira, baita TON ekosistema hobetzeko proposamenak egitea ere. Lehiaketa irailaren 24tik urriaren 15era izan zen, eta emaitzak azaroaren 15ean baino ez ziren jakinarazi. Denbora dezente, kontuan izanda denbora horretan Telegramek Telegram-en VoIP deien kalitatea probatzeko eta ebaluatzeko C++-ko aplikazioen diseinu eta garapenari buruzko lehiaketen emaitzak egitea eta iragartzea lortu zuela.

Antolatzaileek proposatutako zerrendatik bi kontratu adimendun aukeratu ditugu. Horietako baterako, TON-ekin banatutako tresnak erabili genituen, eta bigarrena gure ingeniariek TON-rako bereziki garatu eta Haskell-en eraikitako hizkuntza berri batean ezarri zen.

Programazio-lengoaia funtzional bat aukeratzea ez da kasualitatea. Gurean blog korporatiboa Askotan hitz egiten dugu zergatik uste dugun hizkuntza funtzionalen konplexutasuna gehiegikeria handia dela eta zergatik nahiago ditugun, oro har, objektuetara zuzendutakoak baino. Bide batez, badu ere artikulu honen originala.

Zergatik erabaki genuen parte hartzea?

Laburbilduz, gure espezializazioa proiektu ez-estandarrak eta konplexuak direlako, gaitasun bereziak behar dituztenak eta maiz balio zientifikoa duten informatika komunitatearentzat. Kode irekiko garapena gogor onartzen dugu eta bere dibulgazioan dihardugu, eta Errusiako unibertsitate nagusiekin elkarlanean aritzen gara informatika eta matematika arloan.

Lehiaketaren zeregin interesgarriak eta gure Telegram proiektu maitean parte hartzeak berez motibazio bikaina izan ziren, baina sari-funtsa pizgarri gehigarri bihurtu zen. πŸ™‚

TON blockchain ikerketa

Blockchain-en, adimen artifizialaren eta ikaskuntza automatikoaren garapen berriak gertutik kontrolatzen ditugu eta lan egiten dugun arlo bakoitzean argitalpen esanguratsu bakar bat ere ez galtzen saiatzen gara. Horregatik, lehiaketa hasi zenerako, gure taldeak jada ezagutzen zituen ideiak TON paper zuria. Hala ere, TONekin lanean hasi aurretik, ez genuen dokumentazio teknikoa eta plataformaren benetako iturburu-kodea aztertu, beraz, lehen urratsa nahiko begi-bistakoa zen: dokumentazio ofizialaren azterketa sakona. Online eta proiektuen biltegiak.

Lehiaketa hasi zenerako, kodea jada argitaratuta zegoen eta, beraz, denbora aurrezteko, gida edo laburpen bat bilatzea erabaki genuen. erabiltzaileek. Zoritxarrez, honek ez du emaitzarik eman - plataforma Ubuntun muntatzeko argibideez gain, ez dugu beste materialik aurkitu.

Dokumentazioa bera ondo ikertuta zegoen, baina momentu batzuetan zaila zen irakurtzea. Askotan puntu batzuetara itzuli eta ideia abstraktuen goi-mailako deskribapenetatik maila baxuko inplementazioaren xehetasunetara aldatu behar izaten genuen.

Errazagoa izango litzateke zehaztapenak ezarpenaren deskribapen zehatzik sartuko ez balu. Makina birtual batek bere pila adierazten duen moduari buruzko informazioak litekeena da TON plataformarako kontratu adimendunak sortzen dituzten garatzaileak distraitzea haiei laguntzeko baino.

Nix: proiektua elkarrekin jartzea

Serokell-en zale handiak gara Nix. Berarekin gure proiektuak biltzen ditugu eta horiek erabiliz zabaltzen ditugu NixOps, eta gure zerbitzari guztietan instalatuta Nix OS. Horri esker, gure eraikuntza guztiak erreproduzigarriak dira eta Nix instalatu daitekeen edozein sistema eragiletan funtzionatzen dute.

Beraz, sortzen hasi ginen Nix gainjartzea TON muntatzeko adierazpenarekin. Bere laguntzarekin, TON konpilatzea ahalik eta errazena da:

$ cd ~/.config/nixpkgs/overlays && git clone https://github.com/serokell/ton.nix
$ cd /path/to/ton/repo && nix-shell
[nix-shell]$ cmakeConfigurePhase && make

Kontuan izan ez duzula menpekotasunik instalatu behar. Nixek magiaz egingo dizu dena, NixOS, Ubuntu edo macOS erabiltzen ari zaren ala ez.

TON programazioa

TON Sareko kontratu adimendunaren kodea TON Makina Birtualean (TVM) exekutatzen da. TVM beste makina birtual gehienak baino konplexuagoa da, eta funtzionalitate oso interesgarriak ditu, adibidez, lan egin dezake. jarraipenak ΠΈ datuetarako estekak.

Gainera, TONeko mutilek hiru programazio-lengoaia berri sortu zituzten:

Bost antza duen pila bat programatzeko lengoaia unibertsal bat da Aurrera. Bere super gaitasuna TVMrekin elkarreragiteko gaitasuna da.

FunC ren antzekoa den smart contract programazio-lengoaia da C eta beste hizkuntza batean biltzen da - Fift Assembler.

Bosgarren Muntatzailea β€” TVMrako kode exekutagarri bitarra sortzeko bost liburutegia. Fifth Assembler-ek ez du konpilatzailerik. Hau Kapsulatutako domeinu espezifikoen hizkuntza (eDSL).

Gure lehiaketak funtzionatzen du

Azkenik, gure ahaleginaren emaitzak aztertzeko garaia da.

Ordainketa kanal asinkronoa

Ordainketa kanala kontratu adimendun bat da, bi erabiltzaileri ordainketak bidaltzeko aukera ematen diona blockchainetik kanpo. Ondorioz, dirua ez ezik (ez dago komisiorik), denbora ere aurrezten duzu (ez duzu hurrengo blokea prozesatu arte itxaron behar). Ordainketak nahi bezain txikiak izan daitezke eta behar bezain maiz. Kasu honetan, alderdiek ez dute elkarrengandik fidatu behar, azken likidazioaren bidezkotasuna kontratu adimendunak bermatzen baitu.

Arazoari irtenbide nahiko sinplea aurkitu diogu. Bi alderdik sinatutako mezuak trukatu ditzakete, bakoitzak bi zenbaki dituena, alderdi bakoitzak ordaindutako kopuru osoa. Bi zenbaki hauek bezala funtzionatzen dute erloju bektoriala sistema banatu tradizionaletan eta transakzioetan "lehen gertatutakoa" ordena ezarri. Datu horiek erabiliz, kontratuak izan daitezkeen gatazkak konpondu ahal izango ditu.

Izan ere, zenbaki bat nahikoa da ideia hau gauzatzeko, baina biak utzi ditugu horrela erabiltzaile-interfaze erosoagoa egin genezakeelako. Horrez gain, mezu bakoitzean ordainketaren zenbatekoa sartzea erabaki dugu. Hori gabe, mezua arrazoiren batengatik galtzen bada, orduan, zenbateko guztiak eta azken kalkulua zuzenak izango diren arren, baliteke erabiltzaileak galera ez nabaritzea.

Gure ideia probatzeko, ordainketa-kanalaren protokolo sinple eta zehatza erabiltzeko adibideak bilatu ditugu. Harrigarria bada ere, bi baino ez ditugu aurkitu:

  1. Description antzeko ikuspegia, norabide bakarreko kanalaren kasuan bakarrik.
  2. Tutoretza, gure ideia bera deskribatzen duena, baina xehetasun garrantzitsu asko azaldu gabe, hala nola, zuzentasun orokorra eta gatazkak konpontzeko prozedurak.

Argi geratu zen zentzuzkoa dela gure protokoloa zehatz-mehatz deskribatzeak, arreta berezia jarriz bere zuzentasunari. Hainbat errepikapenen ondoren, zehaztapena prest zegoen, eta orain zuk ere egin dezakezu. begiratu zion.

FunC-n inplementatu genuen kontratua, eta komando-lerroko utilitatea idatzi genuen gure kontratuarekin guztiz elkarreragiteko Fift-en, antolatzaileek gomendatutako moduan. Gure CLIrako beste edozein hizkuntza aukeratu genezake, baina Fit probatzea interesatzen zitzaigun praktikan nola funtzionatzen zuen ikusteko.

Egia esateko, Fift-ekin lan egin ondoren, ez genuen arrazoi sendorik ikusten hizkuntza hau hobesteko tresna eta liburutegi garatuekin aktiboki erabiltzen diren hizkuntzak baino. Pilatan oinarritutako lengoaia batean programatzea nahiko desatsegina da, pilan dagoena etengabe gorde behar baituzu buruan, eta konpilatzaileak ez du horretan laguntzen.

Horregatik, gure ustez, Fift-en existentziaren justifikazio bakarra Fift Assembler-en harrera-hizkuntza gisa duen eginkizuna da. Baina ez al litzateke hobe TVM muntatzailea lehendik dagoen hizkuntzaren batean txertatzea, funtsean helburu bakarrarekin berri bat asmatzea baino?

TVM Haskell eDSL

Orain gure bigarren kontratu adimendunari buruz hitz egiteko garaia da. Sinadura anitzeko zorro bat garatzea erabaki genuen, baina FunC-n beste kontratu adimendun bat idaztea aspergarria izango litzateke. Zapore pixka bat eman nahi genuen, eta hori zen TVMren gure muntaia-lengoaia.

Fift Assembler bezala, gure hizkuntza berria txertatuta dago, baina Haskell aukeratu dugu ostalari gisa Fift-en ordez, bere motako sistema aurreratua aprobetxatu ahal izateko. Kontratu adimendunekin lan egiten denean, akats txiki baten kostua oso handia izan daitekeenean, idazketa estatikoa, gure ustez, abantaila handia da.

Haskell-en txertatutako TVM muntatzailea nolakoa den erakusteko, zorro estandar bat ezarri dugu bertan. Hona hemen arreta jarri beharreko gauza batzuk:

  • Kontratu honek funtzio bakarra du, baina nahi adina erabil ditzakezu. Ostalari-hizkuntzan funtzio berri bat definitzen duzunean (hau da, Haskell), gure eDSL-k aukera ematen dizu TVM-n errutina bereizi bihurtu nahi duzun edo, besterik gabe, dei puntuan sartuta.
  • Haskell bezala, funtzioek konpilazio garaian egiaztatzen diren motak dituzte. Gure eDSL-n, funtzio baten sarrera mota funtzioak espero duen pila mota da, eta emaitza mota deiaren ondoren sortuko den pila mota da.
  • Kodeak oharrak ditu stacktype, dei puntuan espero den pila mota deskribatuz. Jatorrizko diru-zorroaren kontratuan hauek iruzkinak besterik ez ziren, baina gure eDSL-n benetan kodearen parte dira eta konpilazio garaian egiaztatzen dira. Garatzaileari arazoa aurkitzen laguntzen dioten dokumentazio edo adierazpen gisa balio dezakete kodea aldatzen bada eta pila mota aldatzen bada. Jakina, horrelako oharpenek ez dute exekuzio garaiko errendimenduan eragiten, ez baita TVM koderik sortzen haientzat.
  • Bi astetan idatzitako prototipoa da oraindik, beraz, oraindik lan asko dago egiteko proiektuan. Adibidez, beheko kodean ikusten dituzun klaseen instantzia guztiak automatikoki sortu behar dira.

Hau da multisig zorro baten ezarpenak gure eDSL-n:

main :: IO ()
main = putText $ pretty $ declProgram procedures methods
  where
    procedures =
      [ ("recv_external", decl recvExternal)
      , ("recv_internal", decl recvInternal)
      ]
    methods =
      [ ("seqno", declMethod getSeqno)
      ]

data Storage = Storage
  { sCnt :: Word32
  , sPubKey :: PublicKey
  }

instance DecodeSlice Storage where
  type DecodeSliceFields Storage = [PublicKey, Word32]
  decodeFromSliceImpl = do
    decodeFromSliceImpl @Word32
    decodeFromSliceImpl @PublicKey

instance EncodeBuilder Storage where
  encodeToBuilder = do
    encodeToBuilder @Word32
    encodeToBuilder @PublicKey

data WalletError
  = SeqNoMismatch
  | SignatureMismatch
  deriving (Eq, Ord, Show, Generic)

instance Exception WalletError

instance Enum WalletError where
  toEnum 33 = SeqNoMismatch
  toEnum 34 = SignatureMismatch
  toEnum _ = error "Uknown MultiSigError id"

  fromEnum SeqNoMismatch = 33
  fromEnum SignatureMismatch = 34

recvInternal :: '[Slice] :-> '[]
recvInternal = drop

recvExternal :: '[Slice] :-> '[]
recvExternal = do
  decodeFromSlice @Signature
  dup
  preloadFromSlice @Word32
  stacktype @[Word32, Slice, Signature]
  -- cnt cs sign

  pushRoot
  decodeFromCell @Storage
  stacktype @[PublicKey, Word32, Word32, Slice, Signature]
  -- pk cnt' cnt cs sign

  xcpu @1 @2
  stacktype @[Word32, Word32, PublicKey, Word32, Slice, Signature]
  -- cnt cnt' pk cnt cs sign

  equalInt >> throwIfNot SeqNoMismatch

  push @2
  sliceHash
  stacktype @[Hash Slice, PublicKey, Word32, Slice, Signature]
  -- hash pk cnt cs sign

  xc2pu @0 @4 @4
  stacktype @[PublicKey, Signature, Hash Slice, Word32, Slice, PublicKey]
  -- pubk sign hash cnt cs pubk

  chkSignU
  stacktype @[Bool, Word32, Slice, PublicKey]
  -- ? cnt cs pubk

  throwIfNot SignatureMismatch
  accept

  swap
  decodeFromSlice @Word32
  nip

  dup
  srefs @Word8

  pushInt 0
  if IsEq
  then ignore
  else do
    decodeFromSlice @Word8
    decodeFromSlice @(Cell MessageObject)
    stacktype @[Slice, Cell MessageObject, Word8, Word32, PublicKey]
    xchg @2
    sendRawMsg
    stacktype @[Slice, Word32, PublicKey]

  endS
  inc

  encodeToCell @Storage
  popRoot

getSeqno :: '[] :-> '[Word32]
getSeqno = do
  pushRoot
  cToS
  preloadFromSlice @Word32

Gure eDSL eta sinadura anitzeko zorroaren kontratuaren iturburu-kode osoa hemen aurki dezakezu biltegi hau. Eta gehiago zehatz-mehatz kontatua hizkuntza barneratuei buruz, gure lankide Georgy Agapov.

Lehiaketari eta TONari buruzko ondorioak

Guztira, 380 ordu behar izan ditu gure lanak (dokumentazioa, bilerak eta benetako garapena ezagutzea barne). Lehiaketako proiektuan bost garatzailek hartu zuten parte: CTO, talde-burua, blockchain plataformako espezialistak eta Haskell software garatzaileak.

Lehiaketan zailtasunik gabe parte hartzeko baliabideak aurkitu ditugu, hackaton baten espiritua, talde-lan hurbila eta teknologia berrien alderdietan azkar murgiltzeko beharra beti baita zirraragarria. Lorik gabeko hainbat gau baliabide mugatuen baldintzetan emaitzarik handiena lortzeko esperientzia eskerga eta oroitzapen bikainekin konpentsatzen dira. Gainera, horrelako zereginetan lan egitea beti da enpresaren prozesuen proba ona, oso zaila baita benetan emaitza duinak lortzea barne-interakzio ondo funtzionatzen ez badu.

Letrak alde batera utzita: harrituta geratu ginen TON taldeak egindako lanarekin. Sistema konplexu, ederra eta, batez ere, lan-sistema bat eraikitzea lortu zuten. TON potentzial handiko plataforma bat dela frogatu du. Hala ere, ekosistema hau garatzeko, askoz gehiago egin behar da, bai blockchain proiektuetan erabiltzeari dagokionez, bai garapen tresnak hobetzeari dagokionez. Harro gaude orain prozesu honen parte izateaz.

Artikulu hau irakurri ondoren oraindik galderarik baduzu edo TON zure arazoak konpontzeko nola erabili jakiteko ideiarik baduzu, idatz iezaguzu β€” pozik egongo gara gure esperientzia partekatzeko.

Iturria: www.habr.com

Gehitu iruzkin berria