Hangzhou
API
New types
type chest
type chest
type chest
A type for chests
type chest_key
type chest_key
type chest_key
A type for chest keys
type chest_opening_result is
Ok_opening of bytes
| Fail_decrypt
| Fail_timelock
type chest_opening_result =
Ok_opening of bytes
| Fail_decrypt
| Fail_timelock
type chest_opening_result =
["Ok_opening", bytes]
| ["Fail_decrypt"]
| ["Fail_timelock"];
A type for the result of chest opening, see Tezos.open_chest
New primitives
Tezos
val open_chest : chest_key -> chest -> nat -> chest_opening_result
val open_chest : chest_key -> chest -> nat -> chest_opening_result
let open_chest : chest_key => chest => nat => chest_opening_result
val call_view<arg,reg> : string -> arg -> address -> option (ret)
val call_view : string -> 'arg -> address -> 'ret option
let call_view : string => 'arg => address => option <'ret>
function constant: string -> 'a
val constant : string -> 'a
let constant : string => 'a
Test
New signature for originate_from_file:
val originate_from_file : string -> string -> list (string) -> michelson_program -> tez -> (address * michelson_program * int)
val originate_from_file : string -> string -> string list -> michelson_program -> tez -> (address * michelson_program * int)
let originate_from_file = (filepath: string, entrypoint: string , views : list <'string> , init: michelson_program, balance: tez) => [address, michelson_program, int]
Originate a contract with a path to the contract file, an entrypoint, a list of views, an initial storage and an initial balance.
val create_chest : bytes -> nat -> chest * chest_key
val create_chest : bytes -> nat -> chest * chest_key
let create_chest : bytes => nat => [chest , chest_key]
Generate a locked value, the RSA parameters and encrypt the payload. Also returns the chest key Exposes tezos timelock library function create_chest_and_chest_key
val create_chest_key : chest -> nat -> chest_key
val create_chest_key : chest -> nat -> chest_key
let create_chest_key : chest => nat => chest_key
Unlock the value and create the time-lock proof. Exposes tezos timelock library function create_chest_key.
Examples
Timelock
Extensive documentation about timelock can be found here. Here is an example of a contract trying to open a chest and the corresponding tests to trigger all error kinds:
type storage = bytes
type parameter = chest_key * chest
type return = operation list * storage
let main (p, _ : parameter * storage) : return =
let (ck,c) = p in
let new_s =
match Tezos.open_chest ck c 10n with
| Ok_opening b -> b
| Fail_timelock -> 0x00
| Fail_decrypt -> 0x01
in [], new_s
let test =
let init_storage : bytes = 0x00 in
let addr, _, _ = Test.originate main init_storage 0tez in
let payload = 0x0101
in
let test_open (cc : chest_key * chest) (expected : bytes) : unit =
let x : parameter contract = Test.to_contract addr in
let _ = Test.transfer_to_contract_exn x cc 0tez in
let s = Test.get_storage addr in
assert (s = expected)
in
let test1 = (* chest key/payload and time matches -> OK *)
let chest, chest_key = Test.create_chest payload 10n
in test_open (chest_key, chest) payload
in
let test2 = (* chest key/payload do not match -> Fail_decrypt *)
let chest, _ = Test.create_chest payload 10n in
let _, chest_key = Test.create_chest 0x2020 10n
in test_open (chest_key,chest) 0x01
in
let test3 = (* chest time do not match -> Fail_timelock *)
let chest, _ = Test.create_chest payload 2n in
let chest_key = Test.create_chest_key chest 10n
in test_open (chest_key, chest) 0x00
in ()
let open_or_fail = ([ck, c, @time] : [chest_key, chest, nat]) : bytes => {
return (match ( Tezos.open_chest(ck,c,@time), {
Ok_opening: (b:bytes) => b,
Fail_decrypt: () => failwith("decrypt"),
Fail_timelock: () => failwith("timelock"),
}))
};
function open_or_fail (const ck : chest_key; const c : chest; const @time : nat) : bytes is
case Tezos.open_chest (ck, c, @time) of [
Ok_opening (b) -> b
| Fail_decrypt -> (failwith("decrypt"))
| Fail_timelock -> (failwith("timelock"))
]
On-chain views
Tezos documentation on views can be found here
On-chain views are named routines attached to your contract allowing
another contract to call them to get a "view" of your contract current
storage. It cannot modify your storage nor emit operations. These
routines can either simply return your contract storage or apply some
kind of processing to it: they take your current storage, a parameter
and returns the data of your choice. Note that parameter and return
types can be anything except big_map
; sapling_state
; operation
and ticket
. Views are named after their declaration name and can be
compiled in two ways:
-
by passing their names to the command line option
--views
(e.g.ligo compile contract --views v1,v2,v3
) -
by annotating their declarations in your code with
view
Important: the first way (
--views
) will override any annotated declarations
Given a very simple contract having a storage of type string
, here
are a few legit views:
type storage = string
let main (((),s): unit * storage) : operation list * storage = [] , s
(* view 'view1', simply returns the storage *)
[@view] let view1 ((),s: unit * storage) : storage = s
(* view 'v2', returns true if the storage has a given length *)
[@view] let v2 (expected_length,s: nat * storage) : bool = (String.length s = expected_length)
(* view 'v3' returns a constant int *)
[@view] let v3 ((),_ : unit * storage) : int = 42
type storage = string
let main = ([_ , s]: [unit , storage]) : [ list<operation> , storage] => [list([]), s];
/* view 'view1', simply returns the storage */
@view
let view1 = ([_ , s]: [unit , storage]) : storage => s;
/* view 'v2', returns true if the storage has a given length */
@view
let v2 = ([expected_length,s] : [nat , storage]) : bool => (String.length (s) == expected_length);
/* view 'view3' returns a constant int */
@view
let view3 = ([_ , _s]: [unit , storage]) : int => 42;
type storage is string
function main (const _ : unit ; const s : storage) : list (operation) * storage is (nil, s)
(* view 'view1', simply returns the storage *)
[@view] function view1 (const _ : unit; const s: storage) : storage is s
(* view 'v2', returns true if the storage has a given length *)
[@view] function v2 (const expected_length : nat; const s: storage) : bool is (String.length (s) = expected_length)
(* view 'v3' returns a constant int *)
[@view] function v3 (const _ : unit; const _ : storage) is 42
Note:
[@view]
attribute is only supported for top-level functions.The use of
[@view]
attribute anywhere other than top-level will be ignored.
A few primitives have a slightly different meaning when executed as part of a view:
Tezos.get_balance
represents the current amount of mutez held by the contract attached to the viewTezos.get_sender
represents the caller of the viewTezos.get_amount
is always 0 mutezTezos.get_self_address
represents the contract attached to the view
On the caller side, the primitive Tezos.call_view
will allow you to call another contract view and get its result by providing the view name; the contract address and the parameter of the view. If the address is nonexistent; the name does not match of of the contract
view or the parameter type do not match, Tezos.call_view
will return None
.
let view_call ((name,parameter,addr): string * int * address) : int option = Tezos.call_view "sto_plus_n" 1 addr
let view_call = ([name,parameter,addr]: [string , int , address]) : option<int> => Tezos.call_view ("sto_plus_n", 1, addr)
function view_call (const name : string; const parameter : int; const addr: address) : option (int) is Tezos.call_view ("sto_plus_n", 1, addr)
Global constant
The new primitive Tezos.constant
allows you to use a predefined
constant already registered on chain. It accepts a hash in the form
of a string and will require a type annotation.