Um hvernig á að skrifa og birta snjallsamning í Telegram Open Network (TON)

Um hvernig á að skrifa og birta snjallsamning í TON

Um hvað fjallar þessi grein?

Í greininni mun ég tala um hvernig ég tók þátt í fyrstu (af tveimur) Telegram blockchain keppninni, fékk ekki verðlaun og ákvað að skrá reynslu mína í grein svo hún sökkvi ekki í gleymskunnar dá og ef til vill hjálpa einhvern.

Þar sem ég vildi ekki skrifa ágripskóða, heldur til að gera eitthvað sem virkar, skrifaði ég fyrir greinina snjallsamning um skyndilottó og vefsíðu sem sýnir snjallsamningsgögn beint frá TON án þess að nota milligeymslu.

Greinin mun nýtast þeim sem vilja gera sinn fyrsta snjalla samning í TON, en vita ekki hvar á að byrja.

Með því að nota happdrættið sem dæmi mun ég fara frá því að setja upp umhverfið yfir í að gefa út snjallsamning, hafa samskipti við hann og skrifa vefsíðu til að taka á móti og birta gögn.

Um þátttöku í keppninni

Í október síðastliðnum tilkynnti Telegram blockchain samkeppni með nýjum tungumálum Fift и FunC. Það var nauðsynlegt að velja úr því að skrifa einhvern af fimm fyrirhuguðum snjöllum samningum. Ég hélt að það væri gaman að gera eitthvað öðruvísi, læra tungumál og búa til eitthvað, jafnvel þótt ég þurfi ekki að skrifa neitt annað í framtíðinni. Auk þess er efnið stöðugt á vörum.

Það er þess virði að segja að ég hafði enga reynslu af því að þróa snjalla samninga.

Ég ætlaði að taka þátt allt til enda þar til ég gæti og skrifa svo yfirlitsgrein, en ég mistókst strax í þeirri fyrstu. ég skrifaði veski með fjölundirskrift á FunC og það virkaði almennt. Ég tók það til grundvallar snjall samningur um Solidity.

Á þeim tíma hélt ég að þetta væri örugglega nóg til að ná að minnsta kosti einhverjum verðlaunasæti. Fyrir vikið urðu um 40 af 60 þátttakendum verðlaunahafar og ég var ekki á meðal þeirra. Almennt séð er ekkert að þessu, en eitt truflaði mig. Þegar niðurstöðurnar voru kynntar var ekki búið að fara yfir prófið fyrir samninginn minn, ég spurði þátttakendur í spjallinu hvort það væri einhver annar sem væri ekki með það, það var enginn.

Eins og gefur að skilja eftir skilaboðum mínum, tveimur dögum síðar birtu dómararnir athugasemd og ég skil ekki enn hvort þeir hafi óvart misst af snjöllum samningi mínum við dómgæsluna eða einfaldlega haldið að það væri svo slæmt að það þyrfti ekki athugasemd. Ég spurði spurningar á síðunni, en fékk ekki svar. Þó að það sé ekkert leyndarmál hver dæmdi taldi ég óþarfi að skrifa persónuleg skilaboð.

Mikill tími fór í skilning og því var ákveðið að skrifa grein. Þar sem það er ekki mikið af upplýsingum ennþá, mun þessi grein hjálpa til við að spara tíma fyrir alla sem hafa áhuga.

Hugmyndin um snjalla samninga í TON

Áður en þú skrifar eitthvað þarftu að finna út frá hvaða hlið þú átt að nálgast þetta. Þess vegna mun ég nú segja þér hvaða hlutar kerfið samanstendur af. Nánar tiltekið, hvaða hlutar þú þarft að vita til að skrifa að minnsta kosti einhvers konar vinnusamning.

Við munum leggja áherslu á að skrifa klár samning og vinna með TON Virtual Machine (TVM), Fift и FunC, þannig að greinin er meira eins og lýsing á þróun venjulegs forrits. Við munum ekki dvelja við hvernig pallurinn sjálfur virkar hér.

Almennt um hvernig það virkar TVM og tungumál Fift það eru góð opinber skjöl. Þegar ég tók þátt í keppninni og núna á meðan ég skrifaði núverandi samning, leitaði ég oft til hennar.

Aðaltungumálið sem snjallsamningar eru skrifaðir á er FunC. Það eru engin skjöl um það í augnablikinu, svo til að skrifa eitthvað þarftu að kynna þér dæmi um snjalla samninga úr opinberu geymslunni og innleiðingu tungumálsins sjálfs þar, auk þess sem þú getur skoðað dæmi um snjalla samninga frá síðustu tveimur keppnum. Tenglar í lok greinarinnar.

Segjum að við höfum þegar skrifað klár samning um FunC, eftir það tökum við kóðann saman í Fift assembler.

Á eftir að birta hinn samantekna snjallsamning. Til að gera þetta þarftu að skrifa fall í Fift, sem mun taka snjallsamningskóðann og nokkrar aðrar breytur sem inntak, og úttakið verður skrá með endingunni .boc (sem þýðir „poka af frumum“), og, eftir því hvernig við skrifum það, einkalykill og heimilisfang, sem er búið til byggt á snjallsamningskóðanum. Þú getur nú þegar sent grömm á heimilisfang snjallsamnings sem hefur ekki enn verið birt.

Til að birta snjallsamning í TON móttekinn .boc skráin verður að senda til blockchain með því að nota léttan viðskiptavin (meira um það hér að neðan). En áður en þú birtir þarftu að flytja grömm á myndað heimilisfang, annars verður snjallsamningurinn ekki birtur. Eftir birtingu geturðu haft samskipti við snjallsamninginn með því að senda honum skilaboð að utan (til dæmis með því að nota léttan viðskiptavin) eða innan frá (td einn snjallsamningur sendir öðrum skilaboð innan TON).

Þegar við skiljum hvernig kóðinn er birtur verður það auðveldara. Við vitum nokkurn veginn hvað við viljum skrifa og hvernig forritið okkar mun virka. Og á meðan við skrifum, leitum við að því hvernig þetta er þegar innleitt í núverandi snjallsamningum, eða við skoðum innleiðingarkóðann Fift и FunC í opinberu geymslunni, eða skoðaðu opinberu skjölin.

Mjög oft leitaði ég að leitarorðum í Telegram spjallinu þar sem allir þátttakendur keppninnar og starfsmenn Telegram komu saman og það kom fyrir að á meðan á keppninni stóð söfnuðust allir saman þar og fóru að ræða Fift og FunC. Linkur í lok greinarinnar.

Það er kominn tími til að færa sig frá kenningu til framkvæmda.

Undirbúa umhverfið fyrir að vinna með TON

Ég gerði allt sem lýst verður í greininni um MacOS og tvítékkaði það í hreinu Ubuntu 18.04 LTS á Docker.

Það fyrsta sem þú þarft að gera er að hlaða niður og setja upp lite-client sem þú getur sent beiðnir með til TON.

Leiðbeiningarnar á opinberu vefsíðunni lýsa uppsetningarferlinu nokkuð ítarlega og skýrt og sleppa nokkrum smáatriðum. Hér fylgjum við leiðbeiningunum og setjum upp ósjálfstæðin sem vantar á leiðinni. Ég tók ekki saman hvert verkefni sjálfur og setti upp frá opinberu Ubuntu geymslunni (á MacOS sem ég notaði brew).

apt -y install git 
apt -y install wget 
apt -y install cmake 
apt -y install g++ 
apt -y install zlib1g-dev 
apt -y install libssl-dev 

Þegar öll ósjálfstæði eru sett upp geturðu sett upp lite-client, Fift, FunC.

Í fyrsta lagi klónum við TON geymsluna ásamt ósjálfstæði hennar. Til hægðarauka munum við gera allt í möppu ~/TON.

cd ~/TON
git clone https://github.com/ton-blockchain/ton.git
cd ./ton
git submodule update --init --recursive

Geymslan geymir einnig útfærslur Fift и FunC.

Nú erum við tilbúin að setja saman verkefnið. Geymslukóði er klónaður í möppu ~/TON/ton. Í ~/TON búa til möppu build og safna verkefninu í það.

mkdir ~/TON/build 
cd ~/TON/build
cmake ../ton

Þar sem við ætlum að skrifa klár samning, þurfum við ekki aðeins lite-clientEn Fift с FunC, svo við skulum setja allt saman. Þetta er ekki fljótlegt ferli, svo við bíðum.

cmake --build . --target lite-client
cmake --build . --target fift
cmake --build . --target func

Næst skaltu hlaða niður stillingarskránni sem inniheldur gögn um hnútinn sem lite-client mun tengjast.

wget https://test.ton.org/ton-lite-client-test1.config.json

Gerir fyrstu beiðnirnar til TON

Nú skulum við ræsa lite-client.

cd ~/TON/build
./lite-client/lite-client -C ton-lite-client-test1.config.json

Ef byggingin heppnaðist, þá muntu sjá skrá yfir tengingu ljósbiðlarans við hnútinn eftir ræsingu.

[ 1][t 2][1582054822.963129282][lite-client.h:201][!testnode]   conn ready
[ 2][t 2][1582054823.085654020][lite-client.cpp:277][!testnode] server version is 1.1, capabilities 7
[ 3][t 2][1582054823.085725069][lite-client.cpp:286][!testnode] server time is 1582054823 (delta 0)
...

Þú getur keyrt skipunina help og sjáðu hvaða skipanir eru tiltækar.

help

Við skulum skrá skipanirnar sem við munum nota í þessari grein.

list of available commands:
last    Get last block and state info from server
sendfile <filename> Load a serialized message from <filename> and send it to server
getaccount <addr> [<block-id-ext>]  Loads the most recent state of specified account; <addr> is in [<workchain>:]<hex-or-base64-addr> format
runmethod <addr> [<block-id-ext>] <method-id> <params>...   Runs GET method <method-id> of account <addr> with specified parameters

last получает последний созданный блок с сервера. 

sendfile <filename> отправляет в TON файл с сообщением, именно с помощью этой команды публикуется смарт-контракт и запрсосы к нему. 

getaccount <addr> загружает текущее состояние смарт-контракта с указанным адресом. 

runmethod <addr> [<block-id-ext>] <method-id> <params>  запускает get-методы смартконтракта. 

Nú erum við tilbúin að skrifa samninginn sjálfan.

Framkvæmd

Hugmynd

Eins og ég skrifaði hér að ofan er snjallsamningurinn sem við erum að skrifa happdrætti.

Þar að auki er þetta ekki happdrætti þar sem þú þarft að kaupa miða og bíða í klukkutíma, dag eða mánuð, heldur augnablik þar sem notandinn flytur á samningsfangið. N grömm, og fær það samstundis til baka 2 * N grömm eða tapar. Við munum gera líkurnar á að vinna um það bil 40%. Ef það eru ekki næg grömm fyrir greiðslu, þá munum við líta á viðskiptin sem áfyllingu.

Þar að auki er mikilvægt að hægt sé að sjá veðmál í rauntíma og á þægilegu formi, svo að notandinn geti strax skilið hvort hann vann eða tapaði. Þess vegna þarftu að búa til vefsíðu sem sýnir veðmál og niðurstöður beint frá TON.

Að skrifa klár samning

Til hægðarauka hef ég auðkennt kóðann fyrir FunC, viðbótina er hægt að finna og setja upp í Visual Studio Code leitinni, ef þú vilt allt í einu bæta einhverju við hef ég gert viðbótina aðgengilega almenningi. Einnig, einhver gerði áður viðbót til að vinna með Fift, þú getur líka sett það upp og fundið það í VSC.

Við skulum strax búa til geymslu þar sem við munum skuldbinda milliniðurstöðurnar.

Til að gera líf okkar auðveldara munum við skrifa snjallsamning og prófa hann á staðnum þar til hann er tilbúinn. Aðeins eftir það munum við birta það í TON.

Snjallsamningurinn hefur tvær ytri aðferðir sem hægt er að nálgast. Í fyrsta lagi, recv_external() þessi aðgerð er framkvæmd þegar beiðni um samninginn kemur frá umheiminum, það er til dæmis ekki frá TON, þegar við sjálf búum til skilaboð og sendum þau í gegnum smáviðskiptavininn. Í öðru lagi, recv_internal() þetta er þegar, innan TON sjálfs, hver samningur vísar til okkar. Í báðum tilfellum er hægt að senda færibreytur til aðgerðarinnar.

Við skulum byrja á einföldu dæmi sem mun virka ef það er birt, en það er ekkert hagnýtt álag í því.

() recv_internal(slice in_msg) impure {
    ;; TODO: implementation 
}

() recv_external(slice in_msg) impure {
    ;; TODO: implementation  
}

Hér þurfum við að útskýra hvað það er slice. Öll gögn sem geymd eru í TON Blockchain eru safn TVM cell eða einfaldlega cell, í slíkum hólf er hægt að geyma allt að 1023 bita af gögnum og allt að 4 tengla á aðrar frumur.

TVM cell slice eða slice þetta er hluti af því sem fyrir er cell er notað til að flokka það, það kemur í ljós síðar. Aðalatriðið fyrir okkur er að við getum flutt slice og fer eftir tegund skilaboða, vinna úr gögnunum í recv_external() eða recv_internal().

impure — lykilorð sem gefur til kynna að aðgerðin breyti snjallsamningsgögnum.

Við skulum vista samningskóðann í lottery-code.fc og taka saman.

~/TON/build/crypto/func -APSR -o lottery-compiled.fif ~/TON/ton/crypto/smartcont/stdlib.fc ./lottery-code.fc 

Hægt er að skoða merkingu fánanna með skipuninni

~/TON/build/crypto/func -help

Við höfum tekið saman Fift assembler kóða í lottery-compiled.fif:

// lottery-compiled.fif

"Asm.fif" include
// automatically generated from `/Users/rajymbekkapisev/TON/ton/crypto/smartcont/stdlib.fc` `./lottery-code.fc` 
PROGRAM{
  DECLPROC recv_internal
  DECLPROC recv_external
  recv_internal PROC:<{
    //  in_msg
    DROP    // 
  }>
  recv_external PROC:<{
    //  in_msg
    DROP    // 
  }>
}END>c

Það er hægt að hleypa af stokkunum á staðnum, fyrir þetta munum við undirbúa umhverfið.

Athugið að fyrsta línan tengist Asm.fif, þetta er kóði skrifaður í Fift fyrir Fift assembler.

Þar sem við viljum keyra og prófa snjallsamninginn á staðnum munum við búa til skrá lottery-test-suite.fif og afritaðu samantekna kóðann þangað, komdu í stað síðustu línunnar í honum, sem skrifar snjallsamningskóðann í fasta codetil að flytja það síðan yfir á sýndarvélina:

"TonUtil.fif" include
"Asm.fif" include

PROGRAM{
  DECLPROC recv_internal
  DECLPROC recv_external
  recv_internal PROC:<{
    //  in_msg
    DROP    // 
  }>
  recv_external PROC:<{
    //  in_msg
    DROP    // 
  }>
}END>s constant code

Svo langt virðist það vera ljóst, nú skulum við bæta við sömu skrá kóðanum sem við munum nota til að ræsa TVM.

0 tuple 0x076ef1ea , // magic
0 , 0 , // actions msg_sents
1570998536 , // unix_time
1 , 1 , 3 , // block_lt, trans_lt, rand_seed
0 tuple 100000000000000 , dictnew , , // remaining balance
0 , dictnew , // contract_address, global_config
1 tuple // wrap to another tuple
constant c7

0 constant recv_internal // to run recv_internal() 
-1 constant recv_external // to invoke recv_external()

В c7 við skráum samhengið, það er gögnin sem TVM (eða netkerfi) verður ræst með. Jafnvel meðan á keppninni stóð sýndi einn verktaki hvernig á að búa til c7 og ég afritaði. Í þessari grein gætum við þurft að breyta rand_seed þar sem gerð slembitölu er háð henni og ef henni er ekki breytt verður sama númerið skilað í hvert skipti.

recv_internal и recv_external fastar með gildin 0 og -1 munu bera ábyrgð á að kalla samsvarandi aðgerðir í snjallsamningnum.

Nú erum við tilbúin að búa til fyrsta prófið fyrir tóma snjalla samninginn okkar. Til glöggvunar, í bili munum við bæta öllum prófunum við sömu skrána lottery-test-suite.fif.

Við skulum búa til breytu storage og skrifa tómt inn í það cell, þetta verður snjalla samningsgeymslan.

message Þetta eru skilaboðin sem við munum senda til snjalla tengiliðsins utan frá. Við munum líka gera það tómt í bili.

variable storage 
<b b> storage ! 

variable message 
<b b> message ! 

Eftir að við höfum undirbúið fastana og breyturnar, ræsum við TVM með því að nota skipunina runvmctx og sendu búnar breytur til inntaksins.

message @ 
recv_external 
code 
storage @ 
c7 
runvmctx 

Á endanum munum við ná árangri svoleiðis millikóði fyrir Fift.

Nú getum við keyrt kóðann sem myndast.

export FIFTPATH=~/TON/ton/crypto/fift/lib // выполняем один раз для удобства 
~/TON/build/crypto/fift -s lottery-test-suite.fif 

Forritið ætti að keyra án villna og í úttakinu munum við sjá framkvæmdaskrána:

execute SETCP 0
execute DICTPUSHCONST 19 (xC_,1)
execute DICTIGETJMPZ
execute DROP
execute implicit RET
[ 3][t 0][1582281699.325381279][vm.cpp:479]     steps: 5 gas: used=304, max=9223372036854775807, limit=9223372036854775807, credit=0

Frábært, við höfum skrifað fyrstu vinnuútgáfuna af snjallsamningnum.

Nú þurfum við að bæta við virkni. Fyrst skulum við takast á við skilaboð sem koma frá umheiminum til recv_external()

Framkvæmdaraðili velur sjálfur skilaboðaformið sem samningurinn getur samþykkt.

En venjulega

  • Í fyrsta lagi viljum við vernda samning okkar fyrir umheiminum og gera það þannig að aðeins eigandi samningsins geti sent utanaðkomandi skilaboð til hans.
  • í öðru lagi, þegar við sendum gild skilaboð til TON viljum við að þetta gerist nákvæmlega einu sinni og þegar við sendum sömu skilaboðin aftur þá hafnar snjallsamningurinn því.

Þannig að næstum sérhver samningur leysir þessi tvö vandamál, þar sem samningur okkar tekur við ytri skilaboðum, við þurfum að sjá um það líka.

Við gerum það í öfugri röð. Fyrst skulum við leysa vandamálið með endurtekningu; ef samningurinn hefur þegar fengið slík skilaboð og unnið úr þeim mun hann ekki framkvæma hann í annað sinn. Og þá munum við leysa vandamálið þannig að aðeins ákveðinn hópur fólks geti sent skilaboð til snjallsamningsins.

Það eru mismunandi leiðir til að leysa vandamálið með tvíteknum skilaboðum. Svona gerum við það. Í snjallsamningnum frumstillum við teljara móttekinna skeyta með upphafsgildinu 0. Í hverju skeyti við snjallsamninginn munum við bæta við núverandi teljaragildi. Ef teljaragildið í skilaboðunum passar ekki við gildið í snjallsamningnum, þá vinnum við það ekki; ef það gerir það, þá vinnum við það og hækkum teljarann ​​í snjallsamningnum um 1.

Snúum okkur aftur að lottery-test-suite.fif og bæta öðru prófi við það. Ef við sendum rangt númer ætti kóðinn að gefa undantekningu. Til dæmis, láttu samningsgögnin geyma 166 og við sendum 165.

<b 166 32 u, b> storage !
<b 165 32 u, b> message !

message @ 
recv_external 
code 
storage @ 
c7 
runvmctx

drop 
exit_code ! 
."Exit code " exit_code @ . cr 
exit_code @ 33 - abort"Test #2 Not passed"

Við skulum ræsa.

 ~/TON/build/crypto/fift -s lottery-test-suite.fif 

Og við munum sjá að prófið er keyrt með villu.

[ 1][t 0][1582283084.210902214][words.cpp:3046] lottery-test-suite.fif:67: abort": Test #2 Not passed
[ 1][t 0][1582283084.210941076][fift-main.cpp:196]      Error interpreting file `lottery-test-suite.fif`: error interpreting included file `lottery-test-suite.fif` : lottery-test-suite.fif:67: abort": Test #2 Not passed

Á þessu stigi lottery-test-suite.fif ætti að líta út по ссылке.

Nú skulum við bæta gagnrökfræðinni við snjallsamninginn í lottery-code.fc.

() recv_internal(slice in_msg) impure {
    ;; TODO: implementation 
}

() recv_external(slice in_msg) impure {
    if (slice_empty?(in_msg)) {
        return (); 
    }
    int msg_seqno = in_msg~load_uint(32);
    var ds = begin_parse(get_data());
    int stored_seqno = ds~load_uint(32);
    throw_unless(33, msg_seqno == stored_seqno);
}

В slice in_msg liggja skilaboðin sem við sendum.

Það fyrsta sem við gerum er að athuga hvort skilaboðin innihalda gögn, ef ekki, þá hættum við einfaldlega.

Næst greinum við skilaboðin. in_msg~load_uint(32) hleður númerinu 165, 32-bita unsigned int frá sendum skilaboðum.

Næst hleðum við 32 bita úr snjallsamningsgeymslunni. Við athugum hvort hlaðna númerið passi við það sem hefur verið samþykkt; ef ekki, þá hendum við undanþágu. Í okkar tilviki, þar sem við erum að fara framhjá óleik, ætti að henda undanþágu.

Nú skulum við setja saman.

~/TON/build/crypto/func -APSR -o lottery-compiled.fif ~/TON/ton/crypto/smartcont/stdlib.fc ./lottery-code.fc 

Afritaðu kóðann sem myndast til lottery-test-suite.fif, ekki gleyma að skipta út síðustu línunni.

Við athugum hvort prófið standist:

~/TON/build/crypto/fift -s lottery-test-suite.fif

Hérna Þú getur séð samsvarandi skuldbindingu með núverandi niðurstöðum.

Athugaðu að það er óþægilegt að afrita stöðugt samansafnaðan kóða snjallsamnings inn í skrá með prófunum, þannig að við munum skrifa skriftu sem skrifar kóðann í fasta fyrir okkur, og við munum einfaldlega tengja saman kóðann við prófin okkar með því að nota "include".

Búðu til skrá í verkefnamöppunni build.sh með eftirfarandi efni.

#!/bin/bash

~/TON/build/crypto/func -SPA -R -o lottery-compiled.fif ~/TON/ton/crypto/smartcont/stdlib.fc ./lottery-code.fc

Gerum það keyranlegt.

chmod +x ./build.sh

Nú skaltu bara keyra handritið okkar til að setja saman samninginn. En fyrir utan þetta þurfum við að skrifa það í fasta code. Svo við munum búa til nýja skrá lotter-compiled-for-test.fif, sem við munum hafa með í skránni lottery-test-suite.fif.

Við skulum bæta skirpt kóða við sh, sem mun einfaldlega afrita samansettu skrána inn lotter-compiled-for-test.fif og breyttu síðustu línunni í henni.

# copy and change for test 
cp lottery-compiled.fif lottery-compiled-for-test.fif
sed '$d' lottery-compiled-for-test.fif > test.fif
rm lottery-compiled-for-test.fif
mv test.fif lottery-compiled-for-test.fif
echo -n "}END>s constant code" >> lottery-compiled-for-test.fif

Nú, til að athuga, skulum keyra handritið sem myndast og skrá verður búin til lottery-compiled-for-test.fif, sem við munum taka inn í okkar lottery-test-suite.fif

В lottery-test-suite.fif eyða samningskóðanum og bæta við línunni "lottery-compiled-for-test.fif" include.

Við keyrum próf til að athuga hvort þau standist.

~/TON/build/crypto/fift -s lottery-test-suite.fif

Frábært, til að gera sjálfvirkan ræsingu prófana skulum við búa til skrá test.sh, sem mun fyrst framkvæma build.sh, og keyrðu síðan prófin.

touch test.sh
chmod +x test.sh

Við skrifum inni

./build.sh 

echo "nCompilation completedn"

export FIFTPATH=~/TON/ton/crypto/fift/lib
~/TON/build/crypto/fift -s lottery-test-suite.fif

Gerum það test.sh og keyrðu það til að ganga úr skugga um að prófin virki.

chmod +x ./test.sh
./test.sh

Við athugum hvort samningurinn sé settur saman og prófin séu framkvæmd.

Frábært, núna í gangsetningu test.sh Prófin verða tekin saman og keyrð strax. Hér er tengill á skuldbinda sig.

Allt í lagi, áður en við höldum áfram skulum við gera eitt enn til hægðarauka.

Við skulum búa til möppu build þar sem við munum geyma afritaða samninginn og klón hans skrifaða í fasta lottery-compiled.fif, lottery-compiled-for-test.fif. Við skulum líka búa til möppu test hvar verður prófunarskráin geymd? lottery-test-suite.fif og hugsanlega aðrar stuðningsskrár. Tengill á viðeigandi breytingar.

Höldum áfram að þróa snjallsamninginn.

Næst á að fara í próf sem athugar hvort skilaboðin berist og teljarinn er uppfærður í versluninni þegar við sendum rétt númer. En við gerum það seinna.

Nú skulum við hugsa um hvaða gagnaskipulag og hvaða gögn þarf að geyma í snjallsamningnum.

Ég mun lýsa öllu sem við geymum.

`seqno` 32-х битное целое положительное число счетчик. 

`pubkey` 256-ти битное целое положительное число публичный ключ, с помощью которого, мы будем проверять подпись отправленного извне сообщения, о чем ниже. 

`order_seqno` 32-х битное целое положительное число хранит счетчик количества ставок. 

`number_of_wins` 32-х битное целое положительное число хранит  количество побед. 

`incoming_amount` тип данных Gram (первые 4 бита отвечает за длину), хранит общее количество грамов, которые были отправлены на контртакт. 

`outgoing_amount` общее количество грамов, которое было отправлено победителям. 

`owner_wc` номер воркчейна, 32-х битное (в некоторых местах написано, что 8-ми битное) целое число. В данный момент всего два -1 и 0. 

`owner_account_id` 256-ти битное целое положительное число, адрес контракта в текущем воркчейне. 

`orders` переменная типа словарь, хранит последние двадцать ставок. 

Næst þarftu að skrifa tvær aðgerðir. Við skulum hringja í fyrsta pack_state(), sem mun pakka gögnunum til síðari vistunar í snjallsamningsgeymslunni. Við skulum kalla annað unpack_state() mun lesa og skila gögnum úr geymslu.

_ pack_state(int seqno, int pubkey, int order_seqno, int number_of_wins, int incoming_amount, int outgoing_amount, int owner_wc, int owner_account_id, cell orders) inline_ref {
    return begin_cell()
            .store_uint(seqno, 32)
            .store_uint(pubkey, 256)
            .store_uint(order_seqno, 32)
            .store_uint(number_of_wins, 32)
            .store_grams(incoming_amount)
            .store_grams(outgoing_amount)
            .store_int(owner_wc, 32)
            .store_uint(owner_account_id, 256)
            .store_dict(orders)
            .end_cell();
}

_ unpack_state() inline_ref {
    var ds = begin_parse(get_data());
    var unpacked = (ds~load_uint(32), ds~load_uint(256), ds~load_uint(32), ds~load_uint(32), ds~load_grams(), ds~load_grams(), ds~load_int(32), ds~load_uint(256), ds~load_dict());
    ds.end_parse();
    return unpacked;
}

Við bætum þessum tveimur aðgerðum við upphaf snjallsamningsins. Það mun ganga eftir svoleiðis milliniðurstaða.

Til að vista gögn þarftu að hringja í innbyggðu aðgerðina set_data() og það mun skrifa gögn frá pack_state() í snjallsamningsgeymslunni.

cell packed_state = pack_state(arg_1, .., arg_n); 
set_data(packed_state);

Nú þegar við höfum þægilegar aðgerðir til að skrifa og lesa gögn getum við haldið áfram.

Við þurfum að athuga hvort skilaboðin sem berast að utan séu undirrituð af eiganda samningsins (eða öðrum notanda sem hefur aðgang að einkalyklinum).

Þegar við birtum snjallsamning getum við frumstillt hann með þeim gögnum sem við þurfum í geymslu, sem verða vistuð til notkunar í framtíðinni. Við munum taka upp opinbera lykilinn þar svo við getum staðfest að skilaboðin sem berast hafi verið undirrituð með tilheyrandi einkalykli.

Áður en haldið er áfram skulum við búa til einkalykil og skrifa hann til test/keys/owner.pk. Til að gera þetta skulum við ræsa Fift í gagnvirkum ham og framkvæma fjórar skipanir.

`newkeypair` генерация публичного и приватного ключа и запись их в стек. 

`drop` удаления из стека верхнего элемента (в данном случае публичный ключ)  

`.s` просто посмотреть что лежит в стеке в данный момент 

`"owner.pk" B>file` запись приватного ключа в файл с именем `owner.pk`. 

`bye` завершает работу с Fift. 

Við skulum búa til möppu keys inni í möppunni test og skrifaðu einkalykilinn þar.

mkdir test/keys
cd test/keys
~/TON/build/crypto/fift -i 
newkeypair
 ok
.s 
BYTES:128DB222CEB6CF5722021C3F21D4DF391CE6D5F70C874097E28D06FCE9FD6917 BYTES:DD0A81AAF5C07AAAA0C7772BB274E494E93BB0123AA1B29ECE7D42AE45184128 
drop 
 ok
"owner.pk" B>file
 ok
bye

Við sjáum skrá í núverandi möppu owner.pk.

Við fjarlægjum almenna lykilinn úr staflanum og þegar þörf krefur getum við fengið hann úr einkalyklinum.

Nú þurfum við að skrifa undirskriftarstaðfestingu. Byrjum á prófinu. Fyrst lesum við einkalykilinn úr skránni með því að nota aðgerðina file>B og skrifa það í breytu owner_private_key, og notaðu síðan aðgerðina priv>pub breyttu einkalyklinum í opinberan lykil og skrifaðu niðurstöðuna inn owner_public_key.

variable owner_private_key
variable owner_public_key 

"./keys/owner.pk" file>B owner_private_key !
owner_private_key @ priv>pub owner_public_key !

Við þurfum báða lyklana.

Við frumstillum snjallsamningsgeymsluna með handahófskenndum gögnum í sömu röð og í aðgerðinni pack_state()og skrifa það í breytu storage.

variable owner_private_key
variable owner_public_key 
variable orders
variable owner_wc
variable owner_account_id

"./keys/owner.pk" file>B owner_private_key !
owner_private_key @ priv>pub owner_public_key !
dictnew orders !
0 owner_wc !
0 owner_account_id !

<b 0 32 u, owner_public_key @ B, 0 32 u, 0 32 u, 0 Gram, 0 Gram, owner_wc @ 32 i, owner_account_id @ 256 u,  orders @ dict, b> storage !

Næst munum við semja undirritað skilaboð, það mun aðeins innihalda undirskriftina og teljaragildið.

Fyrst búum við til gögnin sem við viljum senda, síðan undirritum við þau með einkalykli og að lokum búum við til undirrituð skilaboð.

variable message_to_sign
variable message_to_send
variable signature
<b 0 32 u, b> message_to_sign !
message_to_sign @ hashu owner_private_key @ ed25519_sign_uint signature !
<b signature @ B, 0 32 u, b> <s  message_to_send !  

Fyrir vikið eru skilaboðin sem við sendum til snjallsamningsins skráð í breytu message_to_send, um aðgerðir hashu, ed25519_sign_uint þú getur lesið í Fift skjölunum.

Og til að keyra prófið köllum við aftur.

message_to_send @ 
recv_external 
code 
storage @
c7
runvmctx

Hér svo Skráin með prófunum ætti að líta svona út á þessu stigi.

Við skulum keyra prófið og það mun mistakast, svo við breytum snjallsamningnum þannig að hann geti tekið á móti skilaboðum á þessu sniði og staðfest undirskriftina.

Fyrst teljum við 512 bita af undirskriftinni úr skilaboðunum og skrifum hana í breytu, síðan teljum við 32 bita af teljarabreytunni.

Þar sem við höfum aðgerð til að lesa gögn úr snjallsamningsgeymslunni munum við nota það.

Næst er að athuga teljarann ​​sem fluttur er með geymslunni og athuga undirskriftina. Ef eitthvað passar ekki, þá hentum við undantekningu með viðeigandi kóða.

var signature = in_msg~load_bits(512);
var message = in_msg;
int msg_seqno = message~load_uint(32);
(int stored_seqno, int pubkey, int order_seqno, int number_of_wins, int incoming_amount, int outgoing_amount, int owner_wc, int owner_account_id, cell orders) = unpack_state();
throw_unless(33, msg_seqno == stored_seqno);
throw_unless(34, check_signature(slice_hash(in_msg), signature, pubkey));

Viðeigandi skuldbinding hér.

Við skulum keyra prófin og sjá til að annað prófið mistekst. Af tveimur ástæðum eru ekki nógu margir bitar í skilaboðunum og ekki nógu margir bitar í geymslunni, þannig að kóðinn hrynur við þáttun. Við þurfum að bæta undirskrift við skilaboðin sem við erum að senda og afrita geymsluna frá síðustu prófun.

Í öðru prófinu munum við bæta við skilaboðaundirskrift og breyta snjallsamningsgeymslunni. Hér svo skráin með prófunum lítur út eins og í augnablikinu.

Skrifum fjórða prófið, þar sem við munum senda skilaboð undirrituð með einkalykli einhvers annars. Búum til annan einkalykil og vistum hann í skrá not-owner.pk. Við munum skrifa undir skilaboðin með þessum einkalykli. Við skulum keyra prófin og ganga úr skugga um að öll próf standist. Skuldbinda sig á þessari stundu.

Nú getum við loksins haldið áfram að innleiða snjallsamningsrökfræðina.
В recv_external() við munum samþykkja tvenns konar skilaboð.

Þar sem samningur okkar mun safna tapi leikmanna verður að flytja þessa peninga til skapara lottósins. Veskis heimilisfang höfundar lottósins er skráð í geymslunni þegar samningurinn er gerður.

Bara í tilfelli, við þurfum getu til að breyta heimilisfanginu sem við sendum grömm af þeim sem tapa. Við ættum líka að geta sent grömm úr lottóinu á heimilisfang eigandans.

Byrjum á því fyrsta. Við skulum fyrst skrifa próf sem mun athuga að eftir að skilaboðin hafa verið send hafi snjallsamningurinn vistað nýja heimilisfangið í geymslunni. Vinsamlegast athugið að í skilaboðunum sendum við einnig, auk afgreiðsluborðsins og nýja heimilisfangsins action 7 bita heiltala óneikvæð tala, eftir því, munum við velja hvernig á að vinna úr skilaboðunum í snjallsamningnum.

<b 0 32 u, 1 @ 7 u, new_owner_wc @  32 i, new_owner_account_id @ 256 u, b> message_to_sign !

Í prófinu er hægt að sjá hvernig snjallsamningsgeymsla er afserialized storage í Fift. Afserialization breytu er lýst í Fift skjölunum.

Skuldbinding hlekkur með bættu deigi.

Við skulum keyra prófið og ganga úr skugga um að það mistekst. Nú skulum við bæta við rökfræði til að breyta heimilisfangi lottóeiganda.

Í snjallsamningnum höldum við áfram að flokka message, lesið inn action. Minnum á að við verðum með tvö action: breyta heimilisfangi og senda grömm.

Síðan lesum við nýtt heimilisfang samningseiganda og vistum það í geymslu.
Við keyrum prófin og sjáum að þriðja prófið mistekst. Það hrynur vegna þess að samningurinn greinir nú að auki 7 bita úr skilaboðunum, sem vantar í prófið. Bættu einhverju sem ekki er til við skilaboðin action. Við skulum keyra prófin og sjá til að allt standist. Тут skuldbinda sig til breytinga. Frábært.

Nú skulum við skrifa rökfræðina fyrir að senda tilgreindan fjölda gramma á áður vistað heimilisfang.

Fyrst skulum við skrifa próf. Við munum skrifa tvö próf, annað þegar það er ekki nóg jafnvægi, annað þegar allt ætti að standast. Hægt er að skoða próf í þessari skuldbindingu.

Nú skulum við bæta kóðanum við. Fyrst skulum við skrifa tvær hjálparaðferðir. Fyrsta fá aðferðin er að finna út núverandi stöðu snjallsamnings.

int balance() inline_ref method_id {
    return get_balance().pair_first();
}

Og sá seinni er til að senda grömm í annan klár samning. Ég afritaði þessa aðferð algjörlega úr öðrum snjöllum samningi.

() send_grams(int wc, int addr, int grams) impure {
    ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 011000
    cell msg = begin_cell()
    ;;  .store_uint(0, 1) ;; 0 <= format indicator int_msg_info$0 
    ;;  .store_uint(1, 1) ;; 1 <= ihr disabled
    ;;  .store_uint(1, 1) ;; 1 <= bounce = true
    ;;  .store_uint(0, 1) ;; 0 <= bounced = false
    ;;  .store_uint(4, 5)  ;; 00100 <= address flags, anycast = false, 8-bit workchain
        .store_uint (196, 9)
        .store_int(wc, 8)
        .store_uint(addr, 256)
        .store_grams(grams)
        .store_uint(0, 107) ;; 106 zeroes +  0 as an indicator that there is no cell with the data.
        .end_cell(); 
    send_raw_message(msg, 3); ;; mode, 2 for ignoring errors, 1 for sender pays fees, 64 for returning inbound message value
}

Bætum þessum tveimur aðferðum við snjallsamninginn og skrifum rökfræðina. Í fyrsta lagi greinum við fjölda gramma úr skilaboðunum. Næst könnum við jafnvægið, ef það er ekki nóg kastum við undanþágu. Ef allt er í lagi, þá sendum við grömm á vistað heimilisfang og uppfærum teljarann.

int amount_to_send = message~load_grams();
throw_if(36, amount_to_send + 500000000 > balance());
accept_message();
send_grams(owner_wc, owner_account_id, amount_to_send);
set_data(pack_state(stored_seqno + 1, pubkey, order_seqno, number_of_wins, incoming_amount, outgoing_amount, owner_wc, owner_account_id, orders));

Hér svo lítur út eins og snjall samningurinn í augnablikinu. Við skulum keyra prófin og ganga úr skugga um að þau standist.

Við the vegur, þóknun er dregin frá snjallsamningnum í hvert skipti fyrir unnin skilaboð. Til þess að snjallsamningsskilaboðin geti framkvæmt beiðnina þarftu að hringja eftir grunnathuganir accept_message().

Nú skulum við halda áfram að innri skilaboðum. Reyndar tökum við bara við grömm og sendum tvöfalda upphæð til baka til leikmannsins ef hann vinnur og þriðjung til eigandans ef hann tapar.

Fyrst skulum við skrifa einfalt próf. Til að gera þetta þurfum við prófunarvistfang snjallsamningsins sem við sendum grömm frá í snjallsamninginn.

Snjallsamningsvistfangið samanstendur af tveimur tölum, 32 bita heiltölu sem ber ábyrgð á vinnukeðjunni og 256 bita óneikvæðri heiltölu einstakt reikningsnúmer í þessari vinnukeðju. Til dæmis, -1 og 12345, þetta er heimilisfangið sem við munum vista í skrá.

Ég afritaði aðgerðina til að vista heimilisfangið frá TonUtil.fif.

// ( wc addr fname -- )  Save address to file in 36-byte format
{ -rot 256 u>B swap 32 i>B B+ swap B>file } : save-address

Við skulum skoða hvernig aðgerðin virkar, þetta mun gefa skilning á því hvernig Fift virkar. Ræstu Fift í gagnvirkum ham.

~/TON/build/crypto/fift -i 

Fyrst ýtum við -1, 12345 og nafni framtíðarskrárinnar "sender.addr" á staflan:

-1 12345 "sender.addr" 

Næsta skref er að framkvæma aðgerðina -rot, sem færir staflann á þann hátt að efst í bunkanum er einstakt snjallsamningsnúmer:

"sender.addr" -1 12345

256 u>B breytir 256 bita óneikvæðri heiltölu í bæti.

"sender.addr" -1 BYTES:0000000000000000000000000000000000000000000000000000000000003039

swap skiptir um tvo efstu þætti stafla.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 -1

32 i>B breytir 32 bita heiltölu í bæti.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 BYTES:FFFFFFFF

B+ tengir tvær raðir af bætum.

 "sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF

Aftur swap.

BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF "sender.addr" 

Og að lokum eru bætin skrifuð í skrána B>file. Eftir þetta er stafla okkar tómur. Við hættum Fift. Skrá hefur verið búin til í núverandi möppu sender.addr. Við skulum færa skrána í möppuna sem búið var til test/addresses/.

Skrifum einfalt próf sem mun senda grömm í snjallsamning. Hér er skuldbindingin.

Nú skulum við líta á rökfræði lottósins.

Það fyrsta sem við gerum er að athuga skilaboðin bounced eða ekki ef bounced, þá hunsum við það. bounced þýðir að samningurinn skilar grömmum ef einhver villa kemur upp. Við munum ekki skila grömmum ef villa kemur skyndilega upp.

Við athugum, ef staðan er undir hálfu grammi, þá samþykkjum við einfaldlega skilaboðin og hunsum þau.

Næst greinum við heimilisfang snjallsamningsins sem skilaboðin komu frá.

Við lesum gögnin úr geymslunni og eyðum síðan gömlum veðmálum úr sögunni ef þau eru fleiri en tuttugu. Til hægðarauka skrifaði ég þrjár viðbótaraðgerðir pack_order(), unpack_order(), remove_old_orders().

Næst skoðum við hvort staðan dugar ekki fyrir greiðslunni, þá lítum við svo á að þetta sé ekki veðmál heldur áfylling og vistum áfyllinguna í orders.

Þá loksins kjarninn í snjallsamningnum.

Í fyrsta lagi, ef leikmaður tapar, vistum við það í veðmálasögunni og ef upphæðin er meira en 3 grömm sendum við 1/3 til eiganda snjallsamningsins.

Ef spilarinn vinnur sendum við tvöfalda upphæðina á heimilisfang leikmannsins og vistum síðan upplýsingarnar um veðmálið í sögunni.

() recv_internal(int order_amount, cell in_msg_cell, slice in_msg) impure {
    var cs = in_msg_cell.begin_parse();
    int flags = cs~load_uint(4);  ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool
    if (flags & 1) { ;; ignore bounced
        return ();
    }
    if (order_amount < 500000000) { ;; just receive grams without changing state 
        return ();
    }
    slice src_addr_slice = cs~load_msg_addr();
    (int src_wc, int src_addr) = parse_std_addr(src_addr_slice);
    (int stored_seqno, int pubkey, int order_seqno, int number_of_wins, int incoming_amount, int outgoing_amount, int owner_wc, int owner_account_id, cell orders) = unpack_state();
    orders = remove_old_orders(orders, order_seqno);
    if (balance() < 2 * order_amount + 500000000) { ;; not enough grams to pay the bet back, so this is re-fill
        builder order = pack_order(order_seqno, 1, now(), order_amount, src_wc, src_addr);
        orders~udict_set_builder(32, order_seqno, order);
        set_data(pack_state(stored_seqno, pubkey, order_seqno + 1, number_of_wins, incoming_amount + order_amount, outgoing_amount, owner_wc, owner_account_id, orders));
        return ();
    }
    if (rand(10) >= 4) {
        builder order = pack_order(order_seqno, 3, now(), order_amount, src_wc, src_addr);
        orders~udict_set_builder(32, order_seqno, order);
        set_data(pack_state(stored_seqno, pubkey, order_seqno + 1, number_of_wins, incoming_amount + order_amount, outgoing_amount, owner_wc, owner_account_id, orders));
        if (order_amount > 3000000000) {
            send_grams(owner_wc, owner_account_id, order_amount / 3);
        }
        return ();
    }
    send_grams(src_wc, src_addr, 2 * order_amount);
    builder order = pack_order(order_seqno, 2, now(), order_amount, src_wc, src_addr);
    orders~udict_set_builder(32, order_seqno, order);
    set_data(pack_state(stored_seqno, pubkey, order_seqno + 1, number_of_wins + 1, incoming_amount, outgoing_amount + 2 * order_amount, owner_wc, owner_account_id, orders));
}

Það er það. Samsvarandi skuldbinding.

Nú er allt sem eftir er einfalt, við skulum búa til get-aðferðir svo að við getum fengið upplýsingar um stöðu samningsins frá umheiminum (reyndar lesið gögnin úr snjallsamningsgeymslu þeirra).

Við skulum bæta við get-aðferðum. Við munum skrifa hér að neðan um hvernig á að fá upplýsingar um snjallsamning.

Ég gleymdi líka að bæta við kóðanum sem mun vinna úr fyrstu beiðninni sem kemur upp þegar snjallsamningur er birtur. Samsvarandi skuldbinding. Og lengra leiðrétt villu með því að senda 1/3 af upphæðinni á reikning eigandans.

Næsta skref er að birta snjallsamninginn. Við skulum búa til möppu requests.

Ég tók útgáfukóðann til grundvallar simple-wallet-code.fc который getur fundið í opinberu geymslunni.

Eitthvað sem vert er að gefa gaum. Við búum til snjalla samningsgeymslu og inntaksskilaboð. Eftir þetta er heimilisfang snjallsamningsins myndað, það er að segja heimilisfangið er þekkt jafnvel fyrir birtingu í TON. Næst þarftu að senda nokkur grömm á þetta heimilisfang, og aðeins eftir það þarftu að senda skrá með snjallsamningnum sjálfum, þar sem netið tekur þóknun fyrir að geyma snjallsamninginn og aðgerðirnar í honum (staðfestingar sem geyma og framkvæma snjall samningar). Kóðann má skoða hér.

Næst keyrum við útgáfukóðann og fáum lottery-query.boc snjall samningsskrá og heimilisfang.

~/TON/build/crypto/fift -s requests/new-lottery.fif 0

Ekki gleyma að vista myndaðar skrár: lottery-query.boc, lottery.addr, lottery.pk.

Meðal annars munum við sjá heimilisfang snjallsamningsins í framkvæmdaskrám.

new wallet address = 0:044910149dbeaf8eadbb2b28722e7d6a2dc6e264ec2f1d9bebd6fb209079bc2a 
(Saving address to file lottery.addr)
Non-bounceable address (for init): 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd
Bounceable address (for later access): kQAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8KpFY

Til gamans skulum við leggja fram beiðni til TON

$ ./lite-client/lite-client -C ton-lite-client-test1.config.json 
getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Og við munum sjá að reikningurinn með þessu heimilisfangi er tómur.

account state is empty

Við sendum á heimilisfangið 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd 2 grömm og eftir nokkrar sekúndur framkvæmum við sömu skipunina. Til að senda grömm nota ég opinbert veski, og þú getur beðið einhvern úr spjallinu um prófgrömm, sem ég mun tala um í lok greinarinnar.

> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Lítur út eins og óuppstillt (state:account_uninit) snjallsamningur með sama heimilisfangi og eftirstöðvar upp á 1 nanógrömm.

account state is (account
  addr:(addr_std
    anycast:nothing workchain_id:0 address:x044910149DBEAF8EADBB2B28722E7D6A2DC6E264EC2F1D9BEBD6FB209079BC2A)
  storage_stat:(storage_info
    used:(storage_used
      cells:(var_uint len:1 value:1)
      bits:(var_uint len:1 value:103)
      public_cells:(var_uint len:0 value:0)) last_paid:1583257959
    due_payment:nothing)
  storage:(account_storage last_trans_lt:3825478000002
    balance:(currencies
      grams:(nanograms
        amount:(var_uint len:4 value:2000000000))
      other:(extra_currencies
        dict:hme_empty))
    state:account_uninit))
x{C00044910149DBEAF8EADBB2B28722E7D6A2DC6E264EC2F1D9BEBD6FB209079BC2A20259C2F2F4CB3800000DEAC10776091DCD650004_}
last transaction lt = 3825478000001 hash = B043616AE016682699477FFF01E6E903878CDFD6846042BA1BFC64775E7AC6C4
account balance is 2000000000ng

Nú skulum við birta snjallsamninginn. Við skulum ræsa Lite-client og keyra.

> sendfile lottery-query.boc
[ 1][t 2][1583008371.631410122][lite-client.cpp:966][!testnode] sending query from file lottery-query.boc
[ 3][t 1][1583008371.828550100][lite-client.cpp:976][!query]    external message status is 1 

Athugum hvort samningurinn hafi verið birtur.

> last
> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Við fáum meðal annars.

  storage:(account_storage last_trans_lt:3825499000002
    balance:(currencies
      grams:(nanograms
        amount:(var_uint len:4 value:1987150999))
      other:(extra_currencies
        dict:hme_empty))
    state:(account_active

Við sjáum það account_active.

Samsvarandi skuldbinding með breytingum hér.

Nú skulum við búa til beiðnir um að hafa samskipti við snjallsamninginn.

Nánar tiltekið munum við skilja það fyrsta eftir til að breyta heimilisfanginu sem sjálfstætt verk, og við munum gera það síðara til að senda grömm á heimilisfang eigandans. Reyndar þurfum við að gera það sama og í prófinu til að senda grömm.

Þetta eru skilaboðin sem við munum senda til snjallsamningsins, þar sem msg_seqno 165, action 2 og 9.5 grömm til sendingar.

<b 165 32 u, 2 7 u, 9500000000 Gram, b>

Ekki gleyma að skrifa undir skilaboðin með einkalyklinum þínum lottery.pk, sem var búið til áður þegar snjallsamningurinn var búinn til. Hér er samsvarandi skuldbinding.

Að fá upplýsingar frá snjallsamningi með get aðferðum

Nú skulum við líta á hvernig á að keyra snjallsamninga aðferðir.

Sjósetja lite-client og keyrðu get-aðferðirnar sem við skrifuðum.

$ ./lite-client/lite-client -C ton-lite-client-test1.config.json
> runmethod 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd balance
arguments:  [ 104128 ] 
result:  [ 64633878952 ] 
...

В result inniheldur gildið sem fallið skilar balance() frá snjallsamningnum okkar.
Við munum gera það sama fyrir nokkrar fleiri aðferðir.

> runmethod 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd get_seqno
...
arguments:  [ 77871 ] 
result:  [ 1 ] 

Við skulum biðja um veðmálsferil þinn.

> runmethod 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd get_orders
...
arguments:  [ 67442 ] 
result:  [ ([0 1 1583258284 10000000000 0 74649920601963823558742197308127565167945016780694342660493511643532213172308] [1 3 1583258347 4000000000 0 74649920601963823558742197308127565167945016780694342660493511643532213172308] [2 1 1583259901 50000000000 0 74649920601963823558742197308127565167945016780694342660493511643532213172308]) ] 

Við munum nota Lite-client og fá aðferðir til að birta upplýsingar um snjallsamninginn á síðunni.

Sýnir snjöll samningsgögn á vefsíðunni

Ég skrifaði einfalda vefsíðu í Python til að birta gögnin úr snjallsamningnum á þægilegan hátt. Hér ætla ég ekki að fjölyrða um það í smáatriðum og mun birta síðuna í einni skuldbindingu.

Beiðnir til TON eru gerðar frá Python með hjálpinni lite-client. Til þæginda er síðan pakkað í Docker og birt á Google Cloud. Tengill.

Reynir

Nú skulum við reyna að senda grömm þangað til áfyllingar frá veski. Sendum 40 grömm. Og við skulum gera nokkur veðmál til skýrleika. Við sjáum að síðan sýnir sögu veðmála, núverandi vinningshlutfall og aðrar gagnlegar upplýsingar.

Við sjáumað við unnum þann fyrsta, töpuðum þeim síðari.

Eftirsögn

Greinin reyndist vera miklu lengri en ég bjóst við, kannski hefði hún mátt vera styttri, eða kannski bara fyrir manneskju sem veit ekkert um TON og vill skrifa og gefa út ekki svo einfaldan snjallsamning með getu til að hafa samskipti við það. Kannski hefði mátt útskýra sumt á einfaldari hátt.

Kannski hefði mátt gera suma þætti útfærslunnar á skilvirkari og glæsilegri hátt, en þá hefði tekið enn lengri tíma að undirbúa greinina. Það er líka mögulegt að ég hafi gert mistök einhvers staðar eða ekki skilið eitthvað, þannig að ef þú ert að gera eitthvað alvarlegt þarftu að treysta á opinberu skjölin eða opinberu geymsluna með TON kóðanum.

Það skal tekið fram að þar sem TON sjálft er enn á virku þróunarstigi geta breytingar átt sér stað sem munu brjóta eitthvað af skrefunum í þessari grein (sem gerðist á meðan ég var að skrifa, það hefur þegar verið leiðrétt), en almenn nálgun er ólíklegt að breytast.

Ég ætla ekki að tala um framtíð TON. Kannski verður pallurinn eitthvað stórt og við ættum að eyða tíma í að kynna okkur hann og fylla sess með vörum okkar núna.

Það er líka Vog frá Facebook, sem hefur hugsanlega áhorfendur notenda stærri en TON. Ég veit nánast ekkert um Vog, af spjallborðinu að dæma er miklu meiri virkni þar en í TON samfélaginu. Þó að verktaki og samfélag TON séu meira eins og neðanjarðar, sem er líka flott.

tilvísanir

  1. Opinber TON skjöl: https://test.ton.org
  2. Opinber TON geymsla: https://github.com/ton-blockchain/ton
  3. Opinbert veski fyrir mismunandi vettvang: https://wallet.ton.org
  4. Snjöll samningsgeymsla úr þessari grein: https://github.com/raiym/astonished
  5. Tengill á vefsíðu snjallsamninga: https://ton-lottery.appspot.com
  6. Geymsla fyrir viðbótina fyrir Visual Studio Code for FunC: https://github.com/raiym/func-visual-studio-plugin
  7. Spjallaðu um TON í Telegram, sem hjálpaði virkilega til að komast að því á upphafsstigi. Ég held að það verði ekki mistök ef ég segi að allir sem skrifuðu eitthvað fyrir TON séu þarna. Þar er líka hægt að biðja um prófgrömm. https://t.me/tondev_ru
  8. Annað spjall um TON þar sem ég fann gagnlegar upplýsingar: https://t.me/TONgramDev
  9. Fyrsta stig keppninnar: https://contest.com/blockchain
  10. Annað stig keppninnar: https://contest.com/blockchain-2

Heimild: www.habr.com

Bæta við athugasemd