-
-
Save xandkar/949cc2bd6da5bab435abc858587c7110 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open SCaml | |
type action = | |
| Transfer of {amount: tz; dest: unit contract} | |
| Delegate of key_hash option | |
| ChangeKeys of {threshold : nat; keys : key list} | |
type parameter = | |
{counter: nat; action: action; sigs : signature option list} | |
type storage = | |
{stored_counter: nat; threshold: nat; keys: key list} | |
let check_signatures (payload : nat * action) sigs keys = | |
Loop.left (fun (acc, sigs, keys) -> | |
match (sigs, keys) with | |
| (_, []) -> Right (Some acc) | |
| ([], _ :: _) -> Right None | |
| (None :: sigs', _ :: keys') -> Left (acc, sigs', keys') | |
| (Some sig_ :: sigs', key :: keys') -> | |
let chain_id = Global.get_chain_id () in | |
let address = Global.get_sender () in | |
let bytes = Obj.pack ((chain_id, address), payload) in | |
if Crypto.check_signature key sig_ bytes then | |
Left (Nat 1 +^ acc, sigs', keys') | |
else | |
Right None | |
) | |
(Nat 0, sigs, keys) | |
let main (param: parameter) (storage: storage) = | |
let {counter; action; sigs} = param in | |
let {stored_counter; threshold; keys} = storage in | |
if counter <> stored_counter then failwith counter else | |
match check_signatures (counter, action) sigs keys with | |
| None -> failwith "an invalid signature" | |
| Some numb_of_valid_signatures -> | |
if numb_of_valid_signatures < threshold then failwith "signatures" else | |
let new_counter = Nat 1 +^ counter in | |
begin match action with | |
| Transfer {amount; dest} -> | |
let op = Operation.transfer_tokens () amount dest in | |
([op], {storage with stored_counter = new_counter}) | |
| Delegate kh -> | |
let op = Operation.set_delegate kh in | |
([op], {storage with stored_counter = new_counter}) | |
| ChangeKeys {threshold=new_threshold; keys=new_keys} -> | |
let new_storage = { | |
stored_counter = new_counter; | |
threshold = new_threshold; | |
keys = new_keys; | |
} | |
in | |
([], new_storage) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment