Şübhəsiz ki, Telegram-ın . Lakin, bəlkə də, siz Telegram-ın bu platforma üçün bir və ya bir neçə smart kontrakt hazırlanması məqsədilə göz ardı etmisiniz.
Serokell komandası, böyük blockchain layihələrinin inkişafında zəngin təcrübəyə malik bir qrup olaraq geri qalmadı. Biz müsabiqəyə beş işçimizi göndərdik və artıq iki həftədən sonra onlar Sexy Chameleon adını daşıyan (həmin) mücərrəd ləqəblə birinci yerdə irəlilədilər. Bu yazıda onların necə uğur qazandıqlarını sizə izah edəcəyəm. Ümid edirik ki, önümüzdəki on dəqiqə ərzində ya ən azı maraqlı bir hekayə oxuyarsınız, ya da işinizdə tətbiq edə biləcəyiniz bir şey taparsınız.
Amma əvvəlcə kontekstə kiçik bir daldırma edək.
Müsabiqə və onun şərtləri
Beləliklə, iştirakçıların əsas vəzifələri təklif olunan smart kontraktlardan birinin və ya bir neçəsinin icrası, eləcə də TON ekosisteminin təkmilləşdirilməsi üçün təkliflər təqdim etmək idi. Müsabiqə 24 sentyabr - 15 oktyabr tarixləri arasında keçirildi və nəticələr yalnız 15 noyabrda elan edildi. Bu, müvafiq olaraq, Telegram-ın dizayn və C++ tətbiq inkişafı üzrə müsabiqələrin nəticələrini açıqladığı vaxtdan bayaqdır, olduqca uzun bir müddət idi.
Biz təşkilatçılar tərəfindən təklif olunan siyahıdan iki smart kontrakt seçdik. Birinin icrası üçün TON ilə birlikdə təqdim olunan alətlərdən istifadə etdik, ikincisini isə mühəndislərimiz tərəfindən xüsusi olaraq TON üçün hazırlanmış yeni bir dildə reallaşdırdıq və Haskell-ə daxil etdik.
Funksional proqramlaşdırma dilinin seçimi təsadüfi deyil. Bizim biz tez-tez funksional dillərin çətinliyinin böyük bir abartı olduğunu düşündüyümüzü, eləcə də ümumilikdə onların obyekt yönlü dillərə nisbətən niyə üstünlük verdiyimizi izah edirik. Bu yazıda da .
Niyə iştirak etməyə qərar verdik
Qısaca desək, bizim ixtisas sahəmiz qeyri-standart və mürəkkəb layihələrdir ki, bunlar xüsusi bacarıqlar tələb edir və çox vaxt IT icması üçün elmi dəyəri vardır. Biz açıq mənbə inkişafını səmimi olaraq dəstəkləyirik və onun populyarlaşdırılması ilə məşğul oluruq, eyni zamanda Rusiyanın aparıcı universitetləri ilə kompüter elmləri və riyaziyyat sahəsində əməkdaşlıq edirik.
Müsabiqənin maraqlı tapşırıqları və sevimli Telegram layihəmizdə iştirak etməyimiz özlüyündə gözəl motivasiya oldu, mükafat fondu isə əlavə stimula çevrildi. 🙂
TON blockchain-nin araşdırılması
Biz blockchain, süni intellekt və maşın öyrənməsi sahələrindəki yeni inkişafları yaxından izləyirik və hər bir sahədə hər bir əhəmiyyətli buraxılışı qaçırmamağa çalışırıq. Buna görə müsabiqənin başlanmasına qədər komandamız artıq . Lakin TON ilə işə başlamazdan əvvəl texniki sənədləri və faktiki mənbə kodunu analiz etmədiyimiz üçün ilk addım aydın oldu — rəsmi sənədləri diqqətlə araşdırmaq. və .
Müsabiqənin başlanğıcında kod artıq yayımlandığı üçün vaxt qazanmaq məqsədilə rəhbərlik və ya istifadəçilər tərəfindən yazılmış xülasə axtarmağa qərar verdik. istifadəçilər. Təssüf ki, bunun nəticəsi olmadı — Ubuntu-da platformanın yığılmasıyla bağlı təlimatdan başqa heç bir material tapa bilmədik.
Sənədin özü diqqətlə hazırlanmışdı, lakin bəzən oxumaq çətin olurdu. Tez-tez müəyyən bəndlərə qayıtmalı olduq və yüksək səviyyəli abstrakt fikirlərdən aşağı səviyyəli icra detallarına keçməli olduq.
Əgər spesifikasiyada icra detalları olmayaydı, daha asan olardı. Virtual maşının yığını necə təqdim etdiyinə dair məlumat, TON platforması üçün ağıllı müqavilələr yaradan tərtibatçılara kömək etməkdən çox, onları yayındırır.
Nix: layihəni yığırıq
Serokell-də biz böyük pərəstişkarlarıyıq. NixOps NixOS
. Bu sayədə bütün yükləmələrimiz reproducible-dir və Nix quraşdırıla bilən hər bir əməliyyat sistemi altında işləyir. Nix overlay yaratmağa başladıq.
Bu vasitə ilə TON-u yığmaq çox asandır:$ cd ~/.config/nixpkgs/overlays && git clone https://github.com/serokell/ton.nix $ cd /path/to/ton/repo && nix-shell [nix-shell]$ cmakeConfigurePhase && make
Qeyd edək ki, heç bir asılılıq quraşdırmalısınız. Nix sehrli şəkildə sizin üçün hər şeyi edəcək, NixOS, Ubuntu və ya macOS-dan istifadə etmənizəsasən.
TON üçün proqramlaşdırma TON Şəbəkəsində ağıllı müqavilələrin kodu TON Virtual Maşınında (TVM) icra olunur. TVM, əksər digər virtual maşınlardan daha mürəkkəbdir və məsələn, və xüsusiyyətləri ilə zəngin odda (continuations).
məlumatlara istinadlar
Bundan əlavə, TON-dan olanlar tam üç yeni proqramlaşdırma dili yaradıb: Fift FunC
— C-yə bənzəyən ağıllı müqavilə proqramlaşdırma dili və Fift Yığma dilinə tərtib olunur. Fift Yığma inteqrasiya olunmuş predmetə yönəldilmiş dildir (eDSL)
Müsabiqə işlərimiz Nəhayət, səylərimizin nəticələrinə baxma vaxtı gəlib. .
Müsabiqə işlərimiz
Nəhayət, əlimizdən gələnin nəticələrinə nəzər salmağın vaxtı gəldi.
Asinxron ödəmə kanalı
Ödəniş kanalı (payment channel) — smart müqavilədir ki, iki istifadəçiyə blockchain xaricində ödənişlər göndərməyə imkan tanıyır. Nəticədə həm pul (komissiya yoxdur), həm də vaxt (növbəti blokun emal edilməsini gözləmək lazım deyil) qənaət olunur. Ödənişlərin istənilən qədər kiçik olması və lazım olduğu qədər tez-tez baş verməsi mümkündür. Eyni zamanda, tərəflərin bir-birilərinə etibar etmələri zəruri deyil, çünki yekun hesabın ədaləti smart müqavilə ilə təmin olunur.
Biz problemi həll etmək üçün olduqca sadə bir yol tapdıq. İki tərəf imzalanmış mesajlar mübadilə edə bilər, hər biri iştirakçıların ödənilmiş tam məbləğini ehtiva edən iki ədəd daşıyır. Bu iki ədəd ənənəvi paylanmış sistemlərdədir və transaksiyalarda «bu baş verdi» sırasını müəyyən edir. Bu məlumatlardan istifadə edərək, müqavilə hər hansı bir mümkün konfliktin həllini təmin edə biləcək.
Əslində, bu ideyanın həyata keçirilməsi üçün tək ədəd kifayət edir, amma biz həm ikisini saxladıq, çünki bu sayədə daha rahat bir istifadəçi interfeysi qura bildik. Bundan əlavə, hər mesajda ödənişin ölçüsünü daxil etməyə qərar verdik. Bu olmadan, əgər mesaj hər hansı bir səbəbdən itərsə, bütün məbləğlər və yekun hesab düzgün olsa da, istifadəçi itirimi əllə bilmir.
İdeyamızı yoxlamaq üçün belə sadə və sərt protokolun tətbiqinə dair misallar axtardıq. Təəccüblü şəkildə, yalnız iki nümunə tapdıq:
- bənzər yanaşma, yalnız bir istiqamətli kanalla bağlıdır.
- , burada eyni fikrin açıqlanması təklif olunur, amma mühüm detallar, məsələn, ümumi düzgünlük və konfliktlərin həll proseduru haqqında heç bir açıqlama yoxdur.
Aydın oldu ki, protokolumuzu ətraflı təsvir etmək, onun düzgünlüyünə xüsusilə diqqət yetirmək məsləhətlidir. Bir neçə iterasiyadan sonra spesifikasiya hazır oldu və indi siz də .
Biz FunC üzərində müqaviləni həyata keçirdik, komandalar ilə qarşılıqlı əlaqə üçün istifadə etdiyimiz köməkçi vasitəni isə tamamilə Fift üzərində yazdıq, təşkilatçıların tövsiyə etdiyi kimi. CLI üçün istənilən digər dili seçə bilərdik, amma Fiftin özünü necə göstərəcəyini görmək üçün məhz Fift ilə sınamağa maraqlandıq.
Honest olaraq, Fiftilə çalışdıqca, bu dilin geniş alətlər və kitabxanalarla tanınmış və aktiv şəkildə istifadə edilən dillərə nisbətən üstün olduğunu düşünmək üçün ciddi səbəblər görmədik. Stek dilində proqramlaşdırmaq olduqca narahatdır, çünki insanın yaddaşında stackdə nə olduğu daim saxlanılması lazım olur və kompilyator bununla heç bir kömək etmir.
Buna görə də, bizim fikrimizcə, Fift-in mövcud olmasının yeganə əsaslandırılması onun Fift Assembler üçün host dili kimi roludur. Ancaq bir mövcud dilin içində TVM assemblerini yerləşdirmək daha yaxşı olmazdımı, yeni bir dil icad etməkdən ziyadə, bu, əslində yeganə məqsəd üçündür?
TVM Haskell eDSL
İndi ikinci smart müqaviləmiz haqqında danışmağın vaxtıdır. Biz çox imza funksiyalı bir cüzdan hazırlamağa qərar verdik, amma FunC-da daha bir smart müqavilə yazmaq çox darıxdırıcı olacaqdı. Nəsə bir fərqlilik əlavə etmək istədik və bu, TVM üçün öz asan dili olan assemblerimiz oldu.
Fift Assembler-də olduğu kimi, yeni dilimiz daxildir, sadəcə Fift yerinə host kimi Haskell-i seçdiq, bu da onun inkişaf etmiş tip sistemindən tam istifadə etməyə imkan verdi. Smart müqavilələrlə işləyərkən, kiçik bir səhvin qiyməti çox yüksək ola biləcəyi üçün, statik tipizasiya bizim fikrimizcə böyük bir üstünlükdür.
TVM-ni Haskell-ə daxil edilən assembler ilə necə görünəcəyini nümayiş etdirmək üçün standart cüzdanı həyata keçirmişik. Diqqət yetirməlisiniz bir neçə şey:
- Bu müqavilə yalnız bir funksiyadan ibarətdir, amma siz istədiyiniz qədər istifadə edə bilərsiniz. Host dilində (yəni Haskell-də) yeni funksiya müəyyən etdiyiniz zaman, bizim eDSL sizə bunun TVM-də ayrı bir subprograma çevrilməsini və ya sadəcə çağırış yerinə daxil edilməsini seçmək imkanı verir.
- Haskell-də olduğu kimi, funksiyaların tipləri var ki, bu da kompilyasiya zamanı yoxlanılır. Bizim eDSL-də funksiyanın giriş tipi gözlənilən yığın tipidir, funksiyanın çağırılmasından sonra əldə ediləcək nəticə tipi isə yığın tipidir.
- Kodda anotasyonlar var
stacktype, çağırış yerində gözlənilən yığın tipini təsvir edən. Orijinal cüzdan müqaviləsində bunlar sadəcə şərhlər idi, amma bizim eDSL-də bunlar əslində kodun bir hissəsidir və kompilyasiya zamanı yoxlanılır. Onlar inkişaf etdiricinin kodu dəyişdirdikdə yığın tipinin dəyişməsi halında problemi tapmasına kömək edən sənəd və ya iddialar olaraq xidmət edə bilər. Bu anotasyonların icra zamanı performansa heç bir təsiri yoxdur, çünki onlar üçün heç bir TVM kodu yaradılmır. - Bu hələ də iki həftə ərzində yazılmış prototipdir, buna görə də layihə üzərində daha çox iş var. Məsələn, aşağıdakı kodda gördüyünüz bütün sinif nümunələri avtomatik olaraq yaradılmalıdır.
Budur, bizim eDSL-də multisig cüzdanın icrası belə görünür:
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 @Word32Tam bir eDSL-nin tam qaynaq kodunu və çoxsaylı imza ilə cüzdan müqaviləsini burada tapa bilərsiniz Daha ətraflı Tədqiqatın nəticələri və TON
Cəm bizim işimiz 380 saat (sənədlərlə, görüşlərlə və inkişafla birlikdə) çəkdi. Müsabiqə layihəsinə beş inkişafçı qatıldı: CTO, komanda lideri, blokçeyn platformaları üzrə mütəxəssislər və Haskell-də proqram təminatı tərtibatçıları.
Müsabiqədə iştirak üçün resursları asanlıqla tapdıq, çünki hackathon ruhu, sıx komanda işi, yeni texnologiyaların aspektlərinə sürətli uyğunlaşma ehtiyacı həmişə maraqlıdır. Məhdud resurslar şəraitində maksimum nəticə əldə etmək üçün bir neçə yatmamış gecələrin təmin etdiyi dəyərlidir, bu da improper dəyişikliklər qrafiyalardan doğurur. Belə məsələlər üzərində iş görmək, şirkət proseslərinin yaxşı testidir, çünki gerçəkdən layiqli nəticələr əldə etməyi yüksəkdə inkişaf etdirilmiş daxili əməkdaşlıq olmadan çox çətindir.
Müsabiqədə iştirak üçün resursları asanlıqla tapdıq, çünki hackathon ruhu, sıx komanda işi, yeni texnologiyaların aspektlərinə sürətli adaptasiya ehtiyacı həmişə maraqlıdır. Məhdud resurslar şəraitində maksimum nəticəyə nail olmaq üçün bir neçə yuxusuz gecə keçirilmiş olsa da, bu, qiymətsiz təcrübə və gözəl xatirələrlə kompensasiya olunur. Üstəlik, belə tapşırıqlar üzərində işləmək, şirkətin proseslərini yoxlamaq üçün hər zaman yaxşı bir yoldur, çünki həqiqətən layiqli nəticələr əldə etmək üçün mükəmməl təşkil edilmiş daxili əlaqələr olmadan çox çətindir.
Lirikanı bir kenara bırakırsak: TON ekibinin yaptığı çalışmaların hacminden etkilendik. Karmaşık, güzel ve en önemlisi çalışan bir sistem inşa etmeyi başardılar. TON, büyük bir potansiyele sahip bir platform olarak kendini gösterdi. Ancak bu ekosistemin gelişmesi için hala çok şey yapılması gerekiyor; hem blok zincir projelerinde kullanımı açısından, hem de geliştirme araçlarının iyileştirilmesi açısından. Bu sürecin bir parçası olmaktan gurur duyuyoruz.
Bu makaleyi okuduktan sonra herhangi bir sorunuz veya TON'u ihtiyaçlarınızı çözmek için nasıl kullanabileceğinize dair fikirleriniz varsa, — deneyimlerimizi seve seve paylaşırız.
Mənbə: habr.com
