Te olete kindlasti kuulnud, et Telegram . Kuid te vĂ”isite jÀÀda ilma uudisest, et mitte nii kaua tagasi Telegram ĂŒhe vĂ”i mitme nutilepingute elluviimiseks sellel platvormil.
Serokelli meeskond, kellel on ulatuslik kogemus suurte plokiahela projektide arendamisel, ei saanud kĂ”rvale jÀÀda. Me delegaatsime konkursile viis töötajat, ja juba kahe nĂ€dala pĂ€rast saavutasid nad seal esikoha (mitte)vaikselt tegutseva kasutajanimega Sexy Chameleon. Selles artiklis rÀÀgin, kuidas nad selle saavutada suutsid. Loodame, et jĂ€rgmise kĂŒmne minuti jooksul loete vĂ€hemalt huvitava loo, ja ehk leiate selles midagi kasulikku, mida oma töös kasutada.
Aga alustame vÀikese konteksti tÔlgendamisega.
Konkursi tingimused
Nii et osalejate peamised ĂŒlesanded olid ĂŒhe vĂ”i mitme pakutud nutilepingu elluviimine ning ettepanekute tegemine TONi ökosĂŒsteemi tĂ€iustamiseks. Konkurs kestis 24. septembrist kuni 15. oktoobrini, kuid tulemused kuulutati vĂ€lja alles 15. novembril. Suhteliselt pikk aeg, arvestades, et selle aja jooksul suutis Telegram korraldada ja vĂ€lja kuulutada disainikonkursside ja C++ rakenduste arenduskonkursi tulemused VoIP kĂ”nede testimise ja kvaliteedi hindamiseks Telegramis.
Valisime korraldajate pakutud nimekirjast vĂ€lja kaks nutilepingut. Ăhe jaoks kasutasime TONiga kaasasolevaid tööriistu, teise rakendasime uuel keelel, mille meie insenerid koostasid spetsiaalselt TONi jaoks ja mis on integreeritud Haskellisse.
Funktsionaalse programmeerimiskeele valik ei ole juhuslik. Meie rÀÀgime sageli, miks peame funktsionaalsete keelte keerukust suureks liialduseks ja miks eelistame neid ĂŒldiselt objekti-orienteeritud keeltele. Muide, seal on ka .
Miks me ĂŒldse otsustasime osaleda
LĂŒhidalt öeldes, meie spetsialiseerumine on ebatavalised ja keerulised projektid, mis nĂ”uavad erioskusi ja omavad sageli teaduslikku vÀÀrtust IT-kommuunile. Me toetame innukalt open-source arendust ja tegeleme selle populariseerimisega ning teeme koostööd Venemaa juhtivate ĂŒlikoolidega arvutiteaduse ja matemaatika valdkonnas.
VĂ”istluse huvitavad ĂŒlesanded ja seotus meie armastatud projektiga Telegram olid iseenesest suurepĂ€rane motivatsioon, lisaks tĂ”i auhinnafond tĂ€iendavat stiimulit. đ
TONi plokiahela uurimine
Me jĂ€lgime tĂ€helepanelikult uusi arenguid plokiahelas, tehisintellektis ja masinĂ”ppes, pĂŒĂŒdes mitte magada maha ĂŒhtegi olulist vĂ€ljaannet igas valdkonnas, kus töötame. Seega, konkursi alguseks oli meie meeskond juba tuttav ideedega, mis on pĂ€rit . Enne kui alustasime tööga TONi kallal, ei analĂŒĂŒsinud me tehnilist dokumentatsiooni ega platvormi tegelikku lĂ€htekoodi, seega esimene samm oli ĂŒsna selge â pĂ”hjalik uurimine ametlikust dokumentatsioonist ja .
Kuna konkursi alguseks oli kood juba avaldatud, otsustasime aega sÀÀstes otsida juhendit vĂ”i kokkuvĂ”tet, mille olid kirjutanud kasutajad. Kahjuks ei andnud see tulemust â peale juhiste Ubuntu platvormi ĂŒlesehitamiseks ei leidnud me muid materjale.
Dokumentatsioon ise osutus hĂ€sti lĂ€bimĂ”eldud, kuid selle lugemine oli mĂ”ningates kohtades keeruline. Me pidime ĂŒsna sageli tagasi pöörduma erinevate punktide juurde ja liikuma kĂ”rgetasemelistelt abstraktsetelt ideedelt madalama taseme rakenduse detailide juurde.
Oleks olnud lihtsam, kui spetsifikatsioonis ei oleks ĂŒldse olnud ĂŒksikasjalikku rakenduse kirjeldust. Teave selle kohta, kuidas virtuaalne masin oma virna esitleb, pigem segab arendajaid, kes loovad TONi platvormile nutikaid lepinguid, kui aitab neid.
Nix: kogume projekti
Serokellis oleme suured fĂ€nnid . Me kogume oma projekte ja kĂ€ivitame need kasutades , ja kĂ”ikidel meie serveritel on paigaldatud . TĂ€nu sellele on kĂ”ik meie buildid reprodukutitavad ja töötavad igas operatsioonisĂŒsteemis, kuhu Nixi saab installida.
Seega alustasime . Tema abil on TON-i kiiresti kompileerida:
$ cd ~/.config/nixpkgs/overlays && git clone https://github.com/serokell/ton.nix
$ cd /path/to/ton/repo && nix-shell
[nix-shell]$ cmakeConfigurePhase && makePange tÀhele, et te ei pea installima mingeid sÔltuvusi. Nix teeb kÔik teie eest maagiliselt olenemata sellest, kas kasutate NixOS-i, Ubuntu vÔi macOS-i.
Programmeerimine TON-i jaoks
Tarkvaralepingud TON vÔrgus töötavad TON Virtuaalmasinas (TVM). TVM on keerulisem kui enamik teisi virtuaalmasinaid ja omab vÀga huvitavaid funktsioone, nÀiteks oskab ta töötada katkestustega (continuations) ja andmeviidete (data references).
Veelgi enam, TON-i poisid on loonud lausa kolm uut programmeerimiskeelt:
Fift â universaalne virnastatud programmeerimiskeel, mis meenutab . Tema supervĂ”ime on suhelda TVM-iga.
FunC â tarkvaralepingute programmeerimiskeel, mis sarnaneb ja kompileeritakse veel ĂŒheks keeleks â Fift Assembliks.
Fift Assembler â Fifti teek TVM-i jaoks binaarse tĂ€idetava koodi genereerimiseks. Fift Assemblil pole kompilaatorit. See on .
Meie konkursitööd
LÔpuks on aeg vaadata meie pingutuste tulemusi.
AsĂŒnkroonne maksetee
Maksetee (payment channel) â tarkvaraleping, mis vĂ”imaldab kahel kasutajal teha makseid vĂ€ljaspool plokiahelat. SeelĂ€bi sÀÀstetakse mitte ainult raha (komisjoni pole), vaid ka aega (te ei pea ootama, kuni jĂ€rgmine plokk töödeldakse). Maksed vĂ”ivad olla tootmiselt nii vĂ€ikesed kui vaja ja toimuda niipea kui vajalik. Samuti ei pea pooled ĂŒksteisega usaldama, kuna lĂ”pliku arveldamise Ă”iglus on tagatud tarkvaralepinguga.
Me leidsime probleemi jaoks ĂŒsna lihtsa lahenduse. Kaks osalist saavad vahetada allkirjastatud sĂ”numeid, millest igaĂŒks sisaldab kahte numbrit â iga osaleja makstud kogusummat. Need kaks numbrit toimivad nagu traditsioonilistes hajusates sĂŒsteemides ja mÀÀratlevad jĂ€rjekorra "toimus enne" tehingute puhul. Kasutades neid andmeid, suudab leping lahendada iga vĂ”imaliku konflikti.
Tegelikult piisab selle idee elluviimiseks ĂŒhest numbrist, kuid jĂ€tsime mĂ”lemad, kuna nii suudame teha mugavama kasutajaliidese. Lisaks otsustasime igas sĂ”numis nĂ€idata makse suurust. Ilma selleta, kui sĂ”num mingil pĂ”hjusel kaob, vĂ”ib kasutaja kaotust mitte mĂ€rgata, kuigi kĂ”ik summad ja lĂ”plik arvestus on Ă”iged.
Kuna tahtsime meie ideed testida, otsisime nĂ€iteid sellise lihtsa ja lakoonilise maksekanali protokolli kasutamisest. Ăllatuseks leidsime vaid kaks:
- sarnast lĂ€henemist, ainult ĂŒhe suunalise kanali puhul.
- , milles on kirjeldatud sama ideed, mis meil, kuid ilma selgitusteta paljude oluliste detailide kohta, nagu ĂŒldine kehtivus ja konfliktide lahendamise protseduur.
Selgeks sai, et on mĂ”istlik detailselt kirjeldada meie protokolli, pöörates erilist tĂ€helepanu selle kehtivusele. PĂ€rast mitmeid ringe oli spetsifikatsioon valmis ja nĂŒĂŒd saate seda ka .
Rakendasime lepingu FunC-is ning CLI tööriista meie lepinguga suhtlemiseks kirjutasime tÀielikult Fiftis, nagu soovitasid korraldajad. Me oleksime saanud valida mÔne muu keele meie CLI jaoks, kuid meid huvitab proovida just Fiftit, et nÀha, kuidas see praktikas toimib.
Ausalt öeldes, pĂ€rast Fiftiga töötamist ei nĂ€inud me tĂ”siseid pĂ”hjuseid eelistada seda keelt populaarsetele ja laialdaselt kasutatavatele keeltele, millel on hĂ€sti arenenud tööriistad ja raamatukogud. Steke keeles programmeerimine on ĂŒsna ebameeldiv, kuna tuleb pidevalt meeles pidada, kus miski virnas asub, ja kompilaator selles ei aita.
Seega on ainus meie arvates Fift olemasolu Ôigustus selle roll host-keelena Fift Assembler'i jaoks. Kas poleks parem, kui integreerida TVM assembler mÔne olemasoleva keele sisse, selle asemel et vÀlja mÔelda uus just selle, sisuliselt ainulaadse, eesmÀrgi jaoks?
TVM Haskell eDSL
NĂŒĂŒd on aeg rÀÀkida meie teisest nutilepingust. Otsustasime arendada multifirma rahakoti, kuid uue nutilepingu kirjutamine FunC-is oleks olnud liiga igav. Soovisime lisada midagi erilist, ja selleks valisime meie enda assembleri keele TVM jaoks.
Nagu Fift Assembler, on meie uus keel sisseembedatud, kuid hostina valisime Haskelli, mis vĂ”imaldab meil tĂ€ielikult kasutada selle edasijĂ”udnud tĂŒĂŒbistikut. Targa lepingu puhul, kus isegi vĂ€ikse vea hind vĂ”ib olla vĂ€ga kĂ”rge, on staatiline tĂŒĂŒbihindamine meie arvates suur eelis.
Kuidas demonstreerida, kuidas Haskellisse sisseembedatud TVM assembler vÀlja nÀeb, oleme selle peal rakendanud tavalise rahakoti. Siin on mÔned asjad, millele tasub tÀhelepanu pöörata:
- See leping koosneb ĂŒhest funktsioonist, kuid vĂ”ite kasutada nii palju, kui soovite. Kui teete hostkeeles (st Haskellis) uue funktsiooni, vĂ”imaldab meie eDSL teil valida, kas soovite, et see muutuks eraldi alamprogrammi TVMs vĂ”i lihtsalt integreeritakse kutsumisekohta.
- Nagu Haskellis, on funktsioonidel tĂŒĂŒbid, mis kontrollitakse kompileerimise ajal. Meie eDSL-is on funktsiooni sisendi tĂŒĂŒp see, mida funktsioon vĂ€ntab, ja tulemuste tĂŒĂŒp on see, mis tekib pĂ€rast kutset.
- Koodis on annotatsioonid
stacktype, mis kirjeldavad oodatavat tĂŒĂŒbistikut kutsepunktil. Originaalses rahakoti lepingus olid need lihtsalt kommentaarid, kuid meie eDSL-is on need tegelikult osa koodist ja neid kontrollitakse kompileerimise ajal. Need vĂ”ivad toimida dokumentatsioonina vĂ”i kinnitustena, mis aitavad arendajal probleemile jĂ€lile jĂ”uda juhuks, kui koodi muutmisel tĂŒĂŒbistik muutub. Muidugi ei mĂ”juta sellised annotatsioonid tööajal tulemuslikkust, kuna nende jaoks ei genereerita ĂŒhtegi TVM koodi. - See on endiselt prototĂŒĂŒp, mis kirjutati kahe nĂ€dalaga, seega on projektis veel palju tööd teha. NĂ€iteks kĂ”ik klasside eksemplarid, mida nĂ€ete allpool olevas koodis, peavad olema automaatselt genereeritud.
Nii nÀeb vÀlja multisig-rahakoti rakendamine meie eDSL-is:
peamine :: IO ()
peamine = putText $ pretty $ declProgram protsessid meetodid
kus
protsessid =
[ ("recv_external", decl recvExternal)
, ("recv_internal", decl recvInternal)
]
meetodid =
[ ("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
tuletab (Eq, Ord, Show, Generic)
instance Exception WalletError
instance Enum WalletError where
toEnum 33 = SeqNoMismatch
toEnum 34 = SignatureMismatch
toEnum _ = error "Tundmatu 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 @Word32Teie saate tÀielikku algkoodi meie eDSL ja mult_signature rahakoti lepingu leida Ja rohkem meie kolleeg Georgy Agapov.
KokkuvÔtted konkursist ja TON
Kokku meie töö vÔttis 380 tundi (koos dokumentatsiooniga tutvumise, koosolekute ja arendamisega). Konkursi projektis osales viis arendajat: CTO, meeskonna juht, plokiahela platvormide spetsialistid ja Haskellil tarkvara arendajad.
Meeskonnale osalemiseks vajalikke ressursse leidsime kiiresti, kuna hackathoni vaim, tihe meeskonnatöö, vajadus uute tehnoloogiate aspektidesse kiiresti sĂŒveneda â see on alati haarav. Mitmed unetukesed maksimaalse tulemuse nimel piiratud ressursside tingimustes on tasustatud hindamatu kogemuse ja suurepĂ€raste mĂ€lestustega. Lisaks on selliste ĂŒlesannete kallal töötamine alati suurepĂ€rane katsumus ettevĂ”tte protsesside jaoks, kuna tĂ”eliselt rahuldavate tulemuste saavutamine ilma hĂ€sti toimiva sisemise koostööta on ÀÀrmiselt keeruline.
Lisaks lirikale: olime muljetavaldatud TONi meeskonna tehtud töö mahust. Neil Ă”nnestus luua keeruline, ilus ja mis kĂ”ige tĂ€htsam, töötav sĂŒsteem. TON on nĂ€idanud end platvormina, millel on suur potentsiaal. Kuid selleks, et ökosĂŒsteem areneks, tuleb veel palju teha, nii plokiahela projektides kasutamise osas kui ka arendustööriistade tĂ€iustamise osas. Oleme uhked, et oleme nĂŒĂŒd osa sellest protsessist.
Kui pĂ€rast selle artikli lugemist on teil veel kĂŒsimusi vĂ”i olete leidnud ideid, kuidas TONi oma probleemide lahendamiseks rakendada, â me jagame meeleldi oma kogemusi.
Allikas: habr.com
