Babagan carane nulis lan nerbitake kontrak cerdas ing Telegram Open Network (TON)

Babagan carane nulis lan nerbitake kontrak cerdas ing TON

Artikel iki babagan apa?

Ing artikel kasebut, aku bakal ngomong babagan carane aku melu kompetisi blockchain Telegram sing pertama (loro), ora entuk hadiah, lan mutusake kanggo ngrekam pengalamanku ing sawijining artikel supaya ora klelep lan, bisa uga mbantu. wong.

Awit aku ora pengin nulis kode abstrak, nanging kanggo nindakake soko apa, kanggo artikel aku nulis kontrak pinter kanggo lotre cepet lan situs web sing nuduhake data kontrak pinter langsung saka TON tanpa nggunakake panyimpenan penengah.

Artikel bakal migunani kanggo wong-wong sing pengin nggawe kontrak pinter pisanan ing TON, nanging ora ngerti ngendi kanggo miwiti.

Nggunakake lotre minangka conto, aku bakal pindhah saka nginstal lingkungan kanggo nerbitake kontrak pinter, sesambungan karo, lan nulis situs web kanggo nampa lan nerbitake data.

Babagan partisipasi ing kompetisi

Oktober kepungkur, Telegram ngumumake kompetisi blockchain karo basa anyar Fift ΠΈ FunC. Sampeyan kudu milih saka nulis salah siji saka limang kontrak pinter sing diusulake. Aku panginten iku bakal apik kanggo nindakake soko beda, sinau basa lan nggawe soko, malah yen aku ora kudu nulis liyane ing mangsa. Kajaba iku, topik kasebut terus ana ing lambe.

Iku worth ngomong sing aku ora duwe pengalaman ngembangaken kontrak pinter.

Aku ngrencanakake melu nganti pungkasan nganti bisa lan banjur nulis artikel review, nanging aku gagal langsung ing sing pisanan. aku nulis dompet karo multi-teken ing FunC lan umume makarya. Aku njupuk minangka basis kontrak pinter ing Solidity.

Ing wektu iku, aku panginten sing iki mesthi cukup kanggo njupuk paling sawetara Panggonan hadiah. AkibatΓ©, kira-kira 40 saka 60 peserta dadi pemenang hadiah lan aku ora kalebu. UmumΓ©, ora ana sing salah karo iki, nanging ana siji sing ngganggu aku. Nalika pengumuman hasil, review tes kontrakku durung rampung, aku takon marang peserta sing ngobrol yen ana wong liya sing ora duwe, ora ana.

Ketoke menehi perhatian marang pesenku, rong dina sabanjure hakim nerbitake komentar lan aku isih ora ngerti manawa dheweke ora sengaja ora kejawab kontrak cerdasku sajrone ngadili utawa mung mikir yen pancen ala banget lan ora butuh komentar. Aku takon pitakonan ing kaca, nanging ora nampa jawaban. Sanajan ora ana rahasia sing ngadili, aku nganggep ora perlu nulis pesen pribadi.

Akeh wektu kanggo mangerteni, mula diputusake kanggo nulis artikel. Amarga durung ana akeh informasi, artikel iki bakal mbantu ngirit wektu kanggo kabeh wong sing kasengsem.

Konsep kontrak pinter ing TON

Sadurunge nulis apa-apa, sampeyan kudu nemtokake sisih endi kanggo nyedhaki bab iki. Mula, saiki aku bakal pitutur marang kowe apa bagean saka sistem kasebut. Luwih tepat, bagean apa sing sampeyan kudu ngerti supaya bisa nulis paling ora sawetara jinis kontrak kerja.

Kita bakal fokus ing nulis kontrak pinter lan nggarap TON Virtual Machine (TVM), Fift ΠΈ FunC, dadi artikel luwih kaya gambaran babagan pangembangan program biasa. Kita ora bakal mikir babagan carane platform kasebut bisa digunakake ing kene.

UmumΓ© babagan cara kerjane TVM lan basa Fift ana dokumentasi resmi sing apik. Nalika melu kompetisi lan saiki nalika nulis kontrak saiki, aku kerep nyedhaki dheweke.

Basa utama sing ditulis kontrak pinter yaiku FunC. Saiki ora ana dokumentasi, mula kanggo nulis apa wae, sampeyan kudu sinau conto kontrak cerdas saka gudang resmi lan implementasine basa kasebut ing kana, lan sampeyan bisa ndeleng conto kontrak cerdas saka rong kepungkur. lomba-lomba. Pranala ing pungkasan artikel.

Ayo dadi ngomong kita wis nulis kontrak pinter kanggo FunC, sawise iku kita ngumpulake kode menyang Fift assembler.

Kontrak cerdas sing disusun tetep bakal diterbitake. Kanggo nindakake iki, sampeyan kudu nulis fungsi ing Fift, sing bakal njupuk kode kontrak cerdas lan sawetara paramèter liyane minangka input, lan output bakal dadi file kanthi ekstensi .boc (sing tegese "tas sel"), lan, gumantung carane kita nulis, kunci pribadi lan alamat, sing digawe adhedhasar kode kontrak pinter. Sampeyan wis bisa ngirim gram menyang alamat kontrak pinter sing durung diterbitake.

Kanggo nerbitakΓ© kontrak pinter ing TON ditampa .boc file kudu dikirim menyang blockchain nggunakake klien cahya (liyane ing ngisor iki). Nanging sadurunge nerbitake, sampeyan kudu nransfer gram menyang alamat sing digawe, yen ora, kontrak cerdas ora bakal diterbitake. Sawise publikasi, sampeyan bisa sesambungan karo kontrak pinter kanthi ngirim pesen saka njaba (contone, nggunakake klien cahya) utawa saka njero (contone, siji kontrak pinter ngirim pesen liyane ing TON).

Sawise ngerti carane kode diterbitake, dadi luwih gampang. Kita kira-kira ngerti apa sing arep kita tulis lan kepiye program bakal bisa digunakake. Lan nalika nulis, kita goleki carane iki wis dileksanakake ing kontrak pinter sing ana, utawa kita ndeleng kode implementasine Fift ΠΈ FunC ing repositori resmi, utawa katon ing dokumentasi resmi.

Kerep banget aku nggolèki tembung kunci ing obrolan Telegram ing ngendi kabeh peserta kompetisi lan karyawan Telegram ngumpul, lan kedadeyan nalika kompetisi kabeh padha ngumpul ing kono lan wiwit ngrembug Fift lan FunC. Link ing pungkasan artikel.

Iku wektu kanggo pindhah saka teori kanggo laku.

Nyiapake lingkungan kanggo nggarap TON

Aku nindakake kabeh sing bakal diterangake ing artikel ing MacOS lan mriksa kaping pindho ing Ubuntu 18.04 LTS sing resik ing Docker.

Wangsulan: Bab ingkang pisanan sampeyan kudu nindakake iku ngundhuh lan nginstal lite-client karo sampeyan bisa ngirim panjalukan kanggo TON.

Pandhuan ing situs web resmi njlèntrèhaké proses instalasi kanthi cukup rinci lan cetha lan ngilangi sawetara rincian. Ing kene kita tindakake pandhuan, nginstal dependensi sing ilang ing dalan. Aku ora ngumpulake saben proyek dhewe lan diinstal saka repositori Ubuntu resmi (ing MacOS sing digunakake 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 

Sawise kabeh dependensi wis diinstal, sampeyan bisa nginstal lite-client, Fift, FunC.

Pisanan, kita tiron repositori TON bebarengan karo dependensi. Kanggo penak, kita bakal nindakake kabeh ing folder ~/TON.

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

Repositori uga nyimpen implementasine Fift ΠΈ FunC.

Saiki kita siyap kanggo ngumpulake proyek kasebut. Kode repositori dikloning menyang folder ~/TON/ton. ing ~/TON nggawe folder build lan ngumpulake proyek kasebut.

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

Awit kita arep nulis kontrak pinter, kita kudu ora mung lite-clientNanging Fift с FunC, dadi ayo padha ngumpulake kabeh. Iku ora proses cepet, supaya kita ngenteni.

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

Sabanjure, download file konfigurasi sing ngemot data babagan simpul kasebut lite-client bakal nyambung.

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

Nggawe panjalukan pisanan kanggo TON

Saiki ayo diluncurake lite-client.

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

Yen mbangun sukses, banjur sawise diluncurake sampeyan bakal weruh log sambungan klien cahya menyang simpul.

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

Sampeyan bisa mbukak printah help lan ndeleng printah apa sing kasedhiya.

help

Ayo dhaptar printah sing bakal digunakake ing artikel iki.

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-ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ смартконтракта. 

Saiki kita siyap nulis kontrak kasebut dhewe.

РСализация

Idea

Kaya sing daktulis ing ndhuwur, kontrak cerdas sing kita tulis yaiku lotre.

Kajaba iku, iki dudu lotre sing sampeyan kudu tuku tiket lan ngenteni jam, dina utawa sasi, nanging cepet sing pangguna pindhah menyang alamat kontrak. N gram, lan langsung entuk maneh 2 * N gram utawa ilang. Kita bakal nggawe kemungkinan menang babagan 40%. Yen ora cukup gram kanggo pambayaran, mula kita bakal nganggep transaksi kasebut minangka top-up.

Menapa malih, iku penting sing taruhan bisa katon ing wektu nyata lan ing wangun trep, supaya pangguna bisa langsung ngerti apa menang utawa ilang. Mulane, sampeyan kudu nggawe situs web sing bakal nuduhake taruhan lan asil langsung saka TON.

Nulis kontrak pinter

Kanggo penak, aku wis nyorot kode kanggo FunC; plugin bisa ditemokake lan diinstal ing telusuran Visual Studio Code; yen sampeyan dumadakan pengin nambah, aku wis nggawe plugin kasedhiya kanggo umum. Uga, wong sadurunge nggawe plugin kanggo nggarap Fift, sampeyan uga bisa nginstal lan nemokake ing VSC.

Ayo langsung nggawe repositori ing ngendi kita bakal nggawe asil penengah.

Kanggo nggawe urip luwih gampang, kita bakal nulis kontrak cerdas lan nyoba sacara lokal nganti siap. Mung sawise iku kita bakal nerbitakΓ© ing TON.

Kontrak cerdas duwe rong cara eksternal sing bisa diakses. pisanan, recv_external() fungsi iki kaleksanan nalika panjalukan kanggo kontrak teka saka donya njaba, sing, ora saka TON, contone, nalika kita dhewe generate pesen lan ngirim liwat lite-klien. Kapindho, recv_internal() iki nalika, ing TON dhewe, sembarang kontrak nuduhake kita. Ing kasus kasebut, sampeyan bisa ngirim parameter menyang fungsi kasebut.

Ayo dadi miwiti karo conto prasaja sing bakal bisa digunakake yen diterbitake, nanging ora ana beban fungsi ing.

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

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

Ing kene kita kudu nerangake apa iku slice. Kabeh data sing disimpen ing TON Blockchain minangka koleksi TVM cell utawa mung cell, ing sel kasebut sampeyan bisa nyimpen nganti 1023 bit data lan nganti 4 pranala menyang sel liyane.

TVM cell slice utawa slice iki minangka bagΓ©an saka sing wis ana cell digunakake kanggo parsing, iku bakal dadi cetha mengko. Sing utama kanggo kita yaiku bisa transfer slice lan gumantung saka jinis pesen, proses data ing recv_external() utawa recv_internal().

impure - tembung kunci sing nuduhake yen fungsi kasebut ngowahi data kontrak cerdas.

Ayo nyimpen kode kontrak ing lottery-code.fc lan ngumpulake.

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

Tegese panji bisa dideleng nganggo perintah

~/TON/build/crypto/func -help

Kita wis nyusun kode Fift assembler ing 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

Bisa diluncurake sacara lokal, kanggo iki kita bakal nyiapake lingkungan.

Elinga yen baris pisanan nyambung Asm.fif, iki kode ditulis ing Fift kanggo Fift assembler.

Amarga kita pengin mbukak lan nyoba kontrak cerdas sacara lokal, kita bakal nggawe file lottery-test-suite.fif lan nyalin kode kompilasi ing kana, ngganti baris pungkasan, sing nulis kode kontrak cerdas menyang konstanta. codebanjur transfer menyang mesin virtual:

"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

Nganti saiki katon jelas, saiki ayo ditambahake menyang file sing padha kode sing bakal digunakake kanggo miwiti 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 kita ngrekam konteks, yaiku, data sing TVM (utawa negara jaringan) bakal diluncurake. Malah sajrone kompetisi, salah sawijining pangembang nuduhake carane nggawe c7 lan aku nyalin. Ing artikel iki kita bisa uga kudu ngganti rand_seed wiwit generasi nomer acak gumantung lan yen ora diganti, nomer padha bakal bali saben wektu.

recv_internal ΠΈ recv_external konstanta kanthi nilai 0 lan -1 bakal tanggung jawab kanggo nelpon fungsi sing cocog ing kontrak cerdas.

Saiki kita siyap nggawe tes pertama kanggo kontrak cerdas kosong. Kanggo kajelasan, saiki kita bakal nambah kabeh tes menyang file sing padha lottery-test-suite.fif.

Ayo nggawe variabel storage lan tulisen sing kosong cell, iki bakal dadi panyimpenan kontrak pinter.

message Iki pesen sing bakal dikirim menyang kontak pinter saka njaba. Kita uga bakal nggawe kosong kanggo saiki.

variable storage 
<b b> storage ! 

variable message 
<b b> message ! 

Sawise kita wis nyiapake konstanta lan variabel, kita miwiti TVM nggunakake printah runvmctx lan pass paramèter digawe kanggo input.

message @ 
recv_external 
code 
storage @ 
c7 
runvmctx 

Ing pungkasan kita bakal sukses kaya ngono kode penengah kanggo Fift.

Saiki kita bisa mbukak kode asil.

export FIFTPATH=~/TON/ton/crypto/fift/lib // выполняСм ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· для удобства 
~/TON/build/crypto/fift -s lottery-test-suite.fif 

Program kasebut kudu mbukak tanpa kasalahan lan ing output kita bakal weruh log eksekusi:

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

Apik, kita wis nulis versi kerja pertama saka kontrak cerdas.

Saiki kita kudu nambah fungsi. Pisanan ayo kang menehi hasil karo pesen sing teka saka donya njaba kanggo recv_external()

Pangembang dhewe milih format pesen sing bisa ditampa kontrak.

Nanging biasane

  • sepisanan, kita arep kanggo nglindhungi kontrak kita saka donya njaba lan nggawe supaya mung pemilik saka kontrak bisa ngirim pesen external kanggo iku.
  • kapindho, nalika kita ngirim pesen bener kanggo TON, kita arep iki kelakon persis sapisan lan nalika kita ngirim pesen padha maneh, kontrak pinter nolak.

Dadi meh kabeh kontrak ngrampungake rong masalah kasebut, amarga kontrak kita nampa pesen eksternal, mula kita uga kudu ngurus.

Kita bakal nindakake ing urutan mbalikke. Pisanan, ayo ngrampungake masalah kasebut kanthi pengulangan, yen kontrak wis nampa pesen kasebut lan diproses, mula ora bakal ditindakake kaping pindho. Banjur kita bakal ngatasi masalah kasebut supaya mung sawetara wong sing bisa ngirim pesen menyang kontrak cerdas.

Ana macem-macem cara kanggo ngatasi masalah karo pesen duplikat. Mangkene carane kita bakal nindakake. Ing kontrak pinter, kita miwiti counter pesen sing ditampa kanthi nilai awal 0. Ing saben pesen menyang kontrak pinter, kita bakal nambah nilai counter saiki. Yen nilai counter ing pesen ora cocog karo nilai ing kontrak pinter, banjur kita ora proses; yen mengkono, banjur kita proses lan nambah counter ing kontrak pinter dening 1.

Ayo bali menyang lottery-test-suite.fif lan nambah test kapindho kanggo. Yen kita ngirim nomer salah, kode kudu uncalan pangecualian. Contone, supaya data kontrak nyimpen 166, lan kita bakal ngirim 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"

Ayo diluncurake.

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

Lan kita bakal weruh manawa tes kasebut ditindakake kanthi kesalahan.

[ 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

Ing tahap iki lottery-test-suite.fif kudu katon kaya link.

Saiki ayo nambah logika kontra menyang kontrak cerdas ing 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 dumunung pesen kita ngirim.

Kaping pisanan, priksa manawa pesen kasebut ngemot data, yen ora, banjur metu.

Sabanjure kita parse pesen. in_msg~load_uint(32) ngemot nomer 165, 32-bit unsigned int saka pesen sing dikirim.

Sabanjure kita mbukak 32 bit saka panyimpenan kontrak pinter. Kita priksa manawa nomer sing dimuat cocog karo sing dilewati; yen ora, kita mbuwang pengecualian. Ing kasus kita, amarga kita ngliwati non-match, pangecualian kudu dibuwang.

Saiki ayo ngumpulake.

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

Nyalin kode asil menyang lottery-test-suite.fif, ora lali kanggo ngganti baris pungkasan.

Kita priksa manawa tes kasebut lulus:

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

Teng mriki Sampeyan bisa ndeleng komitmen sing cocog karo asil saiki.

Elinga yen ora trep kanggo terus-terusan nyalin kode kompilasi kontrak cerdas menyang file kanthi tes, mula ayo nulis skrip sing bakal nulis kode kasebut dadi konstan kanggo kita, lan kita mung bakal nyambungake kode sing dikompilasi menyang tes nggunakake "include".

Nggawe file ing folder project build.sh kanthi isi ing ngisor iki.

#!/bin/bash

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

Ayo dadi executable.

chmod +x ./build.sh

Saiki, mung mbukak script kita kanggo ngumpulake kontrak. Nanging saliyane iki, kita kudu nulis dadi konstan code. Dadi kita bakal nggawe file anyar lotter-compiled-for-test.fif, sing bakal kita lebokake ing file kasebut lottery-test-suite.fif.

Ayo nambah kode skirpt menyang sh, sing mung bakal nggawe duplikat file sing dikompilasi lotter-compiled-for-test.fif lan ngganti baris pungkasan ing.

# 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

Saiki, kanggo mriksa, ayo mbukak skrip sing diasilake lan file bakal digawe lottery-compiled-for-test.fif, kang bakal kita kalebu ing kita lottery-test-suite.fif

Π’ lottery-test-suite.fif mbusak kode kontrak lan nambah baris "lottery-compiled-for-test.fif" include.

We mbukak tes kanggo mriksa sing padha lulus.

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

Apik, saiki kanggo ngotomatisasi peluncuran tes, ayo nggawe file test.sh, sing bakal dieksekusi dhisik build.sh, banjur tindakake tes.

touch test.sh
chmod +x test.sh

Kita nulis ing njero

./build.sh 

echo "nCompilation completedn"

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

Ayo padha nindakake test.sh lan mbukak kanggo mesthekake tes bisa.

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

Kita mriksa manawa kontrak kasebut disusun lan tes ditindakake.

Apik, saiki wis diwiwiti test.sh Tes kasebut bakal dikompilasi lan langsung ditindakake. Punika link kanggo prasetya.

Oke, sadurunge nerusake, ayo nindakake siji liyane kanggo penak.

Ayo nggawe folder build ngendi kita bakal nyimpen kontrak disalin lan Klone ditulis menyang pancet lottery-compiled.fif, lottery-compiled-for-test.fif. Ayo uga nggawe folder test ngendi file test bakal disimpen? lottery-test-suite.fif lan file sing bisa ndhukung liyane. Link menyang owah-owahan sing cocog.

Ayo terus ngembangake kontrak cerdas.

Sabanjure kudu ana tes sing mriksa manawa pesen kasebut ditampa lan counter dianyari ing toko nalika ngirim nomer sing bener. Nanging mengko.

Saiki ayo mikir babagan struktur data apa lan data apa sing kudu disimpen ing kontrak cerdas.

Aku bakal njlèntrèhaké kabeh sing kita nyimpen.

`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` пСрСмСнная Ρ‚ΠΈΠΏΠ° ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, Ρ…Ρ€Π°Π½ΠΈΡ‚ послСдниС Π΄Π²Π°Π΄Ρ†Π°Ρ‚ΡŒ ставок. 

Sabanjure sampeyan kudu nulis rong fungsi. Ayo nelpon pisanan pack_state(), sing bakal ngemas data kanggo nyimpen sakteruse ing panyimpenan kontrak pinter. Ayo nelpon sing kapindho unpack_state() bakal maca lan bali data saka panyimpenan.

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

Kita nambahake rong fungsi kasebut ing wiwitan kontrak cerdas. Iku bakal bisa metu kaya ngono asil penengah.

Kanggo nyimpen data, sampeyan kudu nelpon fungsi sing dibangun set_data() lan bakal nulis data saka pack_state() ing panyimpenan kontrak pinter.

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

Saiki kita duwe fungsi sing trep kanggo nulis lan maca data, kita bisa nerusake.

Kita kudu mriksa manawa pesen sing mlebu saka njaba ditandatangani dening pemilik kontrak (utawa pangguna liyane sing nduweni akses menyang kunci pribadi).

Nalika kita nerbitakΓ© kontrak pinter, kita bisa initialize karo data sing perlu ing panyimpenan, kang bakal disimpen kanggo nggunakake mangsa. Kita bakal ngrekam kunci umum ing kana supaya kita bisa verifikasi manawa pesen sing mlebu ditandatangani nganggo kunci pribadi sing cocog.

Sadurunge nerusake, ayo gawe kunci pribadhi lan tulisen test/keys/owner.pk. Kanggo nindakake iki, ayo miwiti Fift ing mode interaktif lan nglakokake papat printah.

`newkeypair` гСнСрация ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΈ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° ΠΈ запись ΠΈΡ… Π² стСк. 

`drop` удалСния ΠΈΠ· стСка Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ элСмСнта (Π² Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡)  

`.s` просто ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ Π»Π΅ΠΆΠΈΡ‚ Π² стСкС Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ 

`"owner.pk" B>file` запись ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° Π² Ρ„Π°ΠΉΠ» с ΠΈΠΌΠ΅Π½Π΅ΠΌ `owner.pk`. 

`bye` Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ с Fift. 

Ayo nggawe folder keys nang folder test lan nulis kunci pribadi ing kana.

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

Kita ndeleng file ing folder saiki owner.pk.

Kita mbusak kunci umum saka tumpukan lan yen perlu kita bisa njaluk saka pribadi.

Saiki kita kudu nulis verifikasi teken. Ayo dadi miwiti karo test. Kaping pisanan, kita maca kunci pribadi saka file nggunakake fungsi kasebut file>B lan nulis menyang variabel owner_private_key, banjur nggunakake fungsi priv>pub Ngonversi kunci pribadhi dadi kunci umum lan tulis asil ing 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 !

Kita bakal mbutuhake loro tombol.

Kita miwiti panyimpenan kontrak cerdas kanthi data sewenang-wenang ing urutan sing padha karo fungsi kasebut pack_state()lan nulis menyang variabel 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 !

Sabanjure, kita bakal nulis pesen sing wis ditandatangani, mung bakal ngemot teken lan nilai counter.

Kaping pisanan, kita nggawe data sing arep dikirim, banjur mlebu nganggo kunci pribadi lan pungkasane nggawe pesen sing ditandatangani.

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 !  

AkibatΓ©, pesen sing bakal dikirim menyang kontrak pinter direkam ing variabel message_to_send, babagan fungsi hashu, ed25519_sign_uint sampeyan bisa maca ing dokumentasi Fift.

Lan kanggo mbukak test kita nelpon maneh.

message_to_send @ 
recv_external 
code 
storage @
c7
runvmctx

Kene mangkono File kanthi tes kudu katon kaya iki ing tahap iki.

Ayo dadi tes lan bakal gagal, supaya kita bakal ngganti kontrak pinter supaya bisa nampa pesen format iki lan verifikasi teken.

Kaping pisanan, kita ngetung 512 bit tandha saka pesen lan nulis menyang variabel, banjur ngitung 32 bit saka variabel counter.

Awit kita duwe fungsi kanggo maca data saka panyimpenan kontrak pinter, kita bakal nggunakake.

Sabanjure mriksa counter sing ditransfer karo panyimpenan lan mriksa teken. Yen ana sing ora cocog, mula kita mbuwang pengecualian kanthi kode sing cocog.

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

Komitmen sing relevan tengen kene.

Ayo mbukak tes lan ndeleng yen tes kapindho gagal. Kanggo rong alasan, ora cukup bit ing pesen lan ora cukup bit ing panyimpenan, supaya kode crash nalika parsing. Kita kudu nambah teken menyang pesen sing dikirim lan nyalin panyimpenan saka tes pungkasan.

Ing tes kapindho, kita bakal nambah tandha pesen lan ngganti panyimpenan kontrak cerdas. Kene mangkono file karo tes katon kaya ing wayahe.

Ayo nulis tes kaping papat, ing ngendi kita bakal ngirim pesen sing ditandatangani nganggo kunci pribadi wong liya. Ayo nggawe kunci pribadi liyane lan simpen menyang file not-owner.pk. Kita bakal mlebu pesen nganggo kunci pribadi iki. Ayo nglakoni tes lan priksa manawa kabeh tes lulus. Komitmen saiki.

Saiki kita bisa nerusake kanggo ngetrapake logika kontrak cerdas.
Π’ recv_external() kita bakal nampa rong jinis pesen.

Wiwit kontrak kita bakal nglumpukake kerugian pemain, dhuwit iki kudu ditransfer menyang panyipta lotre. Alamat dompet saka panyipta lotre dicathet ing panyimpenan nalika kontrak digawe.

Mung ing kasus, kita kudu kemampuan kanggo ngganti alamat sing kita ngirim gram kapitunan. Kita uga kudu bisa ngirim gram saka lotre menyang alamat pemilik.

Ayo dadi miwiti karo pisanan. Ayo pisanan nulis tes sing bakal mriksa yen sawise ngirim pesen, kontrak pinter nyimpen alamat anyar ing panyimpenan. Wigati dimangerteni manawa ing pesen kasebut, saliyane menyang counter lan alamat anyar, kita uga ngirim action A nomer non-negatif integer 7-bit, gumantung ing, kita bakal milih carane proses pesen ing kontrak pinter.

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

Ing test sampeyan bisa ndeleng carane panyimpenan smartcontract wis deserialized storage ing Lima. Deserialisasi variabel diterangake ing dokumentasi Fift.

Komit link karo tambahan adonan.

Ayo nglakoni tes lan priksa manawa gagal. Saiki ayo nambah logika kanggo ngganti alamat pemilik lotre.

Ing kontrak pinter kita terus ngurai message, maca ing action. Ayo kita ngelingake yen kita bakal duwe loro action: ngganti alamat lan ngirim gram.

Banjur kita maca alamat anyar saka pemilik kontrak lan nyimpen ing panyimpenan.
Kita mbukak tes lan ndeleng manawa tes katelu gagal. Kacilakan amarga kasunyatane kontrak saiki uga ngurai 7 bit saka pesen, sing ora ana ing tes kasebut. Tambah pesen sing ora ana action. Ayo dadi mbukak tes lan ndeleng sing kabeh liwat. kene prasetya kanggo owah-owahan. Agung.

Saiki ayo nulis logika kanggo ngirim nomer gram sing ditemtokake menyang alamat sing disimpen sadurunge.

Pisanan, ayo nulis tes. Kita bakal nulis loro tes, siji nalika ora cukup imbangan, kaloro nalika kabeh kudu sukses. Tes bisa dideleng ing komitmen iki.

Saiki ayo nambah kode. Pisanan, ayo nulis rong metode helper. Cara entuk pisanan yaiku ngerteni imbangan kontrak cerdas saiki.

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

Lan sing nomer loro yaiku ngirim gram menyang kontrak cerdas liyane. Aku rampung nyalin cara iki saka kontrak pinter liyane.

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

Ayo nambahake rong cara kasebut menyang kontrak cerdas lan tulis logika. Pisanan, kita parse nomer gram saka pesen. Sabanjure kita mriksa imbangan, yen ora cukup kita uncalan pangecualian. Yen kabeh apik, banjur kita ngirim gram menyang alamat sing disimpen lan nganyari counter.

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

Kene mangkono katon kaya kontrak pinter ing wayahe. Ayo nglakoni tes lan priksa manawa dheweke lulus.

Miturut cara, komisi dipotong saka kontrak pinter saben wektu kanggo pesen sing diproses. Supaya pesen kontrak cerdas bisa nindakake panjaluk kasebut, sawise mriksa dhasar sampeyan kudu nelpon accept_message().

Saiki ayo pindhah menyang pesen internal. Ing kasunyatan, kita mung bakal nampa gram lan ngirim bali pindho jumlah kanggo pamuter yen menang lan katelu kanggo pemilik yen ilang.

Pisanan, ayo nulis tes prasaja. Kanggo nindakake iki, kita kudu alamat test saka kontrak pinter saka kang kita ngirim ngirim gram kanggo kontrak pinter.

Alamat kontrak cerdas kasusun saka rong nomer, integer 32-bit sing tanggung jawab kanggo workchain lan nomer akun unik 256-bit non-negatif integer ing workchain iki. Contone, -1 lan 12345, iki alamat sing bakal disimpen ing file.

Aku nyalin fungsi kanggo nyimpen alamat saka 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

Ayo kang katon ing carane fungsi bisa, iki bakal menehi pangerten carane Fift dianggo. Bukak Fift ing mode interaktif.

~/TON/build/crypto/fift -i 

Pisanan kita push -1, 12345 lan jeneng file mangsa "sender.addr" menyang tumpukan:

-1 12345 "sender.addr" 

Langkah sabanjure yaiku nglakokake fungsi kasebut -rot, sing ngowahi tumpukan kanthi cara sing ing ndhuwur tumpukan ana nomer kontrak cerdas sing unik:

"sender.addr" -1 12345

256 u>B Ngonversi integer non-negatif 256-bit dadi bita.

"sender.addr" -1 BYTES:0000000000000000000000000000000000000000000000000000000000003039

swap ngganti rong unsur ndhuwur tumpukan.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 -1

32 i>B Ngonversi integer 32-bit dadi bita.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 BYTES:FFFFFFFF

B+ nyambungake rong urutan bita.

 "sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF

Maneh swap.

BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF "sender.addr" 

Lan pungkasane bait ditulis menyang file B>file. Sawise iki tumpukan kita kosong. Kita mandheg Fift. Berkas wis digawe ing folder saiki sender.addr. Ayo pindhah file menyang folder digawe test/addresses/.

Ayo nulis tes prasaja sing bakal ngirim gram menyang kontrak cerdas. Punika komitmen.

Saiki ayo dideleng ing logika lotre.

Wangsulan: Bab ingkang pisanan kita tindakake iku mriksa pesen bounced utawa ora yen bounced, banjur kita nglirwakake. bounced tegese kontrak bakal ngasilake gram yen ana kesalahan. Kita ora bakal bali gram yen ana kesalahan dumadakan.

Kita mriksa, yen imbangan kurang saka setengah gram, banjur kita mung nampa pesen lan nglirwakake.

Sabanjure, kita ngurai alamat kontrak cerdas saka pesen kasebut.

Kita maca data saka panyimpenan lan banjur mbusak taruhan lawas saka sajarah yen ana luwih saka rong puluh. Kanggo penak, aku nulis telung fungsi tambahan pack_order(), unpack_order(), remove_old_orders().

Sabanjure, kita katon yen imbangan ora cukup kanggo pembayaran, banjur kita nimbang sing iki dudu taruhan, nanging replenishment lan nyimpen replenishment ing. orders.

Banjur pungkasane inti saka kontrak pinter.

First, yen pamuter ilang, kita nyimpen ing sajarah totoan lan yen jumlah luwih saka 3 gram, kita ngirim 1/3 kanggo pemilik saka kontrak pinter.

Yen pamuter menang, banjur kita ngirim pindho jumlah kanggo alamat pamuter lan banjur nyimpen informasi bab nang ing sajarah.

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

Sing kabeh. Komitmen sing cocog.

Saiki kabeh sing isih gampang, ayo nggawe metode entuk supaya bisa entuk informasi babagan kahanan kontrak saka jagad njaba (nyatane, maca data saka panyimpenan kontrak cerdas).

Ayo nambah metode njaluk. Kita bakal nulis ing ngisor iki babagan cara nampa informasi babagan kontrak cerdas.

Aku uga kelalen nambah kode sing bakal ngolah panjalukan pisanan sing kedadeyan nalika nerbitake kontrak cerdas. Komitmen sing cocog. Lan luwih didandani bug karo ngirim 1/3 saka jumlah kanggo akun pemilik.

Langkah sabanjure yaiku nerbitake kontrak cerdas. Ayo nggawe folder requests.

Aku njupuk kode publikasi minangka basis simple-wallet-code.fc kang bisa nggoleki ing repositori resmi.

Soko worth mbayar manungsa waΓ© kanggo. We generate panyimpenan kontrak pinter lan pesen input. Sawise iki, alamat kontrak cerdas digawe, yaiku, alamat kasebut dikenal sanajan sadurunge diterbitake ing TON. Sabanjure, sampeyan kudu ngirim sawetara gram menyang alamat iki, lan mung sawise sampeyan kudu ngirim file karo kontrak pinter dhewe, amarga jaringan njupuk komisi kanggo nyimpen kontrak pinter lan operasi ing (validators sing nyimpen lan nglakokakΓ© pinter. kontrak). Kode kasebut bisa dideleng ing kene.

Sabanjure kita nglakokake kode penerbitan lan entuk lottery-query.boc file kontrak pinter lan alamat.

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

Aja lali nyimpen file sing digawe: lottery-query.boc, lottery.addr, lottery.pk.

Antarane liyane, kita bakal weruh alamat kontrak pinter ing log eksekusi.

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

Mung kanggo seneng-seneng, ayo nggawe panjalukan kanggo TON

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

Lan kita bakal weruh manawa akun kanthi alamat iki kosong.

account state is empty

Kita ngirim menyang alamat 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd 2 Gram lan sawise sawetara detik kita nglakokakΓ© printah padha. Kanggo ngirim gram aku nggunakake dompet resmi, lan sampeyan bisa takon wong saka chatting kanggo test gram, kang aku bakal pirembagan bab ing mburi artikel.

> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Katon kaya ora ngerti (state:account_uninit) kontrak pinter kanthi alamat sing padha lan imbangan 1 nanogram.

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

Saiki ayo nerbitake kontrak cerdas. Ayo miwiti lite-klien lan eksekusi.

> 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 

Ayo priksa manawa kontrak kasebut wis diterbitake.

> last
> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Antarane liyane kita njaluk.

  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

We ndeleng sing account_active.

Komitmen sing cocog karo owah-owahan tengen kene.

Saiki ayo nggawe panjalukan kanggo sesambungan karo kontrak cerdas.

Luwih tepat, kita bakal ninggalake sing pisanan kanggo ngganti alamat minangka karya independen, lan kita bakal nindakake sing liya kanggo ngirim gram menyang alamat pemilik. Nyatane, kita kudu nindakake perkara sing padha kaya ing tes kanggo ngirim gram.

Iki pesen sing bakal dikirim menyang kontrak pinter, ngendi msg_seqno 165, action 2 lan 9.5 gram kanggo ngirim.

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

Aja lali mlebu pesen nganggo kunci pribadi sampeyan lottery.pk, sing digawe sadurunge nalika nggawe kontrak pinter. Mangkene komitmen sing cocog.

Nampa informasi saka kontrak pinter nggunakake metode get

Saiki ayo goleki carane mbukak metode kontrak cerdas.

Bukak lite-client lan mbukak cara njaluk sing kita tulis.

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

Π’ result ngemot nilai sing bali fungsi balance() saka kontrak pinter kita.
Kita bakal nindakake sing padha kanggo sawetara cara liyane.

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

Ayo takon sejarah taruhan sampeyan.

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

Kita bakal nggunakake lite-klien lan njaluk cara kanggo nampilake informasi babagan kontrak pinter ing situs.

Nampilake data kontrak cerdas ing situs web

Aku nulis situs web prasaja ing Python kanggo nampilake data saka kontrak pinter kanthi cara sing trep. Ing kene aku ora bakal ngrembug kanthi rinci lan bakal nerbitake situs kasebut ing siji komitmen.

Panjalukan kanggo TON digawe saka Python kanthi pitulung saka lite-client. Kanggo penak, situs kasebut dikemas ing Docker lan diterbitake ing Google Cloud. Link.

Ayo jajal

Saiki ayo kang nyoba kanggo ngirim gram ana kanggo replenishment saka dompet. Kita bakal ngirim 40 gram. Lan ayo nggawe saperangan taruhan kanggo gamblang. Kita waca sing situs nuduhake sajarah taruhan, persentasi menang saiki lan informasi migunani liyane.

Kita ndelengyen kita menang pisanan, kalah kaloro.

Afterword

Artikel kasebut dadi luwih suwe tinimbang sing dakkarepake, bisa uga luwih cendhek, utawa mung kanggo wong sing ora ngerti apa-apa babagan TON lan pengin nulis lan nerbitake kontrak cerdas sing ora prasaja kanthi kemampuan kanggo sesambungan karo iku. Mbok menawa sawetara bab bisa diterangake luwih gampang.

Mbok menawa sawetara aspek implementasine bisa ditindakake kanthi luwih efisien lan elegan, nanging banjur bakal entuk wektu luwih akeh kanggo nyiapake artikel kasebut. Sampeyan uga bisa uga ana kesalahan ing endi wae utawa ora ngerti apa-apa, mula yen sampeyan nindakake perkara sing serius, sampeyan kudu ngandelake dokumentasi resmi utawa gudang resmi kanthi kode TON.

Perlu dicathet yen wiwit TON dhewe isih ana ing tahap pangembangan aktif, owah-owahan bisa kedadeyan sing bakal ngilangi langkah-langkah ing artikel iki (sing kedadeyan nalika aku nulis, wis didandani), nanging pendekatan umum yaiku ora mungkin kanggo ngganti.

Aku ora bakal ngomong babagan masa depan TON. Bisa uga platform kasebut bakal dadi gedhe lan kita kudu nggunakake wektu kanggo sinau lan ngisi ceruk karo produk kita saiki.

Ana uga Libra saka Facebook, sing nduweni pamirsa potensial pangguna sing luwih gedhe tinimbang TON. Aku meh ora ngerti apa-apa bab Libra, kang menehi kritik dening forum ana kegiatan luwih akeh tinimbang ing masyarakat TON. Sanajan pangembang lan komunitas TON luwih kaya lemah, sing uga keren.

referensi

  1. Dokumentasi resmi TON: https://test.ton.org
  2. Repositori TON resmi: https://github.com/ton-blockchain/ton
  3. Dompet resmi kanggo macem-macem platform: https://wallet.ton.org
  4. Repositori kontrak cerdas saka artikel iki: https://github.com/raiym/astonished
  5. Link menyang situs web kontrak cerdas: https://ton-lottery.appspot.com
  6. Repositori ekstensi kanggo Visual Studio Code kanggo FunC: https://github.com/raiym/func-visual-studio-plugin
  7. Ngobrol babagan TON ing Telegram, sing pancene mbantu ngerteni ing tahap wiwitan. Aku ora bakal salah yen aku ngomong sing saben wong sing nulis soko kanggo TON ana. Sampeyan uga bisa njaluk test gram ana. https://t.me/tondev_ru
  8. Obrolan liyane babagan TON sing aku nemokake informasi sing migunani: https://t.me/TONgramDev
  9. Tahap pisanan kompetisi: https://contest.com/blockchain
  10. Tahap kapindho kompetisi: https://contest.com/blockchain-2

Source: www.habr.com

Add a comment