Skip to main content

Implementation

Start

entry start () {
require {
r1: now > dateofstop;
}
effect {
var t : nat = transferred;
var dur : duration = (get_rate_in_s_by_utz() * t) * 1s;
if dur > read_interval then (
dateofstop := now + dur + read_interval;
dateofstart := now;
user := some(caller)
)
}
}

Duration is computed by multiplying the amount of transferred XTZ by the price rate. The price rate is converted to mutz (one millionth of tez) per second with the get_rate_in_s_by_utz function:

function get_rate_in_s_by_utz () : rational {
var d : int = time_unit;
var t : nat = tez_unit;
return (rate * d / t)
}

dateofstop is computed with the following simple formula now + dur + read_interval.

We note that the Archetype makes it very simple to manipulate durations.

Interrupt

The interrupt entry point pays back the caller so that the caller pays only for the effective duration of service.

entry interrupt () {
require {
r2: caller = opt_get(user) and now < dateofstop
}
effect {
transfer (get_return_tz()) to caller;
dateofstop := now - read_interval;
dateofstart := now - read_interval;
}
}

The get_return_tz function computes the number of XTZ to return to the caller:

function get_return_tz () : tez {
var res : int = 1 / get_rate_in_s_by_utz() * (dateofstop - now);
return (res * 1utz)
}

dateofstop - now is the duration from now to the initially planned date of end of service.

Collect

entry collect () {
called by owner
effect {
var keep = 0tz;
if now < dateofstop then
keep := get_return_tz();
if balance - keep > 0tz then
transfer (balance - keep) to owner
}
}

Set Unit

entry setunits (dunit : duration, tunit : tez) {
called by owner
effect {
time_unit := dunit;
tez_unit := tunit;
}
}