mirror of
https://github.com/danog/toncontest.git
synced 2024-11-30 04:29:14 +01:00
Save
This commit is contained in:
parent
f7ac57b52c
commit
6a5f0fadd9
@ -118,3 +118,46 @@ if ($op === 0) {
|
|||||||
|
|
||||||
storeDb(garbageCollect($db));
|
storeDb(garbageCollect($db));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$keys = [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
];
|
||||||
|
|
||||||
|
$n = count($keys);
|
||||||
|
$nCells = $n / 3;
|
||||||
|
|
||||||
|
$cells = [];
|
||||||
|
$cell = [];
|
||||||
|
for ($x = 0; $x < n; $x++) {
|
||||||
|
for ($y = 0; $y < 3; $y++) {
|
||||||
|
$z = $x + $y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($keys as $k => $key) {
|
||||||
|
if ($k && !($k % 3)) {
|
||||||
|
$cells []= $cell;
|
||||||
|
$cell = [];
|
||||||
|
}
|
||||||
|
$cell []= $key;
|
||||||
|
}
|
||||||
|
if ($cell) {
|
||||||
|
$cells []= $cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
$final = [];
|
||||||
|
for ($x = $nRev = count($cells) - 1; $x >= 0; $x--) {
|
||||||
|
if ($nRev > 2 && $x != $nRev && $x > 1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -21,13 +21,23 @@ multiSigWrapper$0 signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X)
|
|||||||
multiSigWrapperStorage$_ signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapperStorage X;
|
multiSigWrapperStorage$_ signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapperStorage X;
|
||||||
|
|
||||||
|
|
||||||
|
pubKeys1$_ key1:PubKey = PubKeys;
|
||||||
|
pubKeys2$_ key1:PubKey key2:PubKey = PubKeys;
|
||||||
|
pubKeys3$_ key1:PubKey key2:PubKey key3:PubKey = PubKeys;
|
||||||
|
|
||||||
|
pubKeys3and$_ key1:PubKey key2:PubKey key3:PubKey _:^PubKeys = PubKeys;
|
||||||
|
|
||||||
// Not doing explicit versioning here, since the structure of the storage can only change after an update of the onchain wallet code
|
// Not doing explicit versioning here, since the structure of the storage can only change after an update of the onchain wallet code
|
||||||
// Max 10 keys (not sure about this, the contest instruction file says 10 in one place and 100 in another, so I chose 10 => 16 => 2^(4) )
|
// Max 10 keys (not sure about this, the contest instruction file says 10 in one place and 100 in another, so I chose 10 => 16 => 2^(4) )
|
||||||
// Min 3 signatures per message
|
|
||||||
// ^StoredMessage because 256*(40+) > 1023
|
|
||||||
//
|
//
|
||||||
storage$_ seqno:uint32 minSigs:(## 4) keys:(HashmapE 4 ^PubKey) messages:(HashmapE 256 ^(MultiSigWrapperStorage X))
|
// Keys will be deserialized to a simple tuple, using the correct PubKeys constructor depending on the number n of keys left
|
||||||
{k:(## 4)} { k > 0 } { k >= 3 } { n >= k } { n <= 10 } = Storage X;
|
//
|
||||||
|
// The pubKeys3and constructor is used when 10+ keys have to be stored
|
||||||
|
// in which case the last pubKeys3 constructor will contain a references to another PubKeys constructor,
|
||||||
|
// leaving one reference free in the storage cell to store the messages hashmap.
|
||||||
|
//
|
||||||
|
storage$_ seqno:uint32 minSigs:(## 4) n:(## 4) keys:[ ^PubKeys ] messages:(HashmapE 256 ^(MultiSigWrapperStorage X))
|
||||||
|
{ minSigs > 0 } { n >= minSigs } { n <= 10 } { minSigs <= 10 } = Storage X;
|
||||||
|
|
||||||
// TON stuff
|
// TON stuff
|
||||||
|
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
"TonUtil.fif" include
|
"TonUtil.fif" include
|
||||||
|
|
||||||
|
{ constant } : const
|
||||||
|
|
||||||
{ dup ."Loading public key from file " type cr
|
{ dup ."Loading public key from file " type ."..." cr
|
||||||
file>B dup Blen 32 <> abort"Public key must be exactly 32 bytes long"
|
file>B dup Blen 32 <> abort"Public key must be exactly 32 bytes long"
|
||||||
|
256 B>u@
|
||||||
} : load-pubkey
|
} : load-pubkey
|
||||||
|
{ dup ."Loading order from file " type ."..." cr
|
||||||
|
file>B B>boc
|
||||||
|
} : load-boc
|
||||||
|
|
||||||
{ ."usage: " @' $0 type ." <workchain-id> <wallet-name> <n> <k> [<key1> <key2> ...] [<boc1> <boc2>]" cr cr
|
{ ."usage: " @' $0 type ." <workchain-id> <wallet-name> <n> <k> [<key1> <key2> ...] [<boc1> <boc2>]" cr cr
|
||||||
."Creates a new multisignature wallet in specified workchain composed of <n> (1-10) public keys." cr
|
."Creates a new multisignature wallet in specified workchain composed of <n> (1-10) public keys." cr
|
||||||
@ -26,18 +31,101 @@ k n <= not abort"<k> must smaller than or equal to <n>"
|
|||||||
|
|
||||||
$# 4 n + < abort"Not enough keys were provided in args!"
|
$# 4 n + < abort"Not enough keys were provided in args!"
|
||||||
|
|
||||||
5 { dup $() swap 1+ } n times drop
|
5 { dup $() +".pubkey" load-pubkey swap 1+ } n times drop
|
||||||
n tuple constant keys-files
|
n tuple constant keys
|
||||||
|
|
||||||
5 n + { dup $() swap 1+ } m times drop
|
5 n + { dup $() +".boc" load-boc swap 1+ } m times drop
|
||||||
m tuple constant messages
|
m tuple constant messages
|
||||||
|
|
||||||
|
cr
|
||||||
."Creating new advanced wallet in workchain " wc .
|
."Creating new advanced wallet in workchain " wc .
|
||||||
."with n=" n .
|
."with n=" n .
|
||||||
."k=" k .
|
."k=" k .
|
||||||
."m=" m . cr
|
."m=" m . ."..." cr cr
|
||||||
|
|
||||||
keys-files explode { } swap times
|
// idict! (v x s n – s0 −1 or s 0), adds a new value v (represented
|
||||||
|
// by a Slice) with key given by signed big-endian n-bit integer x into
|
||||||
|
// dictionary s with n-bit keys, and returns the new dictionary s0 and −1
|
||||||
|
// on success. Otherwise the unchanged dictionary s and 0 are returned.
|
||||||
|
|
||||||
|
// Create dictionaries with keys and messages
|
||||||
|
|
||||||
|
// Keys will be deserialized to a simple tuple, using the correct PubKeys constructor depending on the number n of keys left
|
||||||
|
//
|
||||||
|
// pubKeys1$_ key1:PubKey = PubKeys;
|
||||||
|
// pubKeys2$_ key1:PubKey key2:PubKey = PubKeys;
|
||||||
|
// pubKeys3$_ key1:PubKey key2:PubKey key3:PubKey = PubKeys;
|
||||||
|
// pubKeys3and$_ key1:PubKey key2:PubKey key3:PubKey _:^PubKeys = PubKeys;
|
||||||
|
//
|
||||||
|
// keys:[ ^PubKeys ]
|
||||||
|
|
||||||
|
// First create builders with groups of (at most) 3 keys each
|
||||||
|
<b
|
||||||
|
0 { dup 1+ swap // Create a counter
|
||||||
|
// Get builder b (or create a new one)
|
||||||
|
// if ($k && !($k % 3)) {
|
||||||
|
dup dup 3 mod 0<> not and { <b } { 2 roll } cond
|
||||||
|
|
||||||
|
keys rot [] // Get n-th value x
|
||||||
|
256 // y
|
||||||
|
|
||||||
|
u, // Write uint
|
||||||
|
swap
|
||||||
|
} n times drop
|
||||||
|
|
||||||
|
// Then convert builders into cells, appropriately inserting references for nested pubkeys
|
||||||
|
n 3 /c const nCeil // Number of builders
|
||||||
|
nCeil 1- const nRev // Steps for reverse counter
|
||||||
|
nCeil 3 > const shouldRef // Whether there are more than 3 builders and references must be created
|
||||||
|
nCeil 1+ const nRoll // Steps for roll
|
||||||
|
|
||||||
|
nRev { dup 1- swap // Create a reverse counter
|
||||||
|
rot // Get current builder
|
||||||
|
swap
|
||||||
|
// if ($x != $nRev && $x > 1 && $nCeil > 3)
|
||||||
|
dup nRev <> swap 1 > shouldRef and and { nCeil pick ref, } if
|
||||||
|
|
||||||
|
b> // Close builder, create cell
|
||||||
|
nCeil -roll // Put cell at the back of the stack
|
||||||
|
|
||||||
|
} nCeil times drop
|
||||||
|
|
||||||
|
'drop nCeil 3 - times
|
||||||
|
|
||||||
|
/*
|
||||||
|
dictnew
|
||||||
|
0 { dup 1+ swap // Create a counter
|
||||||
|
0 { dup 1+ swap // Create another counter
|
||||||
|
2 pick + // Sum counters
|
||||||
|
dup keys swap [] // Get n-th value v
|
||||||
|
}
|
||||||
|
<b swap 256 B>u@ 256 u, // ~
|
||||||
|
|
||||||
|
swap // Get x
|
||||||
|
3 roll // Get dictionary s
|
||||||
|
4 // Get n
|
||||||
|
|
||||||
|
b>idict!
|
||||||
|
not abort"Failure storing dictionary value!"
|
||||||
|
|
||||||
|
swap
|
||||||
|
} nCells times drop const keys-dict
|
||||||
|
*/
|
||||||
|
|
||||||
|
// messages:(HashmapE 256 ^(MultiSigWrapperStorage X))
|
||||||
|
dictnew
|
||||||
|
0 { dup 1+ swap // Create a counter
|
||||||
|
messages swap [] // Get n-th value v
|
||||||
|
dup <b swap ref, // ~
|
||||||
|
|
||||||
|
swap hash // Get x
|
||||||
|
4 roll // Get dictionary s
|
||||||
|
256 // Get n
|
||||||
|
b>idict!
|
||||||
|
not abort"Failure storing dictionary value!"
|
||||||
|
|
||||||
|
swap
|
||||||
|
} m times drop const messages-dict
|
||||||
|
|
||||||
// code
|
// code
|
||||||
"wallet-code.fif" include
|
"wallet-code.fif" include
|
||||||
|
Loading…
Reference in New Issue
Block a user