1
0
mirror of https://github.com/danog/toncontest.git synced 2024-11-26 20:15:01 +01:00
This commit is contained in:
Daniil Gentili 2019-10-06 18:16:41 +02:00
parent f7ac57b52c
commit 6a5f0fadd9
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
3 changed files with 151 additions and 10 deletions

View File

@ -118,3 +118,46 @@ if ($op === 0) {
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) {
}
}

View File

@ -21,13 +21,23 @@ multiSigWrapper$0 signatures:(HashmapE 4 ^Signature) message:(WrappedMessage 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
// 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))
{k:(## 4)} { k > 0 } { k >= 3 } { n >= k } { n <= 10 } = Storage X;
// Keys will be deserialized to a simple tuple, using the correct PubKeys constructor depending on the number n of keys left
//
// 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

View File

@ -1,9 +1,14 @@
"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"
256 B>u@
} : 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
."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!"
5 { dup $() swap 1+ } n times drop
n tuple constant keys-files
5 { dup $() +".pubkey" load-pubkey swap 1+ } n times drop
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
cr
."Creating new advanced wallet in workchain " wc .
."with n=" n .
."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
"wallet-code.fif" include