ligo/src/test/contracts/multisig.ligo

57 lines
1.5 KiB
Plaintext
Raw Normal View History

2019-11-19 18:34:59 +04:00
// storage type
type counter_t is nat
type threshold_t is nat
type authorized_keys_t is list(key)
2019-11-20 21:17:35 +04:00
type id_t is string
2019-11-19 18:34:59 +04:00
type storage_t is record
2019-11-20 21:17:35 +04:00
id : id_t ;
2019-11-19 18:34:59 +04:00
counter : counter_t ;
threshold : threshold_t ;
auth : authorized_keys_t ;
end
// I/O types
type check_message_pt is record
counter : counter_t ;
message : (unit -> list(operation)) ;
signatures : list(signature) ;
end
type contract_return_t is (list(operation) * storage_t)
type entry_point_t is
| CheckMessage of check_message_pt
function check_message (const param : check_message_pt;
const s : storage_t) : contract_return_t is block {
var message : (unit -> list(operation)) := param.message ;
if param.counter =/= s.counter then
failwith ("Counters does not match")
else block {
2019-11-20 21:17:35 +04:00
const packed_payload : bytes =
bytes_pack((message , param.counter , s.id , get_chain_id));
2019-11-19 18:34:59 +04:00
var valid : nat := 0n ;
for sig in list param.signatures block {
var is_valid : bool := False ;
for pk in list s.auth block {
2019-11-20 21:17:35 +04:00
if crypto_check(pk,sig,packed_payload) then is_valid := True
2019-11-19 18:34:59 +04:00
else skip;
};
if is_valid then valid := valid + 1n
else failwith ("Invalid signature")
};
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 : entry_point_t; const s : storage_t) : contract_return_t is
case param of
| CheckMessage (p) -> check_message(p,s)
end