Та тэр Telegram-ыг сонссон байх
Томоохон блокчэйн төслүүдийг хөгжүүлэх арвин туршлагатай Серокелл багийнхан хажуугаар нь зогсож чадсангүй. Бид таван ажилтныг тэмцээнд илгээсэн бөгөөд хоёр долоо хоногийн дараа тэд Sexy Chameleon гэсэн даруухан санамсаргүй хочоор тэргүүн байр эзэллээ. Энэ нийтлэлд би тэд үүнийг хэрхэн хийсэн талаар ярих болно. Ойрын арван минутын дотор та ядаж нэг сонирхолтой түүхийг уншиж, хамгийн ихдээ түүнээс ажилдаа хэрэг болохуйц хэрэгтэй зүйлийг олж авна гэж найдаж байна.
Гэхдээ бага зэрэг контекстээс эхэлье.
Өрсөлдөөн ба түүний нөхцөл
Тиймээс оролцогчдын гол ажил бол санал болгож буй нэг буюу хэд хэдэн ухаалаг гэрээг хэрэгжүүлэх, мөн TON экосистемийг сайжруулах санал гаргах явдал байв. Тэмцээн есдүгээр сарын 24-нөөс аравдугаар сарын 15-ныг хүртэл үргэлжилсэн бөгөөд зөвхөн арваннэгдүгээр сарын 15-нд дүнгээ гаргалаа. Энэ хугацаанд Telegram нь Telegram дахь VoIP дуудлагын чанарыг турших, үнэлэх зорилгоор C++ хэл дээр программ зохиох, хөгжүүлэх уралдааныг зохион байгуулж, үр дүнгээ зарлаж чадсаныг бодвол нэлээд удаж байна.
Зохион байгуулагчдын санал болгосон жагсаалтаас бид хоёр ухаалаг гэрээг сонгосон. Тэдгээрийн нэгд нь бид TON-д тараасан хэрэгслүүдийг ашигласан бол хоёр дахь нь манай инженерүүдийн тусгайлан TON-д зориулан боловсруулж, Haskell-д суулгасан шинэ хэлээр хэрэгжсэн.
Функциональ програмчлалын хэлийг сонгох нь санамсаргүй хэрэг биш юм. Д манай
Бид яагаад оролцохоор шийдсэн бэ?
Товчхондоо, бидний мэргэшил бол тусгай ур чадвар шаарддаг стандарт бус, нарийн төвөгтэй төслүүд бөгөөд мэдээллийн технологийн нийгэмлэгийн хувьд ихэвчлэн шинжлэх ухааны үнэ цэнэтэй байдаг. Бид нээлттэй эхийн хөгжлийг тууштай дэмжиж, түүнийг сурталчлах, мөн Оросын тэргүүлэх их дээд сургуулиудтай компьютерийн шинжлэх ухаан, математикийн чиглэлээр хамтран ажилладаг.
Тэмцээний сонирхолтой даалгавар, бидний хайртай Telegram төсөлд оролцох нь өөрөө маш сайн урам зориг байсан боловч шагналын сан нь нэмэлт урамшуулал болсон. 🙂
TON блокчейн судалгаа
Бид блокчэйн, хиймэл оюун ухаан, машин сургалтын шинэ бүтээн байгуулалтыг анхааралтай ажиглаж, ажиллаж буй салбар бүртээ нэг чухал хувилбарыг алдахгүй байхыг хичээдэг. Тиймээс тэмцээн эхлэхэд манай баг аль хэдийн санаануудыг мэддэг байсан
Тэмцээн эхлэх үед код нь аль хэдийн хэвлэгдсэн байсан тул цаг хэмнэхийн тулд бид гарын авлага эсвэл тоймыг хайж олохоор шийдсэн. хэрэглэгчид. Харамсалтай нь энэ нь ямар ч үр дүнд хүрээгүй - Ubuntu дээр платформ угсрах заавраас гадна бидэнд өөр материал олдсонгүй.
Баримт бичгийг өөрөө сайтар судалсан боловч зарим хэсэгт уншихад хэцүү байсан. Ихэнхдээ бид тодорхой цэгүүд рүү буцаж, хийсвэр санааны өндөр түвшний тайлбараас доод түвшний хэрэгжилтийн дэлгэрэнгүй мэдээлэл рүү шилжих шаардлагатай болдог.
Тодорхойлолтод хэрэгжилтийн дэлгэрэнгүй тайлбарыг огт оруулаагүй бол илүү хялбар байх болно. Виртуал машин нь стекийг хэрхэн төлөөлдөг тухай мэдээлэл нь TON платформд зориулж ухаалаг гэрээ байгуулж буй хөгжүүлэгчдэд туслахаас илүү анхаарал сарниулдаг.
Никс: төслийг нэгтгэж байна
Серокеллд бид том шүтэн бишрэгчид
Тиймээс бид бүтээж эхэлсэн
$ cd ~/.config/nixpkgs/overlays && git clone https://github.com/serokell/ton.nix
$ cd /path/to/ton/repo && nix-shell
[nix-shell]$ cmakeConfigurePhase && make
Та ямар нэгэн хамаарлыг суулгах шаардлагагүй гэдгийг анхаарна уу. Nix, та NixOS, Ubuntu эсвэл macOS ашиглаж байгаа эсэхээс үл хамааран таны төлөө бүх зүйлийг ид шидээр хийх болно.
TON-д зориулсан програмчлал
TON сүлжээн дэх ухаалаг гэрээний код нь TON Virtual Machine (TVM) дээр ажилладаг. TVM нь бусад виртуал машинуудаас илүү төвөгтэй бөгөөд маш сонирхолтой функцтэй, жишээлбэл, түүнтэй ажиллах боломжтой үргэлжлэлүүд и өгөгдөлтэй холбох.
Түүгээр ч зогсохгүй TON-ийн залуус гурван шинэ програмчлалын хэлийг бүтээжээ.
тав төстэй бүх нийтийн стек програмчлалын хэл юм
FunC -тэй төстэй ухаалаг гэрээний програмчлалын хэл юм
Тав дахь Ассемблер — TVM-д зориулсан хоёртын гүйцэтгэх код үүсгэх таван номын сан. Тавдугаар Ассемблерт хөрвүүлэгч байхгүй. Энэ
Манай уралдаан амжилттай болж байна
Эцэст нь хэлэхэд бидний хүчин чармайлтын үр дүнг харах цаг болжээ.
Асинхрон төлбөрийн суваг
Төлбөрийн суваг нь хоёр хэрэглэгчдэд блокчэйноос гадуур төлбөр илгээх боломжийг олгодог ухаалаг гэрээ юм. Үүний үр дүнд та зөвхөн мөнгө төдийгүй цаг хугацаа хэмнэнэ (дараагийн блок боловсруулагдахыг хүлээх шаардлагагүй). Төлбөр нь хүссэн хэмжээгээрээ бага, шаардлагатай давтамжтай байж болно. Энэ тохиолдолд эцсийн тооцооны шударга байдал нь ухаалаг гэрээгээр баталгаажсан тул талууд бие биедээ итгэх шаардлагагүй болно.
Бид асуудлын нэлээд энгийн шийдлийг олсон. Хоёр тал гарын үсэг зурсан мессежийг солилцож болно, тус бүр нь хоёр дугаарыг агуулсан - тал бүрийн төлсөн бүрэн хэмжээний. Энэ хоёр тоо нь адилхан ажилладаг
Үнэн хэрэгтээ энэ санааг хэрэгжүүлэхэд нэг тоо хангалттай, гэхдээ энэ нь хэрэглэгчийн интерфэйсийг илүү тохиромжтой болгохын тулд хоёуланг нь орхисон. Үүнээс гадна бид мессеж бүрт төлбөрийн хэмжээг оруулахаар шийдсэн. Үүнгүйгээр, хэрэв ямар нэг шалтгаанаар мессеж алдагдсан бол бүх дүн, эцсийн тооцоолол зөв байх боловч хэрэглэгч алдагдлыг анзаарахгүй байж магадгүй юм.
Бидний санааг шалгахын тулд бид ийм энгийн бөгөөд товч төлбөрийн сувгийн протоколыг ашиглах жишээг хайсан. Гайхалтай нь бид хоёрыг л олсон:
Тайлбар ижил төстэй арга, зөвхөн нэг чиглэлтэй сувгийн хувьд.Заавар , энэ нь биднийхтэй ижил санааг тодорхойлсон боловч ерөнхий зөв байдал, зөрчилдөөнийг шийдвэрлэх журам гэх мэт олон чухал нарийн ширийн зүйлийг тайлбарлаагүй болно.
Протоколынхоо зөв байдалд онцгой анхаарал хандуулж, нарийвчлан тайлбарлах нь ойлгомжтой болсон. Хэд хэдэн давталтын дараа техникийн үзүүлэлтүүд бэлэн болсон бөгөөд одоо та ч бас чадна.
Бид гэрээг FunC-д хэрэгжүүлсэн бөгөөд зохион байгуулагчдын зөвлөсний дагуу бид гэрээтэйгээ бүрэн харьцах командын мөрийн хэрэглүүрийг Fift дээр бичсэн. Бид CLI-дээ өөр ямар ч хэл сонгож болох байсан ч практикт хэрхэн ажиллаж байгааг харахын тулд Фитийг туршиж үзэх сонирхолтой байсан.
Үнэнийг хэлэхэд, Fift-тай ажилласны дараа бид энэ хэлийг хөгжүүлсэн хэрэгсэл, номын сан бүхий алдартай, идэвхтэй ашигладаг хэлнүүдээс илүүд үзэх ямар ч үндэслэлтэй шалтгааныг олж хараагүй. Стек дээр суурилсан хэлээр програмчлах нь маш тааламжгүй байдаг, учир нь та стек дээр байгаа зүйлийг байнга толгойдоо байлгах хэрэгтэй бөгөөд хөрвүүлэгч үүнд тус болохгүй.
Тиймээс бидний бодлоор Fift-ийн оршин тогтнох цорын ганц үндэслэл бол Fift Assembler-ийн хост хэлний үүрэг юм. Гэхдээ энэ үндсэн зорилгод зориулж шинийг зохион бүтээхийн оронд TVM ассемблерийг одоо байгаа хэл рүү оруулах нь дээр биш гэж үү?
TVM Haskell eDSL
Одоо хоёр дахь ухаалаг гэрээний талаар ярих цаг болжээ. Бид олон гарын үсэг бүхий хэтэвч боловсруулахаар шийдсэн боловч FunC дээр өөр ухаалаг гэрээ бичих нь хэтэрхий уйтгартай байх болно. Бид зарим нэг амтыг нэмэхийг хүссэн бөгөөд энэ нь бидний TVM-ийн ассемблер хэл байсан.
Fift Assembler-ийн нэгэн адил манай шинэ хэлийг суулгасан боловч бид Fift-ийн оронд Haskell-ийг хостоор сонгосон нь түүний дэвшилтэт төрлийн системийг бүрэн ашиглах боломжийг бидэнд олгосон. Ухаалаг гэрээнүүдтэй ажиллахдаа жижиг алдааны зардал маш өндөр байдаг бол бидний бодлоор статик бичих нь том давуу тал юм.
Haskell-д суулгасан TVM ассемблер ямар харагддагийг харуулахын тулд бид түүн дээр стандарт түрийвчийг хэрэгжүүлсэн. Энд анхаарах хэдэн зүйл байна:
- Энэхүү гэрээ нь нэг функцээс бүрдэх боловч та хүссэн хэмжээгээрээ ашиглах боломжтой. Та хост хэл дээр (жишээ нь Haskell) шинэ функцийг тодорхойлоход манай eDSL нь үүнийг TVM-д тусдаа горим болгох уу эсвэл дуудлага хийх цэг дээр энгийн байдлаар оруулах уу гэдгээ сонгох боломжийг танд олгоно.
- Хаскелл шиг функцууд нь хөрвүүлэх үед шалгадаг төрлүүдтэй байдаг. Манай eDSL-д функцийн оролтын төрөл нь функцийн хүлээж буй стекийн төрөл бөгөөд үр дүнгийн төрөл нь дуудлагын дараа үүсэх стекийн төрөл юм.
- Код нь тайлбартай
stacktype
, дуудлагын цэг дээр хүлээгдэж буй стекийн төрлийг дүрсэлсэн. Анхны түрийвчний гэрээнд эдгээр нь зүгээр л тайлбар байсан боловч манай eDSL-д тэдгээр нь үнэндээ кодын нэг хэсэг бөгөөд эмхэтгэх үед шалгадаг. Эдгээр нь код өөрчлөгдөж, стекийн төрөл өөрчлөгдсөн тохиолдолд хөгжүүлэгчид асуудлыг олоход туслах баримт бичиг эсвэл мэдэгдэл болж болно. Мэдээжийн хэрэг, ийм тэмдэглэгээ нь ажиллах үеийн гүйцэтгэлд нөлөөлөхгүй, учир нь тэдэнд зориулж TVM код үүсгэдэггүй. - Энэ нь хоёр долоо хоногийн дотор бичигдсэн прототип хэвээр байгаа тул төсөл дээр хийх ажил их байна. Жишээлбэл, таны доорх кодонд байгаа ангиудын бүх тохиолдлууд автоматаар үүсгэгдэх ёстой.
Манай eDSL дээр multisig түрийвчний хэрэгжилт иймэрхүү харагдаж байна.
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
Манай eDSL болон олон гарын үсгийн хэтэвчний гэрээний бүрэн эх кодыг эндээс авах боломжтой
Тэмцээний талаархи дүгнэлт, ТОН
Нийтдээ бидний ажилд 380 цаг зарцуулсан (баримт бичигтэй танилцах, уулзалт хийх, бодит боловсруулалт зэрэг). Тэмцээний төсөлд таван хөгжүүлэгч оролцсон: CTO, багийн ахлагч, блокчейн платформын мэргэжилтнүүд болон Haskell програм хангамж хөгжүүлэгчид.
Хакатон, нягт багаар ажиллах, шинэ технологийн тал дээр хурдан шимтэх хэрэгцээ үргэлж сэтгэл хөдөлгөм байдаг тул бид тэмцээнд оролцох нөөцийг ямар ч бэрхшээлгүйгээр олсон. Хязгаарлагдмал нөөцийн нөхцөлд хамгийн их үр дүнд хүрэхийн тулд хэд хэдэн нойргүй хоносон нь үнэлж баршгүй туршлага, гайхалтай дурсамжаар нөхөгддөг. Нэмж дурдахад, ийм даалгавар дээр ажиллах нь компанийн үйл явцын сайн шалгуур болдог, учир нь дотоод харилцан үйлчлэл сайн байхгүйгээр үнэхээр зохистой үр дүнд хүрэх нь туйлын хэцүү байдаг.
Дууны үгийг хажуугаар нь дурдвал: ТОН-ын багийн хийсэн ажил бидэнд маш их сэтгэгдэл төрүүлсэн. Тэд нарийн төвөгтэй, үзэсгэлэнтэй, хамгийн чухал нь ажлын системийг байгуулж чадсан. TON бол асар их боломж бүхий платформ гэдгээ баталсан. Гэсэн хэдий ч энэхүү экосистемийг хөгжүүлэхийн тулд блокчэйн төслүүдэд ашиглах, хөгжлийн хэрэгслүүдийг сайжруулах тал дээр илүү их зүйлийг хийх шаардлагатай байна. Бид одоо энэ үйл явцын нэг хэсэг болсондоо бахархаж байна.
Хэрэв энэ нийтлэлийг уншсаны дараа танд ямар нэгэн асуулт байгаа бол эсвэл TON-г ашиглан асуудлаа хэрхэн шийдвэрлэх талаар санаа байвал,
Эх сурвалж: www.habr.com