mirror of
https://github.com/danog/toncontest.git
synced 2024-11-30 04:29:14 +01:00
199 lines
6.9 KiB
Plaintext
199 lines
6.9 KiB
Plaintext
// This is just an approximated TL scheme, explaining the message formats used by the multisig wallet.
|
|
// Multisig wallet constructors
|
|
|
|
// 256 bits
|
|
pubKey$_ k:bits256 = PubKey;
|
|
|
|
// 512 bits
|
|
signature$_ R:bits256 s:bits256 = Signature;
|
|
|
|
// Message + send ModeMessage
|
|
modeMessage$_ mode:uint8 body:^(Message X) = ModeMessage X;
|
|
|
|
// Actual multisigned message
|
|
wrappedMessage$_ expires_at:uint32 seqno:uint32 body:(ModeMessage X) = WrappedMessage X;
|
|
|
|
// key ID => signature
|
|
multiSigWrapper$0 signatures:(HashmapE 4 ^Signature) message:(WrappedMessage X) = MultiSigWrapper X;
|
|
//multiSigFuture$1 = MultiSigWrapper X;
|
|
|
|
// For internal storage, no constructor ID
|
|
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) )
|
|
//
|
|
// 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
|
|
|
|
unit$_ = Unit;
|
|
true$_ = True;
|
|
// EMPTY False;
|
|
bool_false$0 = Bool;
|
|
bool_true$1 = Bool;
|
|
bool_false$0 = BoolFalse;
|
|
bool_true$1 = BoolTrue;
|
|
nothing$0 {X:Type} = Maybe X;
|
|
just$1 {X:Type} value:X = Maybe X;
|
|
left$0 {X:Type} {Y:Type} value:X = Either X Y;
|
|
right$1 {X:Type} {Y:Type} value:Y = Either X Y;
|
|
pair$_ {X:Type} {Y:Type} first:X second:Y = Both X Y;
|
|
|
|
bit$_ (## 1) = Bit;
|
|
/*
|
|
*
|
|
* FROM hashmap.tlb
|
|
*
|
|
*/
|
|
// ordinary Hashmap / HashmapE, with fixed length keys
|
|
//
|
|
hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
|
|
{n = (~m) + l} node:(HashmapNode m X) = Hashmap n X;
|
|
|
|
hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X;
|
|
hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X)
|
|
right:^(Hashmap n X) = HashmapNode (n + 1) X;
|
|
|
|
hml_short$0 {m:#} {n:#} len:(Unary ~n) {n <= m} s:(n * Bit) = HmLabel ~n m;
|
|
hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m;
|
|
hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m;
|
|
|
|
unary_zero$0 = Unary ~0;
|
|
unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);
|
|
|
|
hme_empty$0 {n:#} {X:Type} = HashmapE n X;
|
|
hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X;
|
|
|
|
extra_currencies$_ dict:(HashmapE 32 (VarUInteger 32))
|
|
= ExtraCurrencyCollection;
|
|
// true#_ = True;
|
|
_ {n:#} _:(Hashmap n True) = BitstringSet n;
|
|
|
|
// HashmapAug, hashmap with an extra value
|
|
// (augmentation) of type Y at every node
|
|
//
|
|
ahm_edge#_ {n:#} {X:Type} {Y:Type} {l:#} {m:#}
|
|
label:(HmLabel ~l n) {n = (~m) + l}
|
|
node:(HashmapAugNode m X Y) = HashmapAug n X Y;
|
|
ahmn_leaf#_ {X:Type} {Y:Type} extra:Y value:X = HashmapAugNode 0 X Y;
|
|
ahmn_fork#_ {n:#} {X:Type} {Y:Type} left:^(HashmapAug n X Y)
|
|
right:^(HashmapAug n X Y) extra:Y = HashmapAugNode (n + 1) X Y;
|
|
|
|
ahme_empty$0 {n:#} {X:Type} {Y:Type} extra:Y
|
|
= HashmapAugE n X Y;
|
|
ahme_root$1 {n:#} {X:Type} {Y:Type} root:^(HashmapAug n X Y)
|
|
extra:Y = HashmapAugE n X Y;
|
|
|
|
// VarHashmap / VarHashmapE, with variable-length keys
|
|
//
|
|
vhm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
|
|
{n = (~m) + l} node:(VarHashmapNode m X)
|
|
= VarHashmap n X;
|
|
vhmn_leaf$00 {n:#} {X:Type} value:X = VarHashmapNode n X;
|
|
vhmn_fork$01 {n:#} {X:Type} left:^(VarHashmap n X)
|
|
right:^(VarHashmap n X) value:(Maybe X)
|
|
= VarHashmapNode (n + 1) X;
|
|
vhmn_cont$1 {n:#} {X:Type} branch:Bit child:^(VarHashmap n X)
|
|
value:X = VarHashmapNode (n + 1) X;
|
|
|
|
// nothing$0 {X:Type} = Maybe X;
|
|
// just$1 {X:Type} value:X = Maybe X;
|
|
|
|
vhme_empty$0 {n:#} {X:Type} = VarHashmapE n X;
|
|
vhme_root$1 {n:#} {X:Type} root:^(VarHashmap n X)
|
|
= VarHashmapE n X;
|
|
|
|
//
|
|
// PfxHashmap / PfxHashmapE, with variable-length keys
|
|
// constituting a prefix code
|
|
//
|
|
|
|
phm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
|
|
{n = (~m) + l} node:(PfxHashmapNode m X)
|
|
= PfxHashmap n X;
|
|
|
|
phmn_leaf$0 {n:#} {X:Type} value:X = PfxHashmapNode n X;
|
|
phmn_fork$1 {n:#} {X:Type} left:^(PfxHashmap n X)
|
|
right:^(PfxHashmap n X) = PfxHashmapNode (n + 1) X;
|
|
|
|
phme_empty$0 {n:#} {X:Type} = PfxHashmapE n X;
|
|
phme_root$1 {n:#} {X:Type} root:^(PfxHashmap n X)
|
|
= PfxHashmapE n X;
|
|
/*
|
|
*
|
|
* END hashmap.tlb
|
|
*
|
|
*/
|
|
|
|
// TON messages
|
|
|
|
|
|
addr_none$00 = MsgAddressExt;
|
|
addr_extern$01 len:(## 9) external_address:(bits len)
|
|
= MsgAddressExt;
|
|
anycast_info$_ depth:(#<= 30) { depth >= 1 }
|
|
rewrite_pfx:(bits depth) = Anycast;
|
|
addr_std$10 anycast:(Maybe Anycast)
|
|
workchain_id:int8 address:bits256 = MsgAddressInt;
|
|
addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9)
|
|
workchain_id:int32 address:(bits addr_len) = MsgAddressInt;
|
|
_ _:MsgAddressInt = MsgAddress;
|
|
_ _:MsgAddressExt = MsgAddress;
|
|
//
|
|
var_uint$_ {n:#} len:(#< n) value:(uint (len * 8))
|
|
= VarUInteger n;
|
|
var_int$_ {n:#} len:(#< n) value:(int (len * 8))
|
|
= VarInteger n;
|
|
nanograms$_ amount:(VarUInteger 16) = Grams;
|
|
//
|
|
extra_currencies$_ dict:(HashmapE 32 (VarUInteger 32))
|
|
= ExtraCurrencyCollection;
|
|
currencies$_ grams:Grams other:ExtraCurrencyCollection
|
|
= CurrencyCollection;
|
|
//
|
|
int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool
|
|
src:MsgAddressInt dest:MsgAddressInt
|
|
value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams
|
|
created_lt:uint64 created_at:uint32 = CommonMsgInfo;
|
|
ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt
|
|
import_fee:Grams = CommonMsgInfo;
|
|
ext_out_msg_info$11 src:MsgAddressInt dest:MsgAddressExt
|
|
created_lt:uint64 created_at:uint32 = CommonMsgInfo;
|
|
|
|
|
|
int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool
|
|
src:MsgAddress dest:MsgAddressInt
|
|
value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams
|
|
created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed;
|
|
ext_out_msg_info$11 src:MsgAddress dest:MsgAddressExt
|
|
created_lt:uint64 created_at:uint32 = CommonMsgInfoRelaxed;
|
|
|
|
tick_tock$_ tick:Bool tock:Bool = TickTock;
|
|
|
|
_ split_depth:(Maybe (## 5)) special:(Maybe TickTock)
|
|
code:(Maybe ^Cell) data:(Maybe ^Cell)
|
|
library:(HashmapE 256 SimpleLib) = StateInit;
|
|
|
|
simple_lib$_ public:Bool root:^Cell = SimpleLib;
|
|
|
|
// create a message
|
|
message$_ {X:Type} info:CommonMsgInfo
|
|
init:(Maybe (Either StateInit ^StateInit))
|
|
body:(Either X ^X) = Message X;
|
|
|