Ngarobih FunC janten FunCtional sareng Haskell: Kumaha Serokell meunang Kompetisi Telegram Blockchain

Anjeun meureun geus ngadéngé Telegram éta badé ngaluncurkeun platform blockchain Ton. Tapi anjeun tiasa sono kana warta anu teu lami pisan Telegram ngumumkeun kompetisi pikeun palaksanaan hiji atawa leuwih kontrak pinter pikeun platform ieu.

Tim Serokell, kalayan pangalaman éksténsif dina ngamekarkeun proyék blockchain badag, teu bisa nangtung kumisan. Urang delegated lima pagawé pikeun kompetisi, sarta dua minggu ti harita maranéhna nyokot tempat munggaran di dinya handapeun (dina) nickname acak modest Sexy Chameleon. Dina artikel ieu kuring bakal ngobrol ngeunaan kumaha aranjeunna ngalakukeun eta. Kami ngarepkeun dina sapuluh menit ka hareup anjeun sahenteuna bakal maca carita anu pikaresepeun, sareng paling-paling anjeun bakal mendakan anu mangpaat pikeun anjeun tiasa nerapkeun dina karya anjeun.

Tapi hayu urang mimitian ku konteks saeutik.

Kompetisi jeung kaayaanana

Janten, pancén utama pamilon nyaéta palaksanaan hiji atanapi langkung kontrak pinter anu diusulkeun, ogé ngadamel usulan pikeun ningkatkeun ékosistem TON. Kompetisi lumangsung ti 24 Séptémber nepi ka 15 Oktober, sarta hasilna ngan diumumkeun dina 15 Nopémber. Rada lila, tempo yén salila ieu Telegram junun nahan sarta ngumumkeun hasil kontes dina rarancang jeung ngembangkeun aplikasi dina C ++ pikeun nguji sarta assessing kualitas panggero VoIP dina Telegram.

Kami milih dua kontrak pinter tina daptar anu diusulkeun ku panitia. Pikeun salah sahijina, kami nganggo alat anu disebarkeun sareng TON, sareng anu kadua dilaksanakeun dina basa anyar anu dikembangkeun ku insinyur kami khusus pikeun TON sareng diwangun kana Haskell.

Pilihan basa program fungsional henteu kahaja. Di urang blog perusahaan Urang sering nyarioskeun naha urang nganggap pajeulitna basa fungsional mangrupikeun kaleuleuwihan anu ageung sareng naha urang umumna langkung milih aranjeunna pikeun anu berorientasi obyék. Ku jalan kitu, éta ogé ngandung aslina tina tulisan ieu.

Naha urang malah mutuskeun pikeun ilubiung?

Pondokna, sabab Spésialisasi urang téh non-standar jeung proyék kompléks nu merlukeun kaahlian husus sarta mindeng nilai ilmiah pikeun komunitas IT. Urang niatna ngarojong ngembangkeun open-source sarta kalibet dina popularization na, sarta ogé cooperate kalawan universitas Rusia ngarah dina widang elmu komputer jeung matématika.

Tugas-tugas anu pikaresepeun tina kompetisi sareng kalibet dina proyék Telegram anu dipikacinta ku dirina mangrupikeun motivasi anu saé, tapi dana hadiah janten insentif tambahan. 🙂

Panalungtikan TON blockchain

Urang raket ngawas kamajuan anyar dina blockchain, kecerdasan jieunan sarta learning mesin sarta coba teu sono hiji release signifikan tunggal di unggal wewengkon nu urang gawe. Ku alatan éta, ku waktu kompetisi dimimitian, tim kami geus akrab jeung gagasan ti TON kertas bodas. Nanging, sateuacan ngamimitian damel sareng TON, kami henteu nganalisa dokuméntasi téknis sareng kode sumber anu saleresna tina platform éta, janten léngkah anu munggaran écés - panilitian lengkep ngeunaan dokuméntasi resmi dina website jeung repositories proyék.

Nalika kompetisi dimimitian, kodeu parantos diterbitkeun, janten pikeun ngahémat waktos, urang mutuskeun pikeun milarian pituduh atanapi ringkesan anu ditulis ku pamaké. Hanjakalna, ieu henteu masihan hasil - sajaba ti petunjuk pikeun ngumpul platform dina Ubuntu, kami henteu mendakan bahan anu sanés.

Dokuméntasi sorangan ditalungtik saé, tapi sesah dibaca di sababaraha daérah. Sering urang kedah uih deui ka titik-titik anu tangtu sareng ngalih tina déskripsi tingkat luhur ngeunaan ideu abstrak ka detil palaksanaan tingkat rendah.

Eta bakal leuwih gampang lamun spésifikasi teu kaasup pedaran lengkep ngeunaan palaksanaan pisan. Inpormasi ngeunaan kumaha mesin virtual ngagambarkeun tumpukanna langkung dipikaresep ngaganggu pamekar nyiptakeun kontrak pinter pikeun platform TON tibatan ngabantosan aranjeunna.

Nix: nempatkeun proyék babarengan

Di Serokel kami fans gedé nix. Kami ngumpulkeun proyék kami sareng aranjeunna sareng nyebarkeun aranjeunna nganggo NixOps, sareng dipasang dina sadaya server kami Nix OS. Hatur nuhun kana ieu, sadaya gedong kami tiasa diulang sareng dianggo dina sistem operasi mana waé anu tiasa dipasang Nix.

Ku kituna urang mimitian ku nyieun Nix overlay kalawan éksprési pikeun assembly TON. Kalayan bantosanana, kompilasi TON sasederhana mungkin:

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

Catet yén anjeun henteu kedah masang dependensi naon waé. Nix sacara ajaib bakal ngalakukeun sadayana pikeun anjeun, naha anjeun nganggo NixOS, Ubuntu, atanapi macOS.

Programming pikeun TON

Kode kontrak pinter dina TON Network dijalankeun dina TON Virtual Machine (TVM). TVM téh leuwih kompleks tinimbang paling mesin virtual séjén, sarta ngabogaan pungsi pisan metot, Contona, tiasa dianggo kalayan tuluyan и Tumbu ka data.

Sumawona, lalaki ti TON nyiptakeun tilu basa pamrograman énggal:

Lima mangrupakeun basa programming tumpukan universal anu nyarupaan Laju. Kamampuh superna nyaéta kamampuan berinteraksi sareng TVM.

KasenanganC mangrupakeun basa programming kontrak pinter nu sarupa jeung C sarta disusun kana basa sejen - Fift Assembler.

Assembler Kalima - Perpustakaan Lima pikeun ngahasilkeun kode eksekusi binér pikeun TVM. Fifth Assembler teu gaduh kompiler. Ieu Embedded Domain Spésifik Basa (eDSL).

kompetisi urang jalan

Tungtungna, éta waktu pikeun nempo hasil tina usaha urang.

Saluran pembayaran Asynchronous

Saluran pamayaran mangrupikeun kontrak pinter anu ngamungkinkeun dua pangguna ngirim pamayaran di luar blockchain. Hasilna, anjeun simpen teu ukur duit (euweuh komisi), tapi ogé waktu (anjeun teu kudu ngadagoan blok salajengna diolah). Pangmayaran tiasa sakedik sakumaha anu dipikahoyong sareng sering upami diperyogikeun. Dina hal ieu, pihak-pihak henteu kedah saling percaya, sabab kaadilan padumukan ahir dijamin ku kontrak pinter.

Kami mendakan solusi anu saderhana pikeun masalah éta. Dua pihak tiasa tukeur pesen anu ditandatanganan, masing-masing ngandung dua nomer-jumlah pinuh dibayar ku unggal pihak. Ieu dua angka dianggo kawas jam vektor dina sistem disebarkeun tradisional tur nyetel "kajadian saméméh" urutan on transaksi. Ngagunakeun data ieu, kontrak bakal tiasa ngabéréskeun sagala konflik mungkin.

Kanyataanna, hiji angka cukup pikeun nerapkeun gagasan ieu, tapi urang ninggalkeun duanana sabab ku cara kieu urang bisa nyieun panganteur pamaké leuwih merenah. Salaku tambahan, urang mutuskeun pikeun ngalebetkeun jumlah pamayaran dina unggal pesen. Tanpa éta, upami suratna leungit pikeun sababaraha alesan, teras, sanaos sadaya jumlah sareng itungan ahir bakal leres, pangguna tiasa waé henteu perhatikeun karugian éta.

Pikeun nguji ideu, urang milarian conto ngagunakeun protokol saluran pembayaran anu sederhana sareng singket. Ahéng, urang kapanggih ngan dua:

  1. gambaran pendekatan sarupa, ngan pikeun kasus saluran unidirectional.
  2. Tutorial, anu ngajelaskeun ide anu sami sareng urang, tapi tanpa ngajelaskeun seueur detil penting, sapertos kabeneran umum sareng prosedur resolusi konflik.

Janten jelas yén masuk akal pikeun ngajelaskeun protokol kami sacara rinci, nengetan khusus kana kabeneranna. Saatos sababaraha iterasi, spésifikasi parantos siap, sareng ayeuna anjeun ogé tiasa. neuteup manehna.

Kami ngalaksanakeun kontrak di FunC, sareng kami nyerat utilitas garis paréntah pikeun berinteraksi sareng kontrak kami sadayana di Fift, sakumaha anu disarankeun ku panitia. Urang bisa geus milih mana wae basa sejen pikeun CLI kami, tapi kami kabetot dina nyobian Fit ningali kumaha eta dipigawé dina prakna.

Jujur, saatos damel sareng Fift, kami henteu ningali alesan anu kuat pikeun milih basa ieu tibatan basa anu populer sareng aktip dianggo kalayan alat sareng perpustakaan anu dikembangkeun. Programming dina basa dumasar-tumpukan rada pikaresepeun, saprak anjeun kudu terus-terusan tetep dina sirah anjeun naon dina tumpukan, sarta compiler teu mantuan jeung ieu.

Ku alatan éta, dina pamadegan urang, hiji-hijina alesan pikeun ayana Fift nyaéta peranna salaku basa host pikeun Fift Assembler. Tapi naha éta langkung saé pikeun ngalebetkeun assembler TVM kana sababaraha basa anu tos aya, tinimbang nyiptakeun anu énggal pikeun tujuan ieu?

TVM Haskell eDSL

Ayeuna waktuna pikeun ngobrol ngeunaan kontrak pinter kadua urang. Urang mutuskeun pikeun ngamekarkeun dompét multi-signature, tapi nulis kontrak pinter sejen di FunC bakal teuing boring. Simkuring hoyong nambahkeun sababaraha rasa, sarta éta basa assembly kami sorangan pikeun TVM.

Siga Fift Assembler, basa anyar urang dipasang, tapi kami milih Haskell salaku host tibatan Fift, ngamungkinkeun urang ngamangpaatkeun sistem jinis canggih na. Nalika damel sareng kontrak pinter, dimana biaya kasalahan anu alit tiasa ageung pisan, ngetik statik, dina pendapat kami, mangrupikeun kauntungan anu ageung.

Pikeun nunjukkeun kumaha assembler TVM anu dipasang dina Haskell, kami ngalaksanakeun dompét standar. Ieu sababaraha hal anu kedah diperhatoskeun:

  • kontrak ieu diwangun ku hiji fungsi, tapi anjeun bisa make saloba anjeun resep. Nalika anjeun netepkeun fungsi anyar dina basa host (nyaéta Haskell), eDSL kami ngamungkinkeun anjeun milih naha anjeun hoyong éta janten rutin anu misah dina TVM atanapi ngan saukur inline dina titik telepon.
  • Sapertos Haskell, fungsi ngagaduhan jinis anu dipariksa dina waktos kompilasi. Dina eDSL urang, tipe input fungsi hiji tipe tumpukan nu fungsi ekspektasi, sarta jenis hasilna mangrupa tipe tumpukan anu bakal dihasilkeun sanggeus nelepon.
  • Kodeu gaduh annotations stacktype, ngajéntrékeun tipe tumpukan ekspektasi dina titik panggero. Dina kontrak dompét asli ieu ngan ukur koméntar, tapi dina eDSL kami aranjeunna saleresna bagian tina kode sareng dipariksa dina waktos kompilasi. Éta bisa ngawula salaku dokuméntasi atawa pernyataan nu mantuan pamekar manggihan masalah lamun kode robah jeung tipe tumpukan robah. Tangtosna, anotasi sapertos kitu henteu mangaruhan kinerja runtime, sabab henteu aya kode TVM anu dihasilkeun pikeun aranjeunna.
  • Ieu masih prototipe ditulis dina dua minggu, jadi aya kénéh loba karya kudu dipigawé dina proyék. Salaku conto, sadaya instansi kelas anu anjeun tingali dina kode di handap ieu kedah dibangkitkeun sacara otomatis.

Ieu mangrupikeun palaksanaan dompét multisig dina eDSL kami:

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

Kodeu sumber lengkep pikeun kontrak dompét eDSL sareng multi-signature urang tiasa dipendakan di gudang ieu. Sareng seueur deui dicaritakeun sacara jentre ngeunaan basa diwangun-di, batur sapagawean urang Georgy Agapov.

Kacindekan ngeunaan kompetisi jeung TON

Dina total, karya urang nyandak 380 jam (kaasup familiarization jeung dokuméntasi, rapat jeung ngembangkeun sabenerna). Lima pamekar nyandak bagian dina proyék kompetisi: CTO, kalungguhan tim, spesialis platform blockchain sarta pamekar software Haskell.

Urang manggihan sumberdaya pikeun ilubiung dina kontes tanpa kasusah, saprak sumanget hackathon a, nutup gawé babarengan, sarta kudu gancang neuleumkeun diri dina aspék téknologi anyar sok seru. Sababaraha wengi teu sare pikeun ngahontal hasil anu maksimal dina kaayaan sumber daya anu terbatas dibales ku pangalaman anu berharga sareng kenangan anu saé. Salaku tambahan, ngerjakeun tugas sapertos kitu mangrupikeun tés anu saé pikeun prosés perusahaan, sabab sesah pisan pikeun ngahontal hasil anu saé tanpa interaksi internal anu saé.

Lirik kumisan: kami impressed ku jumlah karya nempatkeun dina ku tim TON. Aranjeunna junun ngawangun kompléks, geulis, sarta paling importantly, sistem kerja. TON parantos ngabuktikeun dirina janten platform anu poténsial hébat. Nanging, supados ékosistem ieu mekar, langkung seueur anu kedah dilakukeun, boh tina segi panggunaanana dina proyék blockchain sareng dina hal ningkatkeun alat pangwangunan. Kami reueus ayeuna janten bagian tina prosés ieu.

Upami saatos maca tulisan ieu anjeun masih gaduh patarosan atanapi gaduh ide ngeunaan cara ngagunakeun TON pikeun ngabéréskeun masalah anjeun, nulis ka kami - urang bakal senang babagi pangalaman urang.

sumber: www.habr.com

Tambahkeun komentar