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
|
2019-11-21 20:11:04 +04:00
|
|
|
type message_t is (unit -> list(operation))
|
|
|
|
type signatures_t is list(key_hash * signature)
|
2019-11-19 18:34:59 +04:00
|
|
|
type check_message_pt is record
|
|
|
|
counter : counter_t ;
|
2019-11-21 20:11:04 +04:00
|
|
|
message : message_t ;
|
|
|
|
signatures : signatures_t ;
|
2019-11-19 18:34:59 +04:00
|
|
|
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 {
|
2019-11-21 20:11:04 +04:00
|
|
|
var message : message_t := param.message ;
|
2019-11-19 18:34:59 +04:00
|
|
|
|
|
|
|
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 ;
|
|
|
|
|
2019-11-21 20:11:04 +04:00
|
|
|
var keys : authorized_keys_t := 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")
|
2019-11-19 18:34:59 +04:00
|
|
|
else skip;
|
2019-11-21 20:11:04 +04:00
|
|
|
}
|
|
|
|
end
|
2019-11-19 18:34:59 +04:00
|
|
|
};
|
2019-11-21 20:11:04 +04:00
|
|
|
|
2019-11-19 18:34:59 +04:00
|
|
|
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
|