Skip to content

Instantly share code, notes, and snippets.

@gaxiiiiiiiiiiii
Last active April 2, 2021 13:55
Show Gist options
  • Save gaxiiiiiiiiiiii/80b216d4ebdd0fc77da12aee8bdf506b to your computer and use it in GitHub Desktop.
Save gaxiiiiiiiiiiii/80b216d4ebdd0fc77da12aee8bdf506b to your computer and use it in GitHub Desktop.
open SCaml;;
type amount = tz;;
type dest = unit contract;;
type threshold = nat;;
type keys = key list;;
type action =
| Transfer of amount * dest
| Change_keys of threshold * keys
| Deposit of unit;;
type payload = {
counter : nat;
action : action
};;
type parameter ={
payload : payload;
sigs : signature option list
};;
type storage = {
counter : nat;
threshold : nat;
keys : key list
};;
let [@entry] main (prm : parameter) (str : storage) =
if not (str.counter = prm.payload.counter) then failwith "invalid count";
let m = Obj.pack (Global.get_chain_id (), Global.get_source (), prm.payload) in
let check k s = match s with
| Some s -> Crypto.check_signature k s m
| None -> false in
let exist = List.fold_left (||) false in
let forall = List.fold_left (&&) true in
let g acc x = if exist x then List.rev_append acc [x] else acc in
let filter = List.fold_left g [] in
let ss = prm.sigs in
let f k = List.map (check k) ss in
let bss = List.map f str.keys in
let bs = filter bss in
let b = List.length bs in
if (b < str.threshold) then failwith "invalid signature";
let str' = {str with counter = str.counter +^ Nat 1} in
match prm.payload.action with
| Transfer (n, c) ->
let op = Operation.transfer_tokens () n c
in ([op], str')
| Change_keys (n,ks) ->
if (n > List.length ks) then failwith "invalid threshold";
let str'' = {str' with threshold = n} in
let str''' = {str'' with keys = ks} in
([], str''')
| Deposit _ ->
([],str')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment