mirror of
https://github.com/danog/toncontest.git
synced 2024-11-26 12:04:50 +01:00
try adding support for tuples
This commit is contained in:
parent
bc0c6a467e
commit
ee6ce55976
2
lib
2
lib
@ -1 +1 @@
|
||||
Subproject commit 2d3b99c2e79558b6cbd91317e2a5628dba3d78c0
|
||||
Subproject commit f73b5d2babb4045a0d80ccf510a710657ca255a9
|
@ -1,5 +1,16 @@
|
||||
;; Multisig wallet smart contract
|
||||
|
||||
|
||||
;; Tuple manipulation primitives for integers
|
||||
tuple tuple_set(tuple t, int index, int value) asm(t value index) "SETINDEXVARQ";
|
||||
(tuple, ()) ~tuple_set(tuple t, int index, int value) asm(t value index) "SETINDEXVARQ";
|
||||
|
||||
;; Tuple manipulation primitives for cells
|
||||
tuple tuple_setcell(tuple t, int index, cell value) asm(t value index) "SETINDEXVARQ";
|
||||
(tuple, ()) ~tuple_setcell(tuple t, int index, cell value) asm(t value index) "SETINDEXVARQ";
|
||||
|
||||
int tuple_len(tuple t) asm "TLEN";
|
||||
|
||||
;; Cleanup expired partial orders
|
||||
;; messages
|
||||
(cell, ()) ~collect_garbage(cell messages) {
|
||||
@ -24,6 +35,50 @@
|
||||
return (messages, ());
|
||||
}
|
||||
|
||||
;; messages
|
||||
(slice, (tuple, tuple)) ~load_keys(slice messages) {
|
||||
int length = messages~load_uint(4);
|
||||
int index = 0;
|
||||
var keys = nil;
|
||||
var keys_cells = nil;
|
||||
var keys_cell = messages~load_ref();
|
||||
keys_cells~tuple_setcell(index / 3, keys_cell);
|
||||
var keys_slice = keys_cell.begin_parse();
|
||||
do {
|
||||
if ((index % 3 == 0)) {
|
||||
if ((index < 9) & (index > 0)) {
|
||||
keys_slice.end_parse();
|
||||
var keys_cell = messages~load_ref();
|
||||
keys_cells~tuple_setcell(index / 3, keys_cell);
|
||||
var keys_slice = keys_cell.begin_parse();
|
||||
} else {
|
||||
var newkeys_slice = keys_slice.preload_ref().begin_parse();
|
||||
keys_slice.end_parse();
|
||||
keys_slice = newkeys_slice;
|
||||
}
|
||||
}
|
||||
int key = keys_slice.preload_uint(256);
|
||||
|
||||
keys~tuple_set(index, key);
|
||||
index += 1;
|
||||
} until (index == length);
|
||||
keys_slice.end_parse();
|
||||
|
||||
return (messages, (keys, keys_cells));
|
||||
}
|
||||
|
||||
builder store_keys(builder b, int length, var keys) {
|
||||
b~store_uint(4, length);
|
||||
|
||||
length = keys.tuple_len();
|
||||
int index = 0;
|
||||
do {
|
||||
b.store_ref(keys.cell_at(index));
|
||||
index += 1;
|
||||
} until (index == length);
|
||||
return b;
|
||||
}
|
||||
|
||||
() store_db(int seqno, cell keys, cell messages) {
|
||||
set_data(begin_cell().store_uint(seqno, 32).store_dict(keys).store_dict(messages).end_cell());
|
||||
}
|
||||
@ -42,19 +97,19 @@
|
||||
throw_unless(33, in_msg.preload_uint(1));
|
||||
|
||||
var signatures = in_msg~load_dict();
|
||||
var message_data = in_msg;
|
||||
slice message_data = in_msg;
|
||||
|
||||
;; wrappedMessage$_ expires_at:uint32 seqno:uint32 body:^(Message X) = WrappedMessage X;
|
||||
var (expires_at, msg_seqno) = (message_data~load_uint(32), message_data~load_uint(32));
|
||||
(int expires_at, int msg_seqno) = (message_data~load_uint(32), message_data~load_uint(32));
|
||||
;; Message expired
|
||||
throw_if(34, expires_at <= now());
|
||||
|
||||
;; We will need the hash anyway
|
||||
var hash = slice_hash(in_msg);
|
||||
int hash = slice_hash(in_msg);
|
||||
|
||||
;; storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 256 ^(StoredMessage X)) = Storage X;
|
||||
var stored_data = get_data().begin_parse();
|
||||
var (stored_seqno, min_sigs, keys, messages) = (stored_data~load_uint(32), stored_data~load_uint(4), stored_data~load_dict(), stored_data~load_dict());
|
||||
slice stored_data = get_data().begin_parse();
|
||||
(int stored_seqno, int min_sigs, (var keys, var kcells), var messages) = (stored_data~load_uint(32), stored_data~load_uint(4), stored_data~load_keys(), stored_data~load_dict());
|
||||
stored_data.end_parse();
|
||||
|
||||
;; This is a new message, so there will be no stored messages
|
||||
@ -83,18 +138,16 @@
|
||||
do {
|
||||
(idx, var signature, var ok) = signatures.udict_get_next?(4, idx);
|
||||
if (ok) {
|
||||
var (public_key, kok) = keys.udict_get?(4, idx);
|
||||
throw_unless(36, kok);
|
||||
var public_key = keys.int_at(idx);
|
||||
;;throw_unless(at(at(36, kok);
|
||||
|
||||
var key = public_key~load_ref().begin_parse().preload_uint(256);
|
||||
var signature_cell = signature~load_ref();
|
||||
var signature_slice = signature_cell.begin_parse();
|
||||
var slice_copy = signature_slice;
|
||||
|
||||
signature_slice.end_parse();
|
||||
public_key.end_parse();
|
||||
|
||||
throw_unless(37, check_signature(hash, slice_copy, key));
|
||||
throw_unless(37, check_signature(hash, slice_copy, public_key));
|
||||
|
||||
storedMessageSignatures~udict_set_ref(4, idx, signature_cell);
|
||||
}
|
||||
@ -128,7 +181,7 @@
|
||||
messages~collect_garbage();
|
||||
|
||||
;; storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 256 ^(Message X)) = Storage X;
|
||||
set_data(begin_cell().store_uint(stored_seqno + 1, 32).store_uint(min_sigs, 4).store_dict(keys).store_dict(messages).end_cell());
|
||||
set_data(begin_cell().store_uint(stored_seqno + 1, 32).store_uint(min_sigs, 4).store_keys(keys.tuple_len(), kcells).store_dict(messages).end_cell());
|
||||
}
|
||||
|
||||
;; Get methods
|
||||
|
@ -2,6 +2,8 @@
|
||||
// automatically generated from `/home/daniil/repos/contest/lib/crypto/smartcont/stdlib.fc` `wallet-code.fc`
|
||||
PROGRAM{
|
||||
DECLPROC ~collect_garbage
|
||||
DECLPROC ~load_keys
|
||||
DECLPROC store_keys
|
||||
DECLPROC store_db
|
||||
DECLPROC recv_internal
|
||||
DECLPROC recv_external
|
||||
@ -39,6 +41,84 @@ PROGRAM{
|
||||
}>
|
||||
DROP
|
||||
}>
|
||||
~load_keys PROC:<{
|
||||
4 LDU
|
||||
0 PUSHINT
|
||||
PUSHNULL
|
||||
PUSHNULL
|
||||
s0 s3 XCHG
|
||||
LDREF
|
||||
s4 s1 XCPU
|
||||
0 PUSHINT
|
||||
SETINDEXVARQ
|
||||
SWAP
|
||||
CTOS
|
||||
UNTIL:<{
|
||||
s3 PUSH
|
||||
3 PUSHINT
|
||||
MOD
|
||||
0 EQINT
|
||||
IF:<{
|
||||
s3 PUSH
|
||||
9 LESSINT
|
||||
s4 PUSH
|
||||
0 GTINT
|
||||
AND
|
||||
IF:<{
|
||||
DUP
|
||||
ENDS
|
||||
s0 s4 XCHG
|
||||
LDREF
|
||||
s4 PUSH
|
||||
3 PUSHINT
|
||||
DIV
|
||||
s3 s2 s(-1) XCPUXC
|
||||
SETINDEXVARQ
|
||||
NIP
|
||||
}>ELSE<{
|
||||
DUP
|
||||
PLDREF
|
||||
CTOS
|
||||
SWAP
|
||||
ENDS
|
||||
s4 s4 XCHG2
|
||||
}>
|
||||
}>ELSE<{
|
||||
s4 s4 XCHG2
|
||||
}>
|
||||
s4 PUSH
|
||||
256 PLDU
|
||||
s3 s0 s4 XC2PU
|
||||
SETINDEXVARQ
|
||||
s0 s3 XCHG
|
||||
INC
|
||||
s0 s5 PUSH2
|
||||
EQUAL
|
||||
s5 s4 s0 XCHG3
|
||||
s3 s3 s0 XCHG3
|
||||
}>
|
||||
s3 POP
|
||||
s4 POP
|
||||
SWAP
|
||||
ENDS
|
||||
ROT
|
||||
}>
|
||||
store_keys PROC:<{
|
||||
4 PUSHINT
|
||||
2SWAP
|
||||
STUX
|
||||
OVER
|
||||
TLEN
|
||||
s2 POP
|
||||
0 PUSHINT
|
||||
UNTIL:<{
|
||||
INC
|
||||
s0 s2 PUSH2
|
||||
EQUAL
|
||||
}>
|
||||
DROP
|
||||
NIP
|
||||
}>
|
||||
store_db PROC:<{
|
||||
NEWC
|
||||
s1 s3 XCHG
|
||||
@ -72,17 +152,18 @@ PROGRAM{
|
||||
CTOS
|
||||
32 LDU
|
||||
4 LDU
|
||||
LDDICT
|
||||
~load_keys CALLDICT
|
||||
s0 s2 XCHG
|
||||
LDDICT
|
||||
ENDS
|
||||
NEWDICT
|
||||
s4 s6 PUSH2
|
||||
s5 s7 PUSH2
|
||||
EQUAL
|
||||
IF:<{
|
||||
s0 s4 XCHG
|
||||
s0 s5 XCHG
|
||||
INC
|
||||
}>ELSE<{
|
||||
s5 s1 PUSH2
|
||||
s6 s1 PUSH2
|
||||
8 PUSHPOW2
|
||||
DICTUGET
|
||||
NULLSWAPIFNOT
|
||||
@ -90,61 +171,52 @@ PROGRAM{
|
||||
LDREF
|
||||
NIP
|
||||
ENDS
|
||||
s0 s4 XCHG
|
||||
s0 s5 XCHG
|
||||
}>
|
||||
ACCEPT
|
||||
s0 s8 XCHG
|
||||
s0 s9 XCHG
|
||||
-1 PUSHINT
|
||||
UNTIL:<{
|
||||
s10 PUSH
|
||||
s11 PUSH
|
||||
4 PUSHINT
|
||||
DICTUGETNEXT
|
||||
NULLSWAPIFNOT
|
||||
NULLSWAPIFNOT
|
||||
DUP
|
||||
IF:<{
|
||||
s1 s5 PUSH2
|
||||
4 PUSHINT
|
||||
DICTUGET
|
||||
NULLSWAPIFNOT
|
||||
36 THROWIFNOT
|
||||
LDREF
|
||||
SWAP
|
||||
CTOS
|
||||
256 PLDU
|
||||
s0 s4 XCHG
|
||||
s5 s1 PUSH2
|
||||
INDEXVAR
|
||||
s0 s3 XCHG
|
||||
LDREF
|
||||
DROP
|
||||
DUP
|
||||
CTOS
|
||||
DUP
|
||||
ENDS
|
||||
s0 s2 XCHG
|
||||
ENDS
|
||||
s10 s(-1) s4 PUXC2
|
||||
s11 s0 s4 PUXC2
|
||||
CHKSIGNU
|
||||
37 THROWIFNOT
|
||||
s1 s2 XCHG
|
||||
4 PUSHINT
|
||||
s3 s8 s8 PUXC2
|
||||
s3 s9 s9 PUXC2
|
||||
DICTUSETREF
|
||||
}>ELSE<{
|
||||
s1 s7 s7 XCHG3
|
||||
s1 s8 s8 XCHG3
|
||||
DROP
|
||||
}>
|
||||
s0 s6 XCHG
|
||||
s0 s7 XCHG
|
||||
NOT
|
||||
}>
|
||||
DROP
|
||||
s9 POP
|
||||
s0 s8 XCHG
|
||||
s10 POP
|
||||
s0 s9 XCHG
|
||||
8 LDU
|
||||
LDREF
|
||||
ENDS
|
||||
0 PUSHINT
|
||||
-1 PUSHINT
|
||||
UNTIL:<{
|
||||
s6 PUSH
|
||||
s7 PUSH
|
||||
4 PUSHINT
|
||||
DICTUGETNEXT
|
||||
NULLSWAPIFNOT
|
||||
@ -154,58 +226,64 @@ PROGRAM{
|
||||
IF:<{
|
||||
s0 s2 XCHG
|
||||
INC
|
||||
s0 s6 PUSH2
|
||||
s0 s7 PUSH2
|
||||
GEQ
|
||||
IF:<{
|
||||
NIP
|
||||
s2 s3 PUSH2
|
||||
SENDRAWMSG
|
||||
8 PUSHPOW2
|
||||
s8 s12 s12 PUXC2
|
||||
s9 s13 s13 PUXC2
|
||||
DICTUDEL
|
||||
DROP
|
||||
0 PUSHINT
|
||||
}>ELSE<{
|
||||
s12 s12 XCHG2
|
||||
s13 s13 XCHG2
|
||||
}>
|
||||
}>ELSE<{
|
||||
s0 s12 s12 XCHG3
|
||||
s0 s13 s13 XCHG3
|
||||
}>
|
||||
NOT
|
||||
s12 s12 s0 XCHG3
|
||||
s13 s13 s0 XCHG3
|
||||
}>
|
||||
DROP
|
||||
s4 PUSH
|
||||
s5 PUSH
|
||||
LESS
|
||||
IF:<{
|
||||
NEWC
|
||||
s1 s5 XCHG
|
||||
s1 s6 XCHG
|
||||
STDICT
|
||||
s1 s7 XCHG
|
||||
s1 s8 XCHG
|
||||
32 STU
|
||||
s1 s5 XCHG
|
||||
s1 s6 XCHG
|
||||
32 STU
|
||||
s1 s5 XCHG
|
||||
s1 s6 XCHG
|
||||
8 STU
|
||||
s1 s2 XCHG
|
||||
STREF
|
||||
ENDC
|
||||
s0 s1 s5 XCHG3
|
||||
s0 s0 s6 XCHG3
|
||||
8 PUSHPOW2
|
||||
DICTUSETREF
|
||||
}>ELSE<{
|
||||
s2 s9 XCHG
|
||||
s3 s7 XCHG
|
||||
s2 s6 XCHG
|
||||
s4 s10 XCHG
|
||||
s3 s8 XCHG
|
||||
s2 s7 XCHG
|
||||
s4 s6 XCHG
|
||||
6 BLKDROP
|
||||
}>
|
||||
~collect_garbage CALLDICT
|
||||
s0 s2 XCHG
|
||||
s0 s3 XCHG
|
||||
INC
|
||||
NEWC
|
||||
32 STU
|
||||
s1 s4 XCHG
|
||||
4 STU
|
||||
s1 s2 XCHG
|
||||
STDICT
|
||||
s0 s3 XCHG
|
||||
TLEN
|
||||
s2 s3 XCHG
|
||||
SWAP
|
||||
store_keys CALLDICT
|
||||
STDICT
|
||||
ENDC
|
||||
c4 POP
|
||||
|
Loading…
Reference in New Issue
Block a user