Kuidas kirjutada ja avaldada nutika lepingut Telegram Open Networkis (TON)

Kuidas kirjutada ja avaldada nutilepingut TONis

Mis on selle artikli sisu?

Artiklis rÀÀgin sellest, kuidas osalesin Telegrami esimeses (kahes) plokiahela konkursis, ei saanud auhinnalist kohta ja otsustasin oma kogemuse kirja panna, et see ei ununeks ning vÔib-olla aitaks kedagi.

Kuna ma ei soovinud kirjutada abstraktset koodi, vaid midagi funktsionaalset, siis koostasin artikli jaoks nutilepingu momentaalset loterii ja veebisaidi, mis nÀitab nutilepingu andmeid otse TON-ist ilma vahepealsete salvestusruumide kasutamiseta.

Artikkel on kasulik neile, kes soovivad teha oma esimese nutilepingu TON-is, kuid ei tea, kust alustada.

Loterii nÀitel viin lÀbi protsessi keskkonna seadistamisest kuni nutilepingu avaldamise ja selle kasutamise ning kirjutamiseni saidiks andmete saamiseks ja avaldamiseks.

Konkursil osalemisest

Eelmisel aastal oktoobris kuulutas Telegram vÀlja plokiahela konkursi uute keeltega Fift ja FunC. KÔik ei pidanud valima mÔne viiest pakutud nutilepingust. Arvasin, et oleks tore tegeleda millegi ebatavalisega, Ôppida keelt ja teha midagi, isegi kui tulevikus ei pea ma midagi muud kirjutama. Lisaks on see teema pidevalt pÀevakorras.

Pean ĂŒtlema, et mul ei olnud nutilepingute arendamise kogemust.

Plaanisin osaleda lĂ”puni, kuni see vĂ”imalik on, ja pĂ€rast kirjutada ĂŒlevaateartikli, kuid kukkusin kohe esimeses katses lĂ€bi. Ma kirjutasin rahakoti mitme allkirjaga FunC ja see töötab ĂŒldiselt. Aluseks vĂ”tsin nutilepingu Solidity-s.

Sel hetkel arvasin, et seda on kindlasti piisavalt, et saavutada vĂ€hemalt mingit auhinnalist kohta. LĂ”puks sai umbes 40 60 osalejast auhinnasaajaks ja mind nende seas ei olnud. Üldiselt pole selle pĂ€rast midagi hullu, kuid ĂŒks asi muretses mind. Auhindade vĂ€ljakuulutamise hetkeks ei olnud minu lepingul tehtud arvustust testimisega, kĂŒsisin osalejatelt vestluses, kas kedagi, kellel pole seda, ei olnud.

Tundub, et pĂ€rast minu sĂ”numite tĂ€helepanu tĂ”mbamist avaldasid kohtunikud kahe pĂ€eva pĂ€rast kommentaari ja ma ei saanud aru, kas nad jĂ€tsid minu nutilepingut lĂ€bivaatamisel kogemata tĂ€helepanuta vĂ”i arvasid lihtsalt, et see on nii halb, et ei vajata kommentaare. KĂŒsisin lehelt, aga vastust ei saanud. Kuigi kes kohtustas — ei ole saladus, arvasin, et isikud sĂ”numid kirjutada oleks ĂŒleliigne.

A lot of time has been spent on understanding, so it was decided to write an article. Since there isn't much information yet, this article will help save time for everyone interested.

The concept of smart contracts in TON

Before write anything, it is important to figure out how to approach this topic. So now I'll explain what parts the system consists of. Specifically, what parts you need to know to write at least some working contract.

We will focus on writing a smart contract and working with TON Virtual Machine (TVM), Fift ja FunC, so the article is more like a description of developing a regular program. We will not delve into how the platform itself works.

In general, there is good official documentation about how TVM and the language Fift are structured. During the competition and now, while writing the current contract, I've referred to it often.

The primary language for writing smart contracts is FunC. There is currently no documentation for it, so to write something, one needs to study examples of smart contracts from the official repository and the language's implementation there, plus look at examples from the previous two competitions. Links are at the end of the article.

Let's say we have already written a smart contract in FunC, after which we compile the code into Fift assembly.

The compiled smart contract is ready to be published. To do this, we need to write a function in Fift, which will take the smart contract code and some additional parameters as input, and output a file with the extension .boc (which means "bag of cells"), and depending on how we write it, a private key and an address generated based on the smart contract code. It is possible to send grams to the address of the smart contract, which has not been published yet.

To publish a smart contract in TON, the obtained .boc file needs to be sent to the blockchain using a light client (more on this below). But before publishing, you need to transfer grams to the generated address; otherwise, the smart contract will not be published. After publication, you can interact with the smart contract by sending it messages from the outside (for example, using a light client) or from the inside (for instance, one smart contract sends another message within TON).

PÀrast seda, kui oleme aru saanud, kuidas kood vÀlja lastakse, muutub kÔik lihtsamaks. Me teame enam-vÀhem, mida soovime kirjutada ja kuidas meie programm töötab. Kirjutamise ajal otsime, kuidas see on juba olemasolevates nutilepingutes realiseeritud, vÔi piilume teostuse koodi. Fift ja FunC ametlikus hoidlas, vÔi vaatame ametlikus dokumentatsioonis.

VÀga tihti otsisin ma mÀrksÔnade jÀrgi Telegrami vestluses, kus kogunesid kÔik konkursi osalejad ja ka Telegrami töötajad. Just seal arutati konkursi ajal Fift ja FunC. Link on artikli lÔpus.

On aeg minna teooriast praktika juurde.

Keskkonna ettevalmistamine TON-iga töötamiseks.

KÔik, mis artiklis kirjeldatakse, tegin ma MacOS-is ja kontrollisin puhtal Ubuntu 18.04 LTS Dockeris.

Esimene asi, mida on vaja teha, on alla laadida ja installida lite-client. Selle abil saab saata pÀringuid TON-ile.

Ametlikul veebisaidil on paigaldusprotsess ĂŒsna detailselt ja arusaadavalt kirjeldatud ning mĂ”ningad aspektid on tĂ”eliselt vahele jĂ€etud. Siin jĂ€rgime juhendit, paigaldades samal ajal puuduolevad sĂ”ltuvused. Ma ei hakanud iga projekti ise kompileerima, vaid installisin need 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 talletatud teostused. Fift ja FunC.

NĂŒĂŒd oleme valmis projekti koguma. Repositooriumi kood on kloonitud kausta ~/TON/ton.. Failis ~/TON Loodame kausta build ja kogume seal projekti.

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

Kuna kavatseme kirjutada nutilepingut, on meil vaja mitte ainult lite-client., vaid ka Fift jot FunC, seetÔttu kompileerime kÔik. See ei ole kiire protsess, seega ootame.

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

JĂ€rgmiseks laadime alla konfiguratsioonifaili, kus on kirjas andmed nodi kohta, kuhu lite-client. ĂŒhendama hakatakse.

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

Teeme esimesed pÀringud TON-ile.

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

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

Kui kogumine Ă”nnestus, nĂ€ete kĂ€ivitamisel kergklientide ĂŒhenduse logi 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)
...

Saame kÀsu ja vaata, millised kÀsud on saadaval. help Loetleme kÀsud, mida me selles artiklis kasutame.

help

saadaval olevate kÀskude loend: viimane Saad last block ja state info serverist failisaata Lae serialiseeritud sÔnum ja saada see serverisse getaccount [] Laadib mÀÀratud konto kÔige uuema oleku; on vormingus [:] vÔtme meetod [] ... KÀivitab GET meetodi konto jaoks mÀÀratud parameetritega

viimane saab serverist viimase loodud ploki.

failisaata  saadab TON-i faili sÔnumiga, just selle kÀsu abil avaldatakse nutileping ja pÀringud selle juurde.

getaccount  laadib mÀÀratud aadressiga nutilepingu praeguse oleku.

vÔtme meetod  []    kÀivitab nutilepingu get-meetodid.

NĂŒĂŒd oleme valmis nutilepingu kirjutamiseks. 

Nagu juba varem mainisin, kirjutame nutilepingu, mis on loterii.

Rakendamine

Idee

See ei ole loterii, kus pead piletit ostma ja tund vÔi pÀev vÔi kuu ootama, vaid kohene, kus kasutaja kannab lepingu aadressile

grammi ja saab kohe tagasi N 2 * N gramm vÔi kaotab. VÔiduvÔimalus tehakse umbes 40%. Kui grammi maksmiseks ei piisa, loeme tehingu tÀiendamiseks. Oluline on, et panuseid oleks vÔimalik reaalajas mugavalt nÀha, et kasutaja saaks kohe aru, kas ta vÔitis vÔi kaotas. SeetÔttu on vaja luua veebisait, mis nÀitab panuseid ja tulemusi otse TON-ist.

Nutilepingu kirjutamine

Mugavuse huvides tegin FunC jaoks koodi esiletoomise, plugina saab leida ja installida Visual Studio Code'i otsingust. Kui keegi soovib midagi lisada, olen plugina avalikult vÀlja pannud. Samuti oli keegi varem teinud Fiftide jaoks plugina, mida ka saab VSC-st leida ja installida.

Loome kohe repositooriumi, kuhu hakkame vahepealseid tulemusi salvestama.

Oma elu lihtsustamiseks hakkame kirjutama nutilepingut ja testima seda kohapeal, kuni see on valmis. Alles pÀrast seda avaldame selle TON-is.

Nutilepingul on kaks vÀlist meetodit, millele saab ligi pÀÀseda. Esimene,

recv_external() seda funktsiooni kÀivitatakse, kui lepingule tehakse pÀring vÀlismaailmast, st mitte TON-ist, nÀiteks kui me ise koostame sÔnumi ja saadame selle lÀbi lite-clienti. Teine, see funktsioon toimub, kui lepingule esitatakse pÀring vÀljastpoolt, st mitte TON-ist, nÀiteks siis, kui me ise koostame sÔnumi ja saadame selle lÀbi lite-clienti. Teine, recv_internal() see, kui TON-i sees mÔni leping kutsub meie enda lepingut. MÔlemal juhul saab funktsiooni parameetreid edastada.

Alustame lihtsast nÀitest, mis töötab, kui see avaldatakse, kuid sisuliselt ei ole selles mingit funktsionaalset koormust.

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

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

Siin tuleb selgitada, mis on slice. KÔik andmed, mis TON Blockchain-is hoitakse, on kogum TVM cell vÔi lihtsalt cell, sellisesse rakusse saab salvestada kuni 1023 bitti andmeid ja kuni 4 viidatud muudesse rakendesse.

TVM cell slice vÔi slice on olemasoleva cell rakenduse lugemiseks, hiljem on see arusaadav. Oluline on see, et saame nutilepingu edastada slice ja sÔltuvalt sÔnumi liigist töödelda andmeid seda funktsiooni kÀivitatakse, kui lepingule tehakse pÀring vÀlismaailmast, st mitte TON-ist, nÀiteks kui me ise koostame sÔnumi ja saadame selle lÀbi lite-clienti. Teine, vÔi recv_internal().

impure — vĂ”tmesĂ”na, mis nĂ€itab, et funktsioon muudab nutilepingu andmeid.

Salvestame lepingukoodi lottery-code.fc ja kompileerime selle.

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

Lipuflagide vÀÀrtusi saab vaadata kÀsuga

~\/TON\/build\/crypto\/func -help

Saime kompileeritud Fift-assembler-koodi failis 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 kohalikult kÀivitada, selleks valmistame keskkonna ette.

MĂ€rkusena, et esimeses real laetakse Asm.fif, see on kood, mis on kirjutatud Fift keeles Fift-assemblerile.

Kuna soovime kohalikult kÀivitada ja testida nutilepingut, loome faili lottery-test-suite.fif ja kopeerime sinna kompileeritud koodi, asendades selles viimase reaga, mis salvestab nutilepingu koodi konstantsesse code, et saaksime selle edasi anda virtuaalsesse masinasse:

"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

Praegu on see selge, nĂŒĂŒd lisame samasse faili koodi, mida me 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 \/\/ kÀivitamiseks recv_internal() 
-1 constant recv_external \/\/ kutsuda recv_external()

Uues c7 salvestame konteksti, st andmed, millega TVM-i kĂ€ivitatakse (vĂ”i vĂ”rgu olek). Juba konkurssi ajal nĂ€itas ĂŒks arendajatest, kuidas luua c7 ja kopeerisin selle. Selles artiklis vĂ”ib-olla peame muutma rand_seed kuna see sĂ”ltub juhuslikku arvu genereerimisest ja ei muutu, tagastatakse iga kord sama number.

recv_internal ja recv_external konstantide vÀÀrtustega 0 ja -1 kutsuvad vastavaid funktsioone esile nutilepingus.

NĂŒĂŒd oleme valmis looma esimese testi meie tĂŒhipaĆŸe nutilepingule. Selguse huvides lisame kĂ”ik testid hetkel sellesse faili. lottery-test-suite.fif.

Loome muutuja salvestusruum ja salvestame sinna tĂŒhja cell, see on nutilepingute salvestus.

message see on sĂ”num, mille edastame nutilepingule vĂ€ljastpoolt. Selle jĂ€tame seni samuti tĂŒhjaks.

muutujate salvestamine 
<b b> salvestamine ! 

muutujate sõnum 
<b b> sõnum ! 

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

sÔnum @ 
recv_external 
kood 
mÀlu @ 
c7 
runvmctx 

Tulemuseks saame sellise vahekoode Fift.

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

export FIFTPATH=~\/TON\/ton\/crypto\/fift\/lib \/\/ teeme seda ĂŒks kord 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]     sammud: 5 gaasi: kasutatud=304, maksimaalne=9223372036854775807, piirang=9223372036854775807, arve=0

SuurepÀrane, oleme kirjutanud esialgse töötava versiooni nutilepingust.

NĂŒĂŒd tuleb lisada funktsionaalsus. Alustame sĂ”numitest, mis tulevad vĂ€lismaailmast. seda funktsiooni kĂ€ivitatakse, kui lepingule tehakse pĂ€ring vĂ€lismaailmast, st mitte TON-ist, nĂ€iteks kui me ise koostame sĂ”numi ja saadame selle lĂ€bi lite-clienti. Teine,

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

Aga tavaliselt,

  • esiteks, me tahame kaitsta meie lepingut vĂ€lismaailma eest ja teha nii, et ainult lepingu omanik vĂ”iks sellele vĂ€liseid sĂ”numeid saata.
  • teiseks, kui me saadame kehtiva sĂ”numi TON-i, tahame, et see juhtuks tĂ€pselt ĂŒhe korra ja sama sĂ”numi korduv saatmine lĂŒkkaks nutilepingu tagasi.

SeetĂ”ttu lahendatakse peaaegu igas lepingus need kaks probleemi, kuna meie leping vĂ”tab vastu vĂ€liseid sĂ”numeid, peame samuti selle ĂŒle hoolitsema.

Teeme Àra vastupidises jÀrjekorras. Esiteks lahendame kordamise probleemi, kui leping on juba sellise sÔnumi saanud ja selle töötlenud, siis ei tÀideta seda teist korda. Ja siis lahendame probleemi, et ainult teatud ring inimesi saaks sÔnumeid nutilepingule saata.

On erinevaid viise, kuidas lahendada korduvate teadete probleem. Teeme jĂ€rgmist. Smart-lepingus initsialiseerime saadud sĂ”numite loendi algvÀÀrtusega 0. Igas sĂ”numis lisame smart-lepingule praeguse loendi vÀÀrtuse. Kui sĂ”numis olev loendi vÀÀrtus ei ĂŒhti smart-lepingus oleva vÀÀrtusega, ei töötle me seda; kui see vastab, töötleme ja suurendame smart-lepingus loendi vÀÀrtust 1 vĂ”rra.

Naaseme lottery-test-suite.fif ja lisame sellele teise testi. Saadame vale numbri, kood peaks viskama erandi. Oletame, et lepingus on salvestatud 166, aga saadame 165.

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

sõnum @ 
recv_external 
kood 
salvestamine @ 
c7 
runningvmctx

tühistama 
väljumise_kood ! 
."Väljumise kood " väljumise_kood @ . cr 
väljumise_kood @ 33 - katkestama"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 saanud lÀbi
[ 1][t 0][1582283084.210941076][fift-main.cpp:196]      Vigane faili tÔlgendamine `lottery-test-suite.fif`: viga faili `lottery-test-suite.fif` tÔlgendamisel: lottery-test-suite.fif:67: abort": Test #2 ei saanud lÀbi

Selles etapis lottery-test-suite.fif peaks vÀlja nÀgema nagu linki pidi.

NĂŒĂŒd lisame smart-lepingu loogika loendi jaoks lottery-code.fc.

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

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

Uues slice in_msg sisaldab sÔnumit, mille me saadame.

Esimene asi, mis me teeme, on kontrollida, kas sÔnumis on andmeid; kui ei, siis lahkume lihtsalt.

SeejĂ€rel analĂŒĂŒsime sĂ”numit. in_msg~load_uint(32) laeb arvu 165, 32-bitine unsigned int edastatud sĂ”numist.

Edasi laeme 32 bitti smart-lepingu hoidlast. Kontrollime, et laetud arv ĂŒhtib edastatuga; kui ei, viskame erandi. Meie puhul, kuna me edastame mitteĂŒhtiva, peaks viskama erandi.

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 viimane rida asendada.

Kontrollime, et test lÀbib:

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

Siin vÔib vaadata vastavat commit'i praeguste tulemustega.

MÀrkame, et pidevalt kompileeritud smart-lepingu koodi testifaili kopeerimine on ebamugav; seetÔttu kirjutame skripti, mis salvestab koodi konstantideks meie eest, ja me lihtsalt lisame kompileeritud koodi oma testidesse kasutades "include".

Loome projekti kausta faili build.sh jÀrgneva 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Àitamiseks sobivaks.

chmod +x .\/build.sh

NĂŒĂŒd piisab, kui kĂ€ivitame meie skripti, et kompileerida leping. Kuid lisaks peame selle salvestama konstantina code. SeetĂ”ttu loome uue faili lotter-compiled-for-test.fif, mille lisame faili lottery-test-suite.fif.

Lisame sh skripti koodi, mis lihtsalt kopeerib kompileeritud faili lotter-compiled-for-test.fif ja muudab selles 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, et kontrollida, kĂ€ivitame saadud skripti ja meil genereeritakse fail lottery-compiled-for-test.fif, mille lisame meie lottery-test-suite.fif

Uues 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Ă€ivitamine, loome faili test.sh, mis kĂ”igepealt kĂ€ivitab build.sh, ja siis 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 toimimises.

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

Kontrollime, et leping kompileeritakse ja testid tÀidetakse.

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

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

Loome kausta build kus hoiame kompileeritud lepingut ja selle klooni, salvestatud konstantina lottery-compiled.fif, lottery-compiled-for-test.fif. Samuti loome kausta test kus hoitakse testifaili lottery-test-suite.fif ja potentsiaalselt muid abifaile. Link vastavatele muudatustele.

JĂ€tkame nutika lepingu arendamist.

JÀrgmiseks peaks olema test, mis kontrollib, et sÔnum vÔetakse vastu ja loendur uuendatakse salvestuses, kui me saadame Ôige numbri. Kuid teeme seda hiljem.

Praegu mÔtleme, milline on andmestruktuur ja milliseid andmeid tuleb nutikas lepingus salvestada.

Kirjeldan kÔike, mida me salvestame.

`seqno` 32-bit unsigned integer counter. 

`pubkey` 256-bit unsigned integer public key, which we will use to verify the signature of the externally sent message, as explained below. 

`order_seqno` 32-bit unsigned integer that stores the counter for the number of bets. 

`number_of_wins` 32-bit unsigned integer that stores the number of wins. 

`incoming_amount` data type Gram (the first 4 bits determine the length), stores the total number of grams sent to the contract. 

`outgoing_amount` the total number of grams sent to the winners. 

`owner_wc` workchain number, 32-bit (in some places it is noted as 8-bit) integer. Currently, there are only two -1 and 0. 

`owner_account_id` 256-bit unsigned integer, the address of the contract in the current workchain. 

`orders` a dictionary variable that stores the last twenty bets. 

Next, we need to write two functions. We will name the first one pack_state(), which will package the data for subsequent storage in the smart contract. The second one, we will call unpack_state() which will read and return the data from the storage.

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

We add these two functions at the beginning of the smart contract. It will result in sellise an intermediate result.

To save the data, we will need to call the built-in function set_data() and it will write the data into pack_state() the smart contract's storage.

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

Now that we have convenient functions for writing and reading data, we can move on.

We need to check that the incoming external message is signed by the contract owner (or another user who has access to the private key).

Kui me avaldame nutilepingut, saame selle algatada vajalike andmetega mÀlus, mis jÀÀvad alles edasiseks kasutamiseks. Salvestame sinna avaliku vÔtme, et oleks vÔimalik kontrollida, et siseneva sÔnumi allkiri on tehtud vastava privaatvÔtmega.

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

`newkeypair` genereerib avaliku ja privaatvÔtme ning salvestab need virna. 

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

`.s` lihtsalt vaatab, mis hetkel virnas on 

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

`bye` lÔpetab töö Fiftiga. 

Loome kausta vÔtmed kaustas test ja sinna salvestame 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Ă€htav praeguses kaustas fail owner.pk.

Kuna eemaldame avaliku vÔtme virnast, saame selle vajadusel privaatvÔtmest tagasi vÔtta.

NĂŒĂŒd peame kirjutama allkirja kontrollimise. Alustame testiga. Esiteks loeme privaatvĂ”tme failist, kasutades funktsiooni file>B ja salvestame selle muutujasse owner_private_key, seejĂ€rel kasutame funktsiooni priv>pub konverteerime privaatvĂ”tme avalikuks ning 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Ôlemad vÔtmed on meile vajalikud.

Algatame nutilepingu salvestuse suvaliste andmetega tÀpselt samas jÀrjestuses nagu funktsioonis pack_state()ja salvestame selle muutujasse salvestusruum.

muutuja omanik_privaatsus_võti
muutuja omanik_avatud_võti
muutuja tellimused
muutuja omanik_wc
muutuja omanik_konto_id

"./keys/owner.pk" fail&gt;B omanik_privaatsus_võti !
omanik_privaatsus_võti @ priv&gt;pub omanik_avatud_võti !
dictnew tellimused !
0 omanik_wc !
0 omanik_konto_id !

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

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

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

muutuv sõnum_allkirjastamiseks
muutuv sõnum_edastamiseks
muutuv allkiri
<b 0 32 u, b> sõnum_allkirjastamiseks !
sõnum_allkirjastamiseks @ hashu omanik_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 hashu, ed25519_sign_uint saab lugeda dokumentatsioonis Fift.

Ja testi kÀivitamiseks kutsume taas.

message_to_send @ 
recv_external 
code 
storage @
c7
runvmctx

Nii tuleb fail vÀlja nÀha antud etapis.

KÀivitame testi ja see kukub, seega muudetakse nutilepingut, et see saaks vastu vÔtta sellises formaadis sÔnumeid ja kontrollida allkirja.

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

Kuna meil on nutilepingust andmete lisamise funktsioon, kasutame seda.

Edasi kontrollime loendurit, mis on edastatud koos salvestusega, ja allkirja kontrollimist. Kui midagi ei ĂŒhti, viskame vĂ€lja erandi vastava koodiga.

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 kommit siit.

KÀivitame testid ja nÀeme, et teine test kukub lÀbi. Kahel pÔhjusel, sÔnumis on puudu bitte ja salvestuses on puudu bitte, seega kood kukub parsimisel. Peame lisama sÔnumi allkirja, mida edastame, ja kopeerima salvestuse viimasest testist.

Teises testis lisame sÔnumi allkirja ja muudame nutilepingut. Nii nÀeb testifail hetkel vÀlja.

Kirjutame neljanda testi, milles saadame sĂ”numi, mis on allkirjastatud kellegi teise privaatvĂ”tmega. Loome veel ĂŒhe privaatvĂ”tme ja salvestame faili not-owner.pk. Selle privaatvĂ”tmega allkirjastame sĂ”numi. KĂ€ivitame testid ja veendume, et kĂ”ik testid lĂ€bivad. Kommit praeguseks hetkeks.

NĂŒĂŒd saame viim finally edasi minna nutilepingu loogika rakendamisega.
Uues seda funktsiooni kĂ€ivitatakse, kui lepingule tehakse pĂ€ring vĂ€lismaailmast, st mitte TON-ist, nĂ€iteks kui me ise koostame sĂ”numi ja saadame selle lĂ€bi lite-clienti. Teine, VĂ”tame vastu kaks tĂŒĂŒpi sĂ”numeid.

Kuna meie leping akumuleerib mÀngijate kaotusi, tuleb need summad edastada loterii looja kÀtte. Loterii looja rahakoti aadress salvestatakse lepingut luues salvestusse.

Igal juhuks vajame vÔimalust muuta aadressi, kuhu saata kaotajate gramme. Peame saama samuti saata gramme loteriist omaniku aadressile.

Alustame esimesega. Kirjutame esmalt testi, mis kontrollib, et pÀrast sÔnumi edastamist on nutileping salvestanud uue aadressi salvestusse. Pöörame tÀhelepanu sellele, et sÔnumisse, vÀlja arvatud loendur ja uus aadress, edastame veel tegevus 7-bitti positiivne tÀisarv, sÔltuvalt sellest valime, kuidas töötleda 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 salvestuse deserialiseerimine. salvestusruum Fiftis. Muutujate deserialiseerimine on kirjeldatud Fift dokumentatsioonis.

Link commit'ile testi lisamisega.

KĂ€ivitame testi ja veendume, et see ebaĂ”nnestub. NĂŒĂŒd lisame loogika loterii omaniku aadressi muutmiseks.

Nutika lepingu sees jÀtkame parsimist message, loeme sisse tegevus. Tuletame meelde, et meil on kaks tegevus: aadressi muutmine ja grammide saatmine.

Siis loeme uue lepinguhalduse aadressi ja salvestame selle salvestusse.
KĂ€ivitame testid ja nĂ€eme, et kolmas test ebaĂ”nnestub. EbaĂ”nnestub seetĂ”ttu, et leping parsimiseks lisab nĂŒĂŒd 7 bitti sĂ”numist, millest testis puuduvad. Lisame sĂ”numisse mitteolemas oleva tegevus. KĂ€ivitame testid ja nĂ€eme, et kĂ”ik lĂ€hevad lĂ€bi. Siin commit muudatustest. SuurepĂ€rane.

NĂŒĂŒd kirjutame loogika mÀÀratud grammide saatmiseks varem salvestatud aadressile.

Esmalt kirjutame testi. Kirjutame kaks testi: ĂŒks, kui saldo ei piisa, teine, kui kĂ”ik peaks edukalt toimuma. Teste saab vaadata selles commit'is.

NĂŒĂŒd kirjutame koodi. Esmalt kirjutame kaks abimeetodit. Esimene get meetod, et teada saada nutika lepingu hetkeseis.

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

Ja teine grammide saatmiseks teisele nutikale lepingule. Selle meetodi kopeerisin ma tÀielikult teisest nutikast lepingust.

() 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 <= formaadi indikaator int_msg_info$0 
    ;;  .store_uint(1, 1) ;; 1 <= ihr keelatud
    ;;  .store_uint(1, 1) ;; 1 <= bounce = true
    ;;  .store_uint(0, 1) ;; 0 <= bounced = false
    ;;  .store_uint(4, 5) ;; 00100 <= aadressi lipud, anycast = vale, 8-bitine tööketas
        .store_uint (196, 9)
        .store_int(wc, 8)
        .store_uint(addr, 256)
        .store_grams(grams)
        .store_uint(0, 107) ;; 106 nulliga + 0 indikaator, et andmeid pole
        .end_cell(); 
    send_raw_message(msg, 3); ;; reĆŸiim, 2 vigade ignoreerimiseks, 1 saatja tasub tasud, 64 sissetuleva sĂ”numi vÀÀrtuse tagastamiseks
}

Lisame need kaks meetodit nutikasse lepingusse ja kirjutame loogika. Esiteks parsime sÔnumist grammide arvu. Siis kontrollime saldo, kui ei piisa, viskame erandi. Kui kÔik on hÀsti, siis saadame grammid salvestatud aadressile ja vÀrskendame loendit.

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 nÀeb nutikas leping vÀlja hetkel. KÀivitame testid ja veendume, et need lÀbivad.

Muide, iga töötleva sĂ”numi eest smart-leping kĂŒsib tasu. Et smart-leping saaks sĂ”numi töötlemise juurde liikuda, tuleb pĂ€rast pĂ”hikontrollide tegemist kutsuda accept_message().

NĂŒĂŒd pöördume siseste sĂ”numite poole. Tegelikult hakkame me lihtsalt gramme vastu vĂ”tma ja kui mĂ€ngija vĂ”idab, siis saatma tale tagasi kahekordse summa ning omaniku osale kolmandiku, kui ta kaotab.

Esialgu kirjutame lihtsa testi. Selleks on meil vaja testadresse smart-lepingu jaoks, millest me nagu saadame gramme smart-lepingule.

Smart-lepingu aadress koosneb kahest numbrist, 32-bitine tĂ€isarv vastutab tööketi ja 256-bitine mitteĂŒhine ainulaadne konto number selles tööketis. NĂ€iteks -1 ja 12345, selle aadressi salvestame faili.

Olen kopeerinud aadressi salvestamise funktsiooni 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

Vaadakem, kuidas funktsioon töötab, see annab ĂŒlevaate, kuidas Fift töötab. KĂ€ivitame Fift interaktiivses reĆŸiimis.

~\/TON\/build\/crypto\/fift -i 

Esialgu paneme steki -1, 12345 ja tulevase faili nime "sender.addr":

-1 12345 "sender.addr" 

JÀrgmisena toimub funktsiooni tÀitmine -rot, mis nihutab steki nii, et steki tipuks saab smart-lepingu ainulaadne number:

"sender.addr" -1 12345

256 u>B muudab 256-bitise mitteĂŒhise tĂ€isarvu baitideks.

"sender.addr" -1 BYTES:0000000000000000000000000000000000000000000000000000000000003039

swap vahetab kahe steki ĂŒlemise elemendi kohti.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 -1

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

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 BYTES:FFFFFFFF

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

 "sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF

JĂ€lle swap.

BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF "sender.addr" 

Ja lĂ”puks salvestatakse baitide failisse B>file. PĂ€rast seda on meie stek tĂŒhi. Peatame Fift. Praeguses kaustas on loodud fail sender.addr. Liigutame faili loodud kausta test\/addresses\/.

Kirjutame lihtsa testi, mis saadab gramme smart-lepingule. Siin on commit.

NĂŒĂŒd liigume loterii loogikani.

Esiteks kontrollime sÔnumit bounced vÔi mitte, kui bounced, siis ignoreerime. bounced See tÀhendab, et leping tagastab gramme, kui juhtub mÔni viga. Me ei kavatse gramme tagasi anda, kui Àkki tekib probleem.

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

JÀtkame nutilepingust pÀringute aadressi sikutamisest, mille kaudu sÔnum tuli.

Lugedes andmeid hoidlast ja seejĂ€rel eemaldame ajaloost vanad pakkumised, kui neid on rohkem kui kakskĂŒmmend. Mugavuse huvides olen kirjutanud kolm tĂ€iendavat funktsiooni pack_order(), unpack_order(), remove_old_orders().

SeejÀrel vaatame, kui tasakaal ei piisa vÀljamaksmiseks, siis peame seda mitte pakkumiseks, vaid tÀiendamiseks ja salvestame tÀiendamise orders.

SeejÀrel jÔuame lÔpuks nutilepinguni.

Esmalt, kui mĂ€ngija kaotab, salvestame ta pakkumiste ajalukku ja kui summa ĂŒletab 3 grammi, saadame 1/3 nutilepingute omanikule.

Kui mÀngija vÔidab, siis saadame kahekordse summa mÀngija aadressile ja seejÀrel salvestame informatsiooni pakkumise kohta ajalukku.

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

NĂŒĂŒd on kĂ”ik. Sellekohane commit.

NĂŒĂŒd jÀÀb teha lihtne, loome GET-meetodid, et vĂ€lisilmast oleks vĂ”imalik saada teavet lepingute seisundi kohta (pĂ”himĂ”tteliselt loeme andmeid nende nutilepingute hoidlast).

Lisame GET-meetodid. Kuidas saada teavet nutilepingute kohta kirjutame allpool.

Samuti unustasin lisada koodi, mis töötleb esimest pÀringut, mis toimub nutilepingute avaldamisel. Sellekohane commit. Ja veel parandasin vea, mis saatis 1/3 summast omaniku kontole.

SeejÀrel tuleb avaldada nutileping. Loome kausta taotlused.

VÔtsin aluseks avaldamise koodi simple-wallet-code.fc mida saab leida ametlikust hoidlast.

Asjad, millele tasub tÀhelepanu pöörata. Loome nutilepingu ladustamise ja sisendi sÔnumi. SeejÀrel genereeritakse nutilepingu aadress, mis on teada isegi enne avaldamist TON-is. SeejÀrel tuleb sellele aadressile saata mÔned grammid ja alles pÀrast seda tuleb saata fail koos nutilepinguga, kuna nutilepingu hoidmise ja sealsetes toimingutes vÔtab vÔrgust tasu (validatooriumid, mis hoiavad ja tÀidavad nutilepinguid). Koodi saab vaadata siit.

SeejÀrel tÀidame avaldamise koodi ja saame 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 teostamise logides nutilepingu aadressi.

uus rahakoti aadress = 0:044910149dbeaf8eadbb2b28722e7d6a2dc6e264ec2f1d9bebd6fb209079bc2a 
(Salvestamine aadressi faili lottery.addr)
Non-bounceable aadress (algatamiseks): 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd
Bounceable 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 sellise aadressiga konto on tĂŒhi.

konto olek on tĂŒhi

Saadame aadressile 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd 2 gramm ja mĂ”ne sekundi pĂ€rast tĂ€idame sama kĂ€su. Grammide saatmiseks kasutan ametlikku rahakotti, ja proovigramme saab kĂŒsida kelleltki vestlusest, millest rÀÀgin allpool.

> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

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

konto olek on (konto
  aadress:(aadress_std
    anycast:mitte tööchain_id:0 aadress: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:mitte)
  storage:(konto_storage last_trans_lt:3825478000002
    saldo:(valuutad
      grammid:(nanograms
        amount:(var_uint len:4 value:2000000000))
      muud:(extra_currencies
        dict:hme_empty))
    olek:konto_uninit))
x{C00044910149DBEAF8EADBB2B28722E7D6A2DC6E264EC2F1D9BEBD6FB209079BC2A20259C2F2F4CB3800000DEAC10776091DCD650004_}
viimane tehing lt = 3825478000001 rahi = B043616AE016682699477FFF01E6E903878CDFD6846042BA1BFC64775E7AC6C4
konto saldo on 2000000000ng

NĂŒĂŒd avaldame nutilepingu. KĂ€ivitame lite-client'i ja tĂ€idame.

> sendfile lottery-query.boc
[ 1][t 2][1583008371.631410122][lite-client.cpp:966][!testnode] saadame pÀringu 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.

> viimased
> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Muudest saame.

  storage:(konto_storage last_trans_lt:3825499000002
    saldo:(valuutad
      grammid:(nanograms
        amount:(var_uint len:4 value:1987150999))
      muud:(extra_currencies
        dict:hme_empty))
    olek:(konto_active

NĂ€hes, et konto_active.

Asjakohane komitee muutustega siit.

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

TÀpselt esimese aadressi muutmiseks jÀtame iseseisvaks tööks, kuid teise grammi saatmiseks omaniku aadressile teeme. Tegelikult peame tegema sama, mis grammide saatmise testis.

Sellise sÔnumi saadame nutilepingule, kus msg_seqno 165, tegevus 2 ja 9.5 grammi saatmiseks.

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

Ärge unustage sĂ”numit allkirjastada privaatse vĂ”tmega lottery.pk, mis genereeriti varem nutilepingu loomise kĂ€igus. Siin on vastav komitee.

Saame teavet nutilepingust koos GET-meetodite abil

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

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

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

Uues result sisaldab vÀÀrtust, mille funktsioon balance() meie nutilepingust.
Teeme sama veel mitme meetodi jaoks.

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

KĂŒsimine panuste ajaloost.

> 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-client'i ja get-teenuseid, et kuvada teavet nutilepingute kohta veebilehel.

NĂ€itame nutilepingute andmeid veebilehel

Kirjutasin lihtsa veebilehe Pythonis, et kuvada nutilepingute andmeid mugavas formaadis. Siin ma ei peatuks sellel pikalt ja avaldan veebilehe. ĂŒhe commit'iga.

TON'i pÀringud tehakse Python kasutades lite-client.. Mugavuse huvides on veebileht pakitud Dockerisse ja avaldatud Google Cloud'is. Link veebilehele.

Katsume

NĂŒĂŒd prooviseme saata sinna grams'e tĂ€iendamiseks rahakotist. Saadame 40 grammi. Ja teeme paar panust, et oleks selgem. NĂ€eme, et veebileht nĂ€itab panuste ajalugu, praegust vĂ”iduprotsenti ja teisi kasulikke teavet.

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

EessÔna

Artikkel osutus palju pikemaks kui ma arvasin, vĂ”ib-olla oleks saanud lĂŒhemalt, aga vĂ”ib-olla just sobib inimesele, kes ei tea TON'ist midagi ja tahab kirjutada ja avaldada mitte kĂ”ige lihtsamat nutilepingut koos selle kasutamise vĂ”imalustega. VĂ”ib-olla oleks mĂ”nda asja saanud lihtsamalt selgitada.

VÔib-olla mÔningaid aspekte rakenduses oleks saanud teha efektiivsemalt ja elegantselt, kuid siis oleks artikli ettevalmistamiseks kulunud veel rohkem aega. Samuti on vÔimalik, et ma kusagil eksisin vÔi ei saanud millestki aru, seega kui teete tÔsist asja, peaksite toetuma ametlikule dokumentatsioonile vÔi ametlikule TON'i koodirepositooriumile.

Tuleb mĂ€rkida, et kuna TON ise on veel aktiivses arendusfaasis, vĂ”ivad toimuda muutused, mis rikuvad mĂ”nda artikli sammu (mis juhtus juba siis, kui ma seda kirjutasin, olen juba parandanud), kuid ĂŒldine lĂ€henemine ei muutu tĂ”enĂ€oliselt.

TON'i tulevikust ei hakka ma rÀÀkima. VĂ”ib-olla platvorm muutub millegiks suuremaks ja tasub investeerida aega selle uurimisse ja vĂ”tta oma toodetega juba nĂŒĂŒd niĆĄĆĄ.

Facebookil on veel Libra, mille potentsiaalne kasutajaskond on suurem kui TONil. Libra kohta ei tea ma peaaegu midagi, kuid foorumi jÀrgi on seal aktiivsus oluliselt suurem kui TON kogukonnas. Kuigi TONi arendajad ja kogukond nÀevad vÀlja nagu underground, on see samuti Àge.

Viidatud lingid

  1. TONi ametlik dokumentatsioon: https://test.ton.org
  2. TONi ametlik hoidla: https://github.com/ton-blockchain/ton
  3. Ametlik rahakott erinevatele platvormidele: https://wallet.ton.org
  4. Selle artikli nutika lepingu hoidla: https://github.com/raiym/astonished
  5. Link nutika lepingu saidile: https://ton-lottery.appspot.com
  6. Visual Studio Code'i laienduse hoidla FunC jaoks: https://github.com/raiym/func-visual-studio-plugin
  7. Telegrami TONi vestlus, mis aitas mul alguses aru saada. Arvan, et ei oleks vale öelda, et seal on kĂ”ik, kes on midagi TONi jaoks kirjutanud. Seal saab ka kĂŒsida testigraame. https://t.me/tondev_ru
  8. Veel ĂŒks TONi vestlus, kus leidsin kasulikku teavet: https://t.me/TONgramDev
  9. Konkurssi esimene etapp: https://contest.com/blockchain
  10. Konkurssi teine etapp: https://contest.com/blockchain-2

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster