ligo/src/test/contracts/multisig.mligo

67 lines
1.8 KiB
Plaintext
Raw Normal View History

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