ProHoster > Блог > басқарма > Сынақ клиенті TON (Telegram Open Network) және смарт келісімшарттар үшін жаңа Fift тілі
Сынақ клиенті TON (Telegram Open Network) және смарт келісімшарттар үшін жаңа Fift тілі
Бір жылдан астам уақыт бұрын Telegram мессенджерінің орталықтандырылмаған желісін шығару жоспары туралы белгілі болды. Telegram ашық желісі. Содан кейін Николай Дуров жазған және болашақ желінің құрылымын сипаттайтын көлемді техникалық құжат қол жетімді болды. Сағынып қалғандар үшін осы құжатты қайталап оқып шығуды ұсынамын (1 бөлігі, 2 бөлігі; үшінші бөлігі, өкінішке орай, әлі күнге дейін сызбаларда шаң жинайды).
Содан бері бірнеше күн бұрын (бірінде) TON дамуының күйі туралы маңызды жаңалық болған жоқ бейресми арналар) бетке сілтеме пайда болмады https://test.ton.org/download.html, қайда орналасқан:
◦ ton-test-liteclient-full.tar.xz — TON сынақ желісі үшін жеңіл клиенттің көздері;
◦ ton-lite-client-test1.config.json — сынақ желісіне қосылуға арналған конфигурация файлы;
◦ README — клиентті құру және іске қосу туралы ақпарат;
◦ ҚАЛАЙ — клиентті пайдалана отырып смарт-келісімшарт жасау бойынша қадамдық нұсқаулар;
◦ ton.pdf — TON желісінің техникалық шолуымен жаңартылған құжат (2 жылғы 2019 наурызда);
◦ tvm.pdf — TVM техникалық сипаттамасы (TON Virtual Machine, TON virtual machine);
◦ tblkch.pdf — TON блокчейнінің техникалық сипаттамасы;
◦ fifthbase.pdf — TON-да смарт келісімшарттарды жасауға арналған жаңа Fift тілінің сипаттамасы.
Қайталап айтамын, Telegram-дан парақтың және осы құжаттардың барлығының ресми растауы болған жоқ, бірақ бұл материалдардың көлемі оларды әбден орынды етеді. Жарияланған клиентті іске қосыңыз өз тәуекеліне байланысты.
Сынақ клиентін құру
Алдымен сынақ клиентін құруға және іске қосуға тырысайық - бақытымызға орай, README бұл қарапайым процесті егжей-тегжейлі сипаттайды. Мен мұны мысал ретінде macOS 10.14.5 арқылы жасаймын; Мен басқа жүйелерде құрастырудың сәттілігіне кепілдік бере алмаймын.
Жүктеп алыңыз және қаптамадан шығарыңыз дереккөз мұрағаты. Соңғы нұсқаны жүктеп алу маңызды, өйткені бұл кезеңде кері үйлесімділікке кепілдік берілмейді.
Жүйеде make, cmake (3.0.2 немесе одан жоғары нұсқасы), OpenSSL (соның ішінде C тақырып файлдары), g++ немесе clang соңғы нұсқалары орнатылғанын тексеріңіз. Маған ештеңе орнатудың қажеті жоқ, бәрі бірден жиналды.
Дереккөздер қалтаға шығарылды делік ~/lite-client. Одан бөлек жиналған жоба үшін бос қалта жасаңыз (мысалы, ~/liteclient-build), және одан (cd ~/liteclient-build) пәрмендерді шақырыңыз:
Егер бәрі дұрыс орындалса, сіз келесідей нәрсені көруіңіз керек:
Көріп отырғанымыздай, қол жетімді командалар аз:
◦ help — осы командалар тізімін экранға шығару;
◦ quit - шығу;
◦ time — серверде ағымдағы уақытты көрсету;
◦ status — қосылымды және жергілікті дерекқор күйін көрсету;
◦ last — блокчейннің күйін жаңарту (соңғы блокты жүктеп алу). Желінің ағымдағы күйін көріп тұрғаныңызға сенімді болу үшін кез келген сұраулардан бұрын осы пәрменді іске қосу маңызды.
◦ sendfile<filename> — TON желісіне жергілікті файлды жүктеңіз. Желімен өзара әрекеттесу осылай жүзеге асады - мысалы, жаңа смарт-келісімшарттарды жасау және шоттар арасында ақша аударуға сұрау салу;
◦ getaccount<address> — ағымды көрсету (команда орындалған кезде) last) көрсетілген мекенжайы бар шоттың күйі;
◦ privkey<filename> — жергілікті файлдан жеке кілтті жүктеңіз.
Егер клиентті іске қосқан кезде, опцияны пайдаланып қалтаны оған тасымалдасаңыз -D, содан кейін ол оған мастерчейннің соңғы блогын қосады:
Енді біз қызықтырақ нәрселерге көшуге болады - Fift тілін үйреніңіз, смарт келісімшартты құрастыруға тырысыңыз (мысалы, сынақ әмиянын жасаңыз), оны желіге жүктеп салыңыз және шоттар арасында ақша аударып көріңіз.
Бесінші тіл
Құжаттан fifthbase.pdf Сіз Telegram командасының смарт келісімшарттар жасау үшін жаңа стек тілін жасағанын біле аласыз Бес (шамасы саннан бесінші, Forth тіліне ұқсас, Бесінші тілмен көп ортақ тіл).
Құжат өте көлемді, 87 беттен тұрады, мен оның мазмұнын осы мақаланың аясында егжей-тегжейлі айтып бермеймін (кем дегенде, мен оны өзім оқып бітірмегендіктен :). Мен негізгі ойларға тоқталып, осы тілде бірнеше кодтық мысалдар келтіремін.
Негізгі деңгейде Fift синтаксисі өте қарапайым: оның коды тұрады сөздер, әдетте бос орындармен немесе жол үзілімдерімен бөлінеді (ерекше жағдай: кейбір сөздер өзінен кейін бөлгішті қажет етпейді). Кез келген сөз белгілі бір мәнге сәйкес келетін таңбалардың регистрге сезімтал тізбегі болып табылады анықтау (шамамен, аудармашы бұл сөзді кездестіргенде не істеу керек). Егер сөздің анықтамасы болмаса, аудармашы оны сан ретінде талдап, стекке қоюға тырысады. Айтпақшы, мұндағы сандар – кенеттен – 257-разрядты бүтін сандар, ал бөлшек мүлде жоқ – дәлірек айтқанда, олар бірден бүтін жұпқа айналады, рационал бөлшектің алымы мен бөлімін құрайды.
Сөздер стектің жоғарғы жағындағы мәндермен әрекеттесуге бейім. Сөздердің жеке түрі - префикс — стекті емес, бастапқы файлдан кейінгі таңбаларды пайдаланады. Мысалы, жол литералдары осылай орындалады - тырнақша таңбасы (") — келесі (жабатын) тырнақшаны іздейтін және олардың арасындағы жолды стекке итеретін префикс сөзі. Бір лайнерлер де солай әрекет етеді (//) және көп жолды (/*) пікірлер.
Бұл жерде тілдің бүкіл ішкі құрылымы дерлік аяқталады. Қалғанның бәрі (басқару құрылымдарын қоса) сөздер ретінде анықталады (ішкі, мысалы, арифметикалық амалдар және жаңа сөздердің анықтамасы; немесе "стандартты кітапханада" анықталған. Fift.fif, ол қалтада орналасқан crypto/fift дереккөздерде).
Fift бағдарламасындағы қарапайым мысал:
{ dup =: x dup * =: y } : setxy
3 setxy x . y . x y + .
7 setxy x . y . x y + .
Бірінші жол жаңа сөзді анықтайды setxy (префикске назар аударыңыз {, ол жабылу алдында блок жасайды } және префикс :, ол шын мәнінде сөзді анықтайды). setxy стектің жоғарғы жағынан санды алады, оны жаһандық ретінде анықтайды (немесе қайта анықтайды). тұрақтыx, және тұрақты шама ретінде осы санның квадраты y (Тұрақтылардың мәндерін қайта анықтауға болатынын ескере отырып, мен оларды айнымалылар деп атағым келеді, бірақ мен тілдегі атау конвенциясын ұстанамын).
Келесі екі жол стекке нөмір қойып, қоңырау шалыңыз setxy, содан кейін тұрақтылардың мәндері көрсетіледі x, y (сөз шығару үшін қолданылады .), екі тұрақты да стекке орналасады, жинақталады және нәтиже де басып шығарылады. Нәтижесінде біз көреміз:
3 9 12 ok
7 49 56 ok
(«OK» жолын интербелсенді енгізу режимінде ағымдағы жолды өңдеуді аяқтаған кезде аудармашы басып шығарады)
Бұл қорқынышты файл смарт келісімшартты жасауға арналған - ол файлға орналастырылады new-wallet-query.boc орындалғаннан кейін. Назар аударыңыз, мұнда TON виртуалды машинасы үшін басқа құрастыру тілі қолданылады (мен оған егжей-тегжейлі тоқталмаймын), оның нұсқаулары блокчейнге орналастырылады.
Осылайша, TVM-ге арналған ассемблер Fift-та жазылған - бұл ассемблердің көздері файлда crypto/fift/Asm.fif және жоғарыдағы код бөлігінің басында қосылған.
Не айта аламын, Николай Дуров жаңа бағдарламалау тілдерін жасауды жақсы көреді :)
Ақылды келісім-шарт жасау және TON-пен әрекеттесу
Сонымен, біз жоғарыда сипатталғандай TON клиенті мен Fift аудармашысын жинап, тілмен таныс болдық делік. Қазір смарт келісімшартты қалай жасауға болады? Бұл файлда сипатталған ҚАЛАЙ, дереккөздерге қоса беріледі.
ТОНдағы шоттар
Мен сипаттағандай TON шолуы, бұл желіде біреуден көп блокчейн бар - бір жалпы деп аталатын бар. «басты тізбек», сондай-ақ 32-биттік нөмірмен анықталған қосымша «жұмыс тізбектерінің» ерікті саны. Мастер тізбегінде -1 идентификаторы бар, оған қосымша 0 идентификаторы бар «негізгі» жұмыс тізбегі де пайдаланылуы мүмкін.Әр жұмыс тізбегінің өз конфигурациясы болуы мүмкін. Ішінде әрбір жұмыс тізбегі shardchains бөлінеді, бірақ бұл есте сақтауды қажет етпейтін іске асыру детальдары.
Бір жұмыс тізбегінде өздерінің account_id идентификаторлары бар көптеген тіркелгілер сақталады. Негізгі тізбек және нөлдік жұмыс тізбегі үшін олардың ұзындығы 256 бит. Осылайша, тіркелгі идентификаторы, мысалы, келесідей жазылады:
Бұл «шикі» пішім: алдымен жұмыс тізбегі идентификаторы, содан кейін қос нүкте және он алтылық белгілеудегі тіркелгі идентификаторы.
Сонымен қатар, қысқартылған пішім бар - жұмыс тізбегінің нөмірі мен тіркелгі мекенжайы екілік пішінде кодталған, оларға бақылау сомасы қосылады және мұның бәрі Base64-те кодталған:
Ef+BVndbeTJeXWLnQtm5bDC2UVpc0vH2TF2ksZPAPwcODSkb
Бұл жазба пішімін біле отырып, пәрменді пайдаланып сынақ клиенті арқылы тіркелгінің ағымдағы күйін сұрай аламыз
[ 3][t 2][1558746708.815218925][test-lite-client.cpp:631][!testnode] requesting account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D
[ 3][t 2][1558746708.858564138][test-lite-client.cpp:652][!testnode] got account state for -1:8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D with respect to blocks (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F and (-1,8000000000000000,72355):F566005749C1B97F18EDE013EBA7A054B9014961BC1AD91F475B9082919A2296:1BD5DE54333164025EE39D389ECE2E93DA2871DA616D488253953E52B50DC03F
account state is (account
addr:(addr_std
anycast:nothing workchain_id:-1 address:x8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D)
storage_stat:(storage_info
used:(storage_used
cells:(var_uint len:1 value:3)
bits:(var_uint len:2 value:539)
public_cells:(var_uint len:0 value:0)) last_paid:0
due_payment:nothing)
storage:(account_storage last_trans_lt:74208000003
balance:(currencies
grams:(nanograms
amount:(var_uint len:7 value:999928362430000))
other:(extra_currencies
dict:hme_empty))
state:(account_active
(
split_depth:nothing
special:nothing
code:(just
value:(raw@^Cell
x{}
x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54}
))
data:(just
value:(raw@^Cell
x{}
x{0000000D}
))
library:hme_empty))))
x{CFF8156775B79325E5D62E742D9B96C30B6515A5CD2F1F64C5DA4B193C03F070E0D2068086C000000000000000451C90E00DC0E35B7DB5FB8C134_}
x{FF0020DDA4F260D31F01ED44D0D31FD166BAF2A1F80001D307D4D1821804A817C80073FB0201FB00A4C8CB1FC9ED54}
x{0000000D}
Біз көрсетілген жұмыс тізбегінің DHT-де сақталған құрылымды көреміз. Мысалы, далада storage.balance ағымдағы шоттың сальдосы, д storage.state.code - смарт келісімшарт коды және storage.state.data - оның ағымдағы деректері. TON деректер қоймасы - Ұяшық, ұяшықтар - ағаш тәрізді, әрбір ұяшықта өзінің деректері де, еншілес ұяшықтары да болуы мүмкін екенін ескеріңіз. Бұл соңғы жолдарда шегініс ретінде көрсетіледі.
Ақылды келісімшарт құру
Енді осындай құрылымды өзіміз жасайық (ол BOC деп аталады - жасушалар қапшығы) Fift тілін пайдалану. Бақытымызға орай, смарт келісімшартты өзіңіз жазудың қажеті жоқ - қалтада crypto/block бастапқы мұрағаттағы файл бар new-wallet.fif, бұл бізге жаңа әмиян жасауға көмектеседі. Оны жиналған клиент бар қалтаға көшірейік (~/liteclient-build, жоғарыдағы нұсқауларды орындасаңыз). Мен оның мазмұнын Fift-тегі кодтың мысалы ретінде келтірдім.
Бұл <source-directory> орамадан шығарылған көздерге жолмен ауыстырылуы керек («~» таңбасы, өкінішке орай, мұнда пайдалану мүмкін емес, толық жол қажет). Кілтті пайдаланудың орнына -I ортаның айнымалы мәнін анықтауға болады FIFTPATH және оған осы жолды қойыңыз.
Файл атауымен Fift-ті іске қосқаннан бері new-wallet.fif, ол оны орындайды және шығады. Егер файл атауын қалдырсаңыз, интерпретатормен интерактивті түрде ойнай аласыз.
Орындаудан кейін консольде келесідей нәрсе көрсетілуі керек:
StateInit: x{34_}
x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54}
x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B}
new wallet address = -1 : 4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2
0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ
signing message: x{00000000}
External message for initialization is x{89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001_}
x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54}
x{0000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B}
B5EE9C724104030100000000D60002CF89FEE120E20C7E953E31546F64C23CD654002C1AA919ADD24DB12DDF85C6F3B58AE41198A28AD8DAF3B9588E7A629252BA3DB88F030D00BC1016110B2073359EAC3C13823C53245B65D056F2C070B940CDA09789585935C7ABA4D2AD4BED139281CFA1200000001001020084FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED5400480000000055375F730EDC2292E8CB15C42E8036EE9C25AA958EE002D2DE48A205E3A3426B6290698B
(Saved to file new-wallet-query.boc)
Бұл ID бар әмиян дегенді білдіреді -1:4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2 (немесе, не бірдей, 0f9PzVILj8yglrVn1zS-NSjtxr7QBfaTCp7JrBqnFPIR8nhZ) сәтті құрылды. Сәйкес код файлда болады new-wallet-query.boc, оның мекен-жайы бар new-wallet.addr, және жеке кілт ішінде new-wallet.pk (сақ болыңыз – сценарийді қайта іске қосу бұл файлдарды қайта жазады).
Әрине, TON желісі бұл әмиян туралы әлі білмейді, ол тек осы файлдар түрінде сақталады. Енді оны желіге жүктеп салу керек. Дегенмен, мәселе мынада, ақылды келісімшарт жасау үшін комиссия төлеу керек, ал сіздің шотыңыздағы теңгерім әлі де нөлге тең.
Жұмыс режимінде бұл мәселе биржадан грамм сатып алу (немесе басқа әмияннан аудару) арқылы шешіледі. Ағымдағы сынақ режимінде арнайы смарт келісім-шарт жасалды, одан сіз дәл осылай 20 грамға дейін сұрай аласыз.
Басқа біреудің смарт келісімшартына сұрау жасау
Біз граммдарды солға және оңға тарататын смарт келісімшартқа сұраныс жасаймыз. Сол қалтада crypto/block файлды табыңыз testgiver.fif:
// "testgiver.addr" file>B 256 B>u@
0x8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
dup constant wallet_addr ."Test giver address = " x. cr
0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2
constant dest_addr
-1 constant wc
0x00000011 constant seqno
1000000000 constant Gram
{ Gram swap */ } : Gram*/
6.666 Gram*/ constant amount
// b x --> b' ( serializes a Gram amount )
{ -1 { 1+ 2dup 8 * ufits } until
rot over 4 u, -rot 8 * u, } : Gram,
// create a message (NB: 01b00.., b = bounce)
<b b{010000100} s, wc 8 i, dest_addr 256 u, amount Gram, 0 9 64 32 + + 1+ 1+ u, "GIFT" $, b>
<b seqno 32 u, 1 8 u, swap ref, b>
dup ."enveloping message: " <s csr. cr
<b b{1000100} s, wc 8 i, wallet_addr 256 u, 0 Gram, b{00} s,
swap <s s, b>
dup ."resulting external message: " <s csr. cr
2 boc+>B dup Bx. cr
"wallet-query.boc" B>file
Біз оны жиналған клиентпен қалтаға сақтаймыз, бірақ біз бесінші жолды түзетеміз - жолдың алдында «constant dest_addr«. Оны бұрын жасаған әмиянның мекенжайымен ауыстырайық (толық, қысқартылған емес). Басында «-1:» деп жазудың қажеті жоқ, оның орнына «0x» басына қойыңыз.
Сондай-ақ сызықты өзгертуге болады 6.666 Gram*/ constant amount — бұл сіз сұрап отырған грамдағы сома (20-дан аспайды). Тіпті бүтін санды көрсетсеңіз де, ондық үтірді қалдырыңыз.
Соңында сызықты түзету керек 0x00000011 constant seqno. Мұндағы бірінші сан – грамды беру шотында сақталатын ағымдағы реттік нөмір. Мен оны қайдан аламын? Жоғарыда айтылғандай, клиентті іске қосыңыз және іске қосыңыз:
last
getaccount -1:8156775b79325e5d62e742d9b96c30b6515a5cd2f1f64c5da4b193c03f070e0d
0000000D саны (сіздікі үлкенірек болады) реттік нөмірге ауыстырылуы керек. testgiver.fif.
Міне, файлды сақтаңыз және іске қосыңыз (./crypto/fift testgiver.fif). Шығару файл болады wallet-query.boc. Бұл қалыптасады хабарлама басқа біреудің ақылды келісім-шартына - «сонша граммды осындай және осындай шотқа аудару» сұрауы.
Клиентті пайдаланып, оны желіге жүктейміз:
> sendfile wallet-query.boc
[ 1][t 1][1558747399.456575155][test-lite-client.cpp:577][!testnode] sending query from file wallet-query.boc
[ 3][t 2][1558747399.500236034][test-lite-client.cpp:587][!query] external message status is 1
Қазір қоңырау шалсаңыз last, содан кейін біз грамм сұраған шоттың күйін қайтадан сұраймыз, содан кейін оның реттік нөмірі біреуге көбейгенін көруіміз керек - бұл оның біздің шотымызға ақша жібергенін білдіреді.
Соңғы қадам қалады - әмиянымыздың кодын жүктеп алыңыз (оның балансы әлдеқашан толтырылған, бірақ смарт келісімшарт коды болмаса, біз оны басқара алмаймыз). орындаймыз sendfile new-wallet-query.boc - және міне, сіздің TON желісінде жеке әмияныңыз бар (тіпті бұл тек сынақ болса да).
Шығыс транзакцияларды құру
Құрылған шоттағы теңгерімнен ақша аудару үшін файл бар crypto/block/wallet.fif, ол да жиналған клиенті бар қалтаға орналастырылуы керек.
Алдыңғы қадамдарға ұқсас, сіз аударатын соманы, алушының мекенжайын (dest_addr) және әмияныңыздың секносын реттеуіңіз керек (әмиянды инициализациялаудан кейін ол 1-ге тең және әрбір шығыс транзакциядан кейін 1-ге артады - сіз тіркелгіңіздің күйін сұрау арқылы қараңыз). Тесттер үшін сіз, мысалы, менің әмиянымды пайдалана аласыз - 0x4fcd520b8fcca096b567d734be3528edc6bed005f6930a9ec9ac1aa714f211f2.
Іске қосу кезінде (./crypto/fift wallet.fif) сценарий әмияныңыздың мекенжайын (сіз тасымалдайтын жерден) және оның жеке кілтін файлдардан алады new-wallet.addr и new-wallet.pk, және қабылданған хабарлама келесіге жазылады new-wallet-query.boc.
Бұрынғыдай транзакцияны тікелей орындау үшін қоңырау шалыңыз sendfile new-wallet-query.boc клиентте. Осыдан кейін блокчейннің күйін жаңартуды ұмытпаңыз (last) және әмиянымыздың балансы мен секносының өзгергенін тексеріңіз (getaccount <account_id>).
Барлығы, енді біз TON-да ақылды келісімшарттар жасай аламыз және оларға сұраныс жібере аламыз. Көріп отырғаныңыздай, ағымдағы функционалдылық, мысалы, графикалық интерфейсі бар анағұрлым ыңғайлы әмиян жасау үшін жеткілікті (бірақ ол мессенджердің бір бөлігі ретінде қол жетімді болады деп күтілуде).
Сауалнамаға тек тіркелген пайдаланушылар қатыса алады. Кіру, өтінемін.
Сіз TON, TVM, Fift талдауларымен мақалаларды жалғастырғыңыз келе ме?
Иә, мен TON туралы жалпы шолу бар мақалалар сериясының аяқталуын күтемін
Иә, Fift тілі туралы көбірек оқу қызықты
Иә, мен TON виртуалды машинасы және оның ассемблері туралы көбірек білгім келеді
Жоқ, мұның ешқайсысы қызық емес
39 пайдаланушы дауыс берді. 12 пайдаланушы қалыс қалды.
Telegram-тың TON-ды іске қосу жоспарлары туралы не ойлайсыз?
Бұл жобадан үлкен үміт күтемін
Мен оның дамуын қызығушылықпен бақылап жүрмін.
Мен оның сәттілігіне күмәнданамын және күмәнданамын.
Мен бұл бастаманы сәтсіз және қалың бұқараға қажет емес деп санаймын
47 пайдаланушы дауыс берді. 12 пайдаланушы қалыс қалды.