Ngeunaan kumaha cara nyerat sareng nyebarkeun kontrak pinter dina Telegram Open Network (TON)

Ngeunaan kumaha cara nyerat sareng nyebarkeun kontrak pinter dina TON

Naon artikel ieu ngeunaan?

Dina artikel kuring bakal ngobrol ngeunaan kumaha kuring ilubiung dina kompetisi blockchain munggaran (dua) Telegram, henteu nyandak hadiah, sareng mutuskeun pikeun ngarékam pangalaman kuring dina tulisan supados henteu tilelep kana oblivion sareng, panginten, ngabantosan. batur.

Kusabab kuring henteu hoyong nyerat kode abstrak, tapi pikeun ngalakukeun hal anu damel, pikeun tulisan kuring nyerat kontrak pinter pikeun lotre sakedapan sareng halaman wéb anu nunjukkeun data kontrak pinter langsung ti TON tanpa nganggo panyimpenan panengah.

Tulisan éta bakal mangpaat pikeun anu hoyong ngadamel kontrak pinter munggaran di TON, tapi henteu terang dimana ngamimitian.

Ngagunakeun lotre sabagé conto, kuring bakal balik ti masang lingkungan pikeun medarkeun kontrak pinter, interacting jeung eta, sarta nulis ramatloka pikeun narima jeung nyebarkeun data.

Ngeunaan partisipasi dina kompetisi

Oktober kamari, Telegram ngumumkeun kompetisi blockchain kalawan basa anyar Fift и FunC. Ieu diperlukeun pikeun milih ti nulis salah sahiji lima kontrak pinter diusulkeun. Panginten éta langkung saé pikeun ngalakukeun hal anu béda, diajar basa sareng ngadamel hiji hal, sanaos kuring henteu kedah nyerat anu sanés deui ka hareup. Tambih Deui, topik anu terus dina biwir.

Eta sia nyebutkeun yen kuring teu boga pangalaman ngembangkeun kontrak pinter.

Kuring ngarencanakeun pikeun ilubiung dugi ka akhir dugi ka kuring tiasa teras nyerat tulisan ulasan, tapi kuring gagal langsung dina anu munggaran. abdi nulis dompét kalawan multi-signature on FunC sarta umumna digawé. Kuring nyandak eta salaku dadasar kontrak pinter dina Solidity.

Waktu éta, kuring ngira yén ieu pasti cukup pikeun nyandak sahenteuna sababaraha tempat hadiah. Hasilna, kira-kira 40 tina 60 pamilon anu meunang hadiah sareng kuring henteu kalebet. Sacara umum, teu aya anu lepat sareng ieu, tapi hiji hal anu ngaganggu kuring. Dina waktu pengumuman hasil, resensi tes kontrak kuring teu acan rengse, kuring nanya ka pamilon obrolan lamun aya batur nu teu boga, teu aya.

Tétéla nengetan seratan kuring, dua poé sanggeusna hakim diterbitkeun komentar na kuring masih teu ngarti naha maranéhna ngahaja lasut kontrak pinter kuring salila ditilik atawa ngan saukur ngira yén éta jadi goréng yén éta teu perlu komentar. Kuring naroskeun patarosan dina halaman, tapi henteu nampi jawaban. Sanajan éta euweuh rusiah anu judged, Kuring dianggap teu perlu nulis pesen pribadi.

A loba waktu ieu spent dina pamahaman, jadi ieu mutuskeun pikeun nulis artikel. Kusabab teu aya seueur inpormasi, tulisan ieu bakal ngabantosan waktos pikeun sadayana anu resep.

Konsep kontrak pinter dina TON

Sateuacan anjeun nyerat naon waé, anjeun kedah terang sisi mana pikeun ngadeukeutan hal ieu. Ku alatan éta, ayeuna kuring bakal ngabejaan Anjeun naon bagian sistem diwangun ku. Leuwih tepat, bagian naon nu peryogi kauninga dina urutan nulis sahenteuna sababaraha jenis kontrak kerja.

Urang bakal difokuskeun nulis kontrak pinter jeung gawé bareng TON Virtual Machine (TVM), Fift и FunC, jadi artikel leuwih kawas pedaran ngeunaan ngembangkeun program biasa. Kami moal mikirkeun kumaha platformna sorangan di dieu.

Sacara umum ngeunaan kumaha gawéna TVM jeung basa Fift aya dokuméntasi resmi anu saé. Nalika miluan kompetisi sareng ayeuna bari nyerat kontrak ayeuna, kuring sering ngalieuk ka anjeunna.

Basa utama dimana kontrak pinter ditulis nyaéta FunC. Henteu aya dokuméntasi dina éta ayeuna, janten pikeun nyerat hiji hal anjeun kedah diajar conto kontrak pinter ti gudang resmi sareng palaksanaan basa sorangan di dinya, tambah anjeun tiasa ningali conto kontrak pinter ti dua katukang. pasanggiri. Tumbu di ahir artikel.

Anggap urang parantos nyerat kontrak pinter FunC, Sanggeus éta urang compile kode kana Fift assembler.

Kontrak pinter anu disusun tetep diterbitkeun. Jang ngalampahkeun ieu anjeun kudu nulis fungsi dina Fift, anu bakal nyandak kode kontrak pinter sareng sababaraha parameter sanésna salaku input, sareng kaluaranna bakal janten file kalayan ekstensi .boc (anu hartosna "kantong sél"), sareng, gumantung kana kumaha urang nyerat, konci sareng alamat pribadi, anu didamel dumasar kana kode kontrak pinter. Anjeun parantos tiasa ngirim gram ka alamat kontrak pinter anu henteu acan diterbitkeun.

Pikeun nyebarkeun kontrak pinter dina TON narima .boc file bakal perlu dikirim ka blockchain ngagunakeun klien lampu (langkung lengkep ihwal nu handap). Tapi sateuacan nyebarkeun, anjeun kedah nransper gram ka alamat anu dibangkitkeun, upami henteu, kontrak pinter moal diterbitkeun. Saatos publikasi, anjeun tiasa berinteraksi sareng kontrak pinter ku ngirim pesen ti luar (contona, nganggo klien lampu) atanapi ti jero (contona, hiji kontrak pinter ngirim pesen anu sanés di jero TON).

Sakali kami ngartos kumaha kode ieu diterbitkeun, janten gampang. Urang kasarna terang naon anu urang hoyong nyerat sareng kumaha program urang bakal jalan. Sareng nalika nyerat, urang milarian kumaha ieu parantos dilaksanakeun dina kontrak pinter anu tos aya, atanapi urang ningali kana kode palaksanaan Fift и FunC dina Repository resmi, atanapi tingali dina dokuméntasi resmi.

Sering pisan kuring milarian kecap konci dina obrolan Telegram dimana sadaya pamilon kompetisi sareng karyawan Telegram kumpul, sareng kajantenan nalika kompetisi sadayana ngumpul di dinya sareng ngamimitian ngabahas Fift sareng FunC. Link di ahir artikel.

Waktosna pikeun ngalih tina téori ka prakték.

Nyiapkeun lingkungan pikeun gawé bareng TON

Kuring ngalakukeun sadayana anu bakal dijelaskeun dina tulisan dina MacOS sareng pariksa dua kali dina bersih Ubuntu 18.04 LTS dina Docker.

Hal kahiji anu anjeun kedah laksanakeun nyaéta unduh sareng pasang lite-client kalawan nu bisa ngirim requests ka TON.

Parentah dina situs wéb resmi ngajelaskeun prosés pamasangan sacara rinci sareng jelas sareng ngaleungitkeun sababaraha detil. Di dieu urang turutan parentah, masang dependensi leungit sapanjang jalan. Kuring henteu nyusun unggal proyék sorangan sareng dipasang tina gudang resmi Ubuntu (dina MacOS anu kuring dianggo 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 

Sakali sadayana katergantungan dipasang anjeun tiasa pasang lite-client, Fift, FunC.

Kahiji, urang clone gudang TON babarengan jeung kagumantungan na. Pikeun genah, urang bakal ngalakukeun sagalana dina polder ~/TON.

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

Repositori ogé nyimpen palaksanaan Fift и FunC.

Ayeuna kami siap ngumpul proyek. Kodeu gudang diklon kana polder ~/TON/ton. The ~/TON nyieun polder build sarta ngumpulkeun proyék di dinya.

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

Kusabab urang bade nulis kontrak pinter, urang kudu teu ukur lite-clienttapi Fift с FunC, ku kituna hayu urang ngumpulkeun sagalana. Éta sanés prosés anu gancang, janten urang ngantosan.

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

Salajengna, unduh file konfigurasi anu ngandung data ngeunaan node anu mana lite-client bakal nyambung.

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

Nyieun requests munggaran ka TON

Ayeuna hayu urang ngajalankeun lite-client.

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

Upami ngawangun éta suksés, teras saatos peluncuran anjeun bakal ningali log sambungan klien lampu kana titik.

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

Anjeun tiasa ngajalankeun paréntah help tur tingal Paréntah naon sadia.

help

Hayu urang daptar paréntah anu bakal kami anggo dina tulisan ieu.

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

Ayeuna urang siap nulis kontrak sorangan.

Реализация

gagasan

Sakumaha anu kuring nyerat di luhur, kontrak pinter anu kami tulis nyaéta lotre.

Sumawona, ieu sanés lotre dimana anjeun kedah mésér tikét sareng ngantosan sajam, dinten atanapi sasih, tapi sakedapan dimana pangguna mindahkeun ka alamat kontrak. N gram, sarta langsung meunang deui 2 * N gram atawa leungit. Kami bakal ngajantenkeun kamungkinan meunang sakitar 40%. Upami teu aya cukup gram pikeun pamayaran, maka kami bakal nganggap transaksi éta salaku top-up.

Leuwih ti éta, hal anu penting nu bets bisa ditempo sacara real waktu jeung dina formulir merenah, ku kituna pamaké bisa langsung ngarti naha anjeunna meunang atawa leungit. Kituna, anjeun kudu nyieun hiji ramatloka anu bakal némbongkeun bets sarta hasil langsung ti TON.

Nulis kontrak pinter

Pikeun genah, kuring parantos nyorot kodeu pikeun FunC; plugin tiasa dipendakan sareng dipasang dina pamilarian Visual Studio Code; upami anjeun ujug-ujug hoyong nambihan hiji hal, kuring parantos ngajantenkeun plugin éta sayogi umum. Ogé, batur saacanna ngadamel plugin pikeun gawé bareng Fift, anjeun ogé tiasa masang sareng mendakanana di VSC.

Hayu urang geura-giru nyieun gudang dimana urang bakal ngalakukeun hasil panengah.

Pikeun ngagampangkeun kahirupan urang, urang bakal nyerat kontrak pinter sareng nguji sacara lokal dugi ka siap. Ngan sanggeus éta urang bakal nyebarkeun eta di TON.

Kontrak pinter ngagaduhan dua metode éksternal anu tiasa diaksés. kahiji, recv_external() fungsi ieu dieksekusi nalika pamundut ka kontrak asalna ti dunya luar, nyaeta, teu ti TON, contona, nalika urang sorangan ngahasilkeun pesen na ngirimkeunana ngaliwatan lite-klien. kadua, recv_internal() Ieu nalika, dina TON sorangan, sagala kontrak nujul kana kami. Dina duanana kasus, Anjeun bisa lulus parameter ka fungsi.

Hayu urang mimitian ku conto saderhana anu bakal dianggo upami diterbitkeun, tapi henteu aya beban fungsional.

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

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

Di dieu urang kudu ngajelaskeun naon éta slice. Sadaya data anu disimpen dina TON Blockchain mangrupikeun kumpulan TVM cell atawa sakadar cell, dina sél sapertos anjeun tiasa nyimpen nepi ka 1023 bit data jeung nepi ka 4 tumbu ka sél séjén.

TVM cell slice atawa slice ieu bagian tina hiji aya cell dipaké pikeun parse eta, eta bakal jadi jelas engké. Hal utama pikeun urang nyaéta yén urang tiasa mindahkeun slice sarta gumantung kana jenis pesen, ngolah data dina recv_external() atawa recv_internal().

impure - kecap konci anu nunjukkeun yén fungsina ngarobih data kontrak pinter.

Hayu urang simpen kode kontrak di lottery-code.fc jeung nyusun.

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

Harti bandéra tiasa ditingali nganggo paréntah

~/TON/build/crypto/func -help

Kami geus disusun Lima kode assembler di 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

Éta tiasa diluncurkeun sacara lokal, pikeun ieu kami bakal nyiapkeun lingkungan.

Catet yén garis kahiji nyambungkeun Asm.fif, Ieu kode ditulis dina Lima pikeun assembler Lima.

Kusabab urang hoyong ngajalankeun sareng nguji kontrak pinter sacara lokal, kami bakal nyiptakeun file lottery-test-suite.fif sareng salin kodeu anu disusun di dinya, ngagentos baris terakhir di jerona, anu nyerat kode kontrak pinter kana konstanta. codelajeng mindahkeun eta ka 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

Sajauh ieu sigana jelas, ayeuna hayu urang tambahkeun kana file anu sami kodeu anu bakal kami anggo pikeun ngaluncurkeun 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 urang ngarékam kontéks, nyaéta, data sareng TVM (atanapi kaayaan jaringan) bakal diluncurkeun. Malah dina mangsa kompetisi, salah sahiji pamekar némbongkeun cara nyieun c7 sarta kuring disalin. Dina artikel ieu urang bisa jadi kudu ngarobah rand_seed saprak generasi angka acak gumantung kana eta jeung lamun teu robah, jumlah anu sarua bakal balik unggal waktu.

recv_internal и recv_external konstanta kalawan nilai 0 jeung -1 bakal nanggungjawaban kanggo nelepon fungsi pakait dina kontrak pinter.

Ayeuna kami siap nyieun tés munggaran pikeun kontrak pinter kosong urang. Pikeun kajelasan, ayeuna urang bakal nambihan sadaya tés kana file anu sami lottery-test-suite.fif.

Hayu urang nyieun variabel storage jeung nulis hiji kosong kana eta cell, ieu bakal gudang kontrak pinter.

message Ieu pesen anu bakal kami kirimkeun ka kontak pinter ti luar. Urang ogé bakal nyieun kosong pikeun ayeuna.

variable storage 
<b b> storage ! 

variable message 
<b b> message ! 

Saatos urang nyiapkeun konstanta sareng variabel, urang ngajalankeun TVM nganggo paréntah runvmctx tur lulus parameter dijieun kana input.

message @ 
recv_external 
code 
storage @ 
c7 
runvmctx 

Dina tungtungna urang bakal sukses siga kitu kode panengah pikeun Fift.

Ayeuna urang tiasa ngajalankeun kode anu dihasilkeun.

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

Programna kedah dijalankeun tanpa kasalahan sareng dina kaluaran urang bakal ningali log palaksanaan:

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

Hébat, kami parantos nyerat versi kerja munggaran tina kontrak pinter.

Ayeuna urang kedah nambihan fungsionalitas. Kahiji hayu urang nungkulan pesen anu datang ti dunya luar ka recv_external()

Pamekar sorangan milih format pesen anu tiasa ditampi ku kontrak.

Tapi biasana

  • firstly, urang rék ngajaga kontrak urang ti dunya luar jeung nyieun ku kituna ngan nu boga kontrak bisa ngirim pesen éksternal ka dinya.
  • kadua, lamun urang ngirim pesen valid ka TON, urang hoyong ieu lumangsung persis sakali jeung lamun urang ngirim pesen sarua deui, kontrak pinter nampik eta.

Janten ampir unggal kontrak ngabéréskeun dua masalah ieu, sabab kontrak kami nampi pesen éksternal, kami ogé kedah ngurus éta.

Urang bakal ngalakukeun dina urutan sabalikna. Kahiji, hayu urang ngabéréskeun masalah ku pengulangan; upami kontrak parantos nampi pesen sapertos kitu sareng ngolah éta, éta moal dieksekusi kadua kalina. Teras kami bakal ngabéréskeun masalah éta ngan ukur sababaraha jalma anu tiasa ngirim pesen ka kontrak pinter.

Aya sababaraha cara pikeun ngabéréskeun masalah sareng pesen duplikat. Ieu kumaha urang bakal ngalakukeunana. Dina kontrak pinter, urang initialize counter tina pesen nampi kalayan nilai awal 0. Dina unggal pesen ka kontrak pinter, urang bakal nambahan nilai counter ayeuna. Upami nilai counter dina pesen henteu cocog sareng nilai dina kontrak pinter, maka kami henteu ngolah éta; upami éta, maka kami ngolah sareng ningkatkeun counter dina kontrak pinter ku 1.

Hayu urang balik ka lottery-test-suite.fif sareng tambahkeun tés kadua pikeun éta. Lamun urang ngirim hiji nomer lepat, kode kudu buang iwal. Contona, hayu data kontrak nyimpen 166, sarta kami 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"

Hayu urang ngajalankeun.

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

Sareng urang bakal ningali yén tés dilaksanakeun kalayan kasalahan.

[ 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

Dina tahap ieu lottery-test-suite.fif kudu kasampak kawas link.

Ayeuna hayu urang tambahkeun logika kontra kana kontrak pinter dina 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 perenahna pesen urang kirimkeun.

Hal kahiji anu urang laksanakeun nyaéta mariksa upami pesen ngandung data, upami henteu, maka urang ngan ukur kaluar.

Salajengna urang parse pesen. in_msg~load_uint(32) beban angka 165, 32-bit unsigned int tina pesen anu dikirimkeun.

Salajengna urang muka 32 bit ti gudang kontrak pinter. Kami pariksa yén nomer anu dimuat cocog sareng anu lulus; upami henteu, urang buang pengecualian. Dina kasus urang, saprak urang ngalirkeun non-cocok, iwal kudu dialungkeun.

Ayeuna hayu urang nyusun.

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

Nyalin kodeu hasilna ka lottery-test-suite.fif, teu hilap ngagentos baris terakhir.

Kami pariksa yén tés lulus:

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

Di dieu Anjeun tiasa ningali komitmen anu saluyu sareng hasil ayeuna.

Catet yén éta henteu pikaresepeun pikeun terus-terusan nyalin kodeu kontrak pinter anu disusun kana file kalayan tés, ku kituna urang bakal nyerat naskah anu bakal nyerat kodeu janten konstanta pikeun urang, sareng urang ngan saukur bakal nyambungkeun kode anu disusun kana tés kami nganggo. "include".

Jieun file dina folder proyék build.sh kalawan eusi ieu di handap.

#!/bin/bash

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

Hayu urang laksanakeun.

chmod +x ./build.sh

Ayeuna, jalankeun skrip kami pikeun nyusun kontrak. Tapi salian ti ieu, urang kedah nyerat kana konstanta code. Janten urang bakal nyiptakeun file énggal lotter-compiled-for-test.fif, nu urang bakal kaasup dina file lottery-test-suite.fif.

Hayu urang tambahkeun kode rok ka sh, anu ngan saukur bakal duplikat file anu disusun lotter-compiled-for-test.fif sarta ngarobah garis panungtungan di dinya.

# 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

Ayeuna, pikeun pariksa, hayu urang ngajalankeun skrip anu hasilna sareng file bakal dibangkitkeun lottery-compiled-for-test.fif, nu urang bakal kaasup dina urang lottery-test-suite.fif

В lottery-test-suite.fif ngahapus kode kontrak tur nambahkeun garis "lottery-compiled-for-test.fif" include.

Kami ngajalankeun tés pikeun mariksa yén aranjeunna lulus.

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

Hébat, ayeuna pikeun ngajadikeun otomatis peluncuran tés, hayu urang jieun file test.sh, anu bakal dieksekusi heula build.sh, lajeng ngajalankeun tés.

touch test.sh
chmod +x test.sh

Urang nulis di jero

./build.sh 

echo "nCompilation completedn"

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

Hayu urang laksanakeun test.sh tur ngajalankeun eta pikeun mastikeun tes jalan.

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

Kami pariksa yén kontrak disusun sareng tés dilaksanakeun.

Hebat, ayeuna nuju ngamimitian test.sh Tés bakal disusun sareng dijalankeun langsung. Ieu link ka komitmen.

Oké, saméméh urang neruskeun, hayu urang ngalakukeun hiji deui hal pikeun genah.

Hayu urang nyieun polder build dimana urang bakal nyimpen kontrak disalin sarta clone na ditulis kana konstanta lottery-compiled.fif, lottery-compiled-for-test.fif. Hayu urang ogé nyieun polder test dimana file tés bakal disimpen? lottery-test-suite.fif sareng file pangrojong anu berpotensi sanésna. Tumbu ka parobahan relevan.

Hayu urang teraskeun ngembangkeun kontrak pinter.

Salajengna kedah aya tes anu mariksa yén pesen anu ditampi sareng loket diropéa di toko nalika kami ngirimkeun nomer anu leres. Tapi urang bakal ngalakukeun éta engké.

Ayeuna hayu urang pikir ngeunaan struktur data naon sareng data naon anu kedah disimpen dina kontrak pinter.

Kuring bakal ngajelaskeun sagalana yén urang 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` переменная типа словарь, хранит последние двадцать ставок. 

Satuluyna anjeun perlu nulis dua fungsi. Hayu urang nelepon heula pack_state(), nu bakal pak data pikeun nyimpen saterusna dina gudang kontrak pinter. Hayu urang nelepon kadua unpack_state() bakal maca jeung mulangkeun data ti gudang.

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

Urang tambahkeun dua fungsi ieu ka awal kontrak pinter. Bakal jalan kaluar siga kitu hasil panengah.

Pikeun nyimpen data anjeun kedah nyauran fungsi anu diwangun set_data() sarta eta bakal nulis data ti pack_state() dina gudang kontrak pinter.

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

Ayeuna urang gaduh fungsi anu merenah pikeun nyerat sareng maca data, urang tiasa ngaléngkah.

Urang kedah pariksa yén pesen anu datang ti luar ditandatanganan ku nu gaduh kontrak (atanapi pangguna sanés anu ngagaduhan aksés kana konci pribadi).

Nalika urang nyebarkeun kontrak pinter, urang tiasa initialize eta kalawan data urang kudu di gudang, nu bakal disimpen pikeun pamakéan hareup. Kami bakal ngarékam konci umum di dinya supados urang tiasa pariksa yén pesen anu asup ditandatanganan nganggo konci pribadi anu cocog.

Sateuacan neraskeun, hayu urang ngadamel konci pribadi sareng nyeratna test/keys/owner.pk. Jang ngalampahkeun ieu, hayu urang ngajalankeun Fift dina modeu interaktif tur ngajalankeun opat paréntah.

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

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

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

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

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

Hayu urang nyieun polder keys jero polder test jeung nulis konci swasta aya.

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

Kami ningali file dina folder ayeuna owner.pk.

Urang miceun konci publik tina tumpukan jeung lamun diperlukeun urang bisa meunangkeun eta ti swasta.

Ayeuna urang kedah nyerat verifikasi tandatangan. Hayu urang mimitian ku tés. Mimiti urang baca konci pribadi tina file nganggo fungsina file>B sareng nyerat kana variabel owner_private_key, teras nganggo fungsi priv>pub ngarobah konci swasta kana konci publik jeung nulis hasilna dina 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 !

Urang bakal butuh duanana konci.

Urang initialize gudang kontrak pinter jeung data sawenang dina runtuyan sarua sakumaha dina fungsi pack_state()jeung nuliskeun kana 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 !

Salajengna, urang bakal nyusun pesen anu ditandatanganan, éta ngan ukur ngandung tanda tangan sareng nilai kontra.

Mimiti, urang nyiptakeun data anu urang hoyong kirimkeun, teras urang asupkeun ku konci pribadi sareng tungtungna urang ngahasilkeun pesen anu ditandatanganan.

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 !  

Hasilna, pesen anu bakal kami kirimkeun ka kontrak pinter kacatet dina variabel message_to_send, ngeunaan fungsi hashu, ed25519_sign_uint anjeun tiasa maca dina dokuméntasi Lima.

Jeung ngajalankeun test urang nelepon deui.

message_to_send @ 
recv_external 
code 
storage @
c7
runvmctx

kawas kieu Berkas sareng tés kedah siga kieu dina tahap ieu.

Hayu urang ngajalankeun tés sareng éta bakal gagal, janten urang ngarobih kontrak pinter supados tiasa nampi pesen tina format ieu sareng pariksa tandatangan.

Kahiji, urang ngitung 512 bit tina tanda tangan tina pesen sareng nyerat kana variabel, teras urang ngitung 32 bit tina variabel counter.

Kusabab urang boga fungsi pikeun maca data ti gudang kontrak pinter, urang bakal make eta.

Salajengna nyaéta mariksa counter anu ditransfer sareng neundeun sareng mariksa tandatangan. Upami aya anu henteu cocog, maka urang buang pengecualian kalayan kode anu pas.

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 relevan di dieu.

Hayu urang ngajalankeun tés sareng tingali yén tés kadua gagal. Pikeun dua alesan, aya teu cukup bit dina suratna jeung aya teu cukup bit dina gudang, jadi kode ngadat nalika parsing. Urang kedah nambihan tanda tangan kana pesen anu kami kirimkeun sareng nyalin panyimpenan tina tés anu terakhir.

Dina tés kadua, kami bakal nambihan tandatangan pesen sareng ngarobih gudang kontrak pinter. kawas kieu file kalawan tés Sigana di momen.

Hayu urang nyerat tés kaopat, dimana urang bakal ngirim pesen anu ditandatanganan ku konci pribadi batur. Hayu urang ngadamel konci pribadi anu sanés sareng simpen kana file not-owner.pk. Kami bakal nandatanganan pesen nganggo konci pribadi ieu. Hayu urang ngajalankeun tés sareng pastikeun yén sadaya tés lulus. Komitmen dina momen ieu.

Ayeuna urang tungtungna tiasa ngaléngkah ka ngalaksanakeun logika kontrak pinter.
В recv_external() kami bakal nampa dua jenis pesen.

Kusabab kontrak kami bakal ngumpulkeun karugian pamaén, artos ieu kedah ditransfer ka panyipta lotre. Alamat dompét tina panyipta lotre kacatet dina panyimpenan nalika kontrak didamel.

Ngan bisi, urang kudu kamampuhan pikeun ngarobah alamat nu urang ngirim gram losers. Urang ogé kudu bisa ngirim gram ti lotre ka alamat nu boga urang.

Hayu urang mimitian ku nu kahiji. Hayu urang mimiti nulis tés anu bakal pariksa yén sanggeus ngirim pesen, kontrak pinter nyimpen alamat anyar dina gudang. Punten dicatet yén dina suratna, salian ti counter sareng alamat énggal, kami ogé ngirimkeun action Sajumlah non-négatip 7-bit integer, gumantung kana éta, urang bakal milih kumaha ngolah pesen dina kontrak pinter.

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

Dina tés anjeun tiasa ningali kumaha panyimpen kontrak pinter deserialized storage dina Lima. Deserialisasi variabel dijelaskeun dina dokuméntasi Lima.

Tautan komitmen kalawan adonan ditambahkeun.

Hayu urang ngajalankeun tés sareng pastikeun éta gagal. Ayeuna hayu urang tambahkeun logika pikeun ngarobah alamat nu boga lotre.

Dina kontrak pinter urang neruskeun parse message, maca dina action. Hayu urang ngingetan yén urang bakal boga dua action: ngarobah alamat jeung ngirim gram.

Teras we maca alamat anyar nu boga kontrak sarta simpen dina gudang.
Kami ngajalankeun tés sareng ningali yén tés katilu gagal. Éta ngadat kusabab kanyataan yén kontrak ayeuna ogé ngémutan 7 bit tina pesen, anu leungit dina tés. Tambahkeun hiji non-existent kana suratna action. Hayu urang ngajalankeun tés sareng tingali yén sadayana pas. di dieu komitmen kana parobahan. Hebat.

Ayeuna hayu urang nyerat logika pikeun ngirim jumlah gram anu ditangtukeun ka alamat anu disimpen sateuacana.

Kahiji, hayu urang nulis tés. Kami bakal nyerat dua tés, hiji nalika henteu cekap kasaimbangan, anu kadua nalika sadayana kedah suksés. Tés tiasa ditingali dina komitmen ieu.

Ayeuna hayu urang tambahkeun kode. Kahiji, hayu urang nulis dua métode helper. Metodeu meunang anu munggaran nyaéta pikeun milarian kasaimbangan ayeuna tina kontrak pinter.

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

Sareng anu kadua nyaéta pikeun ngirim gram ka kontrak pinter anu sanés. Kuring nyalin lengkep metode ieu tina kontrak pinter anu sanés.

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

Hayu urang tambahkeun dua metode ieu kana kontrak pinter sareng nyerat logika. Kahiji, urang parse jumlah gram tina suratna. Salajengna urang pariksa kasaimbangan, lamun teu cukup urang buang iwal. Upami sadayana henteu kunanaon, maka kami ngirim gram ka alamat anu disimpen sareng ngapdet loket.

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

kawas kieu Sigana kontrak pinter ayeuna. Hayu urang ngajalankeun tés sareng pastikeun aranjeunna lulus.

Ku jalan kitu, komisi a deducted tina kontrak pinter unggal waktu pikeun pesen olahan. Dina raraga pesen kontrak pinter ngaéksekusi pamundut, sanggeus cék dasar anjeun kudu nelepon accept_message().

Ayeuna hayu urang ngaléngkah ka pesen internal. Kanyataanna, urang ngan bakal nampa gram sarta ngirimkeun deui ganda jumlah ka pamuter lamun manehna ngéléhkeun sarta katilu mun boga lamun manehna leungit.

Kahiji, hayu urang nulis tés basajan. Jang ngalampahkeun ieu, urang peryogi alamat test tina kontrak pinter ti mana urang sakuduna dituju ngirim gram ka kontrak pinter.

Alamat kontrak pinter diwangun ku dua angka, a integer 32-bit jawab workchain jeung 256-bit non-négatip angka akun unik integer dina workchain ieu. Salaku conto, -1 sareng 12345, ieu mangrupikeun alamat anu bakal kami simpen kana file.

Kuring nyalin fungsi pikeun nyimpen alamat tina 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

Hayu urang tingali kumaha fungsina jalan, ieu bakal masihan pamahaman kumaha Fift jalan. Jalankeun Fift dina modeu interaktif.

~/TON/build/crypto/fift -i 

Mimiti urang nyorong -1, 12345 sareng nami file hareup "sender.addr" kana tumpukan:

-1 12345 "sender.addr" 

Lengkah saterusna nyaéta ngaéksekusi fungsi -rot, anu mindahkeun tumpukan ku cara anu di luhur tumpukan aya nomer kontrak pinter anu unik:

"sender.addr" -1 12345

256 u>B ngarobah integer non-négatip 256-bit kana bait.

"sender.addr" -1 BYTES:0000000000000000000000000000000000000000000000000000000000003039

swap swaps dua elemen luhur tumpukan.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 -1

32 i>B ngarobah integer 32-bit kana bait.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 BYTES:FFFFFFFF

B+ nyambungkeun dua sekuen bait.

 "sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF

Deui swap.

BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF "sender.addr" 

Sarta pamustunganana bait ditulis kana file B>file. Saatos ieu tumpukan kami kosong. Urang eureun Fift. A file geus dijieun dina folder ayeuna sender.addr. Hayu urang mindahkeun file ka folder dijieun test/addresses/.

Hayu urang nulis tés basajan anu bakal ngirim gram ka kontrak pinter. Ieu komitmen.

Ayeuna hayu urang nempo logika lotre.

Hal kahiji anu urang lakukeun nyaéta pariksa pesen bounced atanapi henteu upami bounced, lajeng urang malire eta. bounced hartina kontrak bakal balik gram lamun sababaraha kasalahan lumangsung. Urang moal balik gram lamun kasalahan dumadakan lumangsung.

Kami pariksa, upami kasaimbangan kirang ti satengah gram, teras urang nampi pesen sareng teu malire.

Salajengna, urang parse alamat kontrak pinter ti mana pesen sumping.

Urang baca data ti gudang lajeng ngahapus bets heubeul ti sajarah lamun aya leuwih ti dua puluh aranjeunna. Pikeun genah, kuring nulis tilu fungsi tambahan pack_order(), unpack_order(), remove_old_orders().

Salajengna, urang tingali lamun kasaimbangan teu cukup pikeun pamayaran, mangka urang nganggap yén ieu téh lain alungan hiji, tapi replenishment sarta simpen replenishment dina. orders.

Lajeng tungtungna hakekat kontrak pinter.

Kahiji, lamun pamuter nu leungiteun, urang simpen dina sajarah tohan jeung lamun jumlahna leuwih ti 3 gram, urang ngirim 1/3 ka nu boga kontrak pinter.

Lamun pamaén ngéléhkeun , lajeng urang ngirim ganda jumlah ka alamat pamuter urang lajeng nyimpen informasi ngeunaan alungan dina 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));
}

Éta sadayana. Komitmen anu cocog.

Ayeuna sadayana anu tetep saderhana, hayu urang nyiptakeun metode-metode supados urang tiasa nampi inpormasi ngeunaan kaayaan kontrak ti dunya luar (saleresna, maca data tina panyimpenan kontrak pinterna).

Hayu urang tambahkeun metodeu. Kami bakal nyerat di handap ngeunaan kumaha carana nampi inpormasi ngeunaan kontrak pinter.

Kuring ogé poho pikeun nambahkeun kodeu anu bakal ngolah pamundut pisan munggaran anu lumangsung nalika medarkeun kontrak pinter. Komitmen anu cocog. Sareng salajengna dilereskeun bug kalayan ngirim 1/3 tina jumlah ka akun nu boga urang.

Lengkah saterusna nyaéta nyebarkeun kontrak pinter. Hayu urang nyieun polder requests.

Kuring nyokot kode publikasi salaku dadasar simple-wallet-code.fc nu mana tiasa mendakan dina gudang resmi.

Hal anu patut diperhatoskeun. Urang ngahasilkeun gudang kontrak pinter jeung pesen input. Saatos ieu, alamat kontrak pinter dibangkitkeun, nyaéta, alamatna dipikanyaho sateuacan publikasi dina TON. Salajengna, anjeun kedah ngirim sababaraha gram ka alamat ieu, sareng saatos éta anjeun kedah ngirim file kalayan kontrak pinter sorangan, sabab jaringan nyandak komisi pikeun nyimpen kontrak pinter sareng operasi di jerona (validator anu nyimpen sareng ngalaksanakeun pinter. kontrak). Kodeu tiasa ditingali di dieu.

Salajengna urang ngaéksekusi kode penerbitan sarta meunang lottery-query.boc file kontrak pinter jeung alamat.

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

Tong hilap simpen file anu dihasilkeun: lottery-query.boc, lottery.addr, lottery.pk.

Diantara hal séjén, urang bakal ningali alamat kontrak pinter dina log palaksanaan.

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

Ради интереса сделаем запрос в TON

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

Sareng urang bakal ningali yén akun sareng alamat ieu kosong.

account state is empty

Urang kirimkeun ka alamat 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd 2 Gram sareng saatos sababaraha detik urang ngalaksanakeun paréntah anu sami. Pikeun ngirim gram kuring ngagunakeun dompét resmi, tur anjeun bisa nanya batur ti obrolan pikeun gram test, nu kuring bakal ngobrol ngeunaan di ahir artikel.

> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Sigana mah teu dipikanyaah (state:account_uninit) kontrak pinter jeung alamat sarua jeung kasaimbangan 1 nanograms.

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

Ayeuna hayu urang nyebarkeun kontrak pinter. Hayu urang ngajalankeun lite-klien sareng laksanakeun.

> 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 

Hayu urang pariksa yen kontrak geus diterbitkeun.

> last
> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Diantara hal séjén urang meunang.

  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

Kami ningali éta account_active.

Komitmen pakait sareng parobahan di dieu.

Ayeuna hayu urang ngadamel pamundut pikeun berinteraksi sareng kontrak pinter.

Leuwih tepat, urang bakal ninggalkeun kahiji pikeun ngarobah alamat salaku karya bebas, sarta kami bakal ngalakukeun kadua pikeun ngirim gram ka alamat nu boga. Nyatana, urang kedah ngalakukeun hal anu sami sapertos dina tés pikeun ngirim gram.

Ieu pesen anu bakal kami kirimkeun ka kontrak pinter, dimana msg_seqno 165, action 2 jeung 9.5 gram pikeun ngirim.

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

Tong hilap asup pesen nganggo konci pribadi anjeun lottery.pk, nu dihasilkeun saméméhna nalika nyieun kontrak pinter. Ieu mangrupikeun komitmen anu saluyu.

Nampi inpormasi tina kontrak pinter nganggo metode get

Ayeuna hayu urang tingali kumaha ngajalankeun metode kontrak pinter.

Ngaluncurkeun lite-client sareng jalankeun metodeu anu urang tulis.

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

В result ngandung nilai nu mulih fungsi balance() ti kontrak pinter urang.
Urang bakal lakonan hal nu sarua pikeun sababaraha métode deui.

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

Hayu urang nanya sajarah alungan Anjeun.

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

Kami bakal nganggo lite-klien sareng kéngingkeun metode pikeun nunjukkeun inpormasi ngeunaan kontrak pinter dina situs éta.

Mintonkeun data kontrak pinter dina website

Kuring nulis ramatloka basajan dina Python pikeun mintonkeun data tina kontrak pinter dina cara merenah. Di dieu kuring moal Huni on eta di jéntré tur bakal nyebarkeun loka dina hiji komitmen.

Requests ka TON dijieun tina Python kalayan bantuan lite-client. Pikeun genah, situs ieu dibungkus dina Docker sareng diterbitkeun dina Google Cloud. Tumbu.

Nyobaan

Ayeuna hayu urang cobaan pikeun ngirim gram aya pikeun replenishment tina dompét. Urang bakal ngirim 40 gram. Sareng hayu urang ngadamel sababaraha taruhan pikeun kajelasan. Urang nempo yén situs nembongkeun sajarah bets, persentase unggul ayeuna jeung informasi mangpaat séjén.

Urang nempoyén urang meunang kahiji, leungit kadua.

afterword

Tulisan éta tétéla langkung lami tibatan anu kuring ngarepkeun, panginten tiasa langkung pondok, atanapi panginten ngan ukur pikeun jalma anu teu terang nanaon ngeunaan TON sareng hoyong nyerat sareng nyebarkeun kontrak pinter anu henteu saderhana kalayan kamampuan berinteraksi sareng. ieu. Panginten sababaraha hal tiasa dijelaskeun langkung saderhana.

Panginten sababaraha aspék palaksanaan tiasa dilakukeun langkung éfisién sareng elegan, tapi teras éta bakal nyandak waktos langkung seueur pikeun nyiapkeun tulisan. Ieu oge mungkin yen kuring nyieun kasalahan wae atanapi teu ngartos hal, jadi lamun ngalakukeun hal serius, anjeun kudu ngandelkeun dokuméntasi resmi atawa Repository resmi kalawan kode TON.

Ieu kudu dicatet yén saprak TON sorangan masih dina tahap aktip ngembangkeun, parobahan bisa lumangsung anu bakal megatkeun salah sahiji hambalan dina artikel ieu (anu kajantenan nalika kuring nulis, éta geus dilereskeun), tapi pendekatan umum nyaéta. teu mungkin robah.

Kuring moal ngobrol ngeunaan masa depan TON. Panginten platformna bakal janten hal anu ageung sareng urang kedah nyéépkeun waktos diajar sareng ngeusian Ecological produk urang ayeuna.

Aya ogé Libra ti Facebook, nu boga poténsi panongton pamaké leuwih badag batan TON. Kuring nyaho ampir nanaon tentang Libra, ditilik ku forum aya leuwih kagiatan aya ti di komunitas TON. Sanaos pamekar sareng komunitas TON langkung mirip di jero taneuh, anu ogé keren.

rujukan

  1. Dokuméntasi resmi TON: https://test.ton.org
  2. Repository TON resmi: https://github.com/ton-blockchain/ton
  3. Dompét resmi pikeun platform anu béda: https://wallet.ton.org
  4. Repositori kontrak pinter tina tulisan ieu: https://github.com/raiym/astonished
  5. Tautan ka situs wéb kontrak pinter: https://ton-lottery.appspot.com
  6. Repository pikeun ekstensi pikeun Visual Studio Code pikeun FunC: https://github.com/raiym/func-visual-studio-plugin
  7. Ngobrol ngeunaan TON di Telegram, anu leres-leres ngabantosan terangna dina tahap awal. Jigana moal jadi kasalahan lamun kuring nyebutkeun yén dulur anu nulis hal pikeun TON aya. Anjeun oge bisa menta test gram aya. https://t.me/tondev_ru
  8. Obrolan sanés ngeunaan TON dimana kuring mendakan inpormasi anu mangpaat: https://t.me/TONgramDev
  9. Tahap kahiji kompetisi: https://contest.com/blockchain
  10. Tahap kadua kompetisi: https://contest.com/blockchain-2

sumber: www.habr.com

Tambahkeun komentar