ligo/src/test/contracts/multisig.ligo
2020-02-27 19:09:14 +01:00

67 lines
1.6 KiB
Plaintext

// storage type
type counter is nat
type threshold is nat
type authorized_keys is list (key)
type id is string
type storage is
record [
id : id;
counter : counter;
threshold : threshold;
auth : authorized_keys
]
// I/O types
type message is unit -> list (operation)
type signatures is list (key_hash * signature)
type check_message_pt is
record [
counter : counter;
message : message;
signatures : signatures
]
type return is list (operation) * storage
type parameter is CheckMessage of check_message_pt
function check_message (const param : check_message_pt;
const s : storage) : return is block {
var message : message := param.message;
if param.counter =/= s.counter then
failwith ("Counters does not match")
else {
const packed_payload : bytes =
Bytes.pack ((message, param.counter, s.id, Tezos.chain_id));
var valid : nat := 0n;
var keys : authorized_keys := s.auth;
for pkh_sig in list param.signatures block {
case keys of
nil -> skip
| key # tl -> block {
keys := tl;
if pkh_sig.0 = Crypto.hash_key (key) then
if Crypto.check (key, pkh_sig.1, packed_payload)
then valid := valid + 1n
else failwith ("Invalid signature")
else skip
}
end
};
if valid < s.threshold then
failwith ("Not enough signatures passed the check")
else s.counter := s.counter + 1n
}
} with (message (unit), s)
function main (const param : parameter; const s : storage) : return is
case param of CheckMessage (p) -> check_message (p,s) end