Circa cumu scrive è pubblicà un cuntrattu intelligente in a Telegram Open Network (TON)

Circa cumu scrive è pubblicà un cuntrattu intelligente in TON

Cosa hè stu articulu circa?

In l'articulu vi parleraghju di cumu aghju participatu à u primu (di dui) cumpetizione di blocchi Telegram, ùn hà micca pigliatu un premiu, è hà decisu di registrà a mo sperienza in un articulu per ùn affundà in l'obliu è, forse, aiuta. qualcunu.

Siccomu ùn vulia micca scrive codice astrattu, ma per fà qualcosa di travagliu, per l'articulu aghju scrittu un cuntrattu intelligente per una lotteria immediata è un situ web chì mostra i dati di u cuntrattu intelligenti direttamente da TON senza usà l'almacenamiento intermediu.

L'articulu serà utile à quelli chì volenu fà u so primu cuntrattu intelligente in TON, ma ùn sanu micca da induve principià.

Aduprà a lotteria cum'è un esempiu, andaraghju da installà l'ambiente à pubblicà un cuntrattu intelligente, interagisce cun ellu, è scrive un situ web per riceve è publicà dati.

Circa a participazione à u cuncorsu

L'ottobre scorsu, Telegram hà annunziatu una cumpetizione di blockchain cù novi lingue Fift и FunC. Era necessariu di sceglie di scrive qualcunu di i cinque cuntratti intelligenti pruposti. Pensu chì saria bellu di fà qualcosa di sfarente, d'amparà una lingua è di fà qualcosa, ancu s'ellu ùn aghju micca da scrive altru in u futuru. Inoltre, u tema hè constantemente nantu à i labbra.

Hè vale à dì chì ùn aghju avutu micca sperienza in u sviluppu di cuntratti intelligenti.

Aghju pensatu à participà finu à a fine finu à ch'e possu è dopu scrive un articulu di rivista, ma aghju fiascatu subitu à u primu. I hà scrittu un wallet cù multi-firma attivata FunC è in generale hà travagliatu. Aghju pigliatu cum'è una basa cuntrattu intelligenti nantu à Solidità.

À quellu tempu, aghju pensatu chì questu era definitivamente abbastanza per piglià almenu un postu di premiu. In u risultatu, circa 40 di i participanti 60 sò diventati premiati è ùn era micca trà elli. In generale, ùn ci hè nunda di male in questu, ma una cosa m'hà disturbatu. À l'ora di l'annunziu di i risultati, a rivista di a prova per u mo cuntrattu ùn era micca stata fatta, aghju dumandatu à i participanti in u chat s'ellu ci era qualcunu chì ùn l'avia micca, ùn ci era nimu.

Apparentemente attentu à i mo missaghji, dui ghjorni dopu, i ghjudici anu publicatu un cummentariu è ùn capiscu ancu s'ellu anu mancatu accidentalmente u mo cuntrattu intelligente durante u ghjudiziu o simpricimenti pensanu chì era cusì male chì ùn hà micca bisognu di un cummentariu. Aghju fattu una quistione nantu à a pagina, ma ùn aghju micca ricevutu risposta. Ancu s'ellu ùn hè micca un sicretu chì hà ghjudicatu, aghju cunsideratu micca necessariu di scrive missaghji persunali.

Un saccu di tempu hè statu passatu per capiscenu, cusì hè statu decisu di scrive un articulu. Siccomu ùn ci hè micca assai infurmazione, questu articulu aiuterà à salvà tempu per tutti quelli chì interessanu.

U cuncettu di cuntratti intelligenti in TON

Prima di scrive qualcosa, avete bisognu di sapè da quale parte si avvicinassi à sta cosa. Dunque, avà vi dicu di quali parti hè custituitu u sistema. Più precisamente, quale parte avete bisognu di sapè per scrive almenu qualchì tipu di cuntrattu di travagliu.

Ci focalizeremu nantu à scrive un cuntrattu intelligente è travaglià cun TON Virtual Machine (TVM), Fift и FunC, cusì l'articulu hè più cum'è una descrizzione di u sviluppu di un prugramma regulare. Ùn ci stendemu micca nantu à cumu funziona a piattaforma stessa quì.

In generale nantu à cumu si travaglia TVM è lingua Fift ci hè una bona documentazione ufficiale. Mentre participava à a cuncurrenza è avà mentre scrive u cuntrattu attuale, spessu vultò à ella.

A lingua principale in quale i cuntratti intelligenti sò scritti hè FunC. Ùn ci hè micca ducumentazione nantu à questu in u mumentu, cusì per scrive qualcosa avete bisognu di studià esempi di cuntratti intelligenti da u repositoriu ufficiale è l'implementazione di a lingua stessa quì, in più pudete fighjà esempi di cuntratti intelligenti da l'ultimi dui. cuncorsi. Ligami à a fine di l'articulu.

Diciamu chì avemu digià scrittu un cuntrattu intelligente per FunC, dopu avemu compilatu u codice in Fift assembler.

U cuntrattu intelligente cumpilatu resta da esse publicatu. Per fà questu, avete bisognu di scrive una funzione Fift, chì pigliarà u codice di u cuntrattu intelligenti è alcuni altri paràmetri cum'è input, è l'output serà un schedariu cù l'estensione .boc (chì significa "saccu di cellula"), è, secondu cumu scrivemu, una chjave privata è l'indirizzu, chì hè generatu nantu à u codice di u cuntrattu intelligente. Pudete digià mandà grammi à l'indirizzu di un cuntrattu intelligente chì ùn hè ancu publicatu.

Per publicà un cuntrattu intelligente in TON ricevutu .boc u schedariu deve esse mandatu à u blockchain cù un cliente di luce (più nantu à quì sottu). Ma prima di publicà, avete bisognu di trasfiriri grammi à l'indirizzu generatu, altrimente u cuntrattu intelligente ùn serà micca publicatu. Dopu a publicazione, pudete interagisce cù u cuntrattu intelligente mandendu missaghji da l'esternu (per esempiu, utilizendu un cliente ligeru) o da l'internu (per esempiu, un cuntrattu intelligente manda un altru missaghju in TON).

Quandu avemu capitu cumu u codice hè publicatu, diventa più faciule. Sapemu circa ciò chì vulemu scrive è cumu u nostru prugramma hà da travaglià. E mentre scrivite, circhemu cumu questu hè digià implementatu in i cuntratti intelligenti esistenti, o fighjemu in u codice di implementazione Fift и FunC in u repositoriu ufficiale, o cercate in a documentazione ufficiale.

Assai spessu aghju cercatu e parolle chjave in u chat di Telegram induve tutti i participanti di a cumpetizione è l'impiegati di Telegram si sò riuniti, è hè accadutu chì durante a cumpetizione tutti si sò riuniti quì è cuminciaru à discutiri Fift è FunC. Link à a fine di l'articulu.

Hè ora di passà da a teoria à a pratica.

Preparazione di l'ambiente per travaglià cù TON

Aghju fattu tuttu ciò chì serà descrittu in l'articulu nantu à MacOS è duppiu verificatu in Ubuntu 18.04 LTS pulito in Docker.

A prima cosa chì duvete fà hè di scaricà è stallà lite-client cù quale pudete mandà richieste à TON.

L'istruzzioni nantu à u situ ufficiale descrizanu u prucessu di stallazione in abbastanza dettagliu è chjaramente è omette alcuni dettagli. Quì avemu seguitu l'istruzzioni, installendu e dependenzii mancanti longu a strada. Ùn aghju micca compilatu ogni prughjettu stessu è installatu da u repositoriu ufficiale di Ubuntu (in MacOS aghju utilizatu 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 

Una volta tutte e dipendenze sò stallate, pudete installà lite-client, Fift, FunC.

Prima, clonemu u repository TON cù e so dipendenze. Per comodità, faremu tuttu in un cartulare ~/TON.

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

U repository guarda ancu implementazioni Fift и FunC.

Avà simu pronti à assemblà u prugettu. U codice di repository hè clonatu in un cartulare ~/TON/ton. L' ~/TON creà un cartulare build è cullà u prughjettu in questu.

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

Siccomu avemu da scrive un cuntrattu intelligente, avemu bisognu micca solu lite-clientma Fift с FunC, dunque compiemu tuttu. Ùn hè micca un prucessu rapidu, cusì aspettemu.

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

Dopu, scaricate u schedariu di cunfigurazione chì cuntene dati nantu à u node à quale lite-client culligarà.

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

Fendu e prime richieste à TON

Avà lanciamu lite-client.

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

Se a custruzzione hè successu, dopu à u lanciu vi vede un logu di a cunnessione di u cliente di luce à u node.

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

Pudete eseguisce u cumandamentu help è vede ciò chì cumandamenti sò dispunibili.

help

Elencu i cumandamenti chì avemu da aduprà in questu articulu.

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-методы смартконтракта. 

Avà simu pronti à scrive u cuntrattu stessu.

Реализация

Idea

Cumu aghju scrittu sopra, u cuntrattu intelligente chì scrivimu hè una lotteria.

Inoltre, questu ùn hè micca una lotteria in quale avete bisognu di cumprà un bigliettu è aspittà una ora, ghjornu o mese, ma un instante in quale l'utilizatore trasferisce à l'indirizzu di u cuntrattu. N grammi, è istantaneamente torna 2 * N grammi o perde. Facemu a probabilità di vince circa 40%. Se ùn ci hè micca abbastanza grammi per u pagamentu, allora avemu da cunsiderà a transazzione cum'è una cima.

Inoltre, hè impurtante chì e scumesse ponu esse vedute in tempu reale è in una forma cunvene, per chì l'utilizatore pò capisce immediatamente s'ellu hà vintu o persu. Dunque, avete bisognu di fà un situ web chì mostrarà scumesse è risultati direttamente da TON.

Scrivite un cuntrattu intelligente

Per a cunvenzione, aghju evidenziatu u codice per FunC; u plugin pò esse truvatu è installatu in a ricerca di Visual Studio Code; se di colpu vulete aghjunghje qualcosa, aghju fattu u plugin dispunibule publicamente. Inoltre, qualchissia hà fattu prima un plugin per travaglià cù Fift, pudete ancu stallà è truvà in VSC.

Creemu subitu un repository induve cummettemu i risultati intermedi.

Per fà a nostra vita più faciule, scriveremu un cuntrattu intelligente è pruveremu in u locu finu à ch'ella hè pronta. Solu dopu chì a publicaremu in TON.

U cuntrattu intelligente hà dui metudi esterni chì ponu accede. Primu, recv_external() sta funzione hè eseguita quandu una dumanda à u cuntrattu vene da u mondu esternu, vale à dì, micca da TON, per esempiu, quandu noi stessi generà un missaghju è mandà lu à traversu u lite-client. Sicondu, recv_internal() questu hè quandu, in TON stessu, ogni cuntrattu si riferisce à u nostru. In i dui casi, pudete passà parametri à a funzione.

Cuminciamu cù un esempiu simplice chì hà da travaglià s'ellu hè publicatu, ma ùn ci hè micca una carica funziunale in questu.

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

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

Quì avemu bisognu di spiegà ciò chì hè slice. Tutti i dati guardati in TON Blockchain sò una cullizzioni TVM cell o simpricimenti cell, in una tale cellula pudete almacenà finu à 1023 bits di dati è finu à 4 ligami à altre cellule.

TVM cell slice o slice questu hè una parte di l'esistente cell hè utilizatu per analizà, diventerà chjaru dopu. A cosa principal per noi hè chì pudemu trasferisce slice è sicondu u tipu di missaghju, processà i dati in recv_external() o recv_internal().

impure - una keyword chì indica chì a funzione modifica i dati di u cuntrattu intelligenti.

Salvemu u codice di u cuntrattu lottery-code.fc è compilà.

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

U significatu di e bandiere pò esse vistu cù u cumandamentu

~/TON/build/crypto/func -help

Avemu cumpilatu u codice assembler Fift in 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

Pò esse lanciatu in u locu, per questu avemu priparà l'ambiente.

Nota chì a prima linea cunnetta Asm.fif, Questu hè u codice scrittu in Fift per l'assembler Fift.

Siccomu vulemu eseguisce è pruvà u cuntrattu intelligente in u locu, creeremu un schedariu lottery-test-suite.fif è copià u codice compilatu quì, rimpiazzà l'ultima linea in questu, chì scrive u codice di u cuntrattu intelligente à una constante codeper poi trasfiriri à a macchina virtuale:

"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

Finu a ora pare chjaru, avà aghjunghje à u listessu schedariu u codice chì avemu da aduprà per lancià 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 avemu registratu u cuntestu, vale à dì, i dati cù quale u TVM (o statu di a rete) serà lanciatu. Ancu durante a cumpetizione, unu di i sviluppatori hà dimustratu cumu per creà c7 è aghju copiatu. In questu articulu pudemu avè bisognu di cambià rand_seed postu chì a generazione di un numeru aleatoriu dipende da ellu è s'ellu ùn hè micca cambiatu, u listessu numeru serà tornatu ogni volta.

recv_internal и recv_external custanti cù valori 0 è -1 seranu rispunsevuli di chjamà e funzioni currispondenti in u cuntrattu intelligente.

Avà simu pronti à creà a prima prova per u nostru cuntrattu intelligente viotu. Per a chjarità, per avà aghjunghje tutti i testi à u listessu schedariu lottery-test-suite.fif.

Creemu una variabile storage è scrivite un viotu in questu cell, questu serà u almacenamentu di u cuntrattu intelligente.

message Questu hè u missaghju chì avemu da trasmette à u cuntattu intelligente da l'esternu. A faremu ancu viotu per avà.

variable storage 
<b b> storage ! 

variable message 
<b b> message ! 

Dopu avè preparatu e custanti è variabili, lanciamu TVM cù u cumandimu runvmctx è passà i paràmetri creati à l'input.

message @ 
recv_external 
code 
storage @ 
c7 
runvmctx 

In fine, avemu da successu cusì codice intermediariu per Fift.

Avà pudemu eseguisce u codice resultanti.

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

U prugramma deve esse eseguitu senza errori è in u output vedemu u logu d'esekzione:

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

Grande, avemu scrittu a prima versione di travagliu di u cuntrattu intelligente.

Avà avemu bisognu di aghjunghje funziunalità. Prima, avemu trattatu di missaghji chì venenu da u mondu esternu recv_external()

U sviluppatore stessu sceglie u furmatu di missaghju chì u cuntrattu pò accettà.

Ma di solitu

  • prima, vulemu prutezzione di u nostru cuntrattu da u mondu esternu è fà cusì chì solu u pruprietariu di u cuntrattu pò mandà missaghji esterni.
  • in segundu, quandu avemu mandatu un missaghju validu à TON, vulemu chì questu succede esattamente una volta è quandu avemu mandatu u stessu missaghju di novu, u cuntrattu intelligente rifiuta.

Allora quasi ogni cuntrattu risolve sti dui prublemi, postu chì u nostru cuntrattu accetta missaghji esterni, avemu bisognu di piglià cura di questu.

A faremu in ordine inversu. Prima, risolvemu u prublema cù a ripetizione; se u cuntrattu hà digià ricevutu un tali missaghju è u processatu, ùn l'eseguirà micca una seconda volta. È tandu avemu risolviri u prublema cusì chì solu un certu circulu di pirsuni pò mandà missaghji à u cuntrattu intelligenti.

Ci sò diverse manere di risolve u prublema cù missaghji duplicate. Eccu cumu a faremu. In u cuntrattu intelligente, avemu inizializatu u contatore di messagi ricivuti cù u valore iniziale 0. In ogni missaghju à u cuntrattu intelligente, aghjunghjemu u valore attuale di u cuntrariu. Se u valore di u contatore in u missaghju ùn currisponde micca à u valore in u cuntrattu intelligente, allora ùn u processemu micca; s'ellu face, allora u processemu è aumentemu u cuntatore in u cuntrattu intelligente di 1.

Riturnemu à lottery-test-suite.fif è aghjunghje una seconda prova. Se mandemu un numeru incorrectu, u codice duveria lancià una eccezzioni. Per esempiu, lasciate i dati di u cuntrattu 166, è manderemu 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"

Lanciamu.

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

È videremu chì a prova hè eseguita cù un errore.

[ 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

À questu stadiu lottery-test-suite.fif duverebbe pare Member.

Avà aghjunghje a logica di cuntrariu à u cuntrattu intelligente in 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 si trova u missaghju chì avemu mandatu.

A prima cosa chì facemu hè di verificà s'ellu u missaghju cuntene dati, s'ellu ùn hè micca, allora simpricimenti esce.

Dopu avemu analizatu u messagiu. in_msg~load_uint(32) carica u numeru 165, 32-bit unsigned int da u missaghju trasmessu.

In seguitu, carchemu 32 bits da u almacenamentu di u cuntrattu intelligente. Cuntrollamu chì u numeru caricatu currisponde à quellu passatu; se no, lancemu una eccezzioni. In u nostru casu, postu chì passemu un non-match, una eccezzioni deve esse ghjittata.

Avà compilemu.

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

Copia u codice risultatu in lottery-test-suite.fif, senza scurdà di rimpiazzà l'ultima linea.

Avemu verificatu chì a prova passa:

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

Giustu quì Pudete vede l'impegnu currispundente cù i risultati attuali.

Innota chì hè sconveniente per copià constantemente u codice compilatu di un cuntrattu intelligente in un schedariu cù testi, cusì scriveremu un script chì scriverà u codice in una constante per noi, è simpricimenti cunnettemu u codice compilatu à i nostri testi usendu. "include".

Crea un schedariu in u cartulare di u prughjettu build.sh cù u seguenti cuntenutu.

#!/bin/bash

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

Facemu eseguibile.

chmod +x ./build.sh

Avà, basta à eseguisce u nostru script per compilà u cuntrattu. Ma in più di questu, avemu bisognu di scrive in una constante code. Allora avemu da creà un novu schedariu lotter-compiled-for-test.fif, chì includeremu in u schedariu lottery-test-suite.fif.

Aghjunghjite u codice skirpt à sh, chì simpricimenti duplicà u schedariu compilatu in lotter-compiled-for-test.fif è cambià l'ultima linea in questu.

# 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

Avà, per verificà, eseguisce u script resultante è un schedariu serà generatu lottery-compiled-for-test.fif, chì includeremu in u nostru lottery-test-suite.fif

В lottery-test-suite.fif sguassate u codice di u cuntrattu è aghjunghje a linea "lottery-compiled-for-test.fif" include.

Facemu teste per verificà chì passanu.

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

Grande, avà per automatizà u lanciu di teste, creamu un schedariu test.sh, chì prima eseguirà build.sh, è poi eseguite i testi.

touch test.sh
chmod +x test.sh

Scrivemu dentru

./build.sh 

echo "nCompilation completedn"

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

Facemu test.sh è eseguite per assicurà chì e teste funzionanu.

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

Avemu verificatu chì u cuntrattu compie è e teste sò eseguite.

Grande, avà à l'iniziu test.sh I testi saranu compilati è eseguiti immediatamente. Eccu u ligame per impegnà.

Va bè, prima di cuntinuà, facemu una cosa più per comodità.

Creemu un cartulare build induve guardemu u cuntrattu copiatu è u so clone scrittu in una constante lottery-compiled.fif, lottery-compiled-for-test.fif. Creemu ancu un cartulare test induve serà guardatu u schedariu di prova? lottery-test-suite.fif è potenzialmente altri schedari di supportu. Link à i cambiamenti pertinenti.

Continuemu à sviluppà u cuntrattu intelligente.

Dopu ci deve esse una prova chì verifica chì u messagiu hè ricevutu è u cuntatore hè aghjurnatu in a tenda quandu mandemu u numeru currettu. Ma a faremu più tardi.

Avà pensemu à quale struttura di dati è quali dati deve esse guardatu in u cuntrattu intelligente.

Descriveraghju tuttu ciò chì guardamu.

`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` переменная типа словарь, хранит последние двадцать ставок. 

Dopu avete bisognu di scrive duie funzioni. Chjamemu u primu pack_state(), chì impaccherà i dati per u salvamentu sussegwente in l'almacenamiento smart contract. Chjamemu u sicondu unpack_state() leghje è restituverà i dati da u almacenamentu.

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

Aghjunghjemu sti dui funzioni à u principiu di u cuntrattu intelligente. Funzionarà cusì risultatu intermediu.

À salvà dati vi tuccherà à chjamà a funzione integrata set_data() è scriverà dati da pack_state() in l'almacenamiento smart contract.

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

Avà chì avemu funzioni convenienti per scrive è leghje dati, pudemu passà.

Avemu bisognu di verificà chì u missaghju chì vene da fora hè firmatu da u pruprietariu di u cuntrattu (o un altru utilizatore chì hà accessu à a chjave privata).

Quandu publichemu un cuntrattu intelligenti, pudemu inizializà cù e dati chì avemu bisognu in u almacenamentu, chì serà salvatu per u futuru usu. Ci hà da arregistrà a chjave publica in modu chì pudemu verificà chì u missaghju entrata hè statu firmatu cù a chjave privata currispundente.

Prima di cuntinuà, creemu una chjave privata è scrivitemu test/keys/owner.pk. Per fà questu, lanciamu Fift in modu interattivu è eseguite quattru cumandamenti.

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

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

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

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

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

Creemu un cartulare keys in u cartulare test è scrivite a chjave privata quì.

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

Avemu vistu un schedariu in u cartulare attuale owner.pk.

Sguassemu a chjave publica da a pila è quandu hè necessariu pudemu uttene da quella privata.

Avà avemu bisognu di scrive una verificazione di firma. Cuminciamu cù a prova. Prima avemu leghje a chjave privata da u schedariu cù a funzione file>B è scrivite à una variabile owner_private_key, dopu aduprà a funzione priv>pub cunvertisce a chjave privata in una chjave publica è scrivite u risultatu in 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 !

Avemu bisognu di e duie chjave.

Inizialemu l'almacenamiento di u cuntrattu intelligente cù dati arbitrarii in a listessa sequenza cum'è in a funzione pack_state()è scrivite in una variabile 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 !

In seguitu, cumponemu un missaghju firmatu, cuntene solu a firma è u valore di u cuntrariu.

Prima, criemu i dati chì vulemu trasmette, dopu avemu firmatu cù una chjave privata è infine generà un missaghju firmatu.

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 !  

In u risultatu, u missaghju chì avemu da mandà à u cuntrattu intelligente hè arregistratu in una variabile message_to_send, nantu à e funzioni hashu, ed25519_sign_uint pudete leghje in a documentazione di Fift.

È per eseguisce a prova chjamemu di novu.

message_to_send @ 
recv_external 
code 
storage @
c7
runvmctx

Eccu accussì U schedariu cù i testi duveria vede cusì in questu stadiu.

Eseguimu a prova è falla, cusì cambieremu u cuntrattu intelligente per pudè riceve missaghji di stu formatu è verificate a firma.

Prima, cuntamu 512 bits di a firma da u missaghju è scrivimu à una variàbile, dopu cuntamu 32 bits di a variabile contatore.

Siccomu avemu una funzione per leghje e dati da l'almacenamiento di u cuntrattu intelligente, l'avemu aduprà.

In seguitu hè cuntrollà u cuntatore trasferitu cù l'almacenamiento è cuntrollà a firma. Se qualcosa ùn currisponde micca, allora lancemu una eccezzioni cù u codice appropritatu.

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

Impegnu pertinente quì quì.

Eseguimu e teste è vede chì a seconda prova falla. Per dui motivi, ùn ci hè micca abbastanza bits in u messagiu è ùn ci hè micca abbastanza bits in u almacenamiento, cusì u codice crashs when parsing. Avemu bisognu di aghjunghje una firma à u missaghju chì avemu mandatu è copià l'almacenamiento da l'ultima prova.

In a seconda prova, aghjunghjemu una firma di missaghju è cambiate l'almacenamiento di u cuntrattu intelligente. Eccu accussì u schedariu cù e teste pare à u mumentu.

Scrivemu una quarta prova, in quale manderemu un missaghju firmatu cù a chjave privata di qualcunu altru. Creemu una altra chjave privata è salvemu in un schedariu not-owner.pk. Firmeremu u missaghju cù sta chjave privata. Eseguimu i testi è assicuratevi chì tutti i testi passanu. Impegnu in stu mumentu.

Avà pudemu infine passà à implementà a logica di u cuntrattu intelligente.
В recv_external() avemu da accettà dui tipi di missaghji.

Siccomu u nostru cuntrattu accumulerà e perdite di i ghjucatori, stu soldi deve esse trasferitu à u creatore di a lotteria. L'indirizzu di a billetera di u creatore di lotterie hè registratu in u almacenamentu quandu u cuntrattu hè creatu.

Solu in casu, avemu bisognu di a capacità di cambià l'indirizzu à quale avemu mandatu grammi di i perdenti. Duvemu ancu esse capace di mandà grammi da a loteria à l'indirizzu di u pruprietariu.

Cuminciamu cù u primu. Scrivemu prima una prova chì verificarà chì dopu avè mandatu u missaghju, u cuntrattu intelligente hà salvatu u novu indirizzu in u almacenamiento. Per piacè nutate chì in u missaghju, in più di u contatore è u novu indirizzu, trasmettemu ancu action Un numeru interu 7-bit non-negativu, sicondu ellu, scegliemu cumu processà u missaghju in u cuntrattu intelligente.

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

In a prova pudete vede cumu l'almacenamiento di smartcontract hè deserializatu storage in cinque. A deserializazione di variabili hè descritta in a documentazione di Fift.

Cummit ligame cù pasta aghjuntu.

Facemu a prova è assicuratevi chì falla. Avà aghjunghje a logica per cambià l'indirizzu di u pruprietariu di lotterie.

In u cuntrattu intelligente cuntinuemu à analizà message, leghje in action. Ricurdemu chì avemu dui action: cambià l'indirizzu è mandà grammi.

Allora leghjemu u novu indirizzu di u pruprietariu di u cuntrattu è salvemu in almacenamiento.
Eseguimu i testi è vedemu chì a terza prova falla. Crashes per u fattu chì u cuntrattu avà analizà in più 7 bits da u messagiu, chì mancanu in a prova. Aghjunghjite un inesistente à u missaghju action. Facemu e teste è vedemu chì tuttu passa. ccà impegnate à i cambiamenti. Perfettu.

Avà scrivemu a logica per mandà u numeru specificatu di grammi à l'indirizzu salvatu prima.

Prima, scrivemu una prova. Scriveremu duie teste, una quandu ùn ci hè micca abbastanza equilibriu, u sicondu quandu tuttu deve passà successu. I testi ponu esse vistu in questu impegnu.

Avà aghjunghje u codice. Prima, scrivemu dui metudi d'aiutu. U primu mètudu di ottene hè di scopre l'equilibriu attuale di un cuntrattu intelligente.

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

È u sicondu hè per mandà grammi à un altru cuntrattu intelligente. Aghju copiatu cumplettamente stu metudu da un altru cuntrattu intelligente.

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

Aghjunghjemu sti dui metudi à u cuntrattu intelligenti è scrivite a logica. Prima, analizemu u numeru di grammi da u messagiu. Dopu avemu verificatu u bilanciu, s'ellu ùn hè micca abbastanza, tittimu una eccezzioni. Se tuttu hè bè, allora mandemu i grammi à l'indirizzu salvatu è aghjurnà u contatore.

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

Eccu accussì s'assumiglia à u cuntrattu intelligente in u mumentu. Facemu e teste è assicuratevi chì passanu.

In modu, una cumissioni hè dedutta da u cuntrattu intelligente ogni volta per un missaghju processatu. In ordine per i missaghji cuntrattu intelligenti à eseguisce a dumanda, dopu à cuntrolli basi vi tuccherà à chjamà accept_message().

Avà andemu à i missaghji internu. In fatti, accetteremu solu grammi è rinviate u doppiu di a quantità à u ghjucatore s'ellu vince è un terzu à u pruprietariu s'ellu perde.

Prima, scrivemu una prova simplice. Per fà questu, avemu bisognu di un indirizzu di prova di u cuntrattu intelligente da quale avemu suppostu mandà grammi à u cuntrattu intelligente.

L'indirizzu di u cuntrattu intelligente hè custituitu da dui numeri, un integer 32-bit rispunsevuli di a catena di travagliu è un numeru interu unicu di 256-bit non-negativu in questa workchain. Per esempiu, -1 è 12345, questu hè l'indirizzu chì salveremu in un schedariu.

Aghju copiatu a funzione per salvà l'indirizzu da 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

Fighjemu cumu funziona a funzione, questu darà una intelligenza di cumu funziona Fift. Lanciate Fift in modu interattivu.

~/TON/build/crypto/fift -i 

Prima spingemu -1, 12345 è u nome di u futuru file "sender.addr" nantu à a pila:

-1 12345 "sender.addr" 

U prossimu passu hè di eseguisce a funzione -rot, chì cambia a pila in tale manera chì in cima di a pila ci hè un numeru unicu di cuntrattu intelligente:

"sender.addr" -1 12345

256 u>B cunverte un interu 256-bit non negativu in byte.

"sender.addr" -1 BYTES:0000000000000000000000000000000000000000000000000000000000003039

swap scambia i primi dui elementi di a pila.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 -1

32 i>B converte un interu 32-bit in byte.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 BYTES:FFFFFFFF

B+ cunnetta dui sequenze di bytes.

 "sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF

Novu swap.

BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF "sender.addr" 

È infine i bytes sò scritti à u schedariu B>file. Dopu questu, a nostra pila hè viota. Ci fermemu Fift. Un schedariu hè statu creatu in u cartulare attuale sender.addr. Andemu spustà u schedariu à u cartulare creatu test/addresses/.

Scrivemu una prova simplice chì mandarà grammi à un cuntrattu intelligente. Eccu l'impegnu.

Avà fighjemu a logica di a loteria.

A prima cosa chì facemu hè di verificà u missaghju bounced o micca si bounced, allora l'ignoramu. bounced significa chì u cuntrattu torna grammi s'ellu ci hè qualchì errore. Ùn vulteremu micca grammi s'ellu ci hè un errore di colpu.

Cuntrollamu, se l'equilibriu hè menu di a mità di grammu, allora accettemu solu u missaghju è ignurà.

In seguitu, analizemu l'indirizzu di u cuntrattu intelligente da quale u missaghju hè vinutu.

Leghjemu i dati da u almacenamiento è dopu sguassate vechji scumesse da a storia s'ellu ci sò più di vinti. Per comodità, aghju scrittu trè funzioni supplementari pack_order(), unpack_order(), remove_old_orders().

In seguitu, guardemu s'ellu u saldo ùn hè micca abbastanza per u pagamentu, allora cunsideremu chì questu ùn hè micca una scumessa, ma una ricuperazione è salvà u rifornimentu in orders.

Allora infine l'essenza di u cuntrattu intelligente.

Prima, se u ghjucatore perde, salvemu in a storia di scumessa è se a quantità hè più di 3 grammi, mandemu 1/3 à u pruprietariu di u cuntrattu intelligente.

Se u ghjucatore vince, allora mandemu u doppiu di a quantità à l'indirizzu di u ghjucatore è dopu salvà l'infurmazioni nantu à a scumessa in a storia.

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

Hè tuttu. Cummissione currispundente.

Avà tuttu ciò chì resta hè simplice, creamu metudi di get-metudi per pudè ottene infurmazioni nantu à u statu di u cuntrattu da u mondu esternu (in fatti, leghjite e dati da u so almacenamiento di u cuntrattu intelligente).

Aghjunghjemu i metudi di ottene. Scriveremu quì sottu cumu per riceve infurmazione nantu à un cuntrattu intelligente.

Aghju ancu scurdatu di aghjunghje u codice chì prucederà a prima dumanda chì accade quandu pubblicà un cuntrattu intelligente. Cummissione currispundente. È più in là currettu bug cù mandà 1/3 di a quantità à u contu di u pruprietariu.

U prossimu passu hè di publicà u cuntrattu intelligente. Creemu un cartulare requests.

Aghju pigliatu u codice di publicazione cum'è basa simple-wallet-code.fc chì ponu esse trovu in u repositoriu ufficiale.

Qualcosa chì vale a pena attente. Generemu un almacenamiento di cuntrattu intelligente è un missaghju di input. Dopu questu, l'indirizzu di u cuntrattu intelligente hè generatu, vale à dì, l'indirizzu hè cunnisciutu ancu prima di a publicazione in TON. In seguitu, avete bisognu di mandà parechji grammi à questu indirizzu, è solu dopu avete bisognu di mandà un schedariu cù u cuntrattu intelligenti stessu, postu chì a rete piglia una cumissioni per almacenà u cuntrattu intelligente è l'operazioni in questu (validatori chì guardanu è eseguisce intelligenti). cuntratti). U codice pò esse vistu quì.

Dopu avemu eseguitu u codice di publicazione è uttene lottery-query.boc schedariu di cuntrattu intelligenti è indirizzu.

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

Ùn vi scurdate di salvà i fugliali generati: lottery-query.boc, lottery.addr, lottery.pk.

Frà altre cose, vedemu l'indirizzu di u cuntrattu intelligente in i logs d'esekzione.

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

Solu per piacè, facemu una dumanda à TON

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

È videremu chì u contu cù questu indirizzu hè viotu.

account state is empty

Mandemu à l'indirizzu 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd 2 Gram è dopu uni pochi di sicondi eseguimu u listessu cumandamentu. Per mandà grammi aghju utilizatu portafoglio ufficiale, è pudete dumandà à qualchissia da u chat per i grammi di teste, chì parleraghju à a fine di l'articulu.

> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Sembra un micca inizializatu (state:account_uninit) un cuntrattu intelligente cù u stessu indirizzu è un saldo di 1 000 000 000 nanogrammi.

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

Avà publichemu u cuntrattu intelligente. Lanciamu lite-client è eseguite.

> 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 

Cuntrollamu chì u cuntrattu hè statu publicatu.

> last
> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Frà altre cose chì avemu.

  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

Avemu vistu chì account_active.

Cummissione currispundente cù cambiamenti quì quì.

Avà creemu dumande per interagisce cù u cuntrattu intelligente.

Più precisamente, lasciaremu u primu per cambià l'indirizzu cum'è un travagliu indipendente, è faremu u sicondu per mandà grammi à l'indirizzu di u pruprietariu. In fatti, avemu bisognu di fà a listessa cosa chì in a prova per mandà grammi.

Questu hè u missaghju chì avemu da mandà à u cuntrattu intelligente, induve msg_seqno 165, action 2 è 9.5 grammi per mandà.

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

Ùn vi scurdate di firmà u missaghju cù a vostra chjave privata lottery.pk, chì hè stata generata prima quandu crea u cuntrattu intelligente. Eccu l'impegnu currispundente.

Riceve infurmazione da un cuntrattu intelligente cù metudi get

Avà fighjulemu cumu fà eseguisce i metudi di cuntratti intelligenti.

Lanciari lite-client è eseguite i metudi get chì avemu scrittu.

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

В result cuntene u valore chì a funzione torna balance() da u nostru cuntrattu intelligente.
Facemu u listessu per parechji metudi più.

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

Dumandimu a vostra storia di scumessa.

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

Avemu aduprà lite-client è uttene metudi per vede infurmazione nantu à u cuntrattu intelligente in u situ.

Visualizzazione di dati di cuntrattu intelligenti nantu à u situ web

Aghju scrittu un situ web simplice in Python per vede e dati da u cuntrattu intelligente in una manera còmuda. Quì ùn aghju micca aspittà nantu à questu in dettagliu è publicheraghju u situ in un impegnu.

E dumande à TON sò fatte da Python cun l'aiutu di lite-client. Per comodità, u situ hè imballatu in Docker è publicatu in Google Cloud. Link.

Pruvendu

Avà pruvemu à mandà grammi quì per rifornimentu da billetera. Manderemu 40 grammi. E facemu un paru di scumesse per a clarità. Avemu vistu chì u situ mostra a storia di e scumesse, u percentualità di vincitore attuale è altre informazioni utili.

Avemu vistuchì avemu vintu u primu, persu u sicondu.

Afterword

L'articulu hè diventatu assai più longu di ciò chì m'aspittava, forse puderia esse più cortu, o forse solu per una persona chì ùn sapi nunda di TON è vole scrive è publicà un cuntrattu intelligente micca cusì simplice cù a capacità di interagisce cù lu. Forse certe cose puderianu esse spiegate più simpliciamente.

Forsi certi aspetti di l'implementazione puderianu esse fattu più efficacimente è eleganti, ma dopu avè avutu ancu più tempu per preparà l'articulu. Hè ancu pussibule chì aghju fattu un sbagliu in un locu o ùn hà micca capitu qualcosa, perchè se fate qualcosa di seriu, avete bisognu di cunfidassi in a documentazione ufficiale o in u repository ufficiale cù u codice TON.

Si deve esse nutatu chì, postu chì TON stessu hè sempre in u stadiu attivu di u sviluppu, ponu accade cambiamenti chì romperanu qualsiasi di i passi in questu articulu (chì hè accadutu mentre scrivu, hè digià currettu), ma l'approcciu generale hè improbabile di cambià.

Ùn parleraghju micca di u futuru di TON. Forse a piattaforma diventerà qualcosa di grande è duvemu passà u tempu studià è riempie un nichu cù i nostri prudutti avà.

Ci hè ancu Libra da Facebook, chì hà un publicu potenziale di utilizatori più grande di TON. Ùn sò quasi nunda di Libra, à ghjudicà da u foru ci hè assai più attività chì in a cumunità TON. Ancu i sviluppatori è a cumunità di TON sò più cum'è underground, chì hè ancu cool.

referenze

  1. Documentazione ufficiale di TON: https://test.ton.org
  2. Repositoriu ufficiale TON: https://github.com/ton-blockchain/ton
  3. Portafoglio ufficiale per diverse piattaforme: https://wallet.ton.org
  4. Repositoriu di cuntrattu intelligenti da questu articulu: https://github.com/raiym/astonished
  5. Link à u situ web di u cuntrattu intelligente: https://ton-lottery.appspot.com
  6. Repository per l'estensione per Visual Studio Code per FunC: https://github.com/raiym/func-visual-studio-plugin
  7. Chat nantu à TON in Telegram, chì hà veramente aiutatu à capisce à a fase iniziale. Pensu chì ùn serà micca un sbagliu se dicu chì tutti quelli chì anu scrittu qualcosa per TON sò quì. Pudete ancu dumandà grammi di teste quì. https://t.me/tondev_ru
  8. Un altru chat nantu à TON in quale aghju trovu informazioni utili: https://t.me/TONgramDev
  9. Prima tappa di u cuncorsu: https://contest.com/blockchain
  10. Seconda tappa di u cuncorsu: https://contest.com/blockchain-2

Source: www.habr.com

Add a comment