ligo/src/test/contracts/multisig.religo
2020-03-02 18:01:56 +01:00

78 lines
2.0 KiB
Plaintext

// storage type
type counter = nat;
type threshold = nat;
type authorized_keys = list (key);
type id = string;
type storage = {
id : id,
counter : counter,
threshold : threshold,
auth : authorized_keys
};
// I/O types
type message = unit => list (operation);
type dummy = (key_hash,signature);
type signatures = list (dummy); /* Waiting to be fixed */
type check_message_pt = {
counter : counter,
message : message,
signatures : signatures
};
type return = (list (operation),storage);
type parameter = CheckMessage (check_message_pt);
let check_message = ((param, s): (check_message_pt, storage)) : return =>
{
let message : message = param.message;
let s =
if (param.counter != s.counter) {
(failwith ("Counters does not match") : storage);
} else {
let packed_payload : bytes =
Bytes.pack ((message, param.counter, s.id, chain_id));
let valid : nat = 0n;
let keys : authorized_keys = s.auth;
let aux = ((vk, pkh_sig) :
((nat, authorized_keys), (key_hash, signature)))
: (nat, authorized_keys) => {
let (valid, keys) = vk;
switch (keys) {
| [] => vk;
| [key, ...keys] =>
if (pkh_sig[0] == Crypto.hash_key (key)) {
let valid =
if (Crypto.check (key, pkh_sig[1], packed_payload)) {
valid + 1n;
}
else { (failwith ("Invalid signature") : nat) };
(valid, keys);
}
else { (valid, keys); };
};
};
let (valid, keys) =
List.fold (aux, param.signatures, (valid, keys));
if (valid < s.threshold) {
(failwith ("Not enough signatures passed the check") : storage);
}
else {
{...s,counter : s.counter + 1n};
};
};
(message (unit),s)
};
let main = ((action, store) : (parameter,storage)) : return =>
switch (action) {
| CheckMessage (p) => check_message ((p, store))
}