mirror of
https://github.com/danog/toncontest.git
synced 2024-11-26 20:15:01 +01:00
Save
This commit is contained in:
parent
f7ac57b52c
commit
6a5f0fadd9
@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user