Reviewing again the PascaLIGO contracts.

This commit is contained in:
Christian Rinderknecht 2020-02-27 19:09:14 +01:00
parent 93682629b4
commit a9214f864d
38 changed files with 209 additions and 216 deletions

View File

@ -7,7 +7,7 @@ let bad_contract basename =
let%expect_test _ = let%expect_test _ =
run_ligo_good [ "measure-contract" ; contract "coase.ligo" ; "main" ] ; run_ligo_good [ "measure-contract" ; contract "coase.ligo" ; "main" ] ;
[%expect {| 1747 bytes |}] ; [%expect {| 1870 bytes |}] ;
run_ligo_good [ "measure-contract" ; contract "multisig.ligo" ; "main" ] ; run_ligo_good [ "measure-contract" ; contract "multisig.ligo" ; "main" ] ;
[%expect {| 1324 bytes |}] ; [%expect {| 1324 bytes |}] ;
@ -86,7 +86,9 @@ let%expect_test _ =
SWAP ; SWAP ;
DIP { DUP ; CAR ; CAR } ; DIP { DUP ; CAR ; CAR } ;
GET ; GET ;
IF_NONE { PUSH string "MAP FIND" ; FAILWITH } {} ; IF_NONE
{ PUSH string "buy_single: No card pattern." ; FAILWITH }
{ DUP ; DIP { DROP } } ;
DUP ; DUP ;
CAR ; CAR ;
DIP { DUP ; CDR ; PUSH nat 1 ; ADD } ; DIP { DUP ; CDR ; PUSH nat 1 ; ADD } ;
@ -159,7 +161,9 @@ let%expect_test _ =
SWAP ; SWAP ;
DIP { DUP ; CAR ; CDR } ; DIP { DUP ; CAR ; CDR } ;
GET ; GET ;
IF_NONE { PUSH string "MAP FIND" ; FAILWITH } {} ; IF_NONE
{ PUSH string "sell_single: No card." ; FAILWITH }
{ DUP ; DIP { DROP } } ;
DUP ; DUP ;
CAR ; CAR ;
SENDER ; SENDER ;
@ -173,7 +177,9 @@ let%expect_test _ =
CDR ; CDR ;
DIP { DIP 2 { DUP } ; DIG 2 ; CAR ; CAR } ; DIP { DIP 2 { DUP } ; DIG 2 ; CAR ; CAR } ;
GET ; GET ;
IF_NONE { PUSH string "MAP FIND" ; FAILWITH } {} ; IF_NONE
{ PUSH string "sell_single: No card pattern." ; FAILWITH }
{ DUP ; DIP { DROP } } ;
DUP ; DUP ;
DIP { DUP } ; DIP { DUP } ;
SWAP ; SWAP ;
@ -209,7 +215,9 @@ let%expect_test _ =
MUL ; MUL ;
SENDER ; SENDER ;
CONTRACT unit ; CONTRACT unit ;
IF_NONE { PUSH string "bad address for get_contract" ; FAILWITH } {} ; IF_NONE
{ PUSH string "sell_single: No contract." ; FAILWITH }
{ DUP ; DIP { DROP } } ;
DIP { DUP } ; DIP { DUP } ;
SWAP ; SWAP ;
DIP { DUP } ; DIP { DUP } ;
@ -246,7 +254,9 @@ let%expect_test _ =
CAR ; CAR ;
DIP { DUP } ; DIP { DUP } ;
GET ; GET ;
IF_NONE { PUSH string "MAP FIND" ; FAILWITH } {} ; IF_NONE
{ PUSH string "transfer_single: No card." ; FAILWITH }
{ DUP ; DIP { DROP } } ;
DUP ; DUP ;
CAR ; CAR ;
SENDER ; SENDER ;

View File

@ -68,30 +68,30 @@ module Simplify = struct
(* Tezos module (ex-Michelson) *) (* Tezos module (ex-Michelson) *)
| "Tezos.chain_id" -> ok C_CHAIN_ID | "Tezos.chain_id" -> ok C_CHAIN_ID
| "chain_id" -> ok C_CHAIN_ID (* Deprecated *) | "chain_id" -> ok C_CHAIN_ID (* Deprecated *)
| "get_chain_id" -> ok C_CHAIN_ID (* Deprecated *) | "get_chain_id" -> ok C_CHAIN_ID (* Deprecated *)
| "Tezos.balance" -> ok C_BALANCE | "Tezos.balance" -> ok C_BALANCE
| "balance" -> ok C_BALANCE (* Deprecated *) | "balance" -> ok C_BALANCE (* Deprecated *)
| "Tezos.now" -> ok C_NOW | "Tezos.now" -> ok C_NOW
| "now" -> ok C_NOW (* Deprecated *) | "now" -> ok C_NOW (* Deprecated *)
| "Tezos.amount" -> ok C_AMOUNT | "Tezos.amount" -> ok C_AMOUNT
| "amount" -> ok C_AMOUNT (* Deprecated *) | "amount" -> ok C_AMOUNT (* Deprecated *)
| "Tezos.sender" -> ok C_SENDER | "Tezos.sender" -> ok C_SENDER
| "sender" -> ok C_SENDER (* Deprecated *) | "sender" -> ok C_SENDER (* Deprecated *)
| "Tezos.address" -> ok C_ADDRESS | "Tezos.address" -> ok C_ADDRESS
| "address" -> ok C_ADDRESS (* Deprecated *) | "address" -> ok C_ADDRESS (* Deprecated *)
| "Tezos.self_address" -> ok C_SELF_ADDRESS | "Tezos.self_address" -> ok C_SELF_ADDRESS
| "self_address" -> ok C_SELF_ADDRESS (* Deprecated *) | "self_address" -> ok C_SELF_ADDRESS (* Deprecated *)
| "Tezos.implicit_account" -> ok C_IMPLICIT_ACCOUNT | "Tezos.implicit_account" -> ok C_IMPLICIT_ACCOUNT
| "implicit_account" -> ok C_IMPLICIT_ACCOUNT (* Deprecated *) | "implicit_account" -> ok C_IMPLICIT_ACCOUNT (* Deprecated *)
| "Tezos.source" -> ok C_SOURCE | "Tezos.source" -> ok C_SOURCE
| "source" -> ok C_SOURCE (* Deprecated *) | "source" -> ok C_SOURCE (* Deprecated *)
| "Tezos.failwith" -> ok C_FAILWITH | "Tezos.failwith" -> ok C_FAILWITH
| "failwith" -> ok C_FAILWITH | "failwith" -> ok C_FAILWITH
| "Tezos.transaction" -> ok C_CALL | "Tezos.transaction" -> ok C_CALL
| "transaction" -> ok C_CALL (* Deprecated *) | "transaction" -> ok C_CALL (* Deprecated *)
| "Tezos.set_delegate" -> ok C_SET_DELEGATE | "Tezos.set_delegate" -> ok C_SET_DELEGATE
| "set_delegate" -> ok C_SET_DELEGATE (* Deprecated *) | "set_delegate" -> ok C_SET_DELEGATE (* Deprecated *)
| "get_contract" -> ok C_CONTRACT (* Deprecated *) | "get_contract" -> ok C_CONTRACT (* Deprecated *)
| "Tezos.get_contract_opt" -> ok C_CONTRACT_OPT | "Tezos.get_contract_opt" -> ok C_CONTRACT_OPT
@ -144,7 +144,7 @@ module Simplify = struct
| "Bytes.unpack" -> ok C_BYTES_UNPACK | "Bytes.unpack" -> ok C_BYTES_UNPACK
| "bytes_unpack" -> ok C_BYTES_UNPACK (* Deprecated *) | "bytes_unpack" -> ok C_BYTES_UNPACK (* Deprecated *)
| "Bytes.length" -> ok C_SIZE | "Bytes.length" -> ok C_SIZE
| "Bytes.size" -> ok C_SIZE | "Bytes.size" -> ok C_SIZE (* Deprecated *)
| "bytes_concat" -> ok C_CONCAT (* Deprecated *) | "bytes_concat" -> ok C_CONCAT (* Deprecated *)
| "Bytes.concat" -> ok C_CONCAT | "Bytes.concat" -> ok C_CONCAT
| "Bytes.slice" -> ok C_SLICE | "Bytes.slice" -> ok C_SLICE
@ -165,7 +165,8 @@ module Simplify = struct
(* Set module *) (* Set module *)
| "Set.size" -> ok C_SIZE | "Set.cardinal" -> ok C_SIZE
| "Set.size" -> ok C_SIZE (* Deprecated *)
| "set_size" -> ok C_SIZE (* Deprecated *) | "set_size" -> ok C_SIZE (* Deprecated *)
| "set_empty" -> ok C_SET_EMPTY (* Deprecated *) | "set_empty" -> ok C_SET_EMPTY (* Deprecated *)
| "Set.mem" -> ok C_SET_MEM | "Set.mem" -> ok C_SET_MEM
@ -339,14 +340,15 @@ module Simplify = struct
(* Set module *) (* Set module *)
| "Set.mem" -> ok C_SET_MEM | "Set.mem" -> ok C_SET_MEM
| "Set.iter" -> ok C_SET_ITER | "Set.iter" -> ok C_SET_ITER
| "Set.empty" -> ok C_SET_EMPTY | "Set.empty" -> ok C_SET_EMPTY
| "Set.literal" -> ok C_SET_LITERAL | "Set.literal" -> ok C_SET_LITERAL
| "Set.add" -> ok C_SET_ADD | "Set.add" -> ok C_SET_ADD
| "Set.remove" -> ok C_SET_REMOVE | "Set.remove" -> ok C_SET_REMOVE
| "Set.fold" -> ok C_SET_FOLD | "Set.fold" -> ok C_SET_FOLD
| "Set.size" -> ok C_SIZE | "Set.size" -> ok C_SIZE (* Deprecated *)
| "Set.cardinal" -> ok C_SIZE
(* Map module *) (* Map module *)

View File

@ -1,5 +1,3 @@
// function main (const c : contract (unit)) : address is address (c)
function main (const p : key_hash) : address is block { function main (const p : key_hash) : address is block {
const c : contract (unit) = implicit_account (p); const c : contract (unit) = Tezos.implicit_account (p);
} with address (c) } with Tezos.address (c)

View File

@ -1,8 +1,5 @@
function check (const p : unit) : int is function check (const p : unit) : int is
block { block {
var result : int := 0; var result : int := 0;
if Tezos.amount = 100tz then if amount = 100tz then result := 42 else result := 0
result := 42
else
result := 0
} with result } with result

View File

@ -1 +1 @@
let check = if Tezos.amount > 100tez then 42 else 0 let check_ (p : unit) : int = if Tezos.amount = 100tz then 42 else 0

View File

@ -1,15 +1,9 @@
// Test PascaLIGO arithmetic operators // Test PascaLIGO arithmetic operators
function mod_op (const n : int) : nat is n mod 42 function mod_op (const n : int) : nat is n mod 42
function plus_op (const n : int) : int is n + 42
function plus_op (const n : int) : int is n + 42
function minus_op (const n : int) : int is n - 42 function minus_op (const n : int) : int is n - 42
function times_op (const n : int) : int is n * 42 function times_op (const n : int) : int is n * 42
function div_op (const n : int) : int is n / 2
function div_op (const n : int) : int is n / 2 function int_op (const n : nat) : int is int (n)
function neg_op (const n : int) : int is -n
function int_op (const n : nat) : int is int (n)
function neg_op (const n : int) : int is -n

View File

@ -1,4 +1 @@
function main (const i : int) : int is function main (const i : int) : int is block {i := i + 1} with i
block {
i := i + 1
} with i

View File

@ -6,4 +6,4 @@ function main (const p : parameter; const s : storage) : return is
block { block {
var stamp : timestamp := ("badtimestamp" : timestamp) var stamp : timestamp := ("badtimestamp" : timestamp)
} }
with ((nil: list(operation)), stamp) with ((nil : list (operation)), stamp)

View File

@ -9,4 +9,4 @@ type storage is tez
type return is list (operation) * storage type return is list (operation) * storage
function main (const param : parameter; const store: storage) : return is function main (const param : parameter; const store: storage) : return is
((nil : list (operation)), balance) ((nil : list (operation)), Tezos.balance)

View File

@ -8,7 +8,7 @@ function main (const p : parameter; const s : storage) : return is
toto := s.0[23]; toto := s.0[23];
s.0[2] := 444 s.0[2] := 444
} }
with ((nil: list(operation)), s) with ((nil : list (operation)), s)
type foo is big_map (int, int) type foo is big_map (int, int)
@ -16,14 +16,12 @@ function set_ (var n : int; var m : foo) : foo is block {
m[23] := n m[23] := n
} with m } with m
function add (var n : int ; var m : foo) : foo is set_(n,m) function add (var n : int ; var m : foo) : foo is set_ (n,m)
function rm (var m : foo) : foo is block { function rm (var m : foo) : foo is block {
remove 42 from map m remove 42 from map m
} with m } with m
function gf (const m : foo) : int is get_force (23, m)
function get (const m : foo) : option (int) is m[42] function get (const m : foo) : option (int) is m[42]
const empty_big_map : big_map (int,int) = big_map [] const empty_big_map : big_map (int,int) = big_map []

View File

@ -1,11 +1,5 @@
// Test PascaLIGO boolean operators function or_true (const b : bool) : bool is b or True
function or_false (const b : bool) : bool is b or False
function or_true (const b : bool) : bool is b or True function and_true (const b : bool) : bool is b and True
function or_false (const b : bool) : bool is b or False
function and_true (const b : bool) : bool is b and True
function and_false (const b : bool) : bool is b and False function and_false (const b : bool) : bool is b and False
function not_bool (const b : bool) : bool is not b
function not_bool (const b : bool) : bool is not b

View File

@ -1,5 +1,3 @@
function concat_op (const s : bytes) : bytes is bytes_concat (s, 0x7070) function concat_op (const s : bytes) : bytes is Bytes.concat (s, 0x7070)
function slice_op (const s : bytes) : bytes is Bytes.sub (1n, 2n, s)
function slice_op (const s : bytes) : bytes is bytes_slice (1n, 2n, s) function hasherman (const s : bytes) : bytes is Crypto.sha256 (s)
function hasherman (const s : bytes) : bytes is sha_256 (s)

View File

@ -1,11 +1,11 @@
function id_string (const p : string) : option (string) is block { function id_string (const p : string) : option (string) is block {
const packed : bytes = bytes_pack (p) const packed : bytes = Bytes.pack (p)
} with (bytes_unpack (packed) : option (string)) } with (Bytes.unpack (packed) : option (string))
function id_int (const p : int) : option (int) is block { function id_int (const p : int) : option (int) is block {
const packed : bytes = bytes_pack (p) const packed : bytes = Bytes.pack (p)
} with (bytes_unpack (packed) : option (int)) } with (Bytes.unpack (packed) : option (int))
function id_address (const p : address) : option (address) is block { function id_address (const p : address) : option (address) is block {
const packed : bytes = bytes_pack (p) const packed : bytes = Bytes.pack (p)
} with (bytes_unpack (packed) : option (address)) } with (Bytes.unpack (packed) : option (address))

View File

@ -1 +1 @@
function chain_id (const tt : chain_id) : chain_id is get_chain_id function chain_id (const tt : chain_id) : chain_id is Tezos.chain_id

View File

@ -1,4 +1,4 @@
function check_signature (const pk : key; function check_signature (const pk : key;
const signed : signature; const signed : signature;
const msg: bytes) : bool const msg : bytes) : bool
is crypto_check (pk, signed, msg) is Crypto.check (pk, signed, msg)

View File

@ -45,27 +45,38 @@ type parameter is
| Transfer_single of action_transfer_single | Transfer_single of action_transfer_single
function transfer_single (const action : action_transfer_single; function transfer_single (const action : action_transfer_single;
const s : storage) : return is block { const s : storage) : return is
block {
const cards : cards = s.cards; const cards : cards = s.cards;
const card : card = get_force (action.card_to_transfer, cards); const card : card =
case cards[action.card_to_transfer] of
Some (card) -> card
| None -> (failwith ("transfer_single: No card.") : card)
end;
if card.card_owner =/= sender then if card.card_owner =/= sender then
failwith ("This card doesn't belong to you") failwith ("This card doesn't belong to you")
else skip; else skip;
card.card_owner := action.destination; card.card_owner := action.destination;
cards[action.card_to_transfer] := card; cards[action.card_to_transfer] := card;
s.cards := cards; s.cards := cards
const operations : list (operation) = nil } with ((nil : list (operation)), s)
} with (operations, s)
function sell_single (const action : action_sell_single; function sell_single (const action : action_sell_single;
const s : storage) : return is const s : storage) : return is
block { block {
const card : card = get_force (action.card_to_sell, s.cards); const card : card =
case s.cards[action.card_to_sell] of
Some (card) -> card
| None -> (failwith ("sell_single: No card.") : card)
end;
if card.card_owner =/= sender if card.card_owner =/= sender
then failwith ("This card doesn't belong to you") then failwith ("This card doesn't belong to you")
else skip; else skip;
const card_pattern : card_pattern = const card_pattern : card_pattern =
get_force (card.card_pattern, s.card_patterns); case s.card_patterns[card.card_pattern] of
Some (pattern) -> pattern
| None -> (failwith ("sell_single: No card pattern.") : card_pattern)
end;
card_pattern.quantity := abs (card_pattern.quantity - 1n); card_pattern.quantity := abs (card_pattern.quantity - 1n);
const card_patterns : card_patterns = s.card_patterns; const card_patterns : card_patterns = s.card_patterns;
card_patterns[card.card_pattern] := card_pattern; card_patterns[card.card_pattern] := card_pattern;
@ -74,8 +85,12 @@ function sell_single (const action : action_sell_single;
remove action.card_to_sell from map cards; remove action.card_to_sell from map cards;
s.cards := cards; s.cards := cards;
const price : tez = card_pattern.coefficient * card_pattern.quantity; const price : tez = card_pattern.coefficient * card_pattern.quantity;
const receiver : contract (unit) = get_contract (sender); const receiver : contract (unit) =
const op : operation = transaction (unit, price, receiver); case (Tezos.get_contract_opt (Tezos.sender) : option (contract (unit))) of
Some (contract) -> contract
| None -> (failwith ("sell_single: No contract.") : contract (unit))
end;
const op : operation = Tezos.transaction (unit, price, receiver);
const operations : list (operation) = list [op] const operations : list (operation) = list [op]
} with (operations, s) } with (operations, s)
@ -84,12 +99,13 @@ function buy_single (const action : action_buy_single;
block { block {
// Check funds // Check funds
const card_pattern : card_pattern = const card_pattern : card_pattern =
get_force (action.card_to_buy, s.card_patterns); case s.card_patterns[action.card_to_buy] of
Some (pattern) -> pattern
| None -> (failwith ("buy_single: No card pattern.") : card_pattern)
end;
const price : tez = const price : tez =
card_pattern.coefficient * (card_pattern.quantity + 1n); card_pattern.coefficient * (card_pattern.quantity + 1n);
if price > amount then failwith ("Not enough money") else skip; if price > amount then failwith ("Not enough money") else skip;
// Administrative procedure
const operations : list(operation) = nil;
// Increase quantity // Increase quantity
card_pattern.quantity := card_pattern.quantity + 1n; card_pattern.quantity := card_pattern.quantity + 1n;
const card_patterns : card_patterns = s.card_patterns; const card_patterns : card_patterns = s.card_patterns;
@ -103,7 +119,7 @@ function buy_single (const action : action_buy_single;
]; ];
s.cards := cards; s.cards := cards;
s.next_id := s.next_id + 1n s.next_id := s.next_id + 1n
} with (operations, s) } with ((nil : list (operation)), s)
function main (const action : parameter; const s : storage) : return is function main (const action : parameter; const s : storage) : return is
case action of case action of

View File

@ -1,4 +1,4 @@
type integer is int type integer = int
let main (i : int) = let main (i : int) =
if (i = 2 : bool) then (42 : int) else (0 : integer) if (i = 2 : bool) then (42 : int) else (0 : integer)

View File

@ -1,5 +1,3 @@
(* TODO : make a test using mutation, not shadowing *)
let main (i : int) = let main (i : int) =
let result = 0 in let result = 0 in
if i = 2 then if i = 2 then

View File

@ -1,3 +1,3 @@
// Test conditional in CameLIGO // Test conditional in CameLIGO
let main (i: int) = if i = 2 then 42 else 0 let main (i : int) = if i = 2 then 42 else 0

View File

@ -1,7 +1,7 @@
type t is int type t is int
function main (const p : int ; const s : t) : list (operation) * int is function main (const p : int; const s : t) : list (operation) * int is
block { block {
skip skip
} // skip is a do nothing instruction, needed for empty blocks } // skip is a do nothing instruction, needed for empty blocks
with ((nil : list(operation)), p + s) with ((nil : list (operation)), p+s)

View File

@ -1,3 +1,2 @@
function hasherman512 (const s: bytes) : bytes is sha_512 (s) function hasherman512 (const s : bytes) : bytes is Crypto.sha512 (s)
function hasherman_blake (const s : bytes) : bytes is Crypto.blake2b (s)
function hasherman_blake (const s: bytes) : bytes is blake2b (s)

View File

@ -1,5 +1,3 @@
// Test PascaLIGO top-level declarations
const foo : int = 42 const foo : int = 42
function main (const i : int) : int is i + foo function main (const i : int) : int is i + foo

View File

@ -21,9 +21,12 @@ function asymetric_tuple_access (const foo : unit) : int is
} with tuple.0 + tuple.1.0 + tuple.1.1.0 + tuple.1.1.1 } with tuple.0 + tuple.1.0 + tuple.1.1.0 + tuple.1.1.1
type nested_record_t is type nested_record_t is
record [nesty : record [mymap : map (int,string)]] record [nesty : record [mymap : map (int, string)]]
function nested_record (var nee : nested_record_t) : string is function nested_record (var nee : nested_record_t) : string is
block { block {
nee.nesty.mymap[1] := "one" nee.nesty.mymap[1] := "one"
} with get_force (1, nee.nesty.mymap) } with case nee.nesty.mymap[1] of
Some (s) -> s
| None -> (failwith ("Should not happen.") : string)
end

View File

@ -7,7 +7,6 @@ type storage is int
type return is list (operation) * storage type return is list (operation) * storage
function increment (const i : int; const n : int) : int is i+n function increment (const i : int; const n : int) : int is i+n
function decrement (const i : int; const n : int) : int is i-n function decrement (const i : int; const n : int) : int is i-n
const nop : list (operation) = nil const nop : list (operation) = nil

View File

@ -4,9 +4,12 @@ type return is list (operation) * storage
function cb (const a : address; const s : storage) : return is function cb (const a : address; const s : storage) : return is
block { block {
const c : contract (unit) = get_entrypoint ("%cb", a) const c : contract (unit) =
} case (Tezos.get_entrypoint_opt ("%cb", a) : option (contract (unit))) of
with (list [transaction (unit, 0mutez, c)], s) Some (contract) -> contract
| None -> (failwith ("cb: Entrypoint not found.") : contract (unit))
end
} with (list [Tezos.transaction (unit, 0tez, c)], s)
function cbo (const a : address; const s : storage) : return is function cbo (const a : address; const s : storage) : return is
@ -14,6 +17,6 @@ function cbo (const a : address; const s : storage) : return is
const c : contract (unit) = const c : contract (unit) =
case (get_entrypoint_opt ("%cbo", a) : option (contract (unit))) of case (get_entrypoint_opt ("%cbo", a) : option (contract (unit))) of
Some (c) -> c Some (c) -> c
| None -> (failwith ("entrypoint not found") : contract (unit)) | None -> (failwith ("cbo: Entrypoint not found.") : contract (unit))
end end
} with (list [transaction(unit, 0mutez, c)], s) } with (list [Tezos.transaction (unit, 0tez, c)], s)

View File

@ -1,4 +1,4 @@
type storage = unit type storage = unit
let main (p : unit; store : storage) : operation list * storage = let main (p, store : unit * storage) : operation list * storage =
if true then failwith "This contract always fails" failwith "This contract always fails"

View File

@ -1,2 +1,2 @@
function main (const a: int) : int is function main (const a : int) : int is
block { for i := 0 to 100 block { skip } } with i block { for i := 0 to 100 block { skip } } with i

View File

@ -1,19 +1,20 @@
type storage is unit type storage is unit
type return is list (operation) * storage type return is list (operation) * storage
function cb (const s : storage) : return is function cb (const s : storage) : return is block {
block { const c : contract (unit) =
const c : contract(unit) = get_contract(sender) case (Tezos.get_contract_opt (Tezos.sender) : option (contract (unit))) of
} Some (contract) -> contract
with (list [transaction(unit, 0mutez, c)], s) | None -> (failwith ("cb: No contract.") : contract (unit))
end
} with (list [Tezos.transaction (unit, 0tez, c)], s)
function cbo (const s : unit) : return is function cbo (const s : unit) : return is
block { block {
const c : contract (unit) = const c : contract (unit) =
case (get_contract_opt(sender) : option(contract(unit))) of case (Tezos.get_contract_opt (Tezos.sender) : option (contract (unit))) of
Some (c) -> c Some (contract) -> contract
| None -> (failwith ("contract not found") : contract (unit)) | None -> (failwith ("contract not found") : contract (unit))
end end
} } with (list [Tezos.transaction (unit, 0tez, c)], s)
with (list [transaction(unit, 0mutez, c)], s)

View File

@ -10,8 +10,12 @@ function get_top (const h : heap) : heap_elt is get_force (1n, h)
function pop_switch (const h : heap) : heap is function pop_switch (const h : heap) : heap is
block { block {
const result : heap_elt = get_top (h); const result : heap_elt = get_top (h);
const s : nat = size (h); const s : nat = Map.size (h);
const last : heap_elt = get_force (s, h); const last : heap_elt =
case h[s] of
Some (e) -> e
| None -> (failwith ("No element.") : heap_elt)
end;
remove 1n from map h; remove 1n from map h;
h[1n] := last h[1n] := last
} with h } with h
@ -19,8 +23,12 @@ function pop_switch (const h : heap) : heap is
function pop_ (const h : heap) : nat is function pop_ (const h : heap) : nat is
block { block {
const result : heap_elt = get_top (h); const result : heap_elt = get_top (h);
const s : nat = size (h); const s : nat = Map.size (h);
var current : heap_elt := get_force (s, h); var current : heap_elt :=
case h[s] of
Some (e) -> e
| None -> (failwith ("No element.") : heap_elt)
end;
const i : nat = 1n; const i : nat = 1n;
const left : nat = 2n * i; const left : nat = 2n * i;
const right : nat = left + 1n; const right : nat = left + 1n;

View File

@ -1 +1,2 @@
function main (const kh: key_hash) : contract (unit) is implicit_account (kh) function main (const kh: key_hash) : contract (unit) is
Tezos.implicit_account (kh)

View File

@ -1,7 +1,5 @@
function check_hash_key (const kh1 : key_hash; function check_hash_key (const kh1 : key_hash;
const k2 : key) : bool * key_hash is const k2 : key) : bool * key_hash is
block { block {
var ret : bool := False; var kh2 : key_hash := Crypto.hash_key (k2);
var kh2 : key_hash := crypto_hash_key (k2); } with ((kh1 = kh2), kh2)
if kh1 = kh2 then ret := True else skip
} with (ret, kh2)

View File

@ -1,8 +1,9 @@
type storage is record type storage is record [
one: map(key_hash, nat); one : map (key_hash, nat);
two: big_map(key_hash, bool); two : big_map (key_hash, bool)
end ]
type return is list (operation) * storage type return is list (operation) * storage
function main (const a : int; const store : storage) : return is ((nil: list(operation)), store) function main (const a : int; const store : storage) : return is
((nil : list (operation)), store)

View File

@ -17,17 +17,17 @@ const bl : foobar = list [144; 51; 42; 120; 421]
function fold_op (const s : list (int)) : int is function fold_op (const s : list (int)) : int is
block { block {
function aggregate (const prec: int; const cur: int) : int is prec+cur function aggregate (const prec: int; const cur: int) : int is prec+cur
} with list_fold (aggregate, s, 10) } with List.fold (aggregate, s, 10)
function iter_op (const s : list (int)) : int is function iter_op (const s : list (int)) : int is
block { block {
var r : int := 0; var r : int := 0;
function aggregate (const i : int) : unit is function aggregate (const i : int) : unit is
block { r := r + i } with unit; block { r := r + i } with unit;
list_iter (aggregate, s) List.iter (aggregate, s)
} with r } with r
function map_op (const s : list (int)) : list (int) is function map_op (const s : list (int)) : list (int) is
block { block {
function increment (const i : int) : int is i+1 function increment (const i : int) : int is i+1
} with list_map (increment, s) } with List.map (increment, s)

View File

@ -1,6 +1,6 @@
function shadowing_in_body (var nee : unit) : string is block { function shadowing_in_body (var nee : unit) : string is block {
var st : string := ""; var st : string := "";
var list1 : list(string) := list "to"; "to" end; var list1 : list (string) := list ["to"; "to"];
for x in list list1 block { for x in list list1 block {
const x : string = "ta"; const x : string = "ta";
st := st ^ x; st := st ^ x;
@ -10,7 +10,7 @@ function shadowing_in_body (var nee : unit) : string is block {
function shadowing_assigned_in_body (var nee : unit) : string is block { function shadowing_assigned_in_body (var nee : unit) : string is block {
var st : string := ""; var st : string := "";
var list1 : list(string) := list "to"; "to" end; var list1 : list (string) := list ["to"; "to"];
for x in list list1 block { for x in list list1 block {
st := st ^ x; st := st ^ x;
var st : string := "ta"; var st : string := "ta";

View File

@ -30,32 +30,28 @@ function patch_ (var m : foobar) : foobar is block {
function patch_deep (var m : foobar * nat) : foobar * nat is function patch_deep (var m : foobar * nat) : foobar * nat is
block { patch m.0 with map [1 -> 9] } with m block { patch m.0 with map [1 -> 9] } with m
function size_ (const m : foobar) : nat is size (m) function size_ (const m : foobar) : nat is Map.size (m)
function gf (const m : foobar) : int is get_force (23, m)
function get (const m : foobar) : option (int) is m[42] function get (const m : foobar) : option (int) is m[42]
function get_ (const m : foobar) : option (int) is map_get (42, m) function mem (const k: int; const m: foobar) : bool is Map.mem (k, m)
function mem (const k: int; const m: foobar) : bool is map_mem (k, m)
function iter_op (const m : foobar) : unit is function iter_op (const m : foobar) : unit is
block { block {
function aggregate (const i : int; const j : int) : unit is block function aggregate (const i : int; const j : int) : unit is block
{ if i=j then skip else failwith ("fail") } with unit { if i=j then skip else failwith ("fail") } with unit
} with map_iter (aggregate, m) } with Map.iter (aggregate, m)
function map_op (const m : foobar) : foobar is function map_op (const m : foobar) : foobar is
block { block {
function increment (const i : int; const j : int) : int is j+1 function increment (const i : int; const j : int) : int is j+1
} with map_map (increment, m) } with Map.map (increment, m)
function fold_op (const m : foobar) : int is function fold_op (const m : foobar) : int is
block { block {
function aggregate (const i : int; const j : int * int) : int is function aggregate (const i : int; const j : int * int) : int is
i + j.0 + j.1 i + j.0 + j.1
} with map_fold(aggregate, m, 10) } with Map.fold (aggregate, m, 10)
function deep_op (var m : foobar) : foobar is function deep_op (var m : foobar) : foobar is
block { block {

View File

@ -37,22 +37,22 @@ function send (const param : send_pt; const s : storage) : return is
block { block {
// check sender against the authorized addresses // check sender against the authorized addresses
if not set_mem (sender, s.authorized_addresses) if not Set.mem (Tezos.sender, s.authorized_addresses)
then failwith("Unauthorized address") then failwith("Unauthorized address")
else skip; else skip;
// check message size against the stored limit // check message size against the stored limit
var message : message := param; var message : message := param;
const packed_msg : bytes = bytes_pack (message); const packed_msg : bytes = Bytes.pack (message);
if size (packed_msg) > s.max_message_size if Bytes.length (packed_msg) > s.max_message_size
then failwith ("Message size exceed maximum limit") then failwith ("Message size exceed maximum limit")
else skip; else skip;
(* compute the new set of addresses associated with the message and (* compute the new set of addresses associated with the message and
update counters *) update counters *)
var new_store : addr_set := set_empty; var new_store : addr_set := set [];
case map_get (packed_msg, s.message_store) of case map_get (packed_msg, s.message_store) of
Some (voters) -> Some (voters) ->
@ -60,26 +60,25 @@ function send (const param : send_pt; const s : storage) : return is
(* The message is already stored. (* The message is already stored.
Increment the counter only if the sender is not already Increment the counter only if the sender is not already
associated with the message. *) associated with the message. *)
if set_mem (sender, voters) if Set.mem (Tezos.sender, voters)
then skip then skip
else s.proposal_counters[sender] := else s.proposal_counters[Tezos.sender] :=
get_force (sender, s.proposal_counters) + 1n; get_force (Tezos.sender, s.proposal_counters) + 1n;
new_store := Set.add (Tezos.sender,voters)
new_store := set_add(sender,voters)
} }
| None -> | None ->
block { block {
// the message has never been received before // the message has never been received before
s.proposal_counters[sender] := s.proposal_counters[sender] :=
get_force (sender, s.proposal_counters) + 1n; get_force (Tezos.sender, s.proposal_counters) + 1n;
new_store := set [sender] new_store := set [Tezos.sender]
} }
end; end;
// check sender counters against the maximum number of proposal // check sender counters against the maximum number of proposal
var sender_proposal_counter : nat := var sender_proposal_counter : nat :=
get_force (sender, s.proposal_counters); get_force (Tezos.sender, s.proposal_counters);
if sender_proposal_counter > s.max_proposal if sender_proposal_counter > s.max_proposal
then failwith ("Maximum number of proposal reached") then failwith ("Maximum number of proposal reached")
@ -89,14 +88,14 @@ function send (const param : send_pt; const s : storage) : return is
var ret_ops : list (operation) := nil; var ret_ops : list (operation) := nil;
if size (new_store) >= s.threshold then { if Set.cardinal (new_store) >= s.threshold then {
remove packed_msg from map s.message_store; remove packed_msg from map s.message_store;
ret_ops := message (s.state_hash); ret_ops := message (s.state_hash);
// update the state hash // update the state hash
s.state_hash := sha_256 (bytes_concat (s.state_hash, packed_msg)); s.state_hash := Crypto.sha256 (Bytes.concat (s.state_hash, packed_msg));
// decrement the counters // decrement the counters
for addr -> ctr in map s.proposal_counters block { for addr -> ctr in map s.proposal_counters block {
if set_mem(addr,new_store) then if Set.mem (addr, new_store) then
s.proposal_counters[addr] := abs (ctr - 1n) s.proposal_counters[addr] := abs (ctr - 1n)
else skip else skip
} }
@ -106,26 +105,26 @@ function send (const param : send_pt; const s : storage) : return is
function withdraw (const param : withdraw_pt; const s : storage) : return is function withdraw (const param : withdraw_pt; const s : storage) : return is
block { block {
var message : message := param; var message : message := param;
const packed_msg : bytes = bytes_pack (message); const packed_msg : bytes = Bytes.pack (message);
case map_get(packed_msg, s.message_store) of case s.message_store[packed_msg] of
Some (voters) -> Some (voters) ->
block { block {
// The message is stored // The message is stored
const new_set : addr_set = set_remove (sender, voters); const new_set : addr_set = Set.remove (Tezos.sender, voters);
(* Decrement the counter only if the sender was already (* Decrement the counter only if the sender was already
associated with the message *) associated with the message *)
if size (voters) =/= size (new_set) if Set.cardinal (voters) =/= Set.cardinal (new_set)
then s.proposal_counters[sender] := then s.proposal_counters[Tezos.sender] :=
abs (get_force (sender, s.proposal_counters) - 1n) abs (get_force (Tezos.sender, s.proposal_counters) - 1n)
else skip ; else skip;
(* If the message is left without any associated addresses, (* If the message is left without any associated addresses,
remove the corresponding message_store field *) remove the corresponding message_store field *)
if size (new_set) = 0n if Set.cardinal (new_set) = 0n
then remove packed_msg from map s.message_store then remove packed_msg from map s.message_store
else s.message_store[packed_msg] := new_set else s.message_store[packed_msg] := new_set
} }

View File

@ -38,7 +38,7 @@ function check_message (const param : check_message_pt;
failwith ("Counters does not match") failwith ("Counters does not match")
else { else {
const packed_payload : bytes = const packed_payload : bytes =
bytes_pack ((message, param.counter, s.id, get_chain_id)); Bytes.pack ((message, param.counter, s.id, Tezos.chain_id));
var valid : nat := 0n; var valid : nat := 0n;
var keys : authorized_keys := s.auth; var keys : authorized_keys := s.auth;
@ -47,12 +47,12 @@ function check_message (const param : check_message_pt;
nil -> skip nil -> skip
| key # tl -> block { | key # tl -> block {
keys := tl; keys := tl;
if pkh_sig.0 = crypto_hash_key (key) then if pkh_sig.0 = Crypto.hash_key (key) then
if crypto_check (key, pkh_sig.1, packed_payload) if Crypto.check (key, pkh_sig.1, packed_payload)
then valid := valid + 1n then valid := valid + 1n
else failwith ("Invalid signature") else failwith ("Invalid signature")
else skip else skip
} }
end end
}; };

View File

@ -1019,21 +1019,11 @@ let map_ type_f path : unit result =
let make_expected = e_nat in let make_expected = e_nat in
expect_eq_n_strict_pos_small program "size_" make_input make_expected expect_eq_n_strict_pos_small program "size_" make_input make_expected
in in
let%bind () =
let make_input = fun n -> ez [(23, n) ; (42, 4)] in
let make_expected = e_int in
expect_eq_n program "gf" make_input make_expected
in
let%bind () = let%bind () =
let make_input = fun n -> ez [(23, n) ; (42, 4)] in let make_input = fun n -> ez [(23, n) ; (42, 4)] in
let make_expected = fun _ -> e_some @@ e_int 4 in let make_expected = fun _ -> e_some @@ e_int 4 in
expect_eq_n program "get" make_input make_expected expect_eq_n program "get" make_input make_expected
in in
let%bind () =
let make_input = fun n -> ez [(23, n) ; (42, 4)] in
let make_expected = fun _ -> e_some @@ e_int 4 in
expect_eq_n program "get_" make_input make_expected
in
let%bind () = let%bind () =
let input_map = ez [(23, 10) ; (42, 4)] in let input_map = ez [(23, 10) ; (42, 4)] in
expect_eq program "mem" (e_tuple [(e_int 23) ; input_map]) (e_bool true) expect_eq program "mem" (e_tuple [(e_int 23) ; input_map]) (e_bool true)
@ -1081,11 +1071,6 @@ let big_map_ type_f path : unit result =
let lst' = List.map (fun (x, y) -> e_int x, e_int y) lst in let lst' = List.map (fun (x, y) -> e_int x, e_int y) lst in
(e_typed_big_map lst' t_int t_int) (e_typed_big_map lst' t_int t_int)
in in
let%bind () =
let make_input = fun n -> ez [(23, n) ; (42, 4)] in
let make_expected = e_int in
expect_eq_n program "gf" make_input make_expected
in
let%bind () = let%bind () =
let make_input = fun n -> let make_input = fun n ->
let m = ez [(23 , 0) ; (42 , 0)] in let m = ez [(23 , 0) ; (42 , 0)] in
@ -2241,51 +2226,51 @@ let empty_case_religo () : unit result =
in in
ok () ok ()
let tuple_type_mligo () : unit result = let tuple_type_mligo () : unit result =
let%bind program = mtype_file "./contracts/tuple_type.mligo" in let%bind program = mtype_file "./contracts/tuple_type.mligo" in
let%bind () = let%bind () =
let input _ = e_int 0 in let input _ = e_int 0 in
let expected _ = e_int 8 in let expected _ = e_int 8 in
expect_eq_n program "test1" input expected expect_eq_n program "test1" input expected
in in
let%bind () = let%bind () =
let input _ = e_int 0 in let input _ = e_int 0 in
let expected _ = e_int 12 in let expected _ = e_int 12 in
expect_eq_n program "test2" input expected expect_eq_n program "test2" input expected
in in
ok () ok ()
let tuple_type_religo () : unit result = let tuple_type_religo () : unit result =
let%bind program = retype_file "./contracts/tuple_type.religo" in let%bind program = retype_file "./contracts/tuple_type.religo" in
let%bind () = let%bind () =
let input _ = e_int 0 in let input _ = e_int 0 in
let expected _ = e_int 8 in let expected _ = e_int 8 in
expect_eq_n program "arguments_test" input expected expect_eq_n program "arguments_test" input expected
in in
let%bind () = let%bind () =
let input _ = e_int 0 in let input _ = e_int 0 in
let expected _ = e_int 8 in let expected _ = e_int 8 in
expect_eq_n program "tuple_test" input expected expect_eq_n program "tuple_test" input expected
in in
let%bind () = let%bind () =
let input _ = e_int 0 in let input _ = e_int 0 in
let expected _ = e_int 8 in let expected _ = e_int 8 in
expect_eq_n program "arguments_test_inline" input expected expect_eq_n program "arguments_test_inline" input expected
in in
let%bind () = let%bind () =
let input _ = e_int 0 in let input _ = e_int 0 in
let expected _ = e_int 8 in let expected _ = e_int 8 in
expect_eq_n program "tuple_test_inline" input expected expect_eq_n program "tuple_test_inline" input expected
in in
ok () ok ()
let no_semicolon_religo () : unit result = let no_semicolon_religo () : unit result =
let%bind program = retype_file "./contracts/no_semicolon.religo" in let%bind program = retype_file "./contracts/no_semicolon.religo" in
let%bind () = let%bind () =
let input _ = e_int 2 in let input _ = e_int 2 in
let expected _ = e_int 3 in let expected _ = e_int 3 in
expect_eq_n program "a" input expected expect_eq_n program "a" input expected
in in
ok () ok ()
let loop_bugs_ligo () : unit result = let loop_bugs_ligo () : unit result =