Di derbarê meriv çawa di Tora Vekirî ya Telegram (TON) de peymanek jîr binivîsîne û biweşîne

Di derbarê meriv çawa di TON de peymanek biaqil dinivîse û diweşîne

Ev gotar li ser çi ye?

Di gotarê de ez ê biaxivim ka çawa min beşdarî pêşbirka yekem (ji du) bloka Telegram-ê bû, xelatek negirt, û biryar da ku ezmûna xwe di gotarekê de tomar bikim da ku ew nekeve nav jibîrbûnê û, dibe ku, bibe alîkar. kesek.

Ji ber ku min nexwest koda razber binivîsim, lê ji bo ku ez tiştek bixebitim, ji bo gotarê min ji bo lotoyek tavilê û malperek ku daneyên peymana hişmend rasterast ji TON-ê bêyî karanîna hilanîna navberê nîşan dide peymanek jîr nivîsî.

Gotar dê ji wan kesên ku dixwazin yekem peymana xweya jîr li TON-ê çêbikin re bikêr be, lê nizanin ji ku dest pê bikin.

Bi karanîna lotoyê wekî mînak, ez ê ji sazkirina hawîrdorê berbi weşandina peymanek biaqil, pê re têkilî daynin û ji bo wergirtin û weşandina daneyan malperek binivîsim.

Derbarê beşdarbûna pêşbirkê de

Cotmeha borî, Telegram bi zimanên nû re pêşbaziyek blokê ragihand Fift и FunC. Pêwîst bû ku ji nivîsandina yek ji pênc peymanên hişmend ên pêşniyarkirî hilbijêrin. Min difikirî ku ez tiştekî cuda bikim, zimanekî hîn bibim û tiştekî çêbikim, heta ku di pêşerojê de ne hewce be jî tiştekî din binivîsim dê xweş be. Wekî din, mijar bi berdewamî li ser lêvan e.

Hêjayî gotinê ye ku ezmûna min a pêşxistina peymanên jîr nebû.

Min plan kir ku ez heya dawiyê beşdar bibim heya ku ez bikaribim û dûv re gotarek nirxandinê binivîsim, lê ez tavilê di yekem de têk çûm. ez walletek nivîsand bi pir-îmza li ser FunC û bi gelemperî xebitî. Min ji xwe re esas girt peymana jîr li ser Solidity.

Wê demê, min fikirîn ku ev bê guman bes e ku bi kêmanî cîhek xelat bigire. Di encamê de ji 40 beşdaran nêzî 60 kes bûn xelatgir û ez ne di nav wan de bûm. Bi gelemperî, di vê yekê de tiştek xelet tune, lê tiştek min xemgîn kir. Di dema ragihandina encaman de, vekolîna testa peymana min nehatibû kirin, min ji beşdarên sohbetê pirsî ku kesek din tune ye, tune ye.

Xuyaye ku bala xwe daye peyamên min, du roj şûnda dadger şîroveyek weşandin û ez hîn jî fam nakim ka wan bi xeletî peymana min a jîr di dema dadkirinê de ji dest da an bi tenê fikirîn ku ew ew qas xirab bû ku hewcedarê şîroveyê nebû. Min li ser rûpelê pirsek kir, lê bersiv negirt. Her çend ne veşartî ye ku kê dadbar dike, min nepêwîst dît ku peyamên kesane binivîsim.

Gelek dem li ser têgihiştinê derbas bû, ji ber vê yekê biryar hat dayîn ku gotarek were nivîsandin. Ji ber ku hîna pir agahdarî tune ye, ev gotar dê ji bo her kesê eleqedar dem xilas bike.

Têgeha peymanên jîr li TON

Berî ku hûn tiştek binivîsin, hûn hewce ne ku fêm bikin ka hûn ji kîjan alî ve nêzîkê vê tiştê bibin. Ji ber vê yekê, niha ez ê ji we re bibêjim ku pergal ji kîjan beşan pêk tê. Zêdetir, kîjan beşan divê hûn zanibin da ku hûn bi kêmanî cûreyek peymanek xebatê binivîsin.

Em ê bala xwe bidin ser nivîsandina peymanek biaqil û bi hev re bixebitin TON Virtual Machine (TVM), Fift и FunC, ji ber vê yekê gotar bêtir wekî ravekirina pêşveçûna bernameyek birêkûpêk e. Em ê li ser vê yekê nesekinin ka platform bixwe li vir çawa dixebite.

Bi gelemperî li ser ka ew çawa dixebite TVM û ziman Fift belgeyên fermî yên baş hene. Dema ku beşdarî pêşbirkê bûm û niha dema ku peymana heyî dinivîsim, min gelek caran berê xwe da wê.

Zimanê sereke yê ku peymanên zîrek tê nivîsandin ev e FunC. Heya nuha tu belgeyek li ser wê tune, ji ber vê yekê ji bo ku hûn tiştek binivîsin hûn hewce ne ku nimûneyên peymanên jîr ji depoya fermî û bicîhkirina zimanê xwe li wir bixwînin, plus hûn dikarin li mînakên peymanên jîr ên ji du paşîn binêrin. pêşbirkên. Girêdanên di dawiya gotarê de.

Em bibêjin ku me berê ji bo peymanek jîr nivîsandiye FunC, piştî wê em kodê di komkera Fift de berhev dikin.

Peymana hişmend a berhevkirî dimîne ku were weşandin. Ji bo vê yekê hûn hewce ne ku fonksiyonek tê de binivîsin Fift, ku dê koda peymana jîr û hin pîvanên din wekî têketinê bigire, û encam dê pelek bi dirêjkirinê be. .boc (ku tê wateya "çenta hucreyan"), û, li gorî ka em wê çawa dinivîsin, mifteyek taybet û navnîşanek, ku li ser bingeha koda peymana jîr tê çêkirin. Hûn dikarin berê gram bişînin navnîşana peymanek jîr a ku hîn nehatiye weşandin.

Ji bo weşandina peymanek biaqil di TON de hatî wergirtin .boc pêdivî ye ku pel bi karanîna xerîdarek sivik ji blokê re were şandin (li ser wê yekê li jêr). Lê berî weşankirinê, hûn hewce ne ku gram bi navnîşana hatî hilberandin veguhezînin, wekî din dê peymana hişmend neyê weşandin. Piştî weşandinê, hûn dikarin bi peymana biaqil re bi şandina wê peyamên ji derve (mînakî, bi karanîna xerîdarek sivik) an jî ji hundur ve bişînin (mînakek, peymanek jîr ji yekî din re peyamek di hundurê TON de dişîne).

Dema ku em fêm bikin ka kod çawa tê weşandin, ew hêsantir dibe. Em bi qasî dizanin ku em dixwazin çi binivîsin û bernameya me dê çawa bixebite. Dema ku dinivîsin, em lê digerin ka ev çawa jixwe di peymanên jîr ên heyî de tête bicîh kirin, an jî em li koda bicîhkirinê dinêrin Fift и FunC di depoya fermî de, an li belgeya fermî binihêrin.

Pir caran ez di chat Telegram de ku hemî beşdarên pêşbaziyê û xebatkarên Telegram li hev civiyan li peyvên sereke geriyam, û wusa bû ku di dema pêşbaziyê de her kes li wir kom bû û dest bi nîqaşkirina Fift û FunC kir. Girêdana di dawiya gotarê de.

Dem hatiye ku ji teoriyê derbasî pratîkê bibin.

Amadekirina jîngehê ji bo xebata bi TON re

Min her tiştê ku dê di gotarê de li ser MacOS-ê were vegotin kir û ew di Ubuntu 18.04 LTS-ya paqij a li ser Docker-ê de du caran kontrol kir.

Yekem tiştê ku divê hûn bikin ev e ku dakêşin û saz bikin lite-client bi ku hûn dikarin daxwazan ji TON re bişînin.

Rêbernameyên li ser malpera fermî pêvajoya sazkirinê bi hûrgulî û zelal vedibêjin û hin hûrguliyan ji holê radikin. Li vir em rêwerzanan dişopînin, girêdanên winda di rê de saz dikin. Min her proje bi xwe berhev nekir û ji depoya fermî ya Ubuntu saz kir (li MacOS-ê ku min bikar anî 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 

Dema ku hemî girêdan têne saz kirin hûn dikarin saz bikin lite-client, Fift, FunC.

Pêşîn, em depoya TON û pêgirên wê klon dikin. Ji bo rehetiyê, em ê her tiştî di peldankê de bikin ~/TON.

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

Depo jî pêkanînan hilîne Fift и FunC.

Niha em amade ne ku projeyê bicivînin. Koda depoyê di peldankekê de tê klon kirin ~/TON/ton. ew ~/TON peldankek çêbikin build û proje tê de kom bike.

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

Ji ber ku em ê peymanek biaqil binivîsin, em ne tenê hewce ne lite-clientlê belê, Fift с FunC, da ku em her tiştî berhev bikin. Ew ne pêvajoyek bilez e, ji ber vê yekê em li bendê ne.

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

Dûv re, pelê mîhengê ku di derheqê girêka ku tê de dane hene dakêşin lite-client dê girêdan.

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

Daxwazên yekem ji TON re dikin

Niha em dest pê bikin lite-client.

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

Ger avakirin serketî bû, wê hingê piştî destpêkirinê hûn ê têketinek pêwendiya xerîdar ronahiyê bi nodê re bibînin.

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

Hûn dikarin fermanê bimeşînin help û bibînin ka çi ferman hene.

help

Ka em emrên ku em ê di vê gotarê de bikar bînin navnîş bikin.

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

Niha em amade ne ku peymanê bi xwe binivîsin.

Реализация

Idea

Wekî ku min li jor jî nivîsî, peymana biaqil a ku em dinivîsin lotikek e.

Digel vê yekê, ev ne lotoyek e ku tê de hewce ye ku hûn bilêtek bikirin û demjimêrek, roj an mehekê li bendê bimînin, lê yek tavilê ye ku tê de bikarhêner vediguhezîne navnîşana peymanê. N gram, û di cih de wê vedigere 2 * N gram an winda dike. Em ê îhtîmala serketinê bi qasî 40% çêbikin. Ger ji bo dravdanê têra gram nebin, wê hingê em ê danûstendinê wekî top-up bihesibînin.

Digel vê yekê, girîng e ku behîs di demek rast û bi rengek hêsan were dîtin, da ku bikarhêner tavilê fêm bike ka wî bi ser ket an winda kir. Ji ber vê yekê, hûn hewce ne ku malperek çêbikin ku rasterast ji TON-ê behîs û encaman nîşan bide.

Nivîsandina peymanek jîr

Ji bo rehetiyê, min koda ji bo FunC ronî kiriye; pêvek dikare di lêgerîna Visual Studio Code de were dîtin û saz kirin; heke hûn ji nişkê ve bixwazin tiştek zêde bikin, min pêvek ji raya giştî re peyda kiriye. Di heman demê de, kesek berê pêvekek çêkir ku bi Fift re bixebite, hûn jî dikarin wê saz bikin û li VSC-ê bibînin.

Werin em tavilê depoyek ku em ê encamên navîn pêk bînin ava bikin.

Ji bo ku jiyana me hêsantir bibe, em ê peymanek biaqil binivîsin û heya ku amade be wê li herêmî ceribandin. Tenê piştî wê em ê di TON de biweşînin.

Peymana zîrek du rêbazên derveyî hene ku dikarin werin gihîştin. Yekem, recv_external() ev fonksiyon dema ku daxwazek peymanê ji cîhana derve tê, ango ne ji TON-ê tê, mînakî, dema ku em bixwe peyamek çêdikin û bi navgîniya lite-mişterî dişînin. Duyem, recv_internal() ev gava ku, di hundurê TON bixwe de, her peymanek ji ya me re vedibêje. Di her du rewşan de, hûn dikarin parameteran ji fonksiyonê re derbas bikin.

Ka em bi mînakek hêsan dest pê bikin ku heke were weşandin dê bixebite, lê di wê de barek fonksiyonel tune.

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

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

Li vir divê em rave bikin ka ew çi ye slice. Hemî daneyên ku di TON Blockchain de têne hilanîn berhevokek e TVM cell an tenê cell, di şaneyek weha de hûn dikarin heta 1023 bit daneyan û heta 4 lînkên şaneyên din hilînin.

TVM cell slice an slice ev beşek ji ya heyî ye cell ji bo parskirina wê tê bikaranîn, wê paşê zelal bibe. Ya sereke ji bo me ew e ku em dikarin veguherînin slice û li gorî celebê peyamê, daneyên tê de pêvajoyê bikin recv_external() an recv_internal().

impure - peyvek sereke ya ku destnîşan dike ku fonksiyon daneyên peymana hişmend diguhezîne.

Ka em koda peymanê tê de hilînin lottery-code.fc û berhev dikin.

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

Wateya alayan bi karanîna fermanê dikare were dîtin

~/TON/build/crypto/func -help

Me koda assembler ya Pêncê di nav de berhev kiriye 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

Li herêmê dikare were destpêkirin, ji bo vê jî em ê hawirdorê amade bikin.

Têbînî ku rêza yekem ve girêdayî ye Asm.fif, ev koda ku di Fift de ji bo komkera Fift hatî nivîsandin e.

Ji ber ku em dixwazin peymana jîr bi herêmî bimeşînin û ceribandin, em ê pelek biafirînin lottery-test-suite.fif û koda berhevkirî li wir kopî bikin, rêza paşîn a tê de biguhezînin, ku koda peymana biaqil bi domdar dinivîse codeDûv re wê veguhezînin makîneya 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

Heya nuha zelal xuya dike, naha em ê koda ku em ê ji bo destpêkirina TVM bikar bînin li heman pelê zêde bikin.

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 em çerçoveyê tomar dikin, ango daneyên ku TVM (an dewleta torê) pê dê were destpêkirin. Tewra di dema pêşbaziyê de, yek ji pêşdebiran nîşan da ku meriv çawa diafirîne c7 û min kopî kir. Di vê gotarê de dibe ku em hewce ne ku biguherînin rand_seed ji ber ku çêkirina jimareke tesadufî bi wê ve girêdayî ye û ger neyê guhertin, dê her car heman hejmar were vegerandin.

recv_internal и recv_external sabitên bi nirxên 0 û -1 dê ji bo bangkirina fonksiyonên têkildar di peymana hişmend de berpirsiyar bin.

Naha em amade ne ku ceribandina yekem ji bo peymana xweya hişmend a vala biafirînin. Ji bo zelaliyê, heya niha em ê hemî ceribandinan li heman pelê zêde bikin lottery-test-suite.fif.

Werin em guhêrbarek çêbikin storage û yekî vala tê de binivîse cell, ev dê bibe hilanîna peymana jîr.

message Ev peyama ku em ê ji derve ve ji têkiliya biaqil re ragihînin ev e. Em ê jî ji bo niha vala bikin.

variable storage 
<b b> storage ! 

variable message 
<b b> message ! 

Piştî ku me domdar û guhêrbar amade kirin, em TVM bi karanîna fermanê dest pê dikin runvmctx û pîvanên çêkirî derbasî têketinê bikin.

message @ 
recv_external 
code 
storage @ 
c7 
runvmctx 

Di dawiyê de em ê bi ser bikevin welî evê koda navîn ji bo Fift.

Naha em dikarin koda encam bimeşînin.

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

Pêdivî ye ku bername bêyî xeletî bimeşîne û di encam de em ê têketina darvekirinê bibînin:

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

Mezin, me yekem guhertoya xebatê ya peymana hişmend nivîsandiye.

Niha em hewce ne ku fonksiyonê zêde bikin. Pêşî bila em bi peyamên ku ji cîhana derve tên re mijûl bibin recv_external()

Pêşdebir bixwe forma peyamê ya ku peyman dikare qebûl bike hildibijêre.

Lê bi gelemperî

  • yekem, em dixwazin peymana xwe ji cîhana derve biparêzin û wisa bikin ku tenê xwediyê peymanê karibe peyamên derve jê re bişîne.
  • ya duyemîn, dema ku em peyamek derbasdar ji TON re dişînin, em dixwazin ku ev yek tam carekê çêbibe û dema ku em dîsa heman peyamê bişînin, peymana jîr wê red dike.

Ji ber vê yekê hema hema her peyman van her du pirsgirêkan çareser dike, ji ber ku peymana me peyamên derveyî qebûl dike, pêdivî ye ku em li ser wê jî bisekinin.

Em ê bi rêza berevajî bikin. Pêşî, em pirsgirêkê bi dubarekirinê çareser bikin, heke peymanek jixwe peyamek weha wergirtibe û pêvajo kiribe, ew ê carek din pêk neyê. Dûv re em ê pirsgirêkê çareser bikin da ku tenê xeleka diyarkirî ya mirovan bikaribe ji peymana hişmend re peyaman bişîne.

Ji bo çareserkirina pirsgirêkê bi peyamên dubare re awayên cûda hene. Li vir em ê çawa bikin. Di peymana jîr de, em jimareya peyamên hatine wergirtin bi nirxa destpêkê 0 dest pê dikin. Di her peyamê de ji peymana biaqil re, em ê nirxa hejmarê ya heyî lê zêde bikin. Ger di peyamê de nirxa dijber bi nirxa peymana biaqil re nebe, wê hingê em wê pêvajo nakin; heke wusa be, wê hingê em wê pêvajoyê dikin û di girêbesta jîr de jimare 1 zêde dikin.

Ka em vegerin lottery-test-suite.fif û ceribandinek duyemîn lê zêde bike. Ger em jimareyek xelet bişînin, divê kod îstisnayek bavêje. Mînakî, bila daneyên peymanê 166 hilîne, û em ê 165 bişînin.

<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"

Ka em dest pê bikin.

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

Û em ê bibînin ku ceribandin bi xeletiyek dimeşîne.

[ 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

Di vê qonaxê de lottery-test-suite.fif divê mîna link.

Naha werin em mantiqa dijber li peymana biaqil zêde bikin 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 peyama ku em dişînin derew e.

Yekem tiştê ku em dikin ev e ku kontrol bikin ka peyam di nav xwe de dane heye, heke na, wê hingê em bi tenê derdikevin.

Piştre em peyamê pars dikin. in_msg~load_uint(32) hejmara 165, 32-bit bar dike unsigned int ji peyama hatî şandin.

Dûv re em 32 bit ji hilanîna peymana jîr bar dikin. Em kontrol dikin ku hejmara barkirî bi ya derbasbûyî re têkildar e; heke na, em îstisnayek bavêjin. Di rewşa me de, ji ber ku em ji maçekê neqewimî derbas dibin, divê îstîsnayek were avêtin.

Niha em berhev bikin.

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

Koda encam li ser kopî bikin lottery-test-suite.fif, ji bîr nekin ku rêza paşîn veguherînin.

Em kontrol dikin ku test derbas dibe:

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

Li vir Hûn dikarin bi encamên heyî re peymana têkildar bibînin.

Bala xwe bidinê ku nerehet e ku meriv bi domdarî koda berhevkirî ya peymanek biaqil di pelek bi ceribandinan de kopî bike, ji ber vê yekê em ê skrîptek binivîsin ku dê kodê ji me re domdar binivîse, û em ê bi tenê koda berhevkirî bi ceribandinên xwe ve girêdin. "include".

Di peldanka projeyê de pelek çêbikin build.sh bi naveroka jêrîn.

#!/bin/bash

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

Ka em wê bikin îcrakar.

chmod +x ./build.sh

Naha, tenê skrîpta me bimeşînin da ku peymanê berhev bikin. Lê ji xeynî vê, divê em wê di nav domdar de binivîsin code. Ji ber vê yekê em ê pelek nû çêbikin lotter-compiled-for-test.fif, ku em ê di dosyayê de bihewînin lottery-test-suite.fif.

Ka em koda skirptê li sh lê zêde bikin, ku dê bi tenê pelê berhevkirî tê de dubare bike lotter-compiled-for-test.fif û rêza dawî ya tê de biguherîne.

# 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

Naha, ji bo kontrolkirinê, em skrîpta encam bidin meşandin û pelek dê were çêkirin lottery-compiled-for-test.fif, ku em ê têxin nav xwe lottery-test-suite.fif

В lottery-test-suite.fif koda peymanê jêbirin û rêzê lê zêde bike "lottery-compiled-for-test.fif" include.

Em îmtîhanan dimeşînin da ku kontrol bikin ku ew derbas dibin.

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

Mezin, naha ji bo destpêkirina ceribandinan otomatîk bikin, em pelê biafirînin test.sh, ya ku dê pêşî were darve kirin build.sh, û paşê ceribandinan bimeşînin.

touch test.sh
chmod +x test.sh

Em li hundur dinivîsin

./build.sh 

echo "nCompilation completedn"

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

Werin em bikin test.sh û wê bimeşînin da ku piştrast bikin ku ceribandinan dixebitin.

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

Em kontrol dikin ku peyman berhev dibe û ceribandin têne kirin.

Mezin, niha li ser destpêkirinê test.sh Îmtîhan dê tavilê bên berhevkirin û bi rê ve bibin. Li vir lînkek heye bikaranîn.

Baş e, berî ku em bidomînin, bila ji bo rehetiyê tiştek din bikin.

Ka em peldankek çêbikin build ku em ê peymana kopîkirî û klona wê ya ku di nav domdar de hatî nivîsandin de hilînin lottery-compiled.fif, lottery-compiled-for-test.fif. Ka em peldankek jî çêbikin test pelê testê dê li ku were hilanîn? lottery-test-suite.fif û potansiyel pelên piştgirî yên din. Girêdana guhertinên têkildar.

Werin em pêşvebirina peymana hişmend bidomînin.

Dûv re pêdivî ye ku ceribandinek hebe ku dema ku em jimareya rast bişînin kontrol dike ka peyam hatî wergirtin û jimarvan li firotgehê nûve dibe. Lê em ê paşê bikin.

Naha em bifikirin ka çi strukturên daneyê û çi dane hewce dike ku di peymana hişmend de were hilanîn.

Ez ê her tiştê ku em hildigirin vebêjim.

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

Piştre hûn hewce ne ku du fonksiyonan binivîsin. Ka em gazî yê yekem bikin pack_state(), ku dê daneyan ji bo hilanîna paşîn di hilanîna peymana hişmend de pak bike. Ka em gazî ya duyemîn bikin unpack_state() dê daneyan ji hilanînê bixwîne û vegerîne.

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

Em van her du fonksiyonan li destpêka peymana jîr zêde dikin. Wê bi ser bikeve welî evê encama navîn.

Ji bo hilanîna daneyan hûn ê hewce bikin ku hûn fonksiyona çêkirî bang bikin set_data() û ew ê daneyan ji binivîse pack_state() di hilanîna peymana jîr de.

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

Naha ku ji bo nivîsandin û xwendina daneyan fonksiyonên me yên rehet hene, em dikarin pêş de biçin.

Pêdivî ye ku em kontrol bikin ka peyama ku ji derve tê ji hêla xwediyê peymanê ve (an bikarhênerek din a ku xwedan mifteya taybet e) ve hatî îmze kirin.

Dema ku em peymanek biaqil diweşînin, em dikarin wê bi daneya ku em di hilanînê de hewce dikin dest pê bikin, ku dê ji bo karanîna pêşerojê werin hilanîn. Em ê mifteya giştî li wir tomar bikin da ku em karibin verast bikin ku peyama hatî bi mifteya taybet a têkildar ve hatî îmze kirin.

Berî ku em berdewam bikin, werin em mifteyek taybet biafirînin û wê binivîsin test/keys/owner.pk. Ji bo kirina vê yekê, werin em Fift di moda înteraktîf de bidin destpêkirin û çar fermanan bicîh bînin.

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

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

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

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

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

Ka em peldankek çêbikin keys di hundurê peldankê de test û mifteya taybet li wir binivîse.

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

Em peldankek di peldanka heyî de dibînin owner.pk.

Em mifteya giştî ji stikê derdixin û gava hewce bike em dikarin ji ya taybet bistînin.

Naha divê em verastkirinek îmzeyê binivîsin. Ka em bi testê dest pê bikin. Pêşî em mifteya taybet ji pelê bi karanîna fonksiyonê dixwînin file>B û li guherbarekê binivîsin owner_private_key, paşê fonksiyonê bikar bînin priv>pub mifteya taybet veguherîne mifteya gelemperî û encamê tê de binivîse 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 !

Em ê her du kilîtan hewce ne.

Em hilanîna peymana biaqil bi daneyên keyfî di heman rêzê de wekî fonksiyonê dest pê dikin pack_state()û di guherbarekê de binivîsin 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 !

Dûv re, em ê peyamek îmzekirî amade bikin, ew ê tenê îmze û nirxa dijber hebe.

Pêşî, em daneyên ku em dixwazin veguhezînin diafirînin, dûv re em bi mifteyek taybet îmze dikin û di dawiyê de em peyamek îmzekirî diafirînin.

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 !  

Wekî encamek, peyama ku em ê ji peymana biaqil re bişînin di guhêrbarek de tê tomar kirin message_to_send, li ser fonksiyonên hashu, ed25519_sign_uint hûn dikarin bixwînin di belgeya pêncan de.

Û ji bo ceribandinê em dîsa bang dikin.

message_to_send @ 
recv_external 
code 
storage @
c7
runvmctx

Va ye Di vê qonaxê de divê pelê bi testan bi vî rengî xuya bike.

Ka em ceribandinê bimeşînin û ew ê têk biçe, ji ber vê yekê em ê peymana hişmend biguhezînin da ku ew bikaribe peyamên bi vî rengî werbigire û îmzeyê verast bike.

Pêşî, em 512 bit îmzayê ji peyamê dihejmêrin û li guhêrbarekê dinivîsin, paşê em 32 bit ji guhêrbara hejmartinê dihejmêrin.

Ji ber ku me fonksiyonek ji bo xwendina daneyên ji hilanîna peymana hişmend heye, em ê wê bikar bînin.

Dûv re jimareya ku bi hilanînê ve hatî veguheztin û kontrolkirina îmzeyê ye. Ger tiştek li hev nayê, wê hingê em bi koda guncan re îstîsnayek bavêjin.

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

Peywira têkildar li vir heye.

Ka em ceribandinan bimeşînin û bibînin ku ceribandina duyemîn têk diçe. Ji ber du sedeman, di peyamê de bit têr nînin û di hilanînê de jî bit têr nîn in, ji ber vê yekê kod dema parskirinê têk diçe. Pêdivî ye ku em îmzeyek li peyama ku em dişînin zêde bikin û hilanînê ji ceribandina paşîn kopî bikin.

Di ceribandina duyemîn de, em ê îmzeyek peyamê zêde bikin û hilanîna peymana hişmend biguhezînin. Va ye dosyaya bi îmtîhanan di vê gavê de xuya dike.

Werin em ceribandinek çaremîn binivîsin, ku tê de em ê peyamek bi mifteya taybetî ya kesek din ve hatî îmzekirin bişînin. Werin em mifteyek taybet a din biafirînin û wê li pelek tomar bikin not-owner.pk. Em ê bi vê mifteya taybet peyamê îmze bikin. Ka em ceribandinan bimeşînin û pê ewle bin ku hemî ceribandin derbas dibin. Bikaranîn di vê gavê de.

Naha em dikarin di dawiyê de derbasî pêkanîna mantiqa peymana biaqil bibin.
В recv_external() em ê du celeb peyaman qebûl bikin.

Ji ber ku peymana me dê windahiyên lîstikvanan berhev bike, divê ev pere ji afirînerê lotoyê re were veguheztin. Dema ku peyman tê çêkirin navnîşana berîka afirînerê lotoyê di hilanînê de tê tomar kirin.

Tenê di rewşê de, em hewceyê kapasîteya ku em navnîşana ku em gramên windayan jê re dişînin biguhezînin. Her weha divê em bikaribin gramên ji lotoyê bişînin navnîşana xwediyê xwe.

Ka em bi ya yekem dest pê bikin. Ka em pêşî ceribandinek binivîsin ku dê kontrol bike ku piştî şandina peyamê, peymana hişmend navnîşana nû di hilanînê de tomar kiriye. Ji kerema xwe bala xwe bidin ku di peyamê de, ji bilî jimare û navnîşana nû, em jî radigihînin action Jimarek ne-neyînî ya 7-bit, li gorî wê, em ê hilbijêrin ka meriv çawa peyamê di peymana jîr de hildibijêre.

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

Di îmtîhanê de hûn dikarin bibînin ka hilanîna peymana smart çawa deserialîze kirin storage li Fift. Deserialization of variables di belgeya Pêncşemê de tête diyar kirin.

Têkiliya girêdanê bi hevîrê pêvekirî.

Werin em ceribandinê bimeşînin û pê ewle bin ku ew têk diçe. Naha em mentiqê zêde bikin da ku navnîşana xwediyê lotoyê biguhezînin.

Di peymana biaqil de em parsekirinê didomînin message, bixwînin action. Werin em bînin bîra we ku em ê du hebin action: navnîşan biguherîne û gram bişîne.

Dûv re em navnîşana nû ya xwediyê peymanê dixwînin û wê di hilanînê de hilînin.
Em testan dimeşînin û dibînin ku ceribandina sêyemîn têk diçe. Ew têk diçe ji ber vê yekê ku peyman naha 7 bit ji peyamê, ku di ceribandinê de winda ne, zêde par dike. Yê ku tune ye li peyamê zêde bike action. Ka em ceribandinan bimeşînin û bibînin ku her tişt derbas dibe. vir guheztinan bikin. Ecêb.

Naha werin em mantiqa şandina jimareya diyarkirî ya gram ji navnîşana ku berê hatî hilanîn re binivîsin.

Pêşîn, em ceribandinek binivîsin. Em ê du ceribandinan binivîsin, yek gava ku hevsengiyek têr nebe, ya duyemîn gava ku divê her tişt bi serfirazî derbas bibe. Test dikare were dîtin di vê kombûnê de.

Naha em kodê lê zêde bikin. Pêşîn, bila em du rêbazên alîkar binivîsin. Rêbaza wergirtina yekem ev e ku meriv balansa heyî ya peymanek jîr bibîne.

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

Û ya duyemîn jî ji bo şandina graman ji peymanek din a jîr re ye. Min ev rêbaz bi tevahî ji peymanek din a jîr kopî kir.

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

Werin em van her du rêbazan li peymana jîr zêde bikin û mantiqê binivîsin. Pêşîn, em hejmara gramên ji peyamê parsek dikin. Dûv re em hevsengiyê kontrol dikin, heke têrê neke em îstisnayek davêjin. Ger her tişt baş e, wê hingê em gramên navnîşana tomarkirî dişînin û jimarvan nûve dikin.

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

Va ye di vê gavê de mîna peymana jîr xuya dike. Werin em ceribandinan bimeşînin û pê ewle bibin ku ew derbas dibin.

Bi awayê, her carê ji bo peyamek pêvajoyî komîsyonek ji peymana hişmend tê derxistin. Ji bo ku peyamên peymana hişmend daxwazê ​​bicîh bînin, piştî kontrolên bingehîn hûn hewce ne ku bang bikin accept_message().

Naha em biçin ser peyamên navxweyî. Di rastiyê de, em ê tenê gramanan qebûl bikin û ger ku lîstikvan bi ser bikeve du qat û ger ku winda bike yek sêyem jî ji xwediyê xwe re bişînin.

Pêşîn, em ceribandinek hêsan binivîsin. Ji bo kirina vê yekê, em hewceyê navnîşek ceribandinê ya peymana jîr e ku em tê texmîn kirin ku gram ji peymana hişmend re bişînin.

Navnîşana peymana biaqil ji du hejmaran pêk tê, jimareyek 32-bit ku berpirsiyarê zincîra xebatê ye û jimareyek yekta ne-neyînî ya 256-bit di vê zincîra xebatê de. Mînakî, -1 û 12345, ev navnîşana ku em ê li pelek tomar bikin ev e.

Min fonksiyona ji bo tomarkirina navnîşan ji kopî kir 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

Ka em binihêrin ka fonksiyon çawa dixebite, ev ê têgihiştinek bide ka Fift çawa dixebite. Fift di moda înteraktîf de dest pê bikin.

~/TON/build/crypto/fift -i 

Pêşî em -1, 12345 û navê pelê paşerojê "sender.addr" davêjin ser stikê:

-1 12345 "sender.addr" 

Pêngava din pêkanîna fonksiyonê ye -rot, ku stikê bi vî rengî diguhezîne ku li serê stikê jimareyek peymanek jîr a bêhempa heye:

"sender.addr" -1 12345

256 u>B jimareyek ne-neyînî ya 256-bit diguherîne bayt.

"sender.addr" -1 BYTES:0000000000000000000000000000000000000000000000000000000000003039

swap du hêmanên jorîn ên stikê diguhezîne.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 -1

32 i>B jimareyek 32-bit diguhure bayt.

"sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039 BYTES:FFFFFFFF

B+ du rêzikên byte girêdide.

 "sender.addr" BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF

Dîsa swap.

BYTES:0000000000000000000000000000000000000000000000000000000000003039FFFFFFFF "sender.addr" 

Û di dawiyê de byte li pelê têne nivîsandin B>file. Piştî vê stûyê me vala ye. Em disekinin Fift. Di peldanka heyî de pelek hate çêkirin sender.addr. Ka em pelê veguherînin peldanka çêkirî test/addresses/.

Ka em ceribandinek hêsan binivîsin ku dê gram ji peymanek jîr re bişîne. Li vir peywirdar e.

Niha em li mantiqa lotikan binêrin.

Yekem tiştê ku em dikin ev e ku peyamê kontrol bikin bounced an na heke bounced, paşê em wê paşguh dikin. bounced tê vê wateyê ku heke hin xeletiyek çêbibe dê peyman gram vegerîne. Ger xeletiyek ji nişka ve çêbibe em ê gram venegerînin.

Em kontrol dikin, heke hevseng ji nîv gram kêmtir be, wê hingê em bi tenê peyamê qebûl dikin û jê guh nadin.

Dûv re, em navnîşana peymana jîr a ku jê peyam hat pars dikin.

Em daneyên ji hilanînê dixwînin û dûv re heke ji bîst ji wan zêdetir be behîsên kevn ji dîrokê jêbirin. Ji bo rehetiyê, min sê fonksiyonên din nivîsî pack_order(), unpack_order(), remove_old_orders().

Dûv re, em lê dinêrin ka hevseng ji bo dravdanê têrê nake, wê hingê em dihesibînin ku ev ne behîs e, lê nûvekirinek e û nûvekirinê di nav de hilînin. orders.

Dûv re di dawiyê de cewhera peymana hişmend.

Pêşî, ger lîstikvan winda bike, em wê di dîroka behîsê de tomar dikin û heke mîqdar ji 3 gram zêdetir be, em 1/3 ji xwediyê peymana jîr re dişînin.

Ger lîstikvan bi ser bikeve, wê hingê em du qat mîqdarê dişînin navnîşana lîstikvan û dûv re agahdariya li ser behîsê di dîrokê de tomar dikin.

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

Ew e. Peywira peywendîdar.

Naha her tiştê ku dimîne hêsan e, ka em rêgezên wergirtinê biafirînin da ku em karibin di derheqê rewşa peymanê de ji cîhana derve agahdarî bistînin (bi rastî, daneyên ji hilanîna peymana wan a jîr bixwînin).

Werin em rêbazên wergirtinê zêde bikin. Em ê li jêr binivîsin ka meriv çawa agahdariya li ser peymanek jîr werdigire.

Di heman demê de min ji bîr kir ku kodê lê zêde bikim ku dê daxwaza yekem a ku di dema weşandina peymanek jîr de çêdibe pêk bîne. Peywira peywendîdar. Û bêtir serrast kirin xeletiyek bi şandina 1/3 ji mîqdarê ji hesabê xwedan re.

Pêngava paşîn weşandina peymana biaqil e. Ka em peldankek çêbikin requests.

Min koda weşanê esas girt simple-wallet-code.fc kîjan dikare bibîne di depoya fermî de.

Tiştek hêjayî balê ye. Em hilanînek peymanek jîr û peyamek têketinê diafirînin. Piştî vê yekê, navnîşana peymana biaqil tê çêkirin, ango navnîş berî weşandina di TON de jî tê zanîn. Dûv re, hûn hewce ne ku çend gram ji vê navnîşanê re bişînin, û tenê piştî wê hûn hewce ne ku pelek bi peymana jîr bi xwe re bişînin, ji ber ku torê ji bo hilanîna peymana biaqil û operasyonên tê de komîsyonek digire (verastkerên ku biaqil hildigirin û bicîh dikin peymanan). Kod dikare li vir were dîtin.

Dûv re em koda weşangeriyê pêk tînin û digirin lottery-query.boc pelê peymana jîr û navnîşan.

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

Ji bîr nekin ku pelên çêkirî hilînin: lottery-query.boc, lottery.addr, lottery.pk.

Di nav tiştên din de, em ê navnîşana peymana biaqil di têketinên darvekirinê de bibînin.

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

Tenê ji bo kêfê, bila em daxwazek ji TON re bikin

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

Û em ê bibînin ku hesabê bi vê navnîşanê vala ye.

account state is empty

Em ji navnîşanê re dişînin 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd 2 Gram û piştî çend saniyan em heman fermanê pêk tînin. Ji bo şandina graman ez bikar tînim berîka fermî, û hûn dikarin ji yekî ji sohbetê gramên ceribandinê bipirsin, ku ez ê di dawiya gotarê de li ser biaxivim.

> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Mîna yekî bêdestpêk xuya dike (state:account_uninit) peymanek jîr bi heman navnîşan û hevsengiya 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

Naha em peymana jîr biweşînin. Werin em lite-client dest pê bikin û darve bikin.

> 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 

Werin em kontrol bikin ku peyman hate weşandin.

> last
> getaccount 0QAESRAUnb6vjq27KyhyLn1qLcbiZOwvHZvr1vsgkHm8Ksyd

Di nav tiştên din de em distînin.

  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

Em wê yekê dibînin account_active.

Lihevhatina bi guhertinan re li vir heye.

Naha werin em daxwaznameyên biafirînin ku bi peymana hişmend re têkilî daynin.

Bi rastî em ê ya yekem ji bo guhertina navnîşanê wekî xebatek serbixwe bihêlin, ya duyemîn jî ji bo şandina graman ji navnîşana xwediyê xwe re em ê bikin. Bi rastî, em ê hewce bikin ku heman tiştê ku di ceribandina şandina gram de bikin.

Ev peyama ku em ê ji peymana biaqil re bişînin, li ku derê ye msg_seqno 165, action 2 û 9.5 gram ji bo şandinê.

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

Ji bîr nekin ku peyamê bi mifteya xweya taybet îmze bikin lottery.pk, ya ku berê di dema afirandina peymana jîr de hate çêkirin. Li vir peywira têkildar heye.

Agahdariya ji peymanek biaqil bi karanîna rêbazên wergirtinê digirin

Naha em binihêrin ka meriv çawa rêbazên bidestxistina peymana hişmend dimeşîne.

Destpêkirin lite-client û rêbazên wergirtinê yên ku me nivîsandine bimeşînin.

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

В result nirxa ku fonksiyon vedigere dihewîne balance() ji peymana me ya jîr.
Em ê ji bo çend rêbazên din jî heman tiştî bikin.

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

Ka em dîroka behîsa we bipirsin.

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

Em ê lite-client bikar bînin û rêbazan bistînin da ku agahdariya li ser peymana hişmend li ser malperê nîşan bidin.

Daneyên peymana hişmend li ser malperê nîşan dide

Min di Python de malperek hêsan nivîsî da ku daneyên ji peymana jîr bi rengek hêsan nîşan bide. Li vir ez ê bi berfirehî li ser nesekinim û malperê biweşînim li yek commit.

Daxwazên ji TON re têne kirin Python bi alîkariya lite-client. Ji bo rehetiyê, malper di Docker de tê pakkirin û li Google Cloud tê weşandin. Pêvek.

Werin em biceribînin

Naha em hewl bidin ku gram ji bo dagirtinê bişînin wir tûrikê diravan. Em ê 40 gram bişînin. Û em ji bo zelaliyê çend behîsan bikin. Em dibînin ku malper dîroka behîsan, rêjeya serkeftina heyî û agahiyên din ên bikêr nîşan dide.

Em dibîninku me ya yekem qezenc kir, ya duyemîn winda kir.

Paşê

Gotar ji ya ku min hêvî dikir pir dirêjtir bû, belkî ew dikaribû kurttir bûya, an jî dibe ku tenê ji bo kesek ku di derbarê TON-ê de tiştek nizane û dixwaze peymanek ne-sade ya jîr binivîsîne û biweşîne. ew. Dibe ku hin tişt bi hêsanî bihatana ravekirin.

Belkî hin aliyên tetbîqatê bi karîgerîtir û xweştir bihatana kirin, lê wê demê ji bo amadekirina gotarê hîn zêdetir wext digirt. Di heman demê de mimkun e ku min li cîhek xeletiyek kir an tiştek fam nekir, ji ber vê yekê heke hûn tiştek cidî dikin, hûn hewce ne ku xwe bispêrin belgeya fermî an depoya fermî ya bi koda TON.

Divê were zanîn ku ji ber ku TON bi xwe hîn di qonaxa çalak a pêşkeftinê de ye, dibe ku guhertin çêbibin ku dê yek ji gavên vê gotarê bişkînin (ku dema ku min dinivîsand qewimî, ew jixwe hatî rast kirin), lê nêzîkatiya gelemperî ev e. ne mimkûne ku biguhere.

Ez ê li ser pêşeroja TON nebêjim. Dibe ku platform bibe tiştek mezin û pêdivî ye ku em wextê xwe bi xwendina wê derbas bikin û naha bi hilberên xwe cîhek tije bikin.

Di heman demê de Libra ji Facebookê jî heye, ku xwedan temaşevanek potansiyel a bikarhênerên ji TON-ê mezintir e. Ez di derbarê Libra de hema hema tiştek nizanim, li gorî forumê dadbar kirin ku li wir ji civata TON-ê pir bêtir çalakî heye. Her çend pêşdebir û civata TON-ê bêtir mîna binê erdê ne, ku ew jî xweş e.

references

  1. Belgeya fermî ya TON: https://test.ton.org
  2. Depoya fermî ya TON: https://github.com/ton-blockchain/ton
  3. Wallet fermî ji bo platformên cihêreng: https://wallet.ton.org
  4. Depoya peymana smart ji vê gotarê: https://github.com/raiym/astonished
  5. Girêdana malpera peymana jîr: https://ton-lottery.appspot.com
  6. Depoya ji bo dirêjkirina Visual Studio Code ji bo FunC: https://github.com/raiym/func-visual-studio-plugin
  7. Li ser TON-ê di Telegram-ê de sohbet bikin, ku bi rastî di qonaxa destpêkê de alîkariya wê kir. Ez difikirim ku ew ê ne xelet be heke ez bibêjim ku her kesê ku ji bo TON tiştek nivîsandiye li wir e. Her weha hûn dikarin li wir gramên ceribandinê bixwazin. https://t.me/tondev_ru
  8. Danûstandinek din di derbarê TON de ku min agahdariya kêrhatî dît: https://t.me/TONgramDev
  9. Qonaxa yekem a pêşbirkê: https://contest.com/blockchain
  10. Qonaxa duyemîn a pêşbirkê: https://contest.com/blockchain-2

Source: www.habr.com

Add a comment