Kuidas kirjutada ja avaldada nutileping Telegram Open Networkis (TON)

Kuidas kirjutada ja avaldada tarkvaralepingut TON-is

Millest on see artikkel?

Artiklis kirjeldan, kuidas osalesin esimeses (kahest) Telegrami plokiahela konkursist, ei saanud auhinnalist kohta ja otsustasin oma kogemuse kirja panna, et see ei jÀÀks unustusse ning vÔib-olla aitaks kedagi.

Kuna ma ei tahtnud kirjutada abstraktset koodi, vaid teha midagi töötavat, siis kirjutasin artikli jaoks tarkvaralepingu kiirlotoga ja veebisaidi, mis nÀitab tarkvaralepingu andmeid otse TON-ist ilma vahepealsete salvestuskohtadeta.

Artikkel on kasulik neile, kes soovivad luua oma esimest tarkvaralepingut TON-is, kuid ei tea, kust alustada.

Lotode nÀitel lÀhenen keskkonna seadistamisest tarkvaralepingu avaldamiseni, suhtlemisest selle kaudu ning kirjutan veebisaidi andmete saamiseks ja avaldamiseks.

Osalemine konkursil

Möödunud aasta oktoobris kuulutas Telegram vĂ€lja uute keeltega plokiahela konkursi Fift ja FunC. Pidi valida valida teha ĂŒkskĂ”ik milline viiest ettepanekust nutilepingust. Arvasin, et oleks tore tegeleda millegagi ebatavalisega, Ă”ppida keelt ja midagi teha, isegi kui tulevikus ei pea ma enam midagi kirjutama. Lisaks, teema on pidevalt pĂ€evakorras.

Tuleb öelda, et mul ei olnud nutilepingute arenduseks kogemust.

EesmĂ€rk oli osaleda kuni lĂ”puni, niikaua kui see Ă”nnestub, ja pĂ€rast kirjutada ĂŒlevaateartikkel, kuid kukkusin kohe esimesel katsel lĂ€bi. Ma kirjutasin rahakoti multisigallkirjadega FunC ja see töötas ĂŒldiselt. Aluseks vĂ”tsin nutilepingut Soliditys.

Sel hetkel arvasin, et seda on kindlasti piisavalt, et saada vĂ€hemalt mĂ”ni auhind. Kokku said umbes 40 60 osalejast auhindadele ja mina ei olnud nende seas. Üldiselt pole selles midagi hullu, aga mind hĂ€iris ĂŒks asi. Tulemuste vĂ€ljakuulutamise hetkel ei olnud minu lepingule tehtud ĂŒlevaadet koos testiga, kĂŒsisin osalejatelt vestlusruumis, kas keegi teine on ka, kellel seda pole, neid ei olnud.

Ilmselt pani tĂ€hele minu sĂ”numeid, sest kahe pĂ€eva pĂ€rast avaldas kohtunik kommentaari, ning ma ei saanud aru, kas nad juhuslikult jĂ€tsid mu nutilepingust mööda vĂ”i arvasid lihtsalt, et see on nii halb, et kommentaari ei vajagi. KĂŒsimuse esitasin lehe peal, aga vastust ei saanud. Kuigi kes kohtustas - ei ole saladus, isiklikke sĂ”numeid pidin liigseks.

Aega arusaamiseks on kulutatud piisavalt, seega otsustati kirjutada artikkel. Kuna teavet pole hetkel eriti palju, aitab artikkel kÔigil huvilistel aega kokku hoida.

Nutilepingute kontseptsioon TON-is

Enne kui midagi kirjutama hakata, tuleb aru saada, mis poolelt antud asjale lĂ€heneda. Seega rÀÀgin nĂŒĂŒd, millistest osadest sĂŒsteem koosneb. TĂ€psemalt, milliseid osi on vaja teada, et kirjutada vĂ€hemalt mingi toimiv leping.

Keskendume nutilepingute kirjutamisele ja TON Virtual Machine (TVM), Fift ja FunC, seega sarnaneb artikkel pigem tavalise programmi arenduse kirjeldusega. Kuidas platvorm iseenesest töötab, sellele ei jÀÀme peatuma.

Üldiselt, kuidas TVM ja keel töötab Fift on hea ametlik dokumentatsioon. Konkursil osalemise ajal ja praegu, kui kirjutatakse kĂ€esolevat lepingut, olen ma sageli sellele viidanud.

Peamine keel, milles nutilepingud on kirjutatud — FunC. Hetkel selle kohta ei ole dokumentatsiooni, seetĂ”ttu tuleb midagi kirjutamiseks uurida nutilepingute nĂ€iteid ametlikust hoidlast ja seal olevaid keele realiseeringuid, lisaks vĂ”ib vaadata nutilepingute nĂ€iteid kahest eelnevast konkursist. Lingid artikli lĂ”pus.

Oletame, et oleme juba kirjutanud nutilepingu FunC, seejÀrel kompileerime koodi Fift-assembleri.

Kompileeritud nutileping jÀÀb avaldamiseks. Selleks tuleb kirjutada funktsioon Fift, mis vÔtab sisendiks nutilepingu koodi ja mÔned muud parameetrid ning vÀljundiks on fail laiendiga .boc (mis tÀhendab "bag of cells"), ja olenevalt sellest, kuidas me kirjutame, privaatvÔti ja aadress, mis genereeritakse nutilepingu koodi alusel. Nutilepingu aadressile, mida veel ei ole avaldatud, on juba vÔimalik saata gramme.

Nutilepingu avaldamiseks TON-is saadud .boc Fail tuleb saata plokiahelasse koos kerge kliendiga (millest allpool). Kuid enne avaldamist tuleb gramme saata genereeritud aadressile, vastasel juhul ei avaldata nutilepingut. PĂ€rast nutilepingute avaldamist saab nendega suhelda, saates neile vĂ€ljastpoolt sĂ”numeid (nĂ€iteks kerge kliendi abil) vĂ”i seestpoolt (nĂ€iteks ĂŒks nutileping saadab teisele sĂ”numi TON-i sees).

PÀrast seda, kui me mÔistsime, kuidas koodi avaldatakse, muutub edasine lihtsamaks. Me teame ligikaudu, mida tahame kirjutada ja kuidas meie programm töötab. Ja kirjutamise ajal otsime, kuidas see on juba olemasolevates nutilepingutes rakendatud, vÔi vaatame teostamise koodi. Fift ja FunC ametlikus hoidlas vÔi vaatame ametlikus dokumentatsioonis.

VÀga sageli otsisin ma vÔtmesÔnade jÀrgi Telegrami vestluses, kus kogunesid kÔik konkursi osalejad ja ka Telegrami töötajad. Karantiini ajal olid kÔik seal ja hakkasid Fift'i ja FunC'i arutama. Link artikli lÔpus.

On aeg liikuda teooriast praktikasse.

TON-iga töötamiseks keskkonna seadistamine

KÔik, mis artiklis kirjas, olen teinud MacOS-is ja kontrollinud puhtas Ubuntu 18.04 LTS Dockeris.

Esimene asi, mida peate tegema, on allalaadimine ja installimine lite-client , mille abil saab saata pÀringuid TON-i.

Ametlikul veebisaidil olev juhend kirjeldab installimisprotsessi ĂŒsna detailselt ja selgelt, kuid jĂ€tab mĂ”ned detailid vĂ€lja. JĂ€rgime juhendit samal ajal, kui installime puuduvad sĂ”ltuvused. Ma ei hakanud iga projekti iseseisvalt kompileerima ja installisin ametlikust Ubuntu hoidlast (MacOS-is kasutasin ma 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 

PÀrast seda, kui kÔik sÔltuvused on installitud, saab installida lite-client, Fift, FunC.

Esmalt kloonime TON-i hoidla koos sÔltuvustega. Mugavuse huvides teeme kÔik kaustas ~/TON.

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

Hoidlas on samuti sÀilitatud rakendused Fift ja FunC.

NĂŒĂŒd oleme valmis projekti koguma. Koodi hoidla on kloonitud kausta ~/TON/ton. Dokumendihalduses ~/TON loome kausta build ja kogume seal projekti.

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

Kuna kavatseme kirjutada nutika lepingu, vajame mitte ainult lite-client, vaid ka Fift koos FunC, seega kompileerime kÔik. See ei ole kiire protsess, seega ootame.

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

Edasi laadime alla konfigureerimifaili, kus on andmed nodi kohta, millega lite-client ĂŒhenduse loomine toimub.

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

Teeme esimesed pÀringud TONis

NĂŒĂŒd kĂ€ivitage lite-client.

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

Kui kogumine Ă”nnestus, nĂ€ete pĂ€rast kĂ€ivitamist logi, kus on kirjas, kuidas kerge klient ĂŒhendub nodiga.

[ 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)
...

Saate kÀivitada kÀsu help ja vaadata, millised kÀsud on saadaval.

help

Loetleme kÀsud, mida me selles artiklis kasutame.

available commands:
last    Get last block and state info from server
sendfile  Load a serialized message from  and send it to server
getaccount  []  Loads the most recent state of specified account;  is in [:] format
runmethod  []  ...   Runs GET method  of account  with specified parameters

viimane saadab serverist viimati loodud bloki. 

sendfile  saatab TON-i faili koos sÔnumiga, just selle kÀsuga avaldatakse nutileping ja sellele esitatakse pÀringud. 

getaccount  laadib alla nutilepingut, millel on antud aadress, hetke seisundi. 

runmethod  []   kÀivitab nutilepingute get-meetodid. 

NĂŒĂŒd oleme valmis lepingu kirjutamiseks.

Rakendus

Idee

Nagu juba eespool mainitud, on nutileping, mida me kirjutame, loterii.

See ei ole loterii, mille puhul tuleb osta pilet ja oodata tund, pĂ€ev vĂ”i kuu, vaid kohene, kus kasutaja kannab summas lepingule ĂŒle. N grammi, ja saab kohe tagasi 2 * N grammi vĂ”i kaotab. VĂ”iduvĂ”imalus seab meie jaoks umbes 40%. Kui grammi maksmiseks ei piisa, loeme tehingu tĂ€iendamiseks.

Oluline on, et panuseid saaks reaalajas nÀha mugaval moel, et kasutaja saaks kohe aru, kas ta on vÔitnud vÔi kaotanud. SeetÔttu tuleb luua veebisait, mis nÀitab panuseid ja tulemusi otse TON-ist.

Nutilepingu kirjutamine

Koodi mugavuse huvides tegin FunC jaoks sĂŒntaksi esiletoomise, mille pistikprogrammi saab Visual Studio Code'i otsingust leida ja installida. Kui soovite midagi lisada, siis olen pistikprogrammi avatud juurdepÀÀsuks jaganud. Samuti on eelnevalt kellegi poolt loodud Fift'i plugin, mille samuti saab VSC-st leida ja installida.

Alustame kohe hoidla loomisega, kuhu lisame vahepealseid tulemusi.

Elu endale lihtsamaks tegemiseks kirjutame nutika lepingu ja testime seda kohapeal, kuni see on valmis. Alles siis avaldame selle TON-is.

Nutikal lepingul on kaks vÀlist meetodit, millele saab pöörduda. Esimene, recv_external() see funktsioon kÀivitatakse, kui lepingule esitatakse pÀring vÀlismaailmast, st mitte TON-ist, nÀiteks kui me ise vormime sÔnumi ja saadame selle lÀbi lite-client'i. Teine, recv_internal() see on siis, kui mÔni leping sisese TON-i raames pöördub meie poole. MÔlemal juhul saab funktsiooni edastada parameetreid.

Alustame lihtsa nÀitega, mis töötab, kui see avaldatakse, kuid sellel pole funktsionaalset koormust.

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

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

Siin tuleb selgitada, mis see on viil. KÔik TON Blockchain'is salvestatud andmed on kogum TVM rakk vÔi lihtsalt rakk, sellises rakus saab hoida kuni 1023 bitti andmeid ja kuni 4 viidet teistele rakkudele.

TVM raku viil vĂ”i viil on osa olemasolevast rakk kasutatakse selle parsimiseks, hiljem saab selgemaks. Peamine, mis meile tĂ€htis on, et saame nutilepingusse edastada viil ja sĂ”ltuvalt sĂ”numi tĂŒĂŒbist töödelda andmeid recv_external() vĂ”i recv_internal().

puhtuseta — mĂ€rksĂ”na, mis nĂ€itab, et funktsioon muudab nutilehe andmeid.

Salvestame lepingu koodi lottery-code.fc ja kompileerime selle.

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

LipuvÀÀrtuseid saab vaadata kÀsu abil

~/TON/build/crypto/func -help

Meil on tekkinud kompileeritud Fift-asm-kood 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

Seda saab kohapeal kÀivitada, selleks valmistame keskkonna.

MĂ€rgin, et esimese reana lisatakse Asm.fif, see on Fift kood, mis on kirjutatud Fift-assemblerile.

Kuna soovime testida ja kÀivitada nutilepingut kohapeal, loome faili lottery-test-suite.fif ja kopeerime sinna kompileeritud koodi, asendades viimase real, mis salvestab nutilepingu koodi konstantsesse. code, et edastada see virtuaalmasinasse:

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

PROGRAM{
  DECLPROC recv_internal
  DECLPROC recv_external
  recv_internal PROC:
  recv_external PROC:
}END>s constant code

Praegu tundub selge, nĂŒĂŒd lisame samasse faili koodi, mida kasutame TVM-i kĂ€ivitamiseks.

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()

V c7 me salvestame konteksti, st andmed, millega TVM-i kĂ€ivitatakse (vĂ”i vĂ”rgu olek). Veel konkursi ajal nĂ€itas ĂŒks arendajatest, kuidas seda luua c7 ja ma kopeerisin selle. Selles artiklis vĂ”ib-olla peame me muutma rand_seed sest see mĂ”jutab juhusliku numbri genereerimist ja kui me ei muuda, tagastatakse igakord sama number.

recv_internal ja recv_external konstandid vÀÀrtusega 0 ja -1 vastutavad vastavate funktsioonide kutsumise eest nutilepingus.

NĂŒĂŒd oleme valmis looma meie tĂŒhja nutilepingu esimest testi. Selguse huvides lisame kĂ”ik testid seni sellesse faili. lottery-test-suite.fif.

Loome muutuja storage ja kirjutame sinna tĂŒhja rakk, see saab olema nutilepingu hoidla.

message see on sÔnum, mille edastame nutilepingule vÀljastpoolt. Teeme selle samuti ajutiseks.

muutuv salvestus 
<b b> salvestus! 

muutuv sõnum 
<b b> sõnum! 

PÀrast seda, kui oleme konstantid ja muutujad ette valmistanud, kÀivitame TVM kÀsu abil runvmctx ja edastame loodud parameetrid sisendiks.

message @ 
recv_external 
code 
storage @ 
c7 
runvmctx 

Tulemusena saame sellise vahe-koodi Fift.

NĂŒĂŒd saame kĂ€ivitada saadud koodi.

export FIFTPATH=~/TON/ton/crypto/fift/lib // teeme seda korra mugavuse huvides 
~/TON/build/crypto/fift -s lottery-test-suite.fif 

Programm peaks töötama ilma vigadeta ja vÀljundis nÀeme tÀitmise logi:

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

SuurepÀrane, oleme kirjutanud esimese töötava nutilepingu versiooni.

NĂŒĂŒd tuleb lisada funktsionaalsus. Alustame sĂ”numitest, mis tulevad vĂ€lismaailmast recv_external()

Arendaja valib ise sÔnumi formaadi, mille leping vÔib vastu vÔtta.

Aga tavaliselt,

  • Esiteks soovime kaitsta meie lepingut vĂ€list maailma eest ning tagada, et ainult lepingu omanik saaks sellele vĂ€liseid sĂ”numeid saata.
  • Teiseks, kui me saadame kehtiva sĂ”numi TON-i, tahame, et see juhtuks tĂ€pselt ĂŒhe korra ning korduva sama sĂ”numi saatmisel lĂŒkkaks nutileping selle tagasi.

SeetĂ”ttu kĂ€sitletakse peaaegu igas lepingus neid kahte probleemi, kuna meie leping aktsepteerib vĂ€liseid sĂ”numeid, peame samuti selle ĂŒle hoolt kandma.

Teeme vastupidi. Esmalt lahendame kordamise probleemi; kui leping on juba saanud sellise sÔnumi ja töötlenud selle, siis ei tÀideta seda teist korda. SeejÀrel lahendame probleemi, et ainult teatud isikute ring saaks sÔnumeid nutilepingu suunata.

On erinevaid viise, kuidas lahendada korduvate sĂ”numite probleem. Me teeme nii. Nutilepingus seadistame saadetud sĂ”numite arvesti algvÀÀrtuseks 0. Igas sĂ”numis lisame nutilepingule arvesti praeguse vÀÀrtuse. Kui sĂ”numi arvesti vÀÀrtus ei ĂŒhti nutilepingus oleva vÀÀrtusega, siis me ei töötle seda, kuid kui see ĂŒhtib, töötleme ja suurendame arvestit nutilepingus 1 vĂ”rra.

Naaseme lottery-test-suite.fif ja lisame sinna teise testi. Saadame vale numbri, kood peaks viskama erandi. NĂ€iteks oletame, et lepingu andmetes on salvestatud 166, kuid me saadame 165.

<b 166 32 u, b> salvestus !
<b 165 32 u, b> sõnum !

sõnum @ 
recv_external 
kood 
salvestus @ 
c7 
runvmctx

dropp 
exit_code ! 
."Väljumise kood " exit_code @ . cr 
exit_code @ 33 - abort"Test #2 ei ole läbitud"

KĂ€ivitame.

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

Ja nÀeme, et test tÀitub veaga.

[ 1][t 0][1582283084.210902214][words.cpp:3046] lottery-test-suite.fif:67: abort": Test #2 ei lÀinud lÀbi
[ 1][t 0][1582283084.210941076][fift-main.cpp:196]      Viga faili `lottery-test-suite.fif` tÔlgendamisel: viga kaasatud faili `lottery-test-suite.fif` tÔlgendamisel : lottery-test-suite.fif:67: abort": Test #2 ei lÀinud lÀbi

Sellel etapil lottery-test-suite.fif peab vÀlja nÀgema nagu lingi kaudu.

NĂŒĂŒd lisame nutilepingusse arvesti loogika lottery-code.fc.

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

() 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);
}

V slice in_msg on sÔnum, mida me saadame.

Esiteks kontrollime, kas sÔnumis on andmeid, kui ei, siis lihtsalt lahkume.

SeejÀrel parsime sÔnumi. in_msg~load_uint(32) laeb numbri 165, 32-bitine unsigned int edastatud sÔnumist.

SeejÀrel laeme 32 bitti nutilepingute salvestusest. Kontrollime, et laetud number vastab edastatud numbrile, kui ei, viskame erandi. Meie puhul, kuna edastame erineva, peaks erand viskama.

NĂŒĂŒd kompileerime.

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

Saadud koodi kopeerime lottery-test-suite.fif, unustamata asendada viimane rida.

Kontrollime, et test lÀbib:

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

Siin saab vaadata vastavat commit'i praeguste tulemustega.

MĂ€rka, et pidev kompileeritud nutilepingute koodi kopeerimine testifaili on ebamugav, seega kirjutame skripti, mis kirjutab koodi konstantidesse meie eest, ja me lihtsalt ĂŒhendame kompileeritud koodi meie testidesse "include".

Loome projekti kausta faili build.sh jÀrgnevate sisuga.

#!/bin/bash

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

Teeme selle kÀivitatavaks.

chmod +x ./build.sh

NĂŒĂŒd piisab, kui kĂ€ivitada meie skript, et kompileerida leping. Kuid lisaks peame selle salvestama konstantina code. Selleks loome uue faili lotter-compiled-for-test.fif, mille kaasame faili lottery-test-suite.fif.

Lisame sh skripti koodi, mis lihtsalt dubleerib kompileeritud faili lotter-compiled-for-test.fif ja muudab seal viimast rida.

# 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ĂŒĂŒd proovime, kĂ€ivitades saadud skripti, mille tulemusena genereeritakse fail lottery-compiled-for-test.fif, mille me kaasame meie lottery-test-suite.fif

V lottery-test-suite.fif eemaldame lepingukoodi ja lisame rea "lottery-compiled-for-test.fif" include.

KÀivitame testid, et kontrollida, kas need lÀbivad.

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

SuurepĂ€rane, nĂŒĂŒd, et automatiseerida testide kĂ€itamine, loome faili test.sh, mis esmalt kĂ€ivitab build.sh, ja seejĂ€rel kĂ€ivitab testid.

touch test.sh
chmod +x test.sh

Kirjutame sisse

./build.sh 

echo "nKompileerimine lÔpetatudn"

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

Teeme test.sh ja kÀivitame, et veenduda testide töökindluses.

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

Kontrollime, et leping kompileeritakse ja testid kÀivad.

SuurepĂ€rane, nĂŒĂŒd kĂ€ivitamisel test.sh kohe toimub kompileerimine ja testide kĂ€ivitamine. Siin on link kommitt.

Olgu, enne kui me jĂ€tkame, teeme mugavuse huvides veel ĂŒhe asja.

Loome kausta build kuhu salvestame kompileeritud lepingu ja selle kloni, mis on salvestatud konstantsina lottery-compiled.fif, lottery-compiled-for-test.fif. Samuti loome kausta test kus asub testifail lottery-test-suite.fif ja potentsiaalselt teised abifailid. Link vastavate muudatuste juurde.

JĂ€tkame nutilepingu arendamist.

Edasi peaks olema test, mis kontrollib, et sÔnumit vÔetakse vastu ja loendur uuendatakse hoidlas, kui me saadame Ôige numbri. Kuid me teeme seda hiljem.

Praegu mÔtleme, milline andmestruktuur ja millised andmed tuleb nutilepingus salvestada.

Kirjeldan kÔike, mida me salvestame.

`seqno` on 32-bit positiivne tÀisarv loendur. 

`pubkey` 256-bit positiivne tÀisarv avalik vÔti, millega me kontrollime vÀljastatud sÔnumi allkirja, millest rÀÀgitakse allpool. 

`order_seqno` on 32-bit positiivne tÀisarv, mis salvestab pakkumiste arvu. 

`number_of_wins` on 32-bit positiivne tÀisarv, mis salvestab vÔitude arvu. 

`incoming_amount` andmetĂŒĂŒp on Gram (esimesed 4 bitti vastutavad pikkuse eest), salvestab koguarvu gramme, mis on saadetud kontrakti. 

`outgoing_amount` on kogus gramme, mis on saadetud vÔitjatele. 

`owner_wc` on töötlemise number, 32-bit (mÔnes kohas on kirjutatud, et 8-bit) tÀisarv. Praegu on neid ainult kaks -1 ja 0. 

`owner_account_id` on 256-bit positiivne tÀisarv, kontrakti aadress praeguses töötlemises. 

`orders` on sĂ”nastiku tĂŒĂŒp muutuja, mis salvestab viimased kakskĂŒmmend pakkumist. 

SeejĂ€rel tuleb kirjutada kaks funktsiooni. Esimese nimetame pack_state(), mis pakib andmed edasise salvestamise jaoks tarkvaralisse hoiustamise sĂŒsteemi. Teise nimetame unpack_state() , mis loeb ja tagastab andmed hoiustamisest.

_ 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;
}

Lisame need kaks funktsiooni nutika lepingute algusesse. Tulemuseks on sellise vaheline tulemus.

Andmete salvestamiseks tuleb kutsuda sisseehitatud funktsioon set_data() ja see salvestab andmed pack_state() nutika lepingu salvestusse.

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

NĂŒĂŒd, kui meil on mugavad andmete salvestamise ja lugemise funktsioonid, saame edasi liikuda.

Peame kontrollima, et vÀljastpoolt tulev sÔnum on nutika lepingu omaniku (vÔi muu kasutaja, kellel on juurdepÀÀs isiklikule vÔtmele) allkirjastatud.

Kuna me avaldame nutilepingut, saame seda algatada vajalike andmetega salvestuses, mis sÀilivad tulevikuks. Kirjutame sinna avaliku vÔtme, et saaks kontrollida, kas sissetuleva sÔnumi allkiri on tehtud vastava privaatvÔtmega.

Enne jĂ€tkamist loome privaatvĂ”tme ja kirjutame selle test/keys/owner.pk. Selleks kĂ€ivitame Fifti interaktiivses reĆŸiimis ja tĂ€idame neli kĂ€sku.

`newkeypair` avaliku ja privaatvÔtme genereerimine ning nende kirjutamine kuhja.

`drop` eemaldab kuhjast ĂŒlemise elemendi (antud juhul avaliku vĂ”tme)

`.s` lihtsalt vaatame, mis hetkel kuhjas on

`"owner.pk" B>file` privaatvÔtme kirjutamine faili nimega `owner.pk`.

`bye` lÔpetab Fifti kasutamise. 

Loome kausta vÔtmed kaustas test ja kirjutame sinna privaatvÔtme.

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

NĂ€eme praeguses kaustas faili owner.pk.

Eemaldame avaliku vÔtme kuhjast, kui seda vaja peaks minema, saame selle privaatvÔtme kaudu kÀtte.

NĂŒĂŒd peame kirjutama allkirjakontrolli. Alustame testist. Esiteks loeme privaatvĂ”tme failist vĂ€lja kasutades funktsiooni file>B ja salvestame selle muutujasse owner_private_key, seejĂ€rel kasutame funktsiooni priv>pub vahendame privaatvĂ”tme avalikuks ja salvestame tulemuse 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 !

MÔlemat vÔtit on meil vaja.

Algatame juhuslike andmetega nutilepingu salvestuse samas jÀrjekorras nagu funktsioonis pack_state()ja salvestame muutujasse storage.

muutujad owner_private_key
muutujad owner_public_key
muutujad orders
muutujad owner_wc
muutujad owner_account_id

"./keys/owner.pk" fail&gt;B owner_private_key !
owner_private_key @ priv&gt;pub owner_public_key !
dictnew orders !
0 owner_wc !
0 owner_account_id !

<b 0 32 u, owner_public_key @ b, gram, owner_wc i, owner_account_id 256 orders dict, b> salvestus !

SeejÀrel koostame allkirjastatud sÔnumi, milles on ainult allkiri ja loenduri vÀÀrtus.

Esiteks loome andmed, mida soovime edastada, seejÀrel allkirjastame need privaatvÔtmega ja lÔpuks vormime allkirjastatud sÔnumi.

muutuja sõnum_allkirjastamiseks
muutuja sõnum_ülekandmiseks
muutuja allkiri
<b 0 32 u, b> sõnum_allkirjastamiseks !
sõnum_allkirjastamiseks @ hashu omaniku_privaatvõti @ ed25519_sign_uint allkiri !
<b signature @ b, 0 32 u, b> &lt;s !  

LÔpuks on sÔnum, mille saadame nutilepingusse, salvestatud muutujasse message_to_send, funktsioonide kohta hashu, ed25519_sign_uint vÔib lugeda Fifti dokumentatsioonist.

Ja testimise kÀivitamiseks kutsume uuesti.

message_to_send @ 
recv_external 
code 
storage @
c7
runvmctx

Nii see peaks see olema testifail sellel etapil.

KÀivitame testi ja see ebaÔnnestub, seega muudame nutilepingut, et see saaks saadud sÔnumeid sellises formaadis vastu vÔtta ja allkirja kontrollida.

Esiteks loeme sÔnumist 512 bitti allkirja ja salvestame selle muutujasse, seejÀrel loeme 32 bitti loendurimuutujast.

Kuna meil on nutilepingust andmete lugemise funktsioon, kasutame seda.

JĂ€rgmiseks kontrollime loendurit, mis on saadetud koos salvestusega, ja kontrollime allkirja. Kui midagi ei klapi, viskame vastava koodiga erandi.

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));

Vastav commit siit.

KĂ€ivitame testid ja nĂ€eme, et teine test ebaĂ”nnestub. Kaks pĂ”hjust: sĂ”numis on bittide puudus ja salvestuses on bittide puudus, seega kood kukub kokku analĂŒĂŒsimisel. Peame lisama saadetava sĂ”numi allkirja ja kopeerima salvestuse viimasest testist.

Teises testis lisame sÔnumi allkirja ja muudame nutilepingu salvestust. Nii see fail nÀeb vÀlja hetkel.

Kirjutame neljanda testi, kus saadame sĂ”numi, mille on allkirjastanud kellegi teise privaatvĂ”ti. Loome veel ĂŒhe privaatvĂ”tme ja salvestame selle faili not-owner.pk. Selle privaatvĂ”tmega allkirjastame sĂ”numi. KĂ€ivitame testid ja veendume, et kĂ”ik testid lĂ€bivad. Kohustus hetkel.

NĂŒĂŒd viime lĂ”puks ellu nutilepingu loogika.
V recv_external() me vĂ”tame vastu kahte tĂŒĂŒpi sĂ”numeid.

Kuna meie leping akumuleerib mĂ€ngijate kaotusi, tuleb need summad ĂŒle kanda lotomĂ€ngu looja. Loterii looja rahakoti aadress salvestatakse ladustamisse lepingu loomisel.

Iga juhuks on meil vaja vÔimet muuta aadressi, kuhu kannata kaotajate gramme. Samuti peame olema vÔimelised saatma gramme loteriist aadressile omaniku rahakotile.

Alustame esimesest. Kirjutame kÔigepealt testi, mis kontrollib, et pÀrast sÔnumi saatmist nutileping on salvestanud uue aadressi ladustamisse. JÀtame tÀhele, et sÔnumis, lisaks loendurile ja uuele aadressile, edastame ka action 7-bitine mittetu negatiivne tÀisarv, sÔltuvalt sellest valime, kuidas töödelda sÔnumit nutilepingus.

<b 0 32 u, 1 @ 7 new_owner_wc i, new_owner_account_id 256 b> sõnum_allkirjastamiseks !

Testis saab nÀha, kuidas toimub nutilepingu salvestamise deseraliseerimine. storage Fiftis on muutujate deseraliseerimine kirjeldatud Fift'i dokumentatsioonis.

Link commiti juurde testi lisamisega.

KĂ€ivitame testi ja veendume, et see kukub lĂ€bi. NĂŒĂŒd lisame loogika loterii omaniku aadressi muutmiseks.

Nutilepingus jĂ€tkame analĂŒĂŒsi message, loeme sisse action. Kordame, et meil on kaks action: aadressi muutmine ja grammide saatmine.

SeejÀrel loeme sisse uue lepingua toa aadressi ja salvestame selle hoiust.
KĂ€ivitame testid ja nĂ€eme, et kolmas test kukub lĂ€bi. See kukub lĂ€bi, kuna leping analĂŒĂŒsib nĂŒĂŒd tĂ€iendavalt 7 bitti sĂ”numist, mida testis ei ole. Lisame sĂ”numisse mitteeksisteeriva action. KĂ€ivitame testid ja nĂ€eme, et kĂ”ik lĂ€hevad lĂ€bi. Siin commiti muudatuste kohta. SuurepĂ€rane.

NĂŒĂŒd kirjutasime loogika, et saata mÀÀratud kogus gramme varem salvestatud aadressile.

Alustuseks kirjutame testi. Kirjutame kaks testi: ĂŒks, kui saldo on madal, ja teine, kui kĂ”ik peaks saama edukalt lĂ€bitud. Teste saab vaadata selles commit'is.

NĂŒĂŒd kirjutame koodi. Kirjutame kĂ”igepealt kaks abimeetodit. Esimene on get meetod, et teada saada hetke saldo nutilepingus.

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

Ja teine on grammide saatmiseks teisele nutilepingule. Selle meetodi kopeerisin ma tÀielikult teisest nutilepingust.

() 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 nulli + 0 nÀitena, et andme rakendusega ei ole. 
        .end_cell(); 
    send_raw_message(msg, 3); ;; reĆŸiim, 2 vead ignoreerimiseks, 1 saatja katab tasud, 64 sisendi sĂ”numi vÀÀrtuse tagastamiseks
}

Lisame need kaks meetodit nutikasse lepingusse ja kirjutame loogika. Esiteks analĂŒĂŒsime grammide arvu sĂ”numist. SeejĂ€rel kontrollime saldot; kui see on ebapiisav, viskame vĂ€lja erandi. Kui kĂ”ik on korras, siis saadame grammid salvestatud aadressile ja uuendame loenduri.

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));

Nii see selline on nutilepingu praegune vÀlimus. KÀivitame testid ja veendume, et need lÀbivad.

Muide, nutileping rakendab iga kord töötletud sÔnumi eest tasu. Selleks et nutileping tÀidaks taotluse, tuleb pÀrast pÔhikontrolle kutsuda accept_message().

NĂŒĂŒd tegeleme sisemiste sĂ”numitega. TĂ”epoolest, me lihtsalt aktsepteerime grammid ja saadame mĂ€ngijale tagasi kaks korda suure summa vĂ”idu korral ning kolmandiku omaniku kĂ”rvale kaotuse korral.

Esiteks kirjutame lihtsa testi. Selleks vajame nutilepingu testaadressi, millelt me nÀiliselt grammid nutilepingule saadame.

Nutikas lepingu aadress koosneb kahest numbrist, 32-bitine tÀisarv vastutab tööketi (workchain) ja 256-bitine mitte-negatiivne unikaalne konto number sellel tööketis. NÀiteks, -1 ja 12345, see aadress salvestame faili.

Mina kopeerisin aadressi salvestamise funktsiooni failist 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

AnalĂŒĂŒsime, kuidas funktsioon töötab, see annab mĂ”istaa, kuidas Fift töötab. KĂ€ivitame Fifti interaktiivses reĆŸiimis.

~/TON/build/crypto/fift -i 

Esmalt paneme kuhja -1, 12345 ja tulevase faili nime "sender.addr":

-1 12345 "sender.addr" 

JÀrgmise sammuna tÀidetakse funktsioon -rot, mis nihutab kuhja, nii et kuhja tippu satub nutika lepingu unikaalne number:

"sender.addr" -1 12345

256 u>B konverteerib 256-bitise mitte-negatiivse tÀisarvu baitideks.

"sender.addr" -1 BYTES:0000000000000000000000000000000000000000000000000000000000003039

swap vahetab kaks ĂŒlemist elementi kuhjas.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 -1

32 i>B konverteerib 32-bitise tÀisarvu baitideks.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 BYTES:FFFFFFFF

B+ ĂŒhendab kahte baitide jĂ€rjestust.

 "sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF

Taaskord swap.

BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF "sender.addr" 

Ja lĂ”puks kirjutatakse baitide faili B>fail. PĂ€rast seda on meie lott tĂŒhi. Peatame Fift. KĂ€esolevas kaustas on loodud fail sender.addr. Viime faili loodud kausta test/addresses/.

Kirjutame lihtsa testi, mis saadab gramme nutilepingule. Siin on commit.

NĂŒĂŒd keskendume loterii loogikale.

Esimene asi, mida teeme, on kontrollida sÔnumit tagasilöök vÔi mitte, kui tagasilöök, siis ignoreerime. tagasilöök see tÀhendab, et leping tagastab gramme, kui toimub mÔni viga. Me ei tagasta gramme, kui peaks olema probleem.

Kontrollime, kui saldo on vÀiksem kui pool grammi, siis vÔtame lihtsalt sÔnumi vastu ja ignoreerime.

SeejÀrel parsimme nutilepingu aadressi, millelt sÔnum tuli.

Lugesime andmed salvest ja seejĂ€rel eemaldame vanad panused ajaloost, kui neid on rohkem kui kakskĂŒmmend. Mugavuse huvides kirjutasin kolm lisafunktsiooni pack_order(), unpack_order(), remove_old_orders().

Edasi vaatame, kui saldo ei piisa vÀljamakseks, siis arvame, et see ei ole panus, vaid tÀiendamine ja salvestame tÀiendamise orders.

LÔpuks jÔuame nutilepingu sisuni.

Esiteks, kui mĂ€ngija kaotas, salvestame ta panuste ajaloosse ja kui summa ĂŒletab 3 grammi, saadame 1/3 nutilepingu omanikule.

Kui mÀngija vÔitis, siis saadame kahekordse summa mÀngija aadressile ja salvestame seejÀrel teabe panuse ajaloos.

() 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() = 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));
}

Siin see on. Seotud kinnitus.

NĂŒĂŒd jÀÀb vaid lihtne ĂŒlesanne, loome get-meetodid, et vĂ€lismaailm saaks teavet lepingu oleku kohta (tegelikult peavad need andmed olema nende nutilepingu salvestuses).

Lisame get-meetodid. Kuidas nutilepingust teavet saada, kirjutame allpool.

Veel unustasin ma lisada koodi, mis töötleb esimest pÀringut, mis toimub nutilepingut avalikustades. Seotud kinnitus. Ja veel parandasin. vea 1/3 summa saatmisega omaniku kontole.

Edasi jÀÀb vaid nutileping avalikustada. Loome kausta requests.

Sain inspiratsiooni avaldamise koodist simple-wallet-code.fc mille vÔib leida leidsin ametlikust hoidlast.

Oluline on tÀhelepanu pöörata sellele. Me vormistame nutilepingus salvestuse ja sisendi sÔnumi. PÀrast seda genereeritakse nutilepingu aadress, mis tÀhendab, et aadress on tuntud juba enne TON-is avaldamist. Siis tuleb sellele aadressile saata paar grammi ja alles seejÀrel tuleks saata fail ise nutilepinguga, kuna nutilepingu ja sellega seotud toimingute salvestamise eest vÔtab vÔrk tasu ( valideerijad, kes salvestavad ja tÀidavad nutilepinguid). Koodi saab vaadata siit.

SeejÀrel kÀivitame avaldamiskoodi ja saadame lottery-query.boc faili ja nutilepingu aadressi.

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

Ärge unustage salvestada genereeritud faile: lottery-query.boc, lottery.addr, lottery.pk.

Muuhulgas nÀeme tÀitmislogis nutilepingu aadressi.

uus rahakoti aadress = 0:044910149dbeaf8eadbb2b28722e7d6a2dc6e264ec2f1d9bebd6fb209079bc2a 
(Salvestame aadressi faili lottery.addr)
KĂŒlastamata aadress (alguseks): 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd
KĂŒlastatav aadress (hilisemaks ligipÀÀsuks): kQAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8KpFY

Huvi pÀrast teeme pÀringu TON-i

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

Ja nĂ€eme, et selle aadressiga konto on tĂŒhi.

konto olek on tĂŒhi

Saadame aadressile 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd 2 Gram ja mĂ”ne sekundi pĂ€rast tĂ€idame sama kĂ€skluse. Grammi saatmiseks kasutan ametlikku rahakotti, ja testgramme vĂ”ib kĂŒsida kellegilt vestlusest, millest rÀÀgin artikli lĂ”pus.

> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Vaata, et vÔrgus on ilmunud initsialiseerimata (state:account_uninit) nutileping sellise aadressi ja saldo 1 000 000 000 nanogrammi.

konto olek on (konto
  addr:(addr_std
    anycast:mida 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:mida)
  storage:(konto_storage last_trans_lt:3825478000002
    balance:(currencies
      grams:(nanograms
        amount:(var_uint len:4 value:2000000000))
      other:(extra_currencies
        dict:hme_empty))
    state:konto_uninit))
x{C00044910149DBEAF8EADBB2B28722E7D6A2DC6E264EC2F1D9BEBD6FB209079BC2A20259C2F2F4CB3800000DEAC10776091DCD650004_}
viimane tehing lt = 3825478000001 hash = B043616AE016682699477FFF01E6E903878CDFD6846042BA1BFC64775E7AC6C4
konto saldo on 2000000000ng

NĂŒĂŒd avaldame nutilepingut. KĂ€ivitame lite-client'i ja teeme.

> sendfile lottery-query.boc
[ 1][t 2][1583008371.631410122][lite-client.cpp:966][!testnode] saatmine failist lottery-query.boc
[ 3][t 1][1583008371.828550100][lite-client.cpp:976][!query]    vÀlise sÔnumi olek on 1 

Kontrollime, et leping on avaldatud.

> last
> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Muuhulgas saame.

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

NĂ€eme, et konto_active.

Asjakohane commit koos muudatustega siit.

NĂŒĂŒd loome pĂ€ringud nutilepinguga suhtlemiseks.

Esimene aadressi muutmine jÀÀb iseseisvaks tööks, teine aga grammide saatmiseks omanikule saab olema. Tegelikult peame tegema sama, mis grammide saatmise testis.

Sellise sÔnumi saadame nutilepingusse, kus msg_seqno 165, action 2 ja 9,5 grammi saatmiseks.

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

Ärge unustage sĂ”numit allkirjastada privaatvĂ”tmega lottery.pk, mis genereeriti varem nutilepingu loomisel. Siin on vastav commit.

Saame teavet nutilepingust, kasutades get-meetodeid

NĂŒĂŒd vaatame, kuidas nutilepingu get-meetodeid kĂ€ivitada.

KÀivitage lite-client ja kÀivitame get-meetodid, mille me kirjutasime.

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

V tulemus sisaldab vÀÀrtust, mille funktsioon balance() meie nutilepingust tagastab.
Teeme sama ka mitmete meetoditega.

> runmethod 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd get_seqno
...
argumentid: [ 77871 ] 
resultaat: [ 1 ] 

KĂŒsime panuste ajalugu.

> 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]) ] 

Kasutame lite-clienti ja get-meetodeid, et edastada teavet nutilepingute kohta veebilehel.

Kuvame nutilepingute andmed veebilehel

Kirjutasin lihtsa veebilehe Pythonis, et kuvada andmeid nutilepingust mugavas vormis. Siin ma ei jÀÀ sellele pikalt pidama ning avaldan veebilehe. ĂŒhe commitiga.

TON-i pÀringud tehakse Python kasutades lite-client. Mugavuse huvides on veebileht pakitud Dockerisse ja avaldatud Google Cloudis. Veebilehe link.

Proovime

NĂŒĂŒd proovime saata sinna gramme tagasimaksmiseks rahakotist. Saadame 40 grammi. Ja teeme paar panust, et illustreerida. NĂ€eme, et veebileht kuvab panuste ajalugu, praegust vĂ”iduprotsenti ja muud kasulikku teavet.

NÀeme, et esimese vÔitsime, teise kaotasime.

JÀrelsÔna

Artikkel osutus palju pikemaks, kui ma algselt arvasin. VĂ”ib-olla oleks saanud lĂŒhemalt, aga vĂ”ib-olla just sellisena sobib see inimesele, kes ei tea midagi TON-ist ja tahab kirjutada ning avaldada mitte kĂ”ige lihtsamat nutilepingut, millega suhelda. VĂ”ib-olla oleks mĂ”ndasid asju saanud lihtsamalt seletada.

VÔib-olla mÔningaid teemasid oleks saanud rakendada tÔhusamalt ja elegantselt, kuid siis oleks artikli ettevalmistamiseks kulunud veel rohkem aega. Samuti on vÔimalik, et ma kuskil eksisin vÔi ei saanud millestki aru, seega kui teete midagi tÔsist, tuleks tugineda ametlikule dokumentatsioonile vÔi ametlikule TON koodi repositooriumile.

Pean mĂ€rkima, et kuna TON ise on endiselt aktiivse arendamise faasis, vĂ”ivad toimuda muudatused, mis rikuvad mĂ”ne selle artikli sammu (mis juhtus ka sel ajal, kui ma kirjutasin, ja ma olen juba parandanud), kuid ĂŒldine lĂ€henemine tĂ”enĂ€oliselt ei muutu.

Tuleviku osas TON-i kohta ei hakka rÀÀkimau. VÔib-olla kasvab platvorm millekski suuremaks ja me peaksime juba praegu investeerima aega selle Ôppimisse ning oma toodetel niche'i hÔivama.

Facebooki Libra'l on potentsiaalne kasutajaskond suurem kui TON-il. Libra'ist ei tea ma palju, aga foorumi pÔhjal on sealne aktiivsus tunduvalt suurem kui TON-i kogukonnas. Kuigi TON-i arendajad ja kogukond meenutavad rohkem underground'i, mis on samuti Àge.

Lingid

  1. TON-i ametlik dokumentatsioon: https://test.ton.org
  2. TON-i ametlik hoidla: https://github.com/ton-blockchain/ton
  3. Ametlik rahakott erinevatele platvormidele: https://wallet.ton.org
  4. Artiklis mainitud nutilepingute hoidla: https://github.com/raiym/astonished
  5. Viide nutilepingu veebilehele: https://ton-lottery.appspot.com
  6. Visual Studio Code'i laienduse hoidla FunC jaoks: https://github.com/raiym/func-visual-studio-plugin
  7. Telegramis TON-i vestlus, mis aitas mul alguses selgusele jĂ”uda. Arvan, et pole vale öelda, et seal on kĂ”ik, kes on midagi TON-ile kirjutanud. Samuti saab seal kĂŒsida testimiseks gramme. https://t.me/tondev_ru
  8. Veel ĂŒks TON-i vestlus, kus leidsin kasulikku teavet: https://t.me/TONgramDev
  9. Konkursi esimene etapp: https://contest.com/blockchain
  10. Konkursi teine etapp: https://contest.com/blockchain-2

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster