Created
October 18, 2019 00:45
-
-
Save rainydio/5af61dd8256b150bcf0b091da261bf0c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"Asm.fif" include | |
0 constant OK | |
34 constant ERR_SIGNATURE_INVALID | |
35 constant ERR_SIGNATURE_KEY_INVALID | |
36 constant ERR_SIGNATURE_PROOF_INVALID | |
37 constant ERR_SIGNATURE_MISSING | |
38 constant ERR_SIGNATURE_REPLAY | |
40 constant ERR_ORDER_NOT_FOUND | |
41 constant ERR_ORDER_EXPIRED | |
50 constant ERR_NUMKEYS_COUNT | |
60 constant ERR_OP_UNKNOWN | |
61 constant ERR_MSG_TYPE_UNKNOWN | |
70 constant ERR_UNREACHABLE | |
-1 constant MSG_TYPE_EXTERNAL | |
0 constant MSG_TYPE_INTERNAL | |
85143 constant MSG_TYPE_SEQNO | |
x{8_} constant EMPTY_SLICE | |
// MERKLE | |
{ | |
DUP TLEN EXPLODEVAR | |
<{ DUP 1 INT GREATER }> PUSHCONT <{ | |
ROTREV | |
MINMAX NEWC 256 STU 256 STU ENDC HASHCU | |
OVER DEC ROLLREVX | |
DEC | |
}> PUSHCONT WHILE | |
DROP | |
} : MERKLE:GET_ROOTHASH | |
// ITER | |
{ // s | |
LDREFRTOS SWAP // iter, s' | |
} : ITER:LD | |
{ // s | |
1 LDU SWAP <{ // s' | |
ITER:LD // iter, s' | |
}> PUSHCONT <{ | |
EMPTY_SLICE PUSHSLICE SWAP | |
}> PUSHCONT IFELSE | |
} : ITER:LD_NULLREF | |
{ | |
DUP SBITS ISZERO SWAP SREFS ISZERO AND | |
} : ITER:IS_EMPTY | |
{ // iter | |
DUP SBITS <{ // iter | |
TRUE // iter, true | |
}> PUSHCONT <{ // iter | |
DUP SREFS 1 INT EQUAL <{ // iter | |
LDREF ENDS CTOS TRUE // list_next, true | |
}> PUSHCONT <{ // iter | |
ENDS FALSE // false | |
}> PUSHCONT IFELSE | |
}> PUSHCONT IFELSE | |
} : ITER:LDNEXTRQ | |
// NUMKEY | |
{ 0 INDEX } : NUMKEY:GET_KEY | |
{ 1 INDEX } : NUMKEY:GET_NO | |
{ 2 INDEX } : NUMKEY:GET_HASH | |
{ // s | |
264 INT LDSLICEX SWAP HASHSU SWAP // hash, s | |
} : NUMKEY:LD_HASH | |
{ // s | |
264 INT LDSLICEX SWAP // s', s_numkey | |
DUP HASHSU SWAP 256 LDU 8 LDU ENDS // s, hash, key, no | |
ROT 3 TUPLE SWAP // numkey, s | |
} : NUMKEY:LD | |
// NUMKEY_ITER | |
{ | |
ITER:LD | |
} : NUMKEY_ITER:LD | |
{ // numkey_iter | |
NIL SWAP // hashes[], numkey_iter | |
<{ ITER:LDNEXTRQ }> PUSHCONT <{ // hashes[], numkey_iter' | |
NUMKEY:LD_HASH // hashes[], hash, numkey_iter' | |
ROTREV TPUSH SWAP // hashes[]', numkey_iter | |
}> PUSHCONT WHILE // hashes[] | |
} : NUMKEY_ITER:GET_HASHES | |
// HHASH_ITER | |
{ | |
ITER:LD_NULLREF | |
} : HHASH_ITER:LD | |
{ // hhash_iter, hash | |
SWAP // hash, hhash_iter | |
<{ ITER:LDNEXTRQ }> PUSHCONT <{ // hash, hhash_iter' | |
1 LDU LDREF 3 ROLLREV // hhash_iter', hash, hash_pos, hhash_cell | |
DUP HASHCU // hhash_iter', hash, hash_pos, hhash_cell, hash_next | |
4 ROLLREV // hash_next, hhash_iter', hash, hash_pos, hhash_cell | |
CTOS 256 LDU 256 LDU ENDS CONDSEL NEQ // hash_next, hhash_iter', hash, hash_expected | |
ERR_SIGNATURE_PROOF_INVALID THROWIFNOT // hash', hhash_iter | |
}> PUSHCONT WHILE | |
} : HHASH_ITER:HASH_WITH | |
// SIG | |
{ 0 INDEX } : SIG:GET_SIGNATURE | |
{ 1 INDEX } : SIG:GET_KEY | |
{ 2 INDEX } : SIG:GET_KEY_NO | |
{ 3 INDEX } : SIG:GET_ROOTHASH | |
{ // sig, order_hash | |
OVER SIG:GET_SIGNATURE // sig, order_hash, signature | |
ROT SIG:GET_KEY // order_hash, signature, key | |
CHKSIGNU | |
} : SIG:CHK_SIGNATURE | |
{ // sig, roothash | |
SWAP SIG:GET_ROOTHASH EQUAL | |
} : SIG:CHK_ROOTHASH | |
{ // s | |
DUP SREFS ISZERO <{ NULL SWAP }> PUSHCONT <{ | |
LDREFRTOS // s', s_sig | |
512 INT LDSLICEX // s, signature, s_sig' | |
DUP 264 INT PLDSLICEX HASHSU ROTREV // s, numkey_hash, signature, s_sig | |
256 LDU 8 LDU HHASH_ITER:LD ENDS // s, numkey_hash, signature, key, no, hhash_iter | |
4 ROLL // s, signature, key, no, hhash_iter, numkey_hash | |
HHASH_ITER:HASH_WITH // s', signature, key, no, roothash | |
4 TUPLE SWAP // sig, s | |
}> PUSHCONT IFELSE | |
} : SIG:LD | |
{ | |
ISNULL | |
} : SIG:IS_MISSING | |
// ORDER | |
{ 0 INDEX } : ORDER:GET_SEQNO | |
{ 1 INDEX } : ORDER:GET_EXP | |
{ 2 INDEX } : ORDER:GET_MODE | |
{ 3 INDEX } : ORDER:GET_TX | |
{ 4 INDEX } : ORDER:GET_HASH | |
{ // s | |
72 INT 1 INT SPLIT SWAP // s', s_order | |
DUP HASHSU SWAP // s, hash, s_order | |
32 LDU 32 LDU 8 LDU LDREF ENDS // s, hash, seqno, exp, mode, tx | |
4 ROLL 5 TUPLE SWAP // order, s | |
} : ORDER:LD | |
{ | |
ORDER:GET_EXP NOW LEQ | |
} : ORDER:IS_EXPIRED | |
// CONFIRMS | |
{ 0 INT } : CONFIRMS:NONE | |
{ POW2 OR } : CONFIRMS:ADD_KEY_NO | |
{ POW2 AND } : CONFIRMS:HAS_KEY_NO | |
{ // confirms | |
0 INT 0 INT // confirms, exp, count | |
s2 PUSH UBITSIZE <{ // confirms, exp, count | |
OVER POW2 s3 PUSH // confirms, exp, count, 2^exp, confirms | |
AND SGN // confirms, exp, count, 0/1 | |
ADD // confirms, exp, count' | |
SWAP INC SWAP // confirms, exp', count | |
}> PUSHCONT REPEAT | |
ROTREV 2DROP // count | |
} : CONFIRMS:GET_COUNT | |
{ // confirms, b | |
OVER UBITSIZE 8 STUR OVER UBITSIZE STUX // b' | |
} : CONFIRMS:ST | |
{ // s | |
8 LDU SWAP LDUX // confirms, s' | |
} : CONFIRMS:LD | |
// STATE | |
{ 0 INDEX } : STATE:GET_SEQNO { 0 SETINDEX } : STATE:SET_SEQNO | |
{ 1 INDEX } : STATE:GET_N { 1 SETINDEX } : STATE:SET_N | |
{ 2 INDEX } : STATE:GET_ROOTHASH { 2 SETINDEX } : STATE:SET_ROOTHASH | |
{ 3 INDEX } : STATE:GET_CONFIRMS_DICT { 3 SETINDEX } : STATE:SET_CONFIRMS_DICT | |
{ | |
DUP STATE:GET_SEQNO INC STATE:SET_SEQNO | |
} : STATE:INC_SEQNO | |
{ // state, order_hash, confirms | |
NEWC CONFIRMS:ST SWAP // state, b, order_hash | |
s2 PUSH STATE:GET_CONFIRMS_DICT // state, order_hash, b, confirms_dict | |
256 INT DICTUADDB ERR_UNREACHABLE THROWIFNOT // state, confirms_dict' | |
STATE:SET_CONFIRMS_DICT // state' | |
} : STATE:STORE_CONFIRMS_FOR | |
{ // state, order_hash | |
OVER STATE:GET_CONFIRMS_DICT // state, order_hash, confirms_dict | |
256 INT DICTUDELGET ERR_ORDER_NOT_FOUND THROWIFNOT // state, confirms_dict', s_confirms | |
CONFIRMS:LD ENDS // state, confirms_dict, confirms | |
ROTREV STATE:SET_CONFIRMS_DICT // confirms, state' | |
} : STATE:DELGET_CONFIRMS_FOR | |
{ // state, order_hash | |
OVER STATE:GET_CONFIRMS_DICT // state, order_hash, confirms_dict | |
256 INT DICTUDEL ERR_ORDER_NOT_FOUND THROWIFNOT // state, confirms_dict' | |
STATE:SET_CONFIRMS_DICT // state' | |
} : STATE:DELETE_CONFIRMS_FOR | |
{ | |
SWAP 4 UNPACKFIRST 5 0 REVERSE | |
32 STU 8 STU 256 STU STDICT | |
} : STATE:ST | |
// STATE_INIT | |
{ 1 INDEX } : STATE_INIT:GET_N | |
{ 2 INDEX } : STATE_INIT:GET_NUMKEY_ITER | |
{ | |
1 INT | |
SWAP DUP STATE_INIT:GET_N | |
SWAP STATE_INIT:GET_NUMKEY_ITER NUMKEY_ITER:GET_HASHES MERKLE:GET_ROOTHASH | |
NEWDICT | |
4 TUPLE | |
} : STATE_INIT:GET_STATE_1 | |
// C4 | |
{ 0 INDEX } : C4:GET_SEQNO | |
{ | |
C4:GET_SEQNO ISZERO | |
} : C4:IS_STATE_INIT | |
{ | |
32 LDU | |
OVER ISZERO <{ | |
8 LDU NUMKEY_ITER:LD | |
3 ROLLREV 3 TUPLE SWAP | |
}> PUSHCONT <{ | |
8 LDU 256 LDU LDDICT | |
4 ROLLREV 4 TUPLE SWAP | |
}> PUSHCONT IFELSE | |
} : C4:LD | |
<{ | |
SETCP0 | |
DUP MSG_TYPE_EXTERNAL INT EQUAL <{ // s_msg, msg_type_external | |
DROP c4 PUSHCTR CTOS C4:LD ENDS // s_msg, c4 | |
DUP C4:IS_STATE_INIT <{ // s_msg, state_init | |
// init state transition | |
NIP // state_init | |
ACCEPT | |
STATE_INIT:GET_STATE_1 // state | |
NEWC STATE:ST ENDC c4 POP | |
}> PUSHCONT IFJMP // s_msg, state | |
SWAP ORDER:LD SIG:LD ENDS // state, order, sig | |
OVER ORDER:IS_EXPIRED <{ | |
// new already expired order | |
s2 PUSH STATE:GET_SEQNO s2 PUSH ORDER:GET_SEQNO EQUAL | |
ERR_ORDER_EXPIRED THROWIF | |
// removing expired order require message without signature | |
SIG:IS_MISSING | |
ERR_ORDER_EXPIRED THROWIFNOT | |
ORDER:GET_HASH STATE:DELETE_CONFIRMS_FOR // state' | |
NEWC STATE:ST ENDC c4 POP | |
}> PUSHCONT IFJMP // state, order, sig | |
DUP SIG:IS_MISSING | |
ERR_SIGNATURE_MISSING THROWIF | |
s2 PUSH STATE:GET_SEQNO s2 PUSH ORDER:GET_SEQNO EQUAL <{ | |
ROT STATE:INC_SEQNO ROTREV // state', order, sig | |
CONFIRMS:NONE // state, order, sig, confirms | |
}> PUSHCONT <{ // state, order, sig | |
ROT s2 PUSH ORDER:GET_HASH STATE:DELGET_CONFIRMS_FOR 3 ROLLREV // state', order, sig, confirms | |
}> PUSHCONT IFELSE // state', order, sig, confirms | |
DUP s2 PUSH SIG:GET_KEY_NO CONFIRMS:HAS_KEY_NO // state, order, sig, confirms | |
ERR_SIGNATURE_REPLAY THROWIF | |
ROTREV // state, confirms, order, sig | |
DUP s2 PUSH ORDER:GET_HASH SIG:CHK_SIGNATURE | |
ERR_SIGNATURE_INVALID THROWIFNOT // state, confirms, order, sig | |
DUP s4 PUSH STATE:GET_ROOTHASH SIG:CHK_ROOTHASH | |
ERR_SIGNATURE_KEY_INVALID THROWIFNOT // state, confirms, order, sig | |
ACCEPT | |
s2 s1 XCHG SIG:GET_KEY_NO CONFIRMS:ADD_KEY_NO // state, order, confirms' | |
DUP CONFIRMS:GET_COUNT s3 PUSH STATE:GET_N GEQ <{ | |
DROP // state, order | |
DUP ORDER:GET_TX SWAP ORDER:GET_MODE SENDRAWMSG // state | |
}> PUSHCONT <{ | |
SWAP ORDER:GET_HASH SWAP // state, order_hash, confirms | |
STATE:STORE_CONFIRMS_FOR // state' | |
}> PUSHCONT IFELSE | |
NEWC STATE:ST ENDC c4 POP | |
}> PUSHCONT IFJMP | |
DUP MSG_TYPE_INTERNAL INT EQUAL <{ // s_msg, msg_type_internal | |
// admin functions here, | |
// remove pending order, | |
// change keyset, etc | |
}> PUSHCONT IFJMP | |
DUP MSG_TYPE_SEQNO INT EQUAL <{ | |
DROP c4 PUSHCTR CTOS C4:LD ENDS | |
STATE:GET_SEQNO | |
}> PUSHCONT IFJMP | |
ERR_MSG_TYPE_UNKNOWN THROW | |
}>c constant contract-code | |
{ // leafs, hash | |
explode // h1, [], ... hn, l | |
{ dup 1 > } { | |
-rot | |
over tuple? { , } { | |
dup tuple? { swap , } { | |
minmax <b swap 256 u, swap 256 u, b> hashu | |
} cond | |
} cond | |
over 1 - -roll | |
1 - | |
} while | |
drop | |
} : merkle-hhash | |
{ // b, null|cell | |
dup null? { | |
drop 0 1 u, | |
} { | |
swap 1 1 u, swap ref, | |
} cond // b' | |
} : nullref, | |
{ | |
dup sbits 0= { // s | |
dup srefs 0= { false } { | |
ref@+ swap s> <s true | |
} cond | |
} { true } cond | |
} : iter-next@+ | |
{ // keys[] | |
dup count 0= abort"empty list of keys" | |
0 swap { // i, keys[] | |
over 3 mod 0= { <b -rot } if // b_prev, b, i, keys[] | |
over over over [] // ..., b, i, keys[], no, key | |
4 roll // ..., i, keys[], no, key, b | |
swap B, swap 8 u, -rot // ..., b', i, keys[] | |
swap 1 + swap // ..., b, i', keys[] | |
} over count times // b1, ... bn, i, keys[] | |
drop { b> ref, } swap 3 /c 1 - times | |
b> // numkeys | |
} : numkeys | |
{ // hhash[], agg_hash | |
over count 0= { | |
2drop null | |
} { | |
swap // agg_hash, hhash[] | |
0 swap { // agg_hash, i, hhash[] | |
over 3 mod 0= { <b 3 -roll } if // b_prev, b, agg_hash, i, hhash[] | |
2dup swap [] // ..., b, agg_hash, i, hhash[], hhash | |
3 roll // ..., b, i, hhash[], hhash, agg_hash | |
2dup > abs -rot // ..., b, i, hhash[], agg_hash_pos, hhash, agg_hash | |
minmax <b swap 256 u, swap 256 u, b> // ..., b, i, hhash[], agg_hash_pos, hhash_item | |
dup hashu // ..., b, i, hhash[], agg_hash_pos, hhash_item, agg_hash | |
4 -roll // ..., b, agg_hash, i, hhash[], agg_hash_pos, hhash_item | |
5 roll // ..., agg_hash, i, hhash[], agg_hash_pos, hhash_item, b | |
swap ref, swap 1 u, // ..., agg_hash, i, hhash[], b' | |
3 -roll // ..., b, agg_hash, i, hhash[] | |
swap 1 + swap // ..., b, agg_hash, i', hhash[] | |
} over count times // b1, ... bn, agg_hash, i, hhash[] | |
drop nip { b> ref, } swap 3 /c 1 - times | |
b> // hhash_list | |
} cond | |
} : hhash-list | |
{ // numbered_keys, key | |
256 B>u@ swap // key', numbered_keys | |
| swap <s { iter-next@+ } { // key, leafs[], s | |
256 u@+ swap // key, leafs[], s', key_n | |
dup 4 pick = { | |
drop swap | , swap // key, leafs[]', s | |
8 u@+ swap 3 -roll // no, key, leafs[], s' | |
} { // ..., key, leafs[], s, numbered_key | |
swap 8 u@+ // ..., key, leafs[], key_n, no, s' | |
3 0 reverse // ..., key, leafs[], s, no, key_n | |
<b swap 256 u, swap 8 u, b> hashu // ..., key, leafs[], s, merkle_leaf | |
1 2 exch2 , swap // ..., key, leafs[]', s | |
} cond | |
} while // no, key, leafs[], s | |
s> merkle-hhash // no, key, hhash[] | |
-rot 2dup <b swap 256 u, swap 8 u, b> hashu // hhash[], no, key, hash | |
3 roll swap // no, key, hhash[], hash | |
hhash-list -rot // hhash_list, no, key | |
<b swap 256 u, swap 8 u, swap nullref, b> // proof | |
} : numkeys-proof-for | |
{ // seqno, exp, mode, tx<> | |
4 0 reverse | |
<b swap 32 u, swap 32 u, swap 8 u, swap ref, b> | |
} : order | |
{ // order, proof, pvtkey | |
2 pick hashu swap ed25519_sign_uint // order, proof, signature | |
<b swap B, swap <s s, b> swap // order, sig | |
<b swap <s s, swap ref, b> // sigorder | |
} : sigorder | |
// comment next line to run tests // /* | |
// /* | |
"TonUtil.fif" include | |
{ // n | |
| swap { newkeypair drop , } swap times // pvtkeys[] | |
} : test-pvtkeys | |
{ // prefix, n | |
| swap { | |
over "_key" $+ over count (.) $+ +".pk" load-generate-keypair nip , | |
} swap times nip // pvtkeys[] | |
} : test-pvtkeys-saved | |
{ // pvtkeys[] | |
explode { | |
swap priv>pub | |
over -roll | |
} over times tuple // keys[] | |
} : priv[]>pub[] | |
{ // pvtkeys[], n | |
over explode { | |
swap | |
priv>pub | |
over -roll | |
} over times tuple numkeys -rot // numkeys, pvtkeys[], i | |
[] priv>pub // numkeys, key_i | |
numkeys-proof-for // proof_i | |
} : test-numkeys-proof-i | |
{ // order, pvtkeys[], i | |
2dup test-numkeys-proof-i -rot [] // order, proof_i, pvtkey_i | |
sigorder // sigorder | |
} : test-sigorder | |
{ | |
<b 0 32 u, b> | |
} : test-init-message | |
{ // pvtkeys[] | |
priv[]>pub[] // keys[] | |
dup count 2 / 1 + swap // n, keys[] | |
numkeys swap // numkeys, n | |
<b 0 32 u, swap 8 u, swap ref, b> | |
} : test-init-c4 | |
{ // state, msg, t_delta | |
| 0 , 1 , 2 , swap now + , 4 , 5 , 6 , 7 , <b b> <s , 1 tuple // state, msg, c7 | |
-rot <s -1 rot // c7, msg{}, -1, state<> | |
contract-code <s swap 4 roll // c7, msg{}, -1, code{}, state<> | |
runvmctx // 0 (, error_code) state' | |
over 0 = { swap } { 3 0 reverse drop } cond // state, exit_code | |
} : test-run-external | |
// gas usage test, should be below 10k gas | |
25 test-pvtkeys constant gasusers | |
gasusers test-init-c4 | |
test-init-message 0 test-run-external 0<> abort"init" | |
1 now 60 + 0 <b b{001100} s, b> order constant gasorder1 | |
gasorder1 gasusers 0 test-sigorder 0 test-run-external OK <> abort"gastest1" | |
gasorder1 gasusers 1 test-sigorder 0 test-run-external OK <> abort"gastest1" | |
drop | |
// state transition tests | |
5 test-pvtkeys constant users7 | |
users7 test-init-c4 | |
test-init-message 0 test-run-external 0<> abort"" | |
// single order | |
1 now 60 + 0 <b b{001100} s, b> order constant order1 | |
order1 users7 0 test-sigorder 0 test-run-external OK <> abort"" | |
order1 users7 1 test-sigorder 0 test-run-external OK <> abort"" | |
order1 users7 2 test-sigorder 0 test-run-external OK <> abort"" | |
order1 users7 3 test-sigorder 0 test-run-external ERR_ORDER_NOT_FOUND <> abort"" | |
// simultaneous orders | |
2 now 60 + 0 <b b> order constant order2 | |
3 now 60 + 0 <b b> order constant order3 | |
order2 users7 0 test-sigorder 0 test-run-external OK <> abort"" | |
order3 users7 0 test-sigorder 0 test-run-external OK <> abort"" | |
order3 users7 1 test-sigorder 0 test-run-external OK <> abort"" | |
order3 users7 2 test-sigorder 0 test-run-external OK <> abort"" | |
order3 users7 3 test-sigorder 0 test-run-external ERR_ORDER_NOT_FOUND <> abort"" | |
order2 users7 3 test-sigorder 0 test-run-external OK <> abort"" | |
order2 users7 4 test-sigorder 0 test-run-external OK <> abort"" | |
order2 users7 1 test-sigorder 0 test-run-external ERR_ORDER_NOT_FOUND <> abort"" | |
// expired order | |
4 now 60 - 0 <b b> order constant order4exp | |
order4exp users7 0 test-sigorder 0 test-run-external ERR_ORDER_EXPIRED <> abort"" | |
// expiring order | |
4 now 60 + 0 <b b> order constant order4 | |
order4 users7 0 test-sigorder 0 test-run-external OK <> abort"" | |
order4 users7 1 test-sigorder 90 test-run-external ERR_ORDER_EXPIRED <> abort"" | |
order4 90 test-run-external OK <> abort"" | |
// missing signature | |
5 now 60 + 0 <b b> order constant order5nosig | |
order5nosig 0 test-run-external ERR_SIGNATURE_MISSING <> abort"" | |
// signature replay | |
5 now 60 + 0 <b b> order constant order5 | |
order5 users7 0 test-sigorder 0 test-run-external OK <> abort"" | |
order5 users7 1 test-sigorder 0 test-run-external OK <> abort"" | |
order5 users7 0 test-sigorder 0 test-run-external ERR_SIGNATURE_REPLAY <> abort"" | |
drop | |
// comment next line to get testnet example | |
/* be careful, it creates many files | |
{ | |
<b b{1000100} s, -rot addr, 0 Gram, b{00} s, swap <s s, b> | |
} : query | |
1 constant wallet1seqno | |
1 constant wallet2seqno | |
"wallet1" 3 test-pvtkeys-saved constant wallet1users3 | |
"wallet2" 5 test-pvtkeys-saved constant wallet2users5 | |
<b b{0011} s, | |
contract-code ref, | |
<b 0 32 u, 2 8 u, wallet1users3 priv[]>pub[] numkeys ref, b> ref, | |
dictnew dict, | |
b> constant wallet1stateinit | |
<b b{0011} s, | |
contract-code ref, | |
<b 0 32 u, 3 8 u, wallet2users5 priv[]>pub[] numkeys ref, b> ref, | |
dictnew dict, | |
b> constant wallet2stateinit | |
0 wallet1stateinit hashu 2constant wallet1addr | |
0 wallet2stateinit hashu 2constant wallet2addr | |
<b | |
b{1000100} s, | |
wallet1addr addr, | |
b{000010} s, | |
wallet1stateinit <s s, | |
b{0} s, | |
b> 2 boc+>B "wallet1_new.boc" B>file | |
wallet1seqno now 7200 + 0 <b | |
b{01} s, false 1 i, b{000100} s, | |
wallet2addr addr, 2000000000 Gram, | |
0 9 64 32 + + 1+ 1+ u, 0 32 u, "W1" $, | |
b> order constant wallet1order | |
"wallet1_" now (.) $+ +"_0.boc" constant wallet1_0.boc | |
"wallet1_" now (.) $+ +"_1.boc" constant wallet1_1.boc | |
"wallet1_" now (.) $+ +"_2.boc" constant wallet1_2.boc | |
wallet1order wallet1users3 0 test-sigorder wallet1addr query 2 boc+>B wallet1_0.boc B>file | |
wallet1order wallet1users3 1 test-sigorder wallet1addr query 2 boc+>B wallet1_1.boc B>file | |
wallet1order wallet1users3 2 test-sigorder wallet1addr query 2 boc+>B wallet1_2.boc B>file | |
wallet1addr 7 smca>$ constant wallet1addr7 | |
cr | |
"wallet1(2/3) 2GR$ to wallet2:" type cr cr | |
"lite-client -c 'last' -c 'getaccount " type wallet1addr7 type "'" type cr | |
"lite-client -c 'last' -c 'runmethod " type wallet1addr7 type " seqno'" type cr | |
"lite-client -c 'sendfile wallet1_new.boc'" type cr | |
"lite-client -c 'sendfile " type wallet1_0.boc type "'" type cr | |
"lite-client -c 'sendfile " type wallet1_1.boc type "'" type cr | |
"lite-client -c 'sendfile " type wallet1_2.boc type "'" type cr | |
cr | |
<b | |
b{1000100} s, | |
wallet2addr addr, | |
b{000010} s, | |
wallet2stateinit <s s, | |
b{0} s, | |
b> 2 boc+>B "wallet2_new.boc" B>file | |
wallet2seqno now 7200 + 0 <b | |
b{01} s, false 1 i, b{000100} s, | |
wallet1addr addr, 1000000000 Gram, | |
0 9 64 32 + + 1+ 1+ u, 0 32 u, "W2" $, | |
b> order constant wallet2order | |
"wallet2_" now (.) $+ +"_0.boc" constant wallet2_0.boc | |
"wallet2_" now (.) $+ +"_1.boc" constant wallet2_1.boc | |
"wallet2_" now (.) $+ +"_2.boc" constant wallet2_2.boc | |
"wallet2_" now (.) $+ +"_3.boc" constant wallet2_3.boc | |
"wallet2_" now (.) $+ +"_4.boc" constant wallet2_4.boc | |
wallet2order wallet2users5 0 test-sigorder wallet2addr query 2 boc+>B wallet2_0.boc B>file | |
wallet2order wallet2users5 1 test-sigorder wallet2addr query 2 boc+>B wallet2_1.boc B>file | |
wallet2order wallet2users5 2 test-sigorder wallet2addr query 2 boc+>B wallet2_2.boc B>file | |
wallet2order wallet2users5 3 test-sigorder wallet2addr query 2 boc+>B wallet2_3.boc B>file | |
wallet2order wallet2users5 4 test-sigorder wallet2addr query 2 boc+>B wallet2_4.boc B>file | |
wallet2addr 7 smca>$ constant wallet2addr7 | |
cr | |
"wallet2 (3/5) 1GR$ to wallet1:" type cr cr | |
"lite-client -c 'last' -c 'getaccount " type wallet2addr7 type "'" type cr | |
"lite-client -c 'last' -c 'runmethod " type wallet2addr7 type " seqno'" type cr | |
"lite-client -c 'sendfile wallet2_new.boc'" type cr | |
"lite-client -c 'sendfile " type wallet2_0.boc type "'" type cr | |
"lite-client -c 'sendfile " type wallet2_1.boc type "'" type cr | |
"lite-client -c 'sendfile " type wallet2_2.boc type "'" type cr | |
"lite-client -c 'sendfile " type wallet2_3.boc type "'" type cr | |
"lite-client -c 'sendfile " type wallet2_4.boc type "'" type cr | |
cr | |
// */ | |
contract-code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment