[
"autonomous agent",
{
"doc_url": "https://obyte.org/obby-forms-store-aa.json",
"init": "{
$challenging_period = 30*24*3600;
$grace_period = 30*24*3600; // new address can change their symbol immediately during this period after the first registration, if a new symbol got overwhelming support over the previous symbol
$overwhelming_multiplier = 5;
$min_amount = 1e8;
$amount = trigger.output[[asset=base]];
$drawer = trigger.data.drawer OTHERWISE 0;
if (!is_integer($drawer))
bounce("drawer must be integer");
if ($drawer != 0 AND $drawer != 1 AND $drawer != 7 AND $drawer != 30 AND $drawer != 90 AND $drawer != 180 AND $drawer != 360)
bounce("bad drawer: " || $drawer);
$symbol = trigger.data.symbol;
if ($symbol){
if (typeof($symbol) != 'string')
bounce("symbol must be string");
if ($symbol != to_lower($symbol))
bounce("symbol must be lowercase");
if (length($symbol) > 20)
bounce("symbol must be max 20 characters long");
if ($symbol == 'store' OR $symbol == 'editor' OR $symbol == 'docs' OR $symbol == 'agent')
bounce("bad symbol");
if (contains($symbol, "/"))
bounce("url must not be followed by a slash");
if (!has_only($symbol, "a-z0-9"))
bounce("url must not valid");
}
$description = trigger.data.description;
if ($description){
if (typeof($description) != 'string')
bounce("description must be string");
if (length($description) > 140)
bounce("description must be max 140 characters long");
}
$url = trigger.data.url;
if (exists($url)){
if ($url != to_lower($url))
bounce("url must be lower");
if (contains($url, "/"))
bounce("url must not be followed by a slash");
}
$address = trigger.data.address;
if ($address){
if (!is_aa($address))
bounce("address is not AA");
}
}",
"messages": {
"cases": [
{
"if": "{ trigger.data.withdraw AND trigger.data.amount AND $address AND $symbol }",
"init": "{
$drawer_key = trigger.address || '_' || $drawer || '_' || $symbol || '_' || $address;
if (var[$drawer_key] < trigger.data.amount)
bounce("not enough funds in this drawer");
if ($drawer){
$expiry_ts = var[$drawer_key || '_expiry_ts'];
if ($expiry_ts AND timestamp < $expiry_ts)
bounce("warm-up period has not expired yet");
$allowed = !!$expiry_ts; // after expiry
}
else
$allowed = true;
}",
"messages": [
{
"if": "{$allowed}",
"app": "payment",
"payload": {
"outputs": [
{
"address": "{trigger.address}",
"amount": "{trigger.data.amount}"
}
]
}
},
{
"app": "state",
"state": "{
if ($allowed){
var[$drawer_key] -= trigger.data.amount;
if ($drawer)
var[$drawer_key || '_expiry_ts'] = false; // lock the drawer again
var['support_' || $symbol || '_' || $address] -= trigger.data.amount; // if the support drops below some competitor, the current leader is not updated automatically, someone has to trigger the update with a new deposit (even a small one)
var['balance_' || trigger.address || '_' || $address] -= trigger.data.amount;
$desc_hash = var['desc_choice_' || $address || '_' || trigger.address];
if ($desc_hash)
var['desc_support_' || $address || '_' || $desc_hash] -= trigger.data.amount;
}
else if (!$expiry_ts)
var[$drawer_key || '_expiry_ts'] = timestamp + $drawer * 24 * 3600;
}"
}
]
},
{
"if": "{$description AND $url AND ($address OR $symbol) AND $amount < $min_amount}",
"init": "{
if ($address){
$voted_address = $address;
$voted_symbol = var['a2s_' || $voted_address];
}
else {
$voted_address = var['s2a_' || $symbol];
if (!$voted_address)
bounce("no address found by symbol " || $symbol);
$voted_symbol = $symbol;
}
$balance = var['balance_' || trigger.address || '_' || $voted_address];
if (!$balance)
bounce("you have no balance in this address");
$desc_hash = sha256($description || $url);
$current_my_desc_hash = var['desc_choice_' || $voted_address || '_' || trigger.address];
$current_desc_hash = var['current_desc_' || $voted_address];
$is_initial_desc = !$current_desc_hash;
if ($is_initial_desc)
$current_desc_changed = true;
else if ($desc_hash != $current_desc_hash){
$new_desc_support = var['desc_support_' || $voted_address || '_' || $desc_hash] + $balance;
$is_removed_support_from_current_desc = ($current_my_desc_hash AND $current_my_desc_hash == $current_desc_hash);
$current_desc_support = var['desc_support_' || $voted_address || '_' || $current_desc_hash] - $is_removed_support_from_current_desc * $balance;
$current_desc_changed = ($new_desc_support > $current_desc_support);
}
if ($current_desc_changed AND !$is_initial_desc){
$current_url = var['url_' || $current_desc_hash];
$url_changed = ($url != $current_url);
}
}",
"messages": [
{
"if": "{ ($is_initial_desc OR $url_changed) AND $voted_symbol }",
"app": "data",
"payload": {
"address": "{$voted_address}",
"name": "{$voted_symbol}",
"url": "{$url}"
}
},
{
"app": "state",
"state": "{
if (!var['desc_' || $desc_hash]){ // a dictionary: description by its hash
var['desc_' || $desc_hash] = $description;
var['url_' || $desc_hash] = $url;
}
if ($current_my_desc_hash) // remove support from the previous description
var['desc_support_' || $voted_address || '_' || $current_my_desc_hash] -= $balance;
var['desc_choice_' || $voted_address || '_' || trigger.address] = $desc_hash;
var['desc_support_' || $voted_address || '_' || $desc_hash] += $balance;
if ($current_desc_changed){
var['current_desc_' || $voted_address] = $desc_hash;
response['updated_support'] = var['desc_support_' || $voted_address || '_' || $desc_hash];
response['message'] = "Your description is now the current";
}
}"
}
]
},
{
"if": "{trigger.data.move AND trigger.data.wallet_address AND $drawer AND $address AND $symbol}",
"init": "{
$drawer_key = trigger.data.wallet_address || '_' || $drawer || '_' || $symbol || '_' || $address;
$balance = var[$drawer_key];
if (!$balance)
bounce("nothing in this drawer");
$expiry_ts = var[$drawer_key || '_expiry_ts'];
if (!$expiry_ts)
bounce("warm-up period has not started yet");
if (timestamp < $expiry_ts)
bounce("warm-up period has not expired yet");
$drawer_0_key = trigger.data.wallet_address || '_0_' || $symbol || '_' || $address;
}",
"messages": [
{
"app": "state",
"state": "{
var[$drawer_key] = false;
var[$drawer_0_key] += $balance;
var[$drawer_key || '_expiry_ts'] = false; // lock the (empty) drawer again
response['message'] = "Moved " || $balance || " to drawer 0";
}"
}
]
},
{
"if": "{$amount >= $min_amount AND $symbol AND $address }",
"init": "{
$support = var['support_' || $symbol || '_' || $address] + $amount;
$current_address = var['s2a_' || $symbol];
$current_symbol = var['a2s_' || $address];
$current_address_with_largest_support = var['by_largest_s2a_' || $symbol];
$current_symbol_with_largest_support = var['by_largest_a2s_' || $address];
if ($current_address AND !$current_address_with_largest_support) // should never happen
bounce("no current address by largest support?");
if ($current_symbol AND !$current_symbol_with_largest_support) // should never happen
bounce("no current symbol by largest support?");
// by symbol
if (!$current_address_with_largest_support OR $current_address_with_largest_support != $address AND var['support_' || $symbol || '_' || $current_address_with_largest_support] < $support)
$update_by_largest_s2a = true;
$symbol_challenge_expiry_ts = var['expiry_ts_' || $symbol];
if (!$current_address){ // the symbol is not taken yet
$s2a_ready = true;
}
else if ($current_address != $address AND var['support_' || $symbol || '_' || $current_address] < $support){
if (!$symbol_challenge_expiry_ts) // start a challenging period
$schedule_symbol_expiry = true;
else if (timestamp > $symbol_challenge_expiry_ts AND var['by_largest_s2a_' || $symbol] == $address){
$s2a_ready = true;
}
}
else if ($current_address == $address AND var['by_largest_s2a_' || $symbol] == $address AND $symbol_challenge_expiry_ts AND timestamp > $symbol_challenge_expiry_ts)
$end_symbol_expiry = true;
// by address
if (!$current_symbol_with_largest_support OR $current_symbol_with_largest_support != $symbol AND var['support_' || $current_symbol_with_largest_support || '_' || $address] < $support)
$update_by_largest_a2s = true;
$address_challenge_expiry_ts = var['expiry_ts_' || $address];
$current_symbol_support = var['support_' || $current_symbol || '_' || $address];
if (!$current_symbol){
$a2s_ready = true;
}
else if ($current_symbol != $symbol AND $current_symbol_support < $support){
$has_largest_support = ($current_symbol_with_largest_support == $symbol);
$will_have_largest_support = ($has_largest_support OR $update_by_largest_a2s);
$has_overwhelming_support = ($support > $overwhelming_multiplier * $current_symbol_support);
$immediate = $will_have_largest_support AND $has_overwhelming_support AND timestamp < var['grace_expiry_ts_' || $address];
if (!$address_challenge_expiry_ts){ // start a challenging period or apply the change immediately
if ($immediate){
$a2s_ready = true;
}
else
$schedule_address_expiry = true;
}
else if ((timestamp > $address_challenge_expiry_ts OR $immediate) AND $has_largest_support){
$a2s_ready = true;
}
}
else if ($current_symbol == $symbol AND $current_symbol_with_largest_support == $symbol AND $address_challenge_expiry_ts AND timestamp > $address_challenge_expiry_ts)
$end_address_expiry = true;
if ($s2a_ready AND $a2s_ready){
if (!$current_address AND !$current_symbol AND exists($url) AND $description){ // new registration
$initial_desc_hash = sha256($description || $url);
$current_url = $url;
}
else { // address already registered
$current_desc_hash = var['current_desc_' || $address];
if ($current_desc_hash)
$current_url = var['url_' || $current_desc_hash];
}
}
}",
"messages": [
{
"if": "{$s2a_ready AND $a2s_ready AND exists($current_url)}",
"app": "data",
"payload": {
"address": "{$address}",
"name": "{$symbol}",
"url": "{$current_url}"
}
},
{
"app": "state",
"state": "{
var['support_' || $symbol || '_' || $address] = $support;
// by symbol
if ($update_by_largest_s2a)
var['by_largest_s2a_' || $symbol] = $address;
if ($schedule_symbol_expiry)
var['expiry_ts_' || $symbol] = timestamp + $challenging_period;
if ($end_symbol_expiry)
var['expiry_ts_' || $symbol] = false;
// by address
if ($update_by_largest_a2s)
var['by_largest_a2s_' || $address] = $symbol;
if ($schedule_address_expiry)
var['expiry_ts_' || $address] = timestamp + $challenging_period;
if ($end_address_expiry)
var['expiry_ts_' || $address] = false;
// only update both links at the same time
if ($s2a_ready AND $a2s_ready){
// tear old links
if ($current_address)
var['a2s_' || $current_address] = false;
if ($current_symbol)
var['s2a_' || $current_symbol] = false;
// create both new links
var['s2a_' || $symbol] = $address;
var['a2s_' || $address] = $symbol;
response[$symbol] = $address;
response[$address] = $symbol;
if ($symbol_challenge_expiry_ts)
var['expiry_ts_' || $symbol] = false;
if ($address_challenge_expiry_ts)
var['expiry_ts_' || $address] = false;
if (!var['grace_expiry_ts_' || $address]) // first registration
var['grace_expiry_ts_' || $address] = timestamp + $grace_period;
}
$drawer_key = trigger.address || '_' || $drawer || '_' || $symbol || '_' || $address;
var[$drawer_key] += $amount;
response[$drawer_key] = $amount;
if ($drawer)
var[$drawer_key || '_expiry_ts'] = false; // abort any timers for this drawer
var['balance_' || trigger.address || '_' || $address] += $amount;
$desc_hash = var['desc_choice_' || $address || '_' || trigger.address];
if ($desc_hash)
var['desc_support_' || $address || '_' || $desc_hash] += $amount;
if ($initial_desc_hash){
if (!var['desc_' || $initial_desc_hash]){
var['desc_' || $initial_desc_hash] = $description;
var['url_' || $initial_desc_hash] = $url;
}
var['desc_choice_' || $address || '_' || trigger.address] = $initial_desc_hash;
var['desc_support_' || $address || '_' || $initial_desc_hash] = $amount;
var['current_desc_' || $address] = $initial_desc_hash;
response['message'] = "Your description is now the current";
}
}"
}
]
}
]
}
}
]