Asset
Archetype assets provide a high-level abstraction to handle collection of structured data.
Introduction
Similarly to a SQL table, an asset is a collection of data, stored in the contract storage, organized in rows and columns and defined by an identifier and a list of fields.
An asset collection provides a set of instructions to manage the collection, and expressions to interrogate the collection (see API section below for more information).
For example, the following declaration defines a collection of loan data:
asset loan identified by id {
id : string;
subscriber : address;
principal : tez;
interest : rational = 2%;
creation : date = now;
delay : duration = 10w; /* 10 weeks */
}
The declaration above creates a collection of loans; each loan is defined by a string identifier id
and five data fields (from subscriber
to delay
). Note that fields may have a default value.
Refer to the declaration section for more information.
API
This section presents the application programming interface of an asset collection. Follow an item's link for a detailed presentation.
Instructions
Expressions
Utility types
Utility builtins
A convenient aspect of this API is the possibility to combine expressions and instructions. For example, consider the following vehicle
asset definition:
asset vehicle {
vin : string;
nbrepairs : nat = 0;
dateofrepair : date = now;
}
The following one line code removes the top 3 recently repaired vehicles with total number of 2 repairs:
vehicle.sort(dateofrepair).select(the.nbrepairs = 2).head(3).remove_all();
Iteration
An asset collection is iterable with the for k in ... do ... done
loop instruction.
For example, the following code iterates on the loan collection:
var total = 0tz;
for k in loan do /* k is a loan key */
/* do something with asset with key k */
total += loan[k].interest * loan[k].principal
done
Note that:
- assets are iterated in the natural key order.
- Note also that the above loop instruction is equivalent to the following expression:
var total = loan.sum(interest * principal);
Relations
It is possible to specify relations between assets of two collections with asset field types partition and aggregate.
Partition
A partition defines a one-to-many relation between an asset B (partitioning asset) and an asset A (partitioned asset) so that an asset from collection A is in relation with exactly one asset from collection B; conversely an asset from collection B is in relation with zero, one or many assets from collection A.
The following declarations define asset B with a partition of A, typed partition<A>
:
asset A {
ida : nat
}
asset B {
idb : nat;
pofa : partition<A> /* field 'pofa' is a partition of A */
}
The partition relation is ensured statically by the compiler as it is not possible to add straightforwardly an asset to collection A. It is only possible through the parition field of an asset from collection B in order to ensure the relation is respected:
B[kb].pofa.add({ ka });
See partition section of add
and remove
instructions for more information.
Aggregate
An aggregate defines a many-to-many relation between an asset B (aggregating asset) and an asset A (aggregated asset) so that an asset from collection A is in relation with zero, one or many assets from collection B; conversely an asset from collection B is in relation with zero, one or many assets from collection A.
The following declarations define asset B with an aggregate of A, typed aggregate<A>
:
asset A {
ida : nat
}
asset B {
idb : nat;
aofa : aggregate<A> /* field 'aofa' is an aggregate of A */
}
Adding a reference (ie. an identifier) in aofa
field fails at runtime if the asset is not in collection A.
See aggregate section of add
and remove
instructions for more information.