Merge branch 'webide/id-example' into 'dev'
[LIGO-499] Add ID layer contract to web IDE examples See merge request ligolang/ligo!451
This commit is contained in:
commit
13eae4be18
159
src/test/contracts/id.ligo
Normal file
159
src/test/contracts/id.ligo
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
type id is int
|
||||||
|
|
||||||
|
type id_details is
|
||||||
|
record [
|
||||||
|
owner: address;
|
||||||
|
controller: address;
|
||||||
|
profile: bytes;
|
||||||
|
]
|
||||||
|
|
||||||
|
type buy is
|
||||||
|
record [
|
||||||
|
profile: bytes;
|
||||||
|
initial_controller: option(address);
|
||||||
|
]
|
||||||
|
|
||||||
|
type update_owner is
|
||||||
|
record [
|
||||||
|
id: id;
|
||||||
|
new_owner: address;
|
||||||
|
]
|
||||||
|
|
||||||
|
type update_details is
|
||||||
|
record [
|
||||||
|
id: id;
|
||||||
|
new_profile: option(bytes);
|
||||||
|
new_controller: option(address);
|
||||||
|
]
|
||||||
|
|
||||||
|
type action is
|
||||||
|
| Buy of buy
|
||||||
|
| Update_owner of update_owner
|
||||||
|
| Update_details of update_details
|
||||||
|
| Skip of unit
|
||||||
|
|
||||||
|
(* The prices kept in storage can be changed by bakers, though they should only be
|
||||||
|
adjusted down over time, not up. *)
|
||||||
|
type storage is
|
||||||
|
record [
|
||||||
|
identities: big_map (id, id_details);
|
||||||
|
next_id: int;
|
||||||
|
name_price: tez;
|
||||||
|
skip_price: tez;
|
||||||
|
]
|
||||||
|
|
||||||
|
(** Preliminary thoughts on ids:
|
||||||
|
|
||||||
|
I very much like the simplicity of http://gurno.com/adam/mne/.
|
||||||
|
5 three letter words means you have a 15 character identity, not actually more
|
||||||
|
annoying than an IP address and a lot more memorable than the raw digits. This
|
||||||
|
can be stored as a single integer which is then translated into the corresponding
|
||||||
|
series of 5 words.
|
||||||
|
|
||||||
|
I in general like the idea of having a 'skip' mechanism, but it does need to cost
|
||||||
|
something so people don't eat up the address space. 256 ^ 5 means you have a lot
|
||||||
|
of address space, but if people troll by skipping a lot that could be eaten up.
|
||||||
|
Should probably do some napkin calculations for how expensive skipping needs to
|
||||||
|
be to deter people from doing it just to chew up address space.
|
||||||
|
*)
|
||||||
|
|
||||||
|
function buy (const parameter : buy; const storage : storage) : list(operation) * storage is
|
||||||
|
begin
|
||||||
|
if amount = storage.name_price
|
||||||
|
then skip
|
||||||
|
else failwith("Incorrect amount paid.");
|
||||||
|
const profile : bytes = parameter.profile;
|
||||||
|
const initial_controller : option(address) = parameter.initial_controller;
|
||||||
|
var identities : big_map (id, id_details) := storage.identities;
|
||||||
|
const new_id : int = storage.next_id;
|
||||||
|
const controller : address =
|
||||||
|
case initial_controller of
|
||||||
|
Some(addr) -> addr
|
||||||
|
| None -> sender
|
||||||
|
end;
|
||||||
|
const new_id_details: id_details =
|
||||||
|
record [
|
||||||
|
owner = sender ;
|
||||||
|
controller = controller ;
|
||||||
|
profile = profile ;
|
||||||
|
];
|
||||||
|
identities[new_id] := new_id_details;
|
||||||
|
end with ((nil : list(operation)), storage with record [
|
||||||
|
identities = identities;
|
||||||
|
next_id = new_id + 1;
|
||||||
|
])
|
||||||
|
|
||||||
|
function update_owner (const parameter : update_owner; const storage : storage) :
|
||||||
|
list(operation) * storage is
|
||||||
|
begin
|
||||||
|
if (amount =/= 0mutez)
|
||||||
|
then
|
||||||
|
begin
|
||||||
|
failwith("Updating owner doesn't cost anything.");
|
||||||
|
end
|
||||||
|
else skip;
|
||||||
|
const id : int = parameter.id;
|
||||||
|
const new_owner : address = parameter.new_owner;
|
||||||
|
var identities : big_map (id, id_details) := storage.identities;
|
||||||
|
const id_details : id_details =
|
||||||
|
case identities[id] of
|
||||||
|
Some(id_details) -> id_details
|
||||||
|
| None -> (failwith("This ID does not exist."): id_details)
|
||||||
|
end;
|
||||||
|
if sender = id_details.owner
|
||||||
|
then skip;
|
||||||
|
else failwith("You are not the owner of this ID.");
|
||||||
|
id_details.owner := new_owner;
|
||||||
|
identities[id] := id_details;
|
||||||
|
end with ((nil: list(operation)), storage with record [ identities = identities; ])
|
||||||
|
|
||||||
|
function update_details (const parameter : update_details; const storage : storage ) :
|
||||||
|
list(operation) * storage is
|
||||||
|
begin
|
||||||
|
if (amount =/= 0mutez)
|
||||||
|
then failwith("Updating details doesn't cost anything.")
|
||||||
|
else skip;
|
||||||
|
const id : int = parameter.id;
|
||||||
|
const new_profile : option(bytes) = parameter.new_profile;
|
||||||
|
const new_controller : option(address) = parameter.new_controller;
|
||||||
|
const identities : big_map (id, id_details) = storage.identities;
|
||||||
|
const id_details: id_details =
|
||||||
|
case identities[id] of
|
||||||
|
Some(id_details) -> id_details
|
||||||
|
| None -> (failwith("This ID does not exist."): id_details)
|
||||||
|
end;
|
||||||
|
if (sender = id_details.controller) or (sender = id_details.owner)
|
||||||
|
then skip;
|
||||||
|
else failwith("You are not the owner or controller of this ID.");
|
||||||
|
const owner: address = id_details.owner;
|
||||||
|
const profile: bytes =
|
||||||
|
case new_profile of
|
||||||
|
None -> (* Default *) id_details.profile
|
||||||
|
| Some(new_profile) -> new_profile
|
||||||
|
end;
|
||||||
|
const controller: address =
|
||||||
|
case new_controller of
|
||||||
|
None -> (* Default *) id_details.controller
|
||||||
|
| Some(new_controller) -> new_controller
|
||||||
|
end;
|
||||||
|
id_details.owner := owner;
|
||||||
|
id_details.controller := controller;
|
||||||
|
id_details.profile := profile;
|
||||||
|
identities[id] := id_details;
|
||||||
|
end with ((nil: list(operation)), storage with record [ identities = identities; ])
|
||||||
|
|
||||||
|
(* Let someone skip the next identity so nobody has to take one that's undesirable *)
|
||||||
|
function skip_ (const p: unit; const storage: storage) : list(operation) * storage is
|
||||||
|
begin
|
||||||
|
if amount = storage.skip_price
|
||||||
|
then skip
|
||||||
|
else failwith("Incorrect amount paid.");
|
||||||
|
end with ((nil: list(operation)), storage with record [ next_id = storage.next_id + 1; ])
|
||||||
|
|
||||||
|
function main (const action : action; const storage : storage) : list(operation) * storage is
|
||||||
|
case action of
|
||||||
|
| Buy(b) -> buy (b, storage)
|
||||||
|
| Update_owner(uo) -> update_owner (uo, storage)
|
||||||
|
| Update_details(ud) -> update_details (ud, storage)
|
||||||
|
| Skip(s) -> skip_ (unit, storage)
|
||||||
|
end;
|
@ -6,9 +6,21 @@ type id_details = {
|
|||||||
profile: bytes
|
profile: bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
type buy = bytes * address option
|
type buy = {
|
||||||
type update_owner = id * address
|
profile: bytes;
|
||||||
type update_details = id * bytes option * address option
|
initial_controller: address option;
|
||||||
|
}
|
||||||
|
|
||||||
|
type update_owner = {
|
||||||
|
id: id;
|
||||||
|
new_owner: address;
|
||||||
|
}
|
||||||
|
|
||||||
|
type update_details = {
|
||||||
|
id: id;
|
||||||
|
new_profile: bytes option;
|
||||||
|
new_controller: address option;
|
||||||
|
}
|
||||||
|
|
||||||
type action =
|
type action =
|
||||||
| Buy of buy
|
| Buy of buy
|
||||||
@ -19,7 +31,14 @@ type action =
|
|||||||
(* The prices kept in storage can be changed by bakers, though they
|
(* The prices kept in storage can be changed by bakers, though they
|
||||||
should only be adjusted down over time, not up. *)
|
should only be adjusted down over time, not up. *)
|
||||||
|
|
||||||
type storage = (id, id_details) big_map * int * (tez * tez)
|
(* The prices kept in storage can be changed by bakers, though they should only be
|
||||||
|
adjusted down over time, not up. *)
|
||||||
|
type storage = {
|
||||||
|
identities: (id, id_details) big_map;
|
||||||
|
next_id: int;
|
||||||
|
name_price: tez;
|
||||||
|
skip_price: tez;
|
||||||
|
}
|
||||||
|
|
||||||
type return = operation list * storage
|
type return = operation list * storage
|
||||||
|
|
||||||
@ -38,12 +57,16 @@ a lot that could be eaten up. Should probably do some napkin
|
|||||||
calculations for how expensive skipping needs to be to deter people
|
calculations for how expensive skipping needs to be to deter people
|
||||||
from doing it just to chew up address space. *)
|
from doing it just to chew up address space. *)
|
||||||
|
|
||||||
let buy (parameter, storage: (bytes * address option) * storage) =
|
let buy (parameter, storage: buy * storage) =
|
||||||
let void: unit =
|
let void: unit =
|
||||||
if Tezos.amount <> storage.2.0
|
if amount = storage.name_price
|
||||||
then (failwith "Incorrect amount paid.": unit) in
|
then ()
|
||||||
let profile, initial_controller = parameter in
|
else (failwith "Incorrect amount paid.": unit)
|
||||||
let identities, new_id, prices = storage in
|
in
|
||||||
|
let profile = parameter.profile in
|
||||||
|
let initial_controller = parameter.initial_controller in
|
||||||
|
let identities = storage.identities in
|
||||||
|
let new_id = storage.next_id in
|
||||||
let controller: address =
|
let controller: address =
|
||||||
match initial_controller with
|
match initial_controller with
|
||||||
| Some addr -> addr
|
| Some addr -> addr
|
||||||
@ -54,74 +77,84 @@ let buy (parameter, storage: (bytes * address option) * storage) =
|
|||||||
profile = profile} in
|
profile = profile} in
|
||||||
let updated_identities : (id, id_details) big_map =
|
let updated_identities : (id, id_details) big_map =
|
||||||
Big_map.update new_id (Some new_id_details) identities
|
Big_map.update new_id (Some new_id_details) identities
|
||||||
in ([]: operation list), (updated_identities, new_id + 1, prices)
|
in
|
||||||
|
([]: operation list), {storage with identities = updated_identities;
|
||||||
|
next_id = new_id + 1;
|
||||||
|
}
|
||||||
|
|
||||||
let update_owner (parameter, storage : (id * address) * storage) =
|
let update_owner (parameter, storage: update_owner * storage) =
|
||||||
if amount <> 0tez
|
if (amount <> 0mutez)
|
||||||
then (failwith "Updating owner doesn't cost anything.": return)
|
then (failwith "Updating owner doesn't cost anything.": (operation list) * storage)
|
||||||
else
|
else
|
||||||
let id, new_owner = parameter in
|
let id = parameter.id in
|
||||||
let identities, last_id, prices = storage in
|
let new_owner = parameter.new_owner in
|
||||||
|
let identities = storage.identities in
|
||||||
let current_id_details: id_details =
|
let current_id_details: id_details =
|
||||||
match Big_map.find_opt id identities with
|
match Big_map.find_opt id identities with
|
||||||
| Some id_details -> id_details
|
| Some id_details -> id_details
|
||||||
| None -> (failwith "This ID does not exist." : id_details) in
|
| None -> (failwith "This ID does not exist.": id_details)
|
||||||
let is_allowed : bool =
|
in
|
||||||
if Tezos.sender = current_id_details.owner
|
let u : unit =
|
||||||
then true
|
if sender = current_id_details.owner
|
||||||
else (failwith "You are not the owner of this ID." : bool) in
|
then ()
|
||||||
|
else failwith "You are not the owner of this ID."
|
||||||
|
in
|
||||||
let updated_id_details: id_details = {
|
let updated_id_details: id_details = {
|
||||||
owner = new_owner;
|
owner = new_owner;
|
||||||
controller = current_id_details.controller;
|
controller = current_id_details.controller;
|
||||||
profile = current_id_details.profile} in
|
profile = current_id_details.profile;
|
||||||
let updated_identities =
|
}
|
||||||
Big_map.update id (Some updated_id_details) identities
|
in
|
||||||
in ([]: operation list), (updated_identities, last_id, prices)
|
let updated_identities = Big_map.update id (Some updated_id_details) identities in
|
||||||
|
([]: operation list), {storage with identities = updated_identities}
|
||||||
|
|
||||||
let update_details (parameter, storage: (id * bytes option * address option) * storage) =
|
let update_details (parameter, storage: update_details * storage) =
|
||||||
if Tezos.amount <> 0tez
|
if (amount <> 0mutez)
|
||||||
then
|
then (failwith "Updating details doesn't cost anything.": (operation list) * storage)
|
||||||
(failwith "Updating details doesn't cost anything." : return)
|
|
||||||
else
|
else
|
||||||
let id, new_profile, new_controller = parameter in
|
let id = parameter.id in
|
||||||
let identities, last_id, prices = storage in
|
let new_profile = parameter.new_profile in
|
||||||
|
let new_controller = parameter.new_controller in
|
||||||
|
let identities = storage.identities in
|
||||||
let current_id_details: id_details =
|
let current_id_details: id_details =
|
||||||
match Big_map.find_opt id identities with
|
match Big_map.find_opt id identities with
|
||||||
| Some id_details -> id_details
|
| Some id_details -> id_details
|
||||||
| None -> (failwith "This ID does not exist.": id_details) in
|
| None -> (failwith "This ID does not exist.": id_details)
|
||||||
let is_allowed : bool =
|
in
|
||||||
if Tezos.sender = current_id_details.controller
|
let u : unit =
|
||||||
|| Tezos.sender = current_id_details.owner
|
if (sender = current_id_details.controller) || (sender = current_id_details.owner)
|
||||||
then true
|
then ()
|
||||||
else
|
else failwith ("You are not the owner or controller of this ID.")
|
||||||
(failwith ("You are not the owner or controller of this ID.")
|
in
|
||||||
: bool) in
|
|
||||||
let owner: address = current_id_details.owner in
|
let owner: address = current_id_details.owner in
|
||||||
let profile: bytes =
|
let profile: bytes =
|
||||||
match new_profile with
|
match new_profile with
|
||||||
| None -> (* Default *) current_id_details.profile
|
| None -> (* Default *) current_id_details.profile
|
||||||
| Some new_profile -> new_profile in
|
| Some new_profile -> new_profile
|
||||||
|
in
|
||||||
let controller: address =
|
let controller: address =
|
||||||
match new_controller with
|
match new_controller with
|
||||||
| None -> (* Default *) current_id_details.controller
|
| None -> (* Default *) current_id_details.controller
|
||||||
| Some new_controller -> new_controller in
|
| Some new_controller -> new_controller
|
||||||
|
in
|
||||||
let updated_id_details: id_details = {
|
let updated_id_details: id_details = {
|
||||||
owner = owner;
|
owner = owner;
|
||||||
controller = controller;
|
controller = controller;
|
||||||
profile = profile} in
|
profile = profile;
|
||||||
|
}
|
||||||
|
in
|
||||||
let updated_identities: (id, id_details) big_map =
|
let updated_identities: (id, id_details) big_map =
|
||||||
Big_map.update id (Some updated_id_details) identities
|
Big_map.update id (Some updated_id_details) identities in
|
||||||
in ([]: operation list), (updated_identities, last_id, prices)
|
([]: operation list), {storage with identities = updated_identities}
|
||||||
|
|
||||||
(* Let someone skip the next identity so nobody has to take one that's
|
|
||||||
undesirable *)
|
|
||||||
|
|
||||||
|
(* Let someone skip the next identity so nobody has to take one that's undesirable *)
|
||||||
let skip (p,storage: unit * storage) =
|
let skip (p,storage: unit * storage) =
|
||||||
let void: unit =
|
let void: unit =
|
||||||
if Tezos.amount <> storage.2.1
|
if amount = storage.skip_price
|
||||||
then (failwith "Incorrect amount paid." : unit) in
|
then ()
|
||||||
let identities, last_id, prices = storage in
|
else failwith "Incorrect amount paid."
|
||||||
([]: operation list), (identities, last_id + 1, prices)
|
in
|
||||||
|
([]: operation list), {storage with next_id = storage.next_id + 1}
|
||||||
|
|
||||||
let main (action, storage : action * storage) : return =
|
let main (action, storage : action * storage) : return =
|
||||||
match action with
|
match action with
|
||||||
|
167
src/test/contracts/id.religo
Normal file
167
src/test/contracts/id.religo
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
type id = int
|
||||||
|
|
||||||
|
type id_details = {
|
||||||
|
owner: address,
|
||||||
|
controller: address,
|
||||||
|
profile: bytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
type buy = {
|
||||||
|
profile: bytes,
|
||||||
|
initial_controller: option(address),
|
||||||
|
}
|
||||||
|
|
||||||
|
type update_owner = {
|
||||||
|
id: id,
|
||||||
|
new_owner: address,
|
||||||
|
}
|
||||||
|
|
||||||
|
type update_details = {
|
||||||
|
id: id,
|
||||||
|
new_profile: option(bytes),
|
||||||
|
new_controller: option(address),
|
||||||
|
}
|
||||||
|
|
||||||
|
type action =
|
||||||
|
| Buy(buy)
|
||||||
|
| Update_owner(update_owner)
|
||||||
|
| Update_details(update_details)
|
||||||
|
| Skip(unit)
|
||||||
|
|
||||||
|
/* The prices kept in storage can be changed by bakers, though they should only be
|
||||||
|
adjusted down over time, not up. */
|
||||||
|
type storage = {
|
||||||
|
identities: big_map (id, id_details),
|
||||||
|
next_id: int,
|
||||||
|
name_price: tez,
|
||||||
|
skip_price: tez,
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Preliminary thoughts on ids:
|
||||||
|
|
||||||
|
I very much like the simplicity of http://gurno.com/adam/mne/.
|
||||||
|
5 three letter words means you have a 15 character identity, not actually more
|
||||||
|
annoying than an IP address and a lot more memorable than the raw digits. This
|
||||||
|
can be stored as a single integer which is then translated into the corresponding
|
||||||
|
series of 5 words.
|
||||||
|
|
||||||
|
I in general like the idea of having a 'skip' mechanism, but it does need to cost
|
||||||
|
something so people don't eat up the address space. 256 ^ 5 means you have a lot
|
||||||
|
of address space, but if people troll by skipping a lot that could be eaten up.
|
||||||
|
Should probably do some napkin calculations for how expensive skipping needs to
|
||||||
|
be to deter people from doing it just to chew up address space.
|
||||||
|
*/
|
||||||
|
|
||||||
|
let buy = ((parameter, storage): (buy, storage)) : (list(operation), storage) => {
|
||||||
|
let void: unit =
|
||||||
|
if (amount == storage.name_price) { (); }
|
||||||
|
else { failwith("Incorrect amount paid."); };
|
||||||
|
let profile = parameter.profile;
|
||||||
|
let initial_controller = parameter.initial_controller;
|
||||||
|
let identities = storage.identities;
|
||||||
|
let new_id = storage.next_id;
|
||||||
|
let controller: address =
|
||||||
|
switch (initial_controller) {
|
||||||
|
| Some(addr) => addr
|
||||||
|
| None => sender
|
||||||
|
};
|
||||||
|
let new_id_details: id_details = {
|
||||||
|
owner : sender,
|
||||||
|
controller : controller,
|
||||||
|
profile : profile,
|
||||||
|
};
|
||||||
|
let updated_identities: big_map (id, id_details) =
|
||||||
|
Big_map.update(new_id, Some(new_id_details), identities);
|
||||||
|
(([]: list(operation)), { ...storage,
|
||||||
|
identities : updated_identities,
|
||||||
|
next_id : new_id + 1,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let update_owner = ((parameter, storage): (update_owner, storage)) : (list(operation), storage) => {
|
||||||
|
let void: unit =
|
||||||
|
if (amount != 0mutez) {
|
||||||
|
failwith("Updating owner doesn't cost anything.");
|
||||||
|
}
|
||||||
|
else { (); };
|
||||||
|
let id : int = parameter.id;
|
||||||
|
let new_owner = parameter.new_owner;
|
||||||
|
let identities = storage.identities;
|
||||||
|
let current_id_details: id_details =
|
||||||
|
switch (Big_map.find_opt(id, identities)) {
|
||||||
|
| Some(id_details) => id_details
|
||||||
|
| None => (failwith("This ID does not exist."): id_details)
|
||||||
|
};
|
||||||
|
let u: unit =
|
||||||
|
if (sender == current_id_details.owner) { (); }
|
||||||
|
else { failwith("You are not the owner of this ID."); };
|
||||||
|
let updated_id_details: id_details = {
|
||||||
|
owner : new_owner,
|
||||||
|
controller : current_id_details.controller,
|
||||||
|
profile : current_id_details.profile,
|
||||||
|
};
|
||||||
|
let updated_identities = Big_map.update(id, (Some updated_id_details), identities);
|
||||||
|
(([]: list(operation)), { ...storage, identities : updated_identities });
|
||||||
|
};
|
||||||
|
|
||||||
|
let update_details = ((parameter, storage): (update_details, storage)) :
|
||||||
|
(list(operation), storage) => {
|
||||||
|
let void : unit =
|
||||||
|
if (amount != 0mutez) {
|
||||||
|
failwith("Updating details doesn't cost anything.");
|
||||||
|
}
|
||||||
|
else { (); };
|
||||||
|
let id = parameter.id;
|
||||||
|
let new_profile = parameter.new_profile;
|
||||||
|
let new_controller = parameter.new_controller;
|
||||||
|
let identities = storage.identities;
|
||||||
|
let current_id_details: id_details =
|
||||||
|
switch (Big_map.find_opt(id, identities)) {
|
||||||
|
| Some(id_details) => id_details
|
||||||
|
| None => (failwith("This ID does not exist."): id_details)
|
||||||
|
};
|
||||||
|
let u: unit =
|
||||||
|
if ((sender != current_id_details.controller) &&
|
||||||
|
(sender != current_id_details.owner)) {
|
||||||
|
failwith ("You are not the owner or controller of this ID.")
|
||||||
|
}
|
||||||
|
else { (); };
|
||||||
|
let owner: address = current_id_details.owner;
|
||||||
|
let profile: bytes =
|
||||||
|
switch (new_profile) {
|
||||||
|
| None => /* Default */ current_id_details.profile
|
||||||
|
| Some(new_profile) => new_profile
|
||||||
|
};
|
||||||
|
let controller: address =
|
||||||
|
switch (new_controller) {
|
||||||
|
| None => /* Default */ current_id_details.controller
|
||||||
|
| Some new_controller => new_controller
|
||||||
|
};
|
||||||
|
let updated_id_details: id_details = {
|
||||||
|
owner : owner,
|
||||||
|
controller : controller,
|
||||||
|
profile : profile,
|
||||||
|
};
|
||||||
|
let updated_identities: big_map (id, id_details) =
|
||||||
|
Big_map.update(id, (Some updated_id_details), identities);
|
||||||
|
(([]: list(operation)), { ...storage, identities : updated_identities });
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Let someone skip the next identity so nobody has to take one that's undesirable */
|
||||||
|
let skip = ((p,storage): (unit, storage)) => {
|
||||||
|
let void : unit =
|
||||||
|
if (amount != storage.skip_price) {
|
||||||
|
failwith("Incorrect amount paid.");
|
||||||
|
}
|
||||||
|
else { (); };
|
||||||
|
(([]: list(operation)), { ...storage, next_id : storage.next_id + 1 });
|
||||||
|
};
|
||||||
|
|
||||||
|
let main = ((action, storage): (action, storage)) : (list(operation), storage) => {
|
||||||
|
switch (action) {
|
||||||
|
| Buy(b) => buy((b, storage))
|
||||||
|
| Update_owner(uo) => update_owner((uo, storage))
|
||||||
|
| Update_details ud => update_details((ud, storage))
|
||||||
|
| Skip s => skip(((), storage))
|
||||||
|
};
|
||||||
|
};
|
243
src/test/examples/cameligo/id.mligo
Normal file
243
src/test/examples/cameligo/id.mligo
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
(*_*
|
||||||
|
name: ID Contract (CameLIGO)
|
||||||
|
language: cameligo
|
||||||
|
compile:
|
||||||
|
entrypoint: main
|
||||||
|
dryRun:
|
||||||
|
entrypoint: main
|
||||||
|
parameters: |
|
||||||
|
Buy (
|
||||||
|
{
|
||||||
|
profile=0x0501000000026869;
|
||||||
|
initial_controller=Some(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
storage: |
|
||||||
|
{
|
||||||
|
identities=Big_map.literal[
|
||||||
|
(1,
|
||||||
|
{owner=("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address);
|
||||||
|
controller=("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address);
|
||||||
|
profile=0x0501000000026869}
|
||||||
|
);
|
||||||
|
];
|
||||||
|
next_id=2;
|
||||||
|
name_price=0tez;
|
||||||
|
skip_price=333mutez
|
||||||
|
}
|
||||||
|
deploy:
|
||||||
|
entrypoint: main
|
||||||
|
storage: |
|
||||||
|
{
|
||||||
|
identities=Big_map.literal[
|
||||||
|
(1,
|
||||||
|
{owner=("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address);
|
||||||
|
controller=("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address);
|
||||||
|
profile=0x0501000000026869}
|
||||||
|
);
|
||||||
|
];
|
||||||
|
next_id=2;
|
||||||
|
name_price=10tez;
|
||||||
|
skip_price=333mutez
|
||||||
|
}
|
||||||
|
evaluateValue:
|
||||||
|
entrypoint: ""
|
||||||
|
evaluateFunction:
|
||||||
|
entrypoint: buy
|
||||||
|
parameters: |
|
||||||
|
{
|
||||||
|
profile=0x0501000000026869;
|
||||||
|
initial_controller=Some(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address))
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
identities=Big_map.literal[
|
||||||
|
(1,
|
||||||
|
{owner=("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address);
|
||||||
|
controller=("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address);
|
||||||
|
profile=0x0501000000026869}
|
||||||
|
);
|
||||||
|
];
|
||||||
|
next_id=2;
|
||||||
|
name_price=0tez;
|
||||||
|
skip_price=333mutez
|
||||||
|
}
|
||||||
|
*_*)
|
||||||
|
|
||||||
|
type id = int
|
||||||
|
|
||||||
|
type id_details = {
|
||||||
|
owner: address;
|
||||||
|
controller: address;
|
||||||
|
profile: bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
type buy = {
|
||||||
|
profile: bytes;
|
||||||
|
initial_controller: address option;
|
||||||
|
}
|
||||||
|
|
||||||
|
type update_owner = {
|
||||||
|
id: id;
|
||||||
|
new_owner: address;
|
||||||
|
}
|
||||||
|
|
||||||
|
type update_details = {
|
||||||
|
id: id;
|
||||||
|
new_profile: bytes option;
|
||||||
|
new_controller: address option;
|
||||||
|
}
|
||||||
|
|
||||||
|
type action =
|
||||||
|
| Buy of buy
|
||||||
|
| Update_owner of update_owner
|
||||||
|
| Update_details of update_details
|
||||||
|
| Skip of unit
|
||||||
|
|
||||||
|
(* The prices kept in storage can be changed by bakers, though they should only be
|
||||||
|
adjusted down over time, not up. *)
|
||||||
|
type storage = {
|
||||||
|
identities: (id, id_details) big_map;
|
||||||
|
next_id: int;
|
||||||
|
name_price: tez;
|
||||||
|
skip_price: tez;
|
||||||
|
}
|
||||||
|
|
||||||
|
(** Preliminary thoughts on ids:
|
||||||
|
|
||||||
|
I very much like the simplicity of http://gurno.com/adam/mne/
|
||||||
|
|
||||||
|
Five three letter words means you have a 15 character identity, not actually more
|
||||||
|
annoying than an IP address and a lot more memorable than the raw digits. This
|
||||||
|
can be stored as a single integer which is then translated into the corresponding
|
||||||
|
series of 5 words.
|
||||||
|
|
||||||
|
I, in general like the idea of having a 'skip' mechanism, but it does need to cost
|
||||||
|
something so people don't eat up the address space. 256 ^ 5 means you have a lot
|
||||||
|
of address space, but if people troll by skipping a lot that could be eaten up.
|
||||||
|
Should probably do some napkin calculations for how expensive skipping needs to
|
||||||
|
be to deter people from doing it just to chew up address space.
|
||||||
|
*)
|
||||||
|
|
||||||
|
let buy (parameter, storage: buy * storage) =
|
||||||
|
let void: unit =
|
||||||
|
if amount = storage.name_price
|
||||||
|
then ()
|
||||||
|
else (failwith "Incorrect amount paid.": unit)
|
||||||
|
in
|
||||||
|
let profile = parameter.profile in
|
||||||
|
let initial_controller = parameter.initial_controller in
|
||||||
|
let identities = storage.identities in
|
||||||
|
let new_id = storage.next_id in
|
||||||
|
let controller: address =
|
||||||
|
match initial_controller with
|
||||||
|
| Some addr -> addr
|
||||||
|
| None -> sender
|
||||||
|
in
|
||||||
|
let new_id_details: id_details = {
|
||||||
|
owner = sender ;
|
||||||
|
controller = controller ;
|
||||||
|
profile = profile ;
|
||||||
|
}
|
||||||
|
in
|
||||||
|
let updated_identities: (id, id_details) big_map =
|
||||||
|
Big_map.update new_id (Some new_id_details) identities
|
||||||
|
in
|
||||||
|
([]: operation list), {identities = updated_identities;
|
||||||
|
next_id = new_id + 1;
|
||||||
|
name_price = storage.name_price;
|
||||||
|
skip_price = storage.skip_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
let update_owner (parameter, storage: update_owner * storage) =
|
||||||
|
if (amount <> 0mutez)
|
||||||
|
then (failwith "Updating owner doesn't cost anything.": (operation list) * storage)
|
||||||
|
else
|
||||||
|
let id = parameter.id in
|
||||||
|
let new_owner = parameter.new_owner in
|
||||||
|
let identities = storage.identities in
|
||||||
|
let current_id_details: id_details =
|
||||||
|
match Big_map.find_opt id identities with
|
||||||
|
| Some id_details -> id_details
|
||||||
|
| None -> (failwith "This ID does not exist.": id_details)
|
||||||
|
in
|
||||||
|
let is_allowed: bool =
|
||||||
|
if sender = current_id_details.owner
|
||||||
|
then true
|
||||||
|
else (failwith "You are not the owner of this ID.": bool)
|
||||||
|
in
|
||||||
|
let updated_id_details: id_details = {
|
||||||
|
owner = new_owner;
|
||||||
|
controller = current_id_details.controller;
|
||||||
|
profile = current_id_details.profile;
|
||||||
|
}
|
||||||
|
in
|
||||||
|
let updated_identities = Big_map.update id (Some updated_id_details) identities in
|
||||||
|
([]: operation list), {identities = updated_identities;
|
||||||
|
next_id = storage.next_id;
|
||||||
|
name_price = storage.name_price;
|
||||||
|
skip_price = storage.skip_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
let update_details (parameter, storage: update_details * storage) =
|
||||||
|
if (amount <> 0mutez)
|
||||||
|
then (failwith "Updating details doesn't cost anything.": (operation list) * storage)
|
||||||
|
else
|
||||||
|
let id = parameter.id in
|
||||||
|
let new_profile = parameter.new_profile in
|
||||||
|
let new_controller = parameter.new_controller in
|
||||||
|
let identities = storage.identities in
|
||||||
|
let current_id_details: id_details =
|
||||||
|
match Big_map.find_opt id identities with
|
||||||
|
| Some id_details -> id_details
|
||||||
|
| None -> (failwith "This ID does not exist.": id_details)
|
||||||
|
in
|
||||||
|
let is_allowed: bool =
|
||||||
|
if (sender = current_id_details.controller) || (sender = current_id_details.owner)
|
||||||
|
then true
|
||||||
|
else (failwith ("You are not the owner or controller of this ID."): bool)
|
||||||
|
in
|
||||||
|
let owner: address = current_id_details.owner in
|
||||||
|
let profile: bytes =
|
||||||
|
match new_profile with
|
||||||
|
| None -> (* Default *) current_id_details.profile
|
||||||
|
| Some new_profile -> new_profile
|
||||||
|
in
|
||||||
|
let controller: address =
|
||||||
|
match new_controller with
|
||||||
|
| None -> (* Default *) current_id_details.controller
|
||||||
|
| Some new_controller -> new_controller
|
||||||
|
in
|
||||||
|
let updated_id_details: id_details = {
|
||||||
|
owner = owner;
|
||||||
|
controller = controller;
|
||||||
|
profile = profile;
|
||||||
|
}
|
||||||
|
in
|
||||||
|
let updated_identities: (id, id_details) big_map =
|
||||||
|
Big_map.update id (Some updated_id_details) identities in
|
||||||
|
([]: operation list), {identities = updated_identities;
|
||||||
|
next_id = storage.next_id;
|
||||||
|
name_price = storage.name_price;
|
||||||
|
skip_price = storage.skip_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
(* Let someone skip the next identity so nobody has to take one that's undesirable *)
|
||||||
|
let skip (p,storage: unit * storage) =
|
||||||
|
let void: unit =
|
||||||
|
if amount = storage.skip_price
|
||||||
|
then ()
|
||||||
|
else (failwith "Incorrect amount paid.": unit)
|
||||||
|
in
|
||||||
|
([]: operation list), {identities = storage.identities;
|
||||||
|
next_id = storage.next_id + 1;
|
||||||
|
name_price = storage.name_price;
|
||||||
|
skip_price = storage.skip_price;
|
||||||
|
}
|
||||||
|
|
||||||
|
let main (action, storage: action * storage) : operation list * storage =
|
||||||
|
match action with
|
||||||
|
| Buy b -> buy (b, storage)
|
||||||
|
| Update_owner uo -> update_owner (uo, storage)
|
||||||
|
| Update_details ud -> update_details (ud, storage)
|
||||||
|
| Skip s -> skip ((), storage)
|
242
src/test/examples/pascaligo/id.ligo
Normal file
242
src/test/examples/pascaligo/id.ligo
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
(*_*
|
||||||
|
name: ID Contract (PascaLIGO)
|
||||||
|
language: pascaligo
|
||||||
|
compile:
|
||||||
|
entrypoint: main
|
||||||
|
dryRun:
|
||||||
|
entrypoint: main
|
||||||
|
parameters: |
|
||||||
|
Buy (
|
||||||
|
record [
|
||||||
|
profile=0x0501000000026869;
|
||||||
|
initial_controller=Some(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address))
|
||||||
|
]
|
||||||
|
)
|
||||||
|
storage: |
|
||||||
|
record [
|
||||||
|
identities=big_map[
|
||||||
|
1->record
|
||||||
|
[owner=("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address);
|
||||||
|
controller=("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address);
|
||||||
|
profile=0x0501000000026869]
|
||||||
|
];
|
||||||
|
next_id=2;
|
||||||
|
name_price=0tez;
|
||||||
|
skip_price=50mutez;
|
||||||
|
]
|
||||||
|
deploy:
|
||||||
|
entrypoint: main
|
||||||
|
storage: |
|
||||||
|
record [
|
||||||
|
identities=big_map[
|
||||||
|
1->record
|
||||||
|
[owner=("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address);
|
||||||
|
controller=("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address);
|
||||||
|
profile=0x0501000000026869]
|
||||||
|
];
|
||||||
|
next_id=2;
|
||||||
|
name_price=0tez;
|
||||||
|
skip_price=50mutez;
|
||||||
|
]
|
||||||
|
evaluateValue:
|
||||||
|
entrypoint: ""
|
||||||
|
evaluateFunction:
|
||||||
|
entrypoint: buy
|
||||||
|
parameters: |
|
||||||
|
(
|
||||||
|
record [
|
||||||
|
profile=0x0501000000026869;
|
||||||
|
initial_controller=Some(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address))
|
||||||
|
],
|
||||||
|
|
||||||
|
record [ identities=big_map[
|
||||||
|
1->record
|
||||||
|
[owner=("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address);
|
||||||
|
controller=("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address);
|
||||||
|
profile=0x0501000000026869]
|
||||||
|
];
|
||||||
|
next_id=2;
|
||||||
|
name_price=0tez;
|
||||||
|
skip_price=333mutez;
|
||||||
|
]
|
||||||
|
)
|
||||||
|
*_*)
|
||||||
|
|
||||||
|
type id is int
|
||||||
|
|
||||||
|
type id_details is
|
||||||
|
record [
|
||||||
|
owner: address;
|
||||||
|
controller: address;
|
||||||
|
profile: bytes;
|
||||||
|
]
|
||||||
|
|
||||||
|
type buy is
|
||||||
|
record [
|
||||||
|
profile: bytes;
|
||||||
|
initial_controller: option(address);
|
||||||
|
]
|
||||||
|
|
||||||
|
type update_owner is
|
||||||
|
record [
|
||||||
|
id: id;
|
||||||
|
new_owner: address;
|
||||||
|
]
|
||||||
|
|
||||||
|
type update_details is
|
||||||
|
record [
|
||||||
|
id: id;
|
||||||
|
new_profile: option(bytes);
|
||||||
|
new_controller: option(address);
|
||||||
|
]
|
||||||
|
|
||||||
|
type action is
|
||||||
|
| Buy of buy
|
||||||
|
| Update_owner of update_owner
|
||||||
|
| Update_details of update_details
|
||||||
|
| Skip of unit
|
||||||
|
|
||||||
|
(* The prices kept in storage can be changed by bakers, though they should only be
|
||||||
|
adjusted down over time, not up. *)
|
||||||
|
type storage is
|
||||||
|
record [
|
||||||
|
identities: big_map (id, id_details);
|
||||||
|
next_id: int;
|
||||||
|
name_price: tez;
|
||||||
|
skip_price: tez;
|
||||||
|
]
|
||||||
|
|
||||||
|
(** Preliminary thoughts on ids:
|
||||||
|
|
||||||
|
I very much like the simplicity of http://gurno.com/adam/mne/.
|
||||||
|
5 three letter words means you have a 15 character identity, not actually more
|
||||||
|
annoying than an IP address and a lot more memorable than the raw digits. This
|
||||||
|
can be stored as a single integer which is then translated into the corresponding
|
||||||
|
series of 5 words.
|
||||||
|
|
||||||
|
I in general like the idea of having a 'skip' mechanism, but it does need to cost
|
||||||
|
something so people don't eat up the address space. 256 ^ 5 means you have a lot
|
||||||
|
of address space, but if people troll by skipping a lot that could be eaten up.
|
||||||
|
Should probably do some napkin calculations for how expensive skipping needs to
|
||||||
|
be to deter people from doing it just to chew up address space.
|
||||||
|
*)
|
||||||
|
|
||||||
|
function buy (const parameter : buy; const storage : storage) : list(operation) * storage is
|
||||||
|
begin
|
||||||
|
if amount = storage.name_price
|
||||||
|
then skip
|
||||||
|
else failwith("Incorrect amount paid.");
|
||||||
|
const profile : bytes = parameter.profile;
|
||||||
|
const initial_controller : option(address) = parameter.initial_controller;
|
||||||
|
var identities : big_map (id, id_details) := storage.identities;
|
||||||
|
const new_id : int = storage.next_id;
|
||||||
|
const controller : address =
|
||||||
|
case initial_controller of
|
||||||
|
Some(addr) -> addr
|
||||||
|
| None -> sender
|
||||||
|
end;
|
||||||
|
const new_id_details: id_details =
|
||||||
|
record [
|
||||||
|
owner = sender ;
|
||||||
|
controller = controller ;
|
||||||
|
profile = profile ;
|
||||||
|
];
|
||||||
|
identities[new_id] := new_id_details;
|
||||||
|
end with ((nil : list(operation)), record [
|
||||||
|
identities = identities;
|
||||||
|
next_id = new_id + 1;
|
||||||
|
name_price = storage.name_price;
|
||||||
|
skip_price = storage.skip_price;
|
||||||
|
])
|
||||||
|
|
||||||
|
function update_owner (const parameter : update_owner; const storage : storage) :
|
||||||
|
list(operation) * storage is
|
||||||
|
begin
|
||||||
|
if (amount =/= 0mutez)
|
||||||
|
then
|
||||||
|
begin
|
||||||
|
failwith("Updating owner doesn't cost anything.");
|
||||||
|
end
|
||||||
|
else skip;
|
||||||
|
const id : int = parameter.id;
|
||||||
|
const new_owner : address = parameter.new_owner;
|
||||||
|
var identities : big_map (id, id_details) := storage.identities;
|
||||||
|
const id_details : id_details =
|
||||||
|
case identities[id] of
|
||||||
|
Some(id_details) -> id_details
|
||||||
|
| None -> (failwith("This ID does not exist."): id_details)
|
||||||
|
end;
|
||||||
|
var is_allowed : bool := False;
|
||||||
|
if sender = id_details.owner
|
||||||
|
then is_allowed := True
|
||||||
|
else failwith("You are not the owner of this ID.");
|
||||||
|
id_details.owner := new_owner;
|
||||||
|
identities[id] := id_details;
|
||||||
|
end with ((nil: list(operation)), record [
|
||||||
|
identities = identities;
|
||||||
|
next_id = storage.next_id;
|
||||||
|
name_price = storage.name_price;
|
||||||
|
skip_price = storage.skip_price;
|
||||||
|
])
|
||||||
|
|
||||||
|
function update_details (const parameter : update_details; const storage : storage ) :
|
||||||
|
list(operation) * storage is
|
||||||
|
begin
|
||||||
|
if (amount =/= 0mutez)
|
||||||
|
then failwith("Updating details doesn't cost anything.")
|
||||||
|
else skip;
|
||||||
|
const id : int = parameter.id;
|
||||||
|
const new_profile : option(bytes) = parameter.new_profile;
|
||||||
|
const new_controller : option(address) = parameter.new_controller;
|
||||||
|
const identities : big_map (id, id_details) = storage.identities;
|
||||||
|
const id_details: id_details =
|
||||||
|
case identities[id] of
|
||||||
|
Some(id_details) -> id_details
|
||||||
|
| None -> (failwith("This ID does not exist."): id_details)
|
||||||
|
end;
|
||||||
|
var is_allowed : bool := False;
|
||||||
|
if (sender = id_details.controller) or (sender = id_details.owner)
|
||||||
|
then is_allowed := True
|
||||||
|
else failwith("You are not the owner or controller of this ID.");
|
||||||
|
const owner: address = id_details.owner;
|
||||||
|
const profile: bytes =
|
||||||
|
case new_profile of
|
||||||
|
None -> (* Default *) id_details.profile
|
||||||
|
| Some(new_profile) -> new_profile
|
||||||
|
end;
|
||||||
|
const controller: address =
|
||||||
|
case new_controller of
|
||||||
|
None -> (* Default *) id_details.controller
|
||||||
|
| Some(new_controller) -> new_controller
|
||||||
|
end;
|
||||||
|
id_details.owner := owner;
|
||||||
|
id_details.controller := controller;
|
||||||
|
id_details.profile := profile;
|
||||||
|
identities[id] := id_details;
|
||||||
|
end with ((nil: list(operation)), record [
|
||||||
|
identities = identities;
|
||||||
|
next_id = storage.next_id;
|
||||||
|
name_price = storage.name_price;
|
||||||
|
skip_price = storage.skip_price;
|
||||||
|
])
|
||||||
|
|
||||||
|
(* Let someone skip the next identity so nobody has to take one that's undesirable *)
|
||||||
|
function skip_ (const p: unit; const storage: storage) : list(operation) * storage is
|
||||||
|
begin
|
||||||
|
if amount = storage.skip_price
|
||||||
|
then skip
|
||||||
|
else failwith("Incorrect amount paid.");
|
||||||
|
end with ((nil: list(operation)), record [
|
||||||
|
identities = storage.identities;
|
||||||
|
next_id = storage.next_id + 1;
|
||||||
|
name_price = storage.name_price;
|
||||||
|
skip_price = storage.skip_price;
|
||||||
|
])
|
||||||
|
|
||||||
|
function main (const action : action; const storage : storage) : list(operation) * storage is
|
||||||
|
case action of
|
||||||
|
| Buy(b) -> buy (b, storage)
|
||||||
|
| Update_owner(uo) -> update_owner (uo, storage)
|
||||||
|
| Update_details(ud) -> update_details (ud, storage)
|
||||||
|
| Skip(s) -> skip_ (unit, storage)
|
||||||
|
end;
|
248
src/test/examples/reasonligo/id.religo
Normal file
248
src/test/examples/reasonligo/id.religo
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
/* (*_*
|
||||||
|
name: ID Contract (ReasonLIGO)
|
||||||
|
language: reasonligo
|
||||||
|
compile:
|
||||||
|
entrypoint: main
|
||||||
|
dryRun:
|
||||||
|
entrypoint: main
|
||||||
|
parameters: |
|
||||||
|
Buy (
|
||||||
|
{
|
||||||
|
profile: 0x0501000000026869,
|
||||||
|
initial_controller: Some(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
storage: |
|
||||||
|
{
|
||||||
|
identities:Big_map.literal([
|
||||||
|
(1,
|
||||||
|
{owner:("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address),
|
||||||
|
controller:("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), profile:0x0501000000026869}
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
next_id:2,
|
||||||
|
name_price:0tez,
|
||||||
|
skip_price:333mutez
|
||||||
|
}
|
||||||
|
deploy:
|
||||||
|
entrypoint: main
|
||||||
|
storage: |
|
||||||
|
{
|
||||||
|
identities:Big_map.literal([
|
||||||
|
(1,
|
||||||
|
{owner:("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address), controller:("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), profile:0x0501000000026869}
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
next_id:2,
|
||||||
|
name_price:10tez,
|
||||||
|
skip_price:333mutez
|
||||||
|
}
|
||||||
|
evaluateValue:
|
||||||
|
entrypoint: ""
|
||||||
|
evaluateFunction:
|
||||||
|
entrypoint: buy
|
||||||
|
parameters: |
|
||||||
|
(
|
||||||
|
{
|
||||||
|
profile: 0x0501000000026869,
|
||||||
|
initial_controller: Some(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
identities:Big_map.literal([
|
||||||
|
(1,
|
||||||
|
{owner:("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address),
|
||||||
|
controller:("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address),
|
||||||
|
profile:0x0501000000026869}
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
next_id:2,
|
||||||
|
name_price:0tez,
|
||||||
|
skip_price:333mutez
|
||||||
|
}
|
||||||
|
)
|
||||||
|
*_*) */
|
||||||
|
|
||||||
|
type id = int
|
||||||
|
|
||||||
|
type id_details = {
|
||||||
|
owner: address,
|
||||||
|
controller: address,
|
||||||
|
profile: bytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
type buy = {
|
||||||
|
profile: bytes,
|
||||||
|
initial_controller: option(address),
|
||||||
|
}
|
||||||
|
|
||||||
|
type update_owner = {
|
||||||
|
id: id,
|
||||||
|
new_owner: address,
|
||||||
|
}
|
||||||
|
|
||||||
|
type update_details = {
|
||||||
|
id: id,
|
||||||
|
new_profile: option(bytes),
|
||||||
|
new_controller: option(address),
|
||||||
|
}
|
||||||
|
|
||||||
|
type action =
|
||||||
|
| Buy(buy)
|
||||||
|
| Update_owner(update_owner)
|
||||||
|
| Update_details(update_details)
|
||||||
|
| Skip(unit)
|
||||||
|
|
||||||
|
/* The prices kept in storage can be changed by bakers, though they should only be
|
||||||
|
adjusted down over time, not up. */
|
||||||
|
type storage = {
|
||||||
|
identities: big_map (id, id_details),
|
||||||
|
next_id: int,
|
||||||
|
name_price: tez,
|
||||||
|
skip_price: tez,
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Preliminary thoughts on ids:
|
||||||
|
|
||||||
|
I very much like the simplicity of http://gurno.com/adam/mne/.
|
||||||
|
5 three letter words means you have a 15 character identity, not actually more
|
||||||
|
annoying than an IP address and a lot more memorable than the raw digits. This
|
||||||
|
can be stored as a single integer which is then translated into the corresponding
|
||||||
|
series of 5 words.
|
||||||
|
|
||||||
|
I in general like the idea of having a 'skip' mechanism, but it does need to cost
|
||||||
|
something so people don't eat up the address space. 256 ^ 5 means you have a lot
|
||||||
|
of address space, but if people troll by skipping a lot that could be eaten up.
|
||||||
|
Should probably do some napkin calculations for how expensive skipping needs to
|
||||||
|
be to deter people from doing it just to chew up address space.
|
||||||
|
*/
|
||||||
|
|
||||||
|
let buy = ((parameter, storage): (buy, storage)) : (list(operation), storage) => {
|
||||||
|
let void: unit =
|
||||||
|
if (amount == storage.name_price) { (); }
|
||||||
|
else { failwith("Incorrect amount paid."); };
|
||||||
|
let profile = parameter.profile;
|
||||||
|
let initial_controller = parameter.initial_controller;
|
||||||
|
let identities = storage.identities;
|
||||||
|
let new_id = storage.next_id;
|
||||||
|
let controller: address =
|
||||||
|
switch (initial_controller) {
|
||||||
|
| Some(addr) => addr
|
||||||
|
| None => sender
|
||||||
|
};
|
||||||
|
let new_id_details: id_details = {
|
||||||
|
owner : sender,
|
||||||
|
controller : controller,
|
||||||
|
profile : profile,
|
||||||
|
};
|
||||||
|
let updated_identities: big_map (id, id_details) =
|
||||||
|
Big_map.update(new_id, Some(new_id_details), identities);
|
||||||
|
(([]: list(operation)), {
|
||||||
|
identities : updated_identities,
|
||||||
|
next_id : new_id + 1,
|
||||||
|
name_price : storage.name_price,
|
||||||
|
skip_price : storage.skip_price,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let update_owner = ((parameter, storage): (update_owner, storage)) : (list(operation), storage) => {
|
||||||
|
let void: unit =
|
||||||
|
if (amount != 0mutez) {
|
||||||
|
failwith("Updating owner doesn't cost anything.");
|
||||||
|
}
|
||||||
|
else { (); };
|
||||||
|
let id : int = parameter.id;
|
||||||
|
let new_owner = parameter.new_owner;
|
||||||
|
let identities = storage.identities;
|
||||||
|
let current_id_details: id_details =
|
||||||
|
switch (Big_map.find_opt(id, identities)) {
|
||||||
|
| Some(id_details) => id_details
|
||||||
|
| None => (failwith("This ID does not exist."): id_details)
|
||||||
|
};
|
||||||
|
let is_allowed: bool =
|
||||||
|
if (sender == current_id_details.owner) { true; }
|
||||||
|
else { (failwith("You are not the owner of this ID."): bool); };
|
||||||
|
let updated_id_details: id_details = {
|
||||||
|
owner : new_owner,
|
||||||
|
controller : current_id_details.controller,
|
||||||
|
profile : current_id_details.profile,
|
||||||
|
};
|
||||||
|
let updated_identities = Big_map.update(id, (Some updated_id_details), identities);
|
||||||
|
(([]: list(operation)), {
|
||||||
|
identities : updated_identities,
|
||||||
|
next_id : storage.next_id,
|
||||||
|
name_price : storage.name_price,
|
||||||
|
skip_price : storage.skip_price,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let update_details = ((parameter, storage): (update_details, storage)) :
|
||||||
|
(list(operation), storage) => {
|
||||||
|
let void : unit =
|
||||||
|
if (amount != 0mutez) {
|
||||||
|
failwith("Updating details doesn't cost anything.");
|
||||||
|
}
|
||||||
|
else { (); };
|
||||||
|
let id = parameter.id;
|
||||||
|
let new_profile = parameter.new_profile;
|
||||||
|
let new_controller = parameter.new_controller;
|
||||||
|
let identities = storage.identities;
|
||||||
|
let current_id_details: id_details =
|
||||||
|
switch (Big_map.find_opt(id, identities)) {
|
||||||
|
| Some(id_details) => id_details
|
||||||
|
| None => (failwith("This ID does not exist."): id_details)
|
||||||
|
};
|
||||||
|
let is_allowed: bool =
|
||||||
|
if ((sender != current_id_details.controller) &&
|
||||||
|
(sender != current_id_details.owner)) {
|
||||||
|
(failwith ("You are not the owner or controller of this ID."): bool)
|
||||||
|
}
|
||||||
|
else { true; };
|
||||||
|
let owner: address = current_id_details.owner;
|
||||||
|
let profile: bytes =
|
||||||
|
switch (new_profile) {
|
||||||
|
| None => /* Default */ current_id_details.profile
|
||||||
|
| Some(new_profile) => new_profile
|
||||||
|
};
|
||||||
|
let controller: address =
|
||||||
|
switch (new_controller) {
|
||||||
|
| None => /* Default */ current_id_details.controller
|
||||||
|
| Some new_controller => new_controller
|
||||||
|
};
|
||||||
|
let updated_id_details: id_details = {
|
||||||
|
owner : owner,
|
||||||
|
controller : controller,
|
||||||
|
profile : profile,
|
||||||
|
};
|
||||||
|
let updated_identities: big_map (id, id_details) =
|
||||||
|
Big_map.update(id, (Some updated_id_details), identities);
|
||||||
|
(([]: list(operation)), {
|
||||||
|
identities : updated_identities,
|
||||||
|
next_id : storage.next_id,
|
||||||
|
name_price : storage.name_price,
|
||||||
|
skip_price : storage.skip_price,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Let someone skip the next identity so nobody has to take one that's undesirable */
|
||||||
|
let skip = ((p,storage): (unit, storage)) => {
|
||||||
|
let void : unit =
|
||||||
|
if (amount != storage.skip_price) {
|
||||||
|
failwith("Incorrect amount paid.");
|
||||||
|
}
|
||||||
|
else { (); };
|
||||||
|
(([]: list(operation)), {
|
||||||
|
identities : storage.identities,
|
||||||
|
next_id : storage.next_id + 1,
|
||||||
|
name_price : storage.name_price,
|
||||||
|
skip_price : storage.skip_price,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let main = ((action, storage): (action, storage)) : (list(operation), storage) => {
|
||||||
|
switch (action) {
|
||||||
|
| Buy(b) => buy((b, storage))
|
||||||
|
| Update_owner(uo) => update_owner((uo, storage))
|
||||||
|
| Update_details ud => update_details((ud, storage))
|
||||||
|
| Skip s => skip(((), storage))
|
||||||
|
};
|
||||||
|
};
|
@ -40,9 +40,10 @@ let buy_id () =
|
|||||||
("controller", e_address owner_addr) ;
|
("controller", e_address owner_addr) ;
|
||||||
("profile", owner_website)]
|
("profile", owner_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1)]) ;
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
e_int 1;
|
("next_id", e_int 1) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let new_addr = first_owner in
|
let new_addr = first_owner in
|
||||||
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
@ -54,11 +55,15 @@ let buy_id () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let param = e_pair owner_website (e_some (e_address new_addr)) in
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
("initial_controller", (e_some (e_address new_addr))) ;
|
||||||
(e_int 1, id_details_2)]) ;
|
] in
|
||||||
e_int 2;
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let%bind () = expect_eq ~options (program, state) "buy"
|
let%bind () = expect_eq ~options (program, state) "buy"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
@ -73,9 +78,10 @@ let buy_id_sender_addr () =
|
|||||||
("controller", e_address owner_addr) ;
|
("controller", e_address owner_addr) ;
|
||||||
("profile", owner_website)]
|
("profile", owner_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1)]) ;
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
e_int 1;
|
("next_id", e_int 1) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let new_addr = first_owner in
|
let new_addr = first_owner in
|
||||||
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
@ -87,11 +93,14 @@ let buy_id_sender_addr () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let param = e_pair owner_website (e_typed_none (t_address ())) in
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
("initial_controller", (e_typed_none (t_address ())))] in
|
||||||
(e_int 1, id_details_2)]) ;
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
e_int 2;
|
[(e_int 0, id_details_1) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let%bind () = expect_eq ~options (program, state) "buy"
|
let%bind () = expect_eq ~options (program, state) "buy"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
@ -107,16 +116,18 @@ let buy_id_wrong_amount () =
|
|||||||
("controller", e_address owner_addr) ;
|
("controller", e_address owner_addr) ;
|
||||||
("profile", owner_website)]
|
("profile", owner_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1)]) ;
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
e_int 1;
|
("next_id", e_int 1) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let new_addr = first_owner in
|
let new_addr = first_owner in
|
||||||
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
~sender:first_contract
|
~sender:first_contract
|
||||||
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) ()
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) ()
|
||||||
in
|
in
|
||||||
let param = e_pair owner_website (e_some (e_address new_addr)) in
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
|
("initial_controller", (e_some (e_address new_addr)))] in
|
||||||
let%bind () = expect_string_failwith ~options (program, state) "buy"
|
let%bind () = expect_string_failwith ~options (program, state) "buy"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
"Incorrect amount paid."
|
"Incorrect amount paid."
|
||||||
@ -144,20 +155,24 @@ let update_details_owner () =
|
|||||||
let id_details_2_diff = e_record_ez [("owner", e_address new_addr) ;
|
let id_details_2_diff = e_record_ez [("owner", e_address new_addr) ;
|
||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)] in
|
("profile", new_website)] in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2_diff)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let details = e_bytes_string "ligolang.org" in
|
let details = e_bytes_string "ligolang.org" in
|
||||||
let param = e_tuple [e_int 1 ;
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
e_some details ;
|
("new_profile", e_some details) ;
|
||||||
e_some (e_address new_addr)] in
|
("new_controller", e_some (e_address new_addr))] in
|
||||||
let%bind () = expect_eq ~options (program, state) "update_details"
|
let%bind () = expect_eq ~options (program, state) "update_details"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
(e_pair (e_list []) new_storage)
|
(e_pair (e_list []) new_storage)
|
||||||
@ -185,20 +200,24 @@ let update_details_controller () =
|
|||||||
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
|
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
("controller", e_address owner_addr) ;
|
("controller", e_address owner_addr) ;
|
||||||
("profile", new_website)] in
|
("profile", new_website)] in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2_diff)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let details = e_bytes_string "ligolang.org" in
|
let details = e_bytes_string "ligolang.org" in
|
||||||
let param = e_tuple [e_int 1 ;
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
e_some details ;
|
("new_profile", e_some details) ;
|
||||||
e_some (e_address owner_addr)] in
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
let%bind () = expect_eq ~options (program, state) "update_details"
|
let%bind () = expect_eq ~options (program, state) "update_details"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
(e_pair (e_list []) new_storage)
|
(e_pair (e_list []) new_storage)
|
||||||
@ -224,15 +243,17 @@ let update_details_nonexistent () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let details = e_bytes_string "ligolang.org" in
|
let details = e_bytes_string "ligolang.org" in
|
||||||
let param = e_tuple [e_int 2 ;
|
let param = e_record_ez [("id", e_int 2) ;
|
||||||
e_some details ;
|
("new_profile", e_some details) ;
|
||||||
e_some (e_address owner_addr)] in
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
let%bind () = expect_string_failwith ~options (program, state) "update_details"
|
let%bind () = expect_string_failwith ~options (program, state) "update_details"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
"This ID does not exist."
|
"This ID does not exist."
|
||||||
@ -257,15 +278,17 @@ let update_details_wrong_addr () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let details = e_bytes_string "ligolang.org" in
|
let details = e_bytes_string "ligolang.org" in
|
||||||
let param = e_tuple [e_int 0 ;
|
let param = e_record_ez [("id", e_int 0) ;
|
||||||
e_some details ;
|
("new_profile", e_some details) ;
|
||||||
e_some (e_address owner_addr)] in
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
let%bind () = expect_string_failwith ~options (program, state) "update_details"
|
let%bind () = expect_string_failwith ~options (program, state) "update_details"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
"You are not the owner or controller of this ID."
|
"You are not the owner or controller of this ID."
|
||||||
@ -291,14 +314,16 @@ let update_details_unchanged () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let param = e_tuple [e_int 1 ;
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
e_typed_none (t_bytes ()) ;
|
("new_profile", e_typed_none (t_bytes ())) ;
|
||||||
e_typed_none (t_address ())] in
|
("new_controller", e_typed_none (t_address ()))] in
|
||||||
let%bind () = expect_eq ~options (program, state) "update_details"
|
let%bind () = expect_eq ~options (program, state) "update_details"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
(e_pair (e_list []) storage)
|
(e_pair (e_list []) storage)
|
||||||
@ -326,17 +351,22 @@ let update_owner () =
|
|||||||
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
|
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)] in
|
("profile", new_website)] in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2_diff)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let param = e_pair (e_int 1) (e_address owner_addr) in
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_owner", e_address owner_addr)] in
|
||||||
let%bind () = expect_eq ~options (program, state) "update_owner"
|
let%bind () = expect_eq ~options (program, state) "update_owner"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
(e_pair (e_list []) new_storage)
|
(e_pair (e_list []) new_storage)
|
||||||
@ -362,12 +392,15 @@ let update_owner_nonexistent () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let param = e_pair (e_int 2) (e_address new_addr) in
|
let param = e_record_ez [("id", e_int 2);
|
||||||
|
("new_owner", e_address new_addr)] in
|
||||||
let%bind () = expect_string_failwith ~options (program, state) "update_owner"
|
let%bind () = expect_string_failwith ~options (program, state) "update_owner"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
"This ID does not exist."
|
"This ID does not exist."
|
||||||
@ -393,12 +426,15 @@ let update_owner_wrong_addr () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let param = e_pair (e_int 0) (e_address new_addr) in
|
let param = e_record_ez [("id", e_int 0);
|
||||||
|
("new_owner", e_address new_addr)] in
|
||||||
let%bind () = expect_string_failwith ~options (program, state) "update_owner"
|
let%bind () = expect_string_failwith ~options (program, state) "update_owner"
|
||||||
(e_pair param storage)
|
(e_pair param storage)
|
||||||
"You are not the owner of this ID."
|
"You are not the owner of this ID."
|
||||||
@ -422,15 +458,19 @@ let skip () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let new_storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 3;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 3) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let%bind () = expect_eq ~options (program, state) "skip"
|
let%bind () = expect_eq ~options (program, state) "skip"
|
||||||
(e_pair (e_unit ()) storage)
|
(e_pair (e_unit ()) storage)
|
||||||
@ -456,17 +496,19 @@ let skip_wrong_amount () =
|
|||||||
("controller", e_address new_addr) ;
|
("controller", e_address new_addr) ;
|
||||||
("profile", new_website)]
|
("profile", new_website)]
|
||||||
in
|
in
|
||||||
let storage = e_tuple [(e_big_map [(e_int 0, id_details_1) ;
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
(e_int 1, id_details_2)]) ;
|
[(e_int 0, id_details_1) ;
|
||||||
e_int 2;
|
(e_int 1, id_details_2)])) ;
|
||||||
e_tuple [e_mutez 1000000 ; e_mutez 1000000]]
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
in
|
in
|
||||||
let%bind () = expect_string_failwith ~options (program, state) "skip"
|
let%bind () = expect_string_failwith ~options (program, state) "skip"
|
||||||
(e_pair (e_unit ()) storage)
|
(e_pair (e_unit ()) storage)
|
||||||
"Incorrect amount paid."
|
"Incorrect amount paid."
|
||||||
in ok ()
|
in ok ()
|
||||||
|
|
||||||
let main = test_suite "ID Layer" [
|
let main = test_suite "ID Layer (CameLIGO)" [
|
||||||
test "buy" buy_id ;
|
test "buy" buy_id ;
|
||||||
test "buy (sender addr)" buy_id_sender_addr ;
|
test "buy (sender addr)" buy_id_sender_addr ;
|
||||||
test "buy (wrong amount)" buy_id_wrong_amount ;
|
test "buy (wrong amount)" buy_id_wrong_amount ;
|
||||||
|
522
src/test/id_tests_p.ml
Normal file
522
src/test/id_tests_p.ml
Normal file
@ -0,0 +1,522 @@
|
|||||||
|
open Trace
|
||||||
|
open Test_helpers
|
||||||
|
open Ast_imperative
|
||||||
|
|
||||||
|
|
||||||
|
let type_file f =
|
||||||
|
let%bind typed,state = Ligo.Compile.Utils.type_file f "pascaligo" (Contract "main") in
|
||||||
|
ok (typed,state)
|
||||||
|
|
||||||
|
let get_program =
|
||||||
|
let s = ref None in
|
||||||
|
fun () -> match !s with
|
||||||
|
| Some s -> ok s
|
||||||
|
| None -> (
|
||||||
|
let%bind program = type_file "./contracts/id.ligo" in
|
||||||
|
s := Some program ;
|
||||||
|
ok program
|
||||||
|
)
|
||||||
|
|
||||||
|
let compile_main () =
|
||||||
|
let%bind typed_prg,_ = get_program () in
|
||||||
|
let%bind mini_c_prg = Ligo.Compile.Of_typed.compile typed_prg in
|
||||||
|
let%bind michelson_prg = Ligo.Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg "main" in
|
||||||
|
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||||
|
(* fails if the given entry point is not a valid contract *)
|
||||||
|
Ligo.Compile.Of_michelson.build_contract michelson_prg in
|
||||||
|
ok ()
|
||||||
|
|
||||||
|
let (first_owner , first_contract) =
|
||||||
|
let open Proto_alpha_utils.Memory_proto_alpha in
|
||||||
|
let id = List.nth dummy_environment.identities 0 in
|
||||||
|
let kt = id.implicit_contract in
|
||||||
|
Protocol.Alpha_context.Contract.to_b58check kt , kt
|
||||||
|
|
||||||
|
let buy_id () =
|
||||||
|
let%bind program, state = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
|
("next_id", e_int 1) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
|
||||||
|
in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
|
("initial_controller", (e_some (e_address new_addr))) ;
|
||||||
|
] in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let%bind () = expect_eq ~options (program, state) "buy"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let buy_id_sender_addr () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
|
("next_id", e_int 1) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
|
||||||
|
in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
|
("initial_controller", (e_typed_none (t_address ())))] in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let%bind () = expect_eq ~options program "buy"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails if we attempt to buy an ID for the wrong amount *)
|
||||||
|
let buy_id_wrong_amount () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
|
("next_id", e_int 1) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) ()
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
|
("initial_controller", (e_some (e_address new_addr)))] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "buy"
|
||||||
|
(e_pair param storage)
|
||||||
|
"Incorrect amount paid."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let update_details_owner () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let id_details_2_diff = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", owner_website)] in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let details = owner_website in
|
||||||
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_profile", e_some details) ;
|
||||||
|
("new_controller", e_some (e_address new_addr))] in
|
||||||
|
let%bind () = expect_eq ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let update_details_controller () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = owner_website in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", new_website)] in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let details = e_bytes_string "ligolang.org" in
|
||||||
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_profile", e_some details) ;
|
||||||
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
|
let%bind () = expect_eq ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails when we attempt to update details of nonexistent ID *)
|
||||||
|
let update_details_nonexistent () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let details = e_bytes_string "ligolang.org" in
|
||||||
|
let param = e_record_ez [("id", e_int 2) ;
|
||||||
|
("new_profile", e_some details) ;
|
||||||
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
"This ID does not exist."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails when we attempt to update details from wrong addr *)
|
||||||
|
let update_details_wrong_addr () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let details = e_bytes_string "ligolang.org" in
|
||||||
|
let param = e_record_ez [("id", e_int 0) ;
|
||||||
|
("new_profile", e_some details) ;
|
||||||
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
"You are not the owner or controller of this ID."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that giving none on both profile and controller address is a no-op *)
|
||||||
|
let update_details_unchanged () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_profile", e_typed_none (t_bytes ())) ;
|
||||||
|
("new_controller", e_typed_none (t_address ()))] in
|
||||||
|
let%bind () = expect_eq ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let update_owner () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)] in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_owner", e_address owner_addr)] in
|
||||||
|
let%bind () = expect_eq ~options program "update_owner"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails when we attempt to update owner of nonexistent ID *)
|
||||||
|
let update_owner_nonexistent () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("id", e_int 2);
|
||||||
|
("new_owner", e_address new_addr)] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "update_owner"
|
||||||
|
(e_pair param storage)
|
||||||
|
"This ID does not exist."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails when we attempt to update owner from non-owner addr *)
|
||||||
|
let update_owner_wrong_addr () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("id", e_int 0);
|
||||||
|
("new_owner", e_address new_addr)] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "update_owner"
|
||||||
|
(e_pair param storage)
|
||||||
|
"You are not the owner of this ID."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let skip () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 3) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let%bind () = expect_eq ~options program "skip_"
|
||||||
|
(e_pair (e_unit ()) storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails if we try to skip without paying the right amount *)
|
||||||
|
let skip_wrong_amount () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) ()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let%bind () = expect_string_failwith ~options program "skip_"
|
||||||
|
(e_pair (e_unit ()) storage)
|
||||||
|
"Incorrect amount paid."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let main = test_suite "ID Layer (PascaLIGO)" [
|
||||||
|
test "buy" buy_id ;
|
||||||
|
test "buy (sender addr)" buy_id_sender_addr ;
|
||||||
|
test "buy (wrong amount)" buy_id_wrong_amount ;
|
||||||
|
test "update_details (owner)" update_details_owner ;
|
||||||
|
test "update_details (controller)" update_details_controller ;
|
||||||
|
test "update_details_nonexistent" update_details_nonexistent ;
|
||||||
|
test "update_details_wrong_addr" update_details_wrong_addr ;
|
||||||
|
test "update_details_unchanged" update_details_unchanged ;
|
||||||
|
test "update_owner" update_owner ;
|
||||||
|
test "update_owner_nonexistent" update_owner_nonexistent ;
|
||||||
|
test "update_owner_wrong_addr" update_owner_wrong_addr ;
|
||||||
|
test "skip" skip ;
|
||||||
|
test "skip (wrong amount)" skip_wrong_amount ;
|
||||||
|
]
|
525
src/test/id_tests_r.ml
Normal file
525
src/test/id_tests_r.ml
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
open Trace
|
||||||
|
open Test_helpers
|
||||||
|
open Ast_imperative
|
||||||
|
|
||||||
|
|
||||||
|
let retype_file f =
|
||||||
|
let%bind typed,state = Ligo.Compile.Utils.type_file f "reasonligo" (Contract "main") in
|
||||||
|
ok (typed,state)
|
||||||
|
|
||||||
|
let get_program =
|
||||||
|
let s = ref None in
|
||||||
|
fun () -> match !s with
|
||||||
|
| Some s -> ok s
|
||||||
|
| None -> (
|
||||||
|
let%bind program = retype_file "./contracts/id.religo" in
|
||||||
|
s := Some program ;
|
||||||
|
ok program
|
||||||
|
)
|
||||||
|
|
||||||
|
let compile_main () =
|
||||||
|
let%bind typed_prg,_ = get_program () in
|
||||||
|
let%bind mini_c_prg = Ligo.Compile.Of_typed.compile typed_prg in
|
||||||
|
let%bind michelson_prg = Ligo.Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg "main" in
|
||||||
|
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||||
|
(* fails if the given entry point is not a valid contract *)
|
||||||
|
Ligo.Compile.Of_michelson.build_contract michelson_prg in
|
||||||
|
ok ()
|
||||||
|
|
||||||
|
let (first_owner , first_contract) =
|
||||||
|
let open Proto_alpha_utils.Memory_proto_alpha in
|
||||||
|
let id = List.nth dummy_environment.identities 0 in
|
||||||
|
let kt = id.implicit_contract in
|
||||||
|
Protocol.Alpha_context.Contract.to_b58check kt , kt
|
||||||
|
|
||||||
|
let buy_id () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
|
("next_id", e_int 1) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
|
("initial_controller", (e_some (e_address new_addr))) ;
|
||||||
|
] in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let%bind () = expect_eq ~options program "buy"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let buy_id_sender_addr () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
|
("next_id", e_int 1) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
|
("initial_controller", (e_typed_none (t_address ())))] in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let%bind () = expect_eq ~options program "buy"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails if we attempt to buy an ID for the wrong amount *)
|
||||||
|
let buy_id_wrong_amount () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map [(e_int 0, id_details_1)])) ;
|
||||||
|
("next_id", e_int 1) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) ()
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("profile", owner_website) ;
|
||||||
|
("initial_controller", (e_some (e_address new_addr)))] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "buy"
|
||||||
|
(e_pair param storage)
|
||||||
|
"Incorrect amount paid."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let update_details_owner () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let id_details_2_diff = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)] in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let details = e_bytes_string "ligolang.org" in
|
||||||
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_profile", e_some details) ;
|
||||||
|
("new_controller", e_some (e_address new_addr))] in
|
||||||
|
let%bind () = expect_eq ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let update_details_controller () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", new_website)] in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let details = e_bytes_string "ligolang.org" in
|
||||||
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_profile", e_some details) ;
|
||||||
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
|
let%bind () = expect_eq ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails when we attempt to update details of nonexistent ID *)
|
||||||
|
let update_details_nonexistent () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let details = e_bytes_string "ligolang.org" in
|
||||||
|
let param = e_record_ez [("id", e_int 2) ;
|
||||||
|
("new_profile", e_some details) ;
|
||||||
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
"This ID does not exist."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails when we attempt to update details from wrong addr *)
|
||||||
|
let update_details_wrong_addr () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let details = e_bytes_string "ligolang.org" in
|
||||||
|
let param = e_record_ez [("id", e_int 0) ;
|
||||||
|
("new_profile", e_some details) ;
|
||||||
|
("new_controller", e_some (e_address owner_addr))] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
"You are not the owner or controller of this ID."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that giving none on both profile and controller address is a no-op *)
|
||||||
|
let update_details_unchanged () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_profile", e_typed_none (t_bytes ())) ;
|
||||||
|
("new_controller", e_typed_none (t_address ()))] in
|
||||||
|
let%bind () = expect_eq ~options program "update_details"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let update_owner () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let id_details_2_diff = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)] in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2_diff)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("id", e_int 1) ;
|
||||||
|
("new_owner", e_address owner_addr)] in
|
||||||
|
let%bind () = expect_eq ~options program "update_owner"
|
||||||
|
(e_pair param storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails when we attempt to update owner of nonexistent ID *)
|
||||||
|
let update_owner_nonexistent () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("id", e_int 2);
|
||||||
|
("new_owner", e_address new_addr)] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "update_owner"
|
||||||
|
(e_pair param storage)
|
||||||
|
"This ID does not exist."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails when we attempt to update owner from non-owner addr *)
|
||||||
|
let update_owner_wrong_addr () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.zero)
|
||||||
|
()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let param = e_record_ez [("id", e_int 0);
|
||||||
|
("new_owner", e_address new_addr)] in
|
||||||
|
let%bind () = expect_string_failwith ~options program "update_owner"
|
||||||
|
(e_pair param storage)
|
||||||
|
"You are not the owner of this ID."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let skip () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.one) ()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let new_storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 3) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let%bind () = expect_eq ~options program "skip"
|
||||||
|
(e_pair (e_unit ()) storage)
|
||||||
|
(e_pair (e_list []) new_storage)
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
(* Test that contract fails if we try to skip without paying the right amount *)
|
||||||
|
let skip_wrong_amount () =
|
||||||
|
let%bind program = get_program () in
|
||||||
|
let owner_addr = addr 5 in
|
||||||
|
let owner_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_1 = e_record_ez [("owner", e_address owner_addr) ;
|
||||||
|
("controller", e_address owner_addr) ;
|
||||||
|
("profile", owner_website)]
|
||||||
|
in
|
||||||
|
let new_addr = first_owner in
|
||||||
|
let options = Proto_alpha_utils.Memory_proto_alpha.make_options
|
||||||
|
~sender:first_contract
|
||||||
|
~amount:(Memory_proto_alpha.Protocol.Alpha_context.Tez.fifty_cents) ()
|
||||||
|
in
|
||||||
|
let new_website = e_bytes_string "ligolang.org" in
|
||||||
|
let id_details_2 = e_record_ez [("owner", e_address new_addr) ;
|
||||||
|
("controller", e_address new_addr) ;
|
||||||
|
("profile", new_website)]
|
||||||
|
in
|
||||||
|
let storage = e_record_ez [("identities", (e_big_map
|
||||||
|
[(e_int 0, id_details_1) ;
|
||||||
|
(e_int 1, id_details_2)])) ;
|
||||||
|
("next_id", e_int 2) ;
|
||||||
|
("name_price", e_mutez 1000000) ;
|
||||||
|
("skip_price", e_mutez 1000000) ; ]
|
||||||
|
in
|
||||||
|
let%bind () = expect_string_failwith ~options program "skip"
|
||||||
|
(e_pair (e_unit ()) storage)
|
||||||
|
"Incorrect amount paid."
|
||||||
|
in ok ()
|
||||||
|
|
||||||
|
let main = test_suite "ID Layer (ReasonLIGO)" [
|
||||||
|
test "buy" buy_id ;
|
||||||
|
test "buy (sender addr)" buy_id_sender_addr ;
|
||||||
|
test "buy (wrong amount)" buy_id_wrong_amount ;
|
||||||
|
test "update_details (owner)" update_details_owner ;
|
||||||
|
test "update_details (controller)" update_details_controller ;
|
||||||
|
test "update_details_nonexistent" update_details_nonexistent ;
|
||||||
|
test "update_details_wrong_addr" update_details_wrong_addr ;
|
||||||
|
test "update_details_unchanged" update_details_unchanged ;
|
||||||
|
test "update_owner" update_owner ;
|
||||||
|
test "update_owner_nonexistent" update_owner_nonexistent ;
|
||||||
|
test "update_owner_wrong_addr" update_owner_wrong_addr ;
|
||||||
|
test "skip" skip ;
|
||||||
|
test "skip (wrong amount)" skip_wrong_amount ;
|
||||||
|
]
|
@ -11,6 +11,8 @@ let () =
|
|||||||
Coase_tests.main ;
|
Coase_tests.main ;
|
||||||
Vote_tests.main ;
|
Vote_tests.main ;
|
||||||
Id_tests.main ;
|
Id_tests.main ;
|
||||||
|
Id_tests_p.main ;
|
||||||
|
Id_tests_r.main ;
|
||||||
Multisig_tests.main ;
|
Multisig_tests.main ;
|
||||||
Multisig_v2_tests.main ;
|
Multisig_v2_tests.main ;
|
||||||
Replaceable_id_tests.main ;
|
Replaceable_id_tests.main ;
|
||||||
|
@ -4,12 +4,6 @@ const join = require('path').join;
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const YAML = require('yamljs');
|
const YAML = require('yamljs');
|
||||||
|
|
||||||
const CURATED_EXAMPLES = [
|
|
||||||
'cameligo/arithmetic-contract.ligo',
|
|
||||||
'pascaligo/arithmetic-contract.ligo',
|
|
||||||
'reasonligo/arithmetic-contract.ligo'
|
|
||||||
];
|
|
||||||
|
|
||||||
function urlFriendlyHash(content) {
|
function urlFriendlyHash(content) {
|
||||||
const hash = createHash('md5');
|
const hash = createHash('md5');
|
||||||
hash.update(content);
|
hash.update(content);
|
||||||
@ -109,6 +103,15 @@ async function main() {
|
|||||||
// const EXAMPLES_GLOB = '**/*.ligo';
|
// const EXAMPLES_GLOB = '**/*.ligo';
|
||||||
// const files = await findFiles(EXAMPLES_GLOB, EXAMPLES_DIR);
|
// const files = await findFiles(EXAMPLES_GLOB, EXAMPLES_DIR);
|
||||||
|
|
||||||
|
const CURATED_EXAMPLES = [
|
||||||
|
'pascaligo/arithmetic-contract.ligo',
|
||||||
|
'cameligo/arithmetic-contract.ligo',
|
||||||
|
'reasonligo/arithmetic-contract.ligo',
|
||||||
|
'pascaligo/id.ligo',
|
||||||
|
'cameligo/id.mligo',
|
||||||
|
'reasonligo/id.religo',
|
||||||
|
];
|
||||||
|
|
||||||
const EXAMPLES_DEST_DIR = join(process.cwd(), 'build', 'static', 'examples');
|
const EXAMPLES_DEST_DIR = join(process.cwd(), 'build', 'static', 'examples');
|
||||||
fs.mkdirSync(EXAMPLES_DEST_DIR, { recursive: true });
|
fs.mkdirSync(EXAMPLES_DEST_DIR, { recursive: true });
|
||||||
|
|
||||||
|
@ -33,9 +33,12 @@ export const DEFAULT_STATE: ExamplesState = {
|
|||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
DEFAULT_STATE.list = [
|
DEFAULT_STATE.list = [
|
||||||
{ id: 'MzkMQ1oiVHJqbcfUuVFKTw', name: 'CameLIGO Contract' },
|
{ id: 'MzkMQ1oiVHJqbcfUuVFKTw', name: 'Increment Example CameLIGO ' },
|
||||||
{ id: 'FEb62HL7onjg1424eUsGSg', name: 'PascaLIGO Contract' },
|
{ id: 'FEb62HL7onjg1424eUsGSg', name: 'Increment Example PascaLIGO' },
|
||||||
{ id: 'JPhSOehj_2MFwRIlml0ymQ', name: 'ReasonLIGO Contract' }
|
{ id: 'JPhSOehj_2MFwRIlml0ymQ', name: 'Increment Example ReasonLIGO' },
|
||||||
|
{ id: 'ehDv-Xaf70mQoiPhQDTAUQ', name: 'ID Example CameLIGO' },
|
||||||
|
{ id: 'CpnK7TFuUjJiQTT8KiiGyQ', name: 'ID Example ReasonLIGO' },
|
||||||
|
{ id: 'yP-THvmURsaqHxpwCravWg', name: 'ID Example PascaLIGO' },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ describe('Share', () => {
|
|||||||
await responseCallback;
|
await responseCallback;
|
||||||
|
|
||||||
const actualShareLink = await page.evaluate(getInputValue, 'share-link');
|
const actualShareLink = await page.evaluate(getInputValue, 'share-link');
|
||||||
const expectedShareLink = `${API_HOST}/p/WxKPBq9-mkZ_kq4cMHXfCQ`;
|
const expectedShareLink = `${API_HOST}/p/2GnQR0cUYeO7feAw71SJYQ`
|
||||||
|
|
||||||
expect(actualShareLink).toEqual(expectedShareLink);
|
expect(actualShareLink).toEqual(expectedShareLink);
|
||||||
done();
|
done();
|
||||||
|
Loading…
Reference in New Issue
Block a user