Unit ID
Y+3QGh1jq5giJiAIP9al5Phx/l8I3Tw2CkiQ2jTH+Lc=
Received
15.04.2020 12:10:57
Confirmation delay (full node)
17 minutes 5 seconds
Confirmation delay (light node)
24 minutes 21 seconds
Messages
Definition
Definition: [ "autonomous agent", { "doc_url": "https://obyte.org/token-registry.json", "init": "{ $challenging_period = 30*24*3600; $grace_period = 30*24*3600; // new assets 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_upper($symbol)) bounce("symbol must be uppercase"); if (length($symbol) > 40) bounce("symbol must be max 40 characters long"); if ($symbol == 'GBYTE' OR $symbol == 'MBYTE' OR $symbol == 'KBYTE' OR $symbol == 'BYTE' OR $symbol == 'TBYTE') bounce("reserved symbol"); } $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"); } $decimals = trigger.data.decimals; if (exists($decimals)){ if (!is_integer($decimals)) bounce("decimals must be integer"); if ($decimals < 0 OR $decimals > 15) bounce("decimals must be between 0 and 15"); } $asset = trigger.data.asset; if ($asset){ if (typeof($asset) != 'string') bounce("asset must be string"); if (!asset[$asset].exists) bounce("asset " || $asset || " does not exist"); } }", "messages": { "cases": [ { "if": "{ trigger.data.withdraw AND trigger.data.amount AND $asset AND $symbol }", "init": "{ $drawer_key = trigger.address || '_' || $drawer || '_' || $symbol || '_' || $asset; 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 || '_' || $asset] -= 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 || '_' || $asset] -= trigger.data.amount; $desc_hash = var['desc_choice_' || $asset || '_' || trigger.address]; if ($desc_hash) var['desc_support_' || $asset || '_' || $desc_hash] -= trigger.data.amount; } else if (!$expiry_ts) var[$drawer_key || '_expiry_ts'] = timestamp + $drawer * 24 * 3600; }" } ] }, { "if": "{$description AND exists($decimals) AND ($asset OR $symbol) AND $amount < $min_amount}", "init": "{ if ($asset){ $voted_asset = $asset; $voted_symbol = var['a2s_' || $voted_asset]; } else { $voted_asset = var['s2a_' || $symbol]; if (!$voted_asset) bounce("no asset found by symbol " || $symbol); $voted_symbol = $symbol; } $balance = var['balance_' || trigger.address || '_' || $voted_asset]; if (!$balance) bounce("you have no balance in this asset"); $desc_hash = sha256($description || $decimals); $current_my_desc_hash = var['desc_choice_' || $voted_asset || '_' || trigger.address]; $current_desc_hash = var['current_desc_' || $voted_asset]; $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_asset || '_' || $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_asset || '_' || $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_decimals = var['decimals_' || $current_desc_hash]; $decimals_changed = ($decimals != $current_decimals); } }", "messages": [ { "if": "{ ($is_initial_desc OR $decimals_changed) AND $voted_symbol }", "app": "data", "payload": { "asset": "{$voted_asset}", "name": "{$voted_symbol}", "decimals": "{$decimals}" } }, { "app": "state", "state": "{ if (!var['desc_' || $desc_hash]){ // a dictionary: description by its hash var['desc_' || $desc_hash] = $description; var['decimals_' || $desc_hash] = $decimals; } if ($current_my_desc_hash) // remove support from the previous description var['desc_support_' || $voted_asset || '_' || $current_my_desc_hash] -= $balance; var['desc_choice_' || $voted_asset || '_' || trigger.address] = $desc_hash; var['desc_support_' || $voted_asset || '_' || $desc_hash] += $balance; if ($current_desc_changed){ var['current_desc_' || $voted_asset] = $desc_hash; response['updated_support'] = var['desc_support_' || $voted_asset || '_' || $desc_hash]; response['message'] = "Your description is now the current"; } }" } ] }, { "if": "{trigger.data.move AND trigger.data.address AND $drawer AND $asset AND $symbol}", "init": "{ $drawer_key = trigger.data.address || '_' || $drawer || '_' || $symbol || '_' || $asset; $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.address || '_0_' || $symbol || '_' || $asset; }", "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 $asset }", "init": "{ $support = var['support_' || $symbol || '_' || $asset] + $amount; $current_asset = var['s2a_' || $symbol]; $current_symbol = var['a2s_' || $asset]; $current_asset_with_largest_support = var['by_largest_s2a_' || $symbol]; $current_symbol_with_largest_support = var['by_largest_a2s_' || $asset]; if ($current_asset AND !$current_asset_with_largest_support) // should never happen bounce("no current asset 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_asset_with_largest_support OR $current_asset_with_largest_support != $asset AND var['support_' || $symbol || '_' || $current_asset_with_largest_support] < $support) $update_by_largest_s2a = true; $symbol_challenge_expiry_ts = var['expiry_ts_' || $symbol]; if (!$current_asset){ // the symbol is not taken yet $s2a_ready = true; } else if ($current_asset != $asset AND var['support_' || $symbol || '_' || $current_asset] < $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] == $asset){ $s2a_ready = true; } } else if ($current_asset == $asset AND var['by_largest_s2a_' || $symbol] == $asset AND $symbol_challenge_expiry_ts AND timestamp > $symbol_challenge_expiry_ts) $end_symbol_expiry = true; // by asset if (!$current_symbol_with_largest_support OR $current_symbol_with_largest_support != $symbol AND var['support_' || $current_symbol_with_largest_support || '_' || $asset] < $support) $update_by_largest_a2s = true; $asset_challenge_expiry_ts = var['expiry_ts_' || $asset]; $current_symbol_support = var['support_' || $current_symbol || '_' || $asset]; 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_' || $asset]; if (!$asset_challenge_expiry_ts){ // start a challenging period or apply the change immediately if ($immediate){ $a2s_ready = true; } else $schedule_asset_expiry = true; } else if ((timestamp > $asset_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 $asset_challenge_expiry_ts AND timestamp > $asset_challenge_expiry_ts) $end_asset_expiry = true; if ($s2a_ready AND $a2s_ready){ if (!$current_asset AND !$current_symbol AND exists($decimals) AND $description){ // new registration $initial_desc_hash = sha256($description || $decimals); $current_decimals = $decimals; } else { // asset already registered $current_desc_hash = var['current_desc_' || $asset]; if ($current_desc_hash) $current_decimals = var['decimals_' || $current_desc_hash]; } } }", "messages": [ { "if": "{$s2a_ready AND $a2s_ready AND exists($current_decimals)}", "app": "data", "payload": { "asset": "{$asset}", "name": "{$symbol}", "decimals": "{$current_decimals}" } }, { "app": "state", "state": "{ var['support_' || $symbol || '_' || $asset] = $support; // by symbol if ($update_by_largest_s2a) var['by_largest_s2a_' || $symbol] = $asset; if ($schedule_symbol_expiry) var['expiry_ts_' || $symbol] = timestamp + $challenging_period; if ($end_symbol_expiry) var['expiry_ts_' || $symbol] = false; // by asset if ($update_by_largest_a2s) var['by_largest_a2s_' || $asset] = $symbol; if ($schedule_asset_expiry) var['expiry_ts_' || $asset] = timestamp + $challenging_period; if ($end_asset_expiry) var['expiry_ts_' || $asset] = false; // only update both links at the same time if ($s2a_ready AND $a2s_ready){ // tear old links if ($current_asset) var['a2s_' || $current_asset] = false; if ($current_symbol) var['s2a_' || $current_symbol] = false; // create both new links var['s2a_' || $symbol] = $asset; var['a2s_' || $asset] = $symbol; response[$symbol] = $asset; response[$asset] = $symbol; if ($symbol_challenge_expiry_ts) var['expiry_ts_' || $symbol] = false; if ($asset_challenge_expiry_ts) var['expiry_ts_' || $asset] = false; if (!var['grace_expiry_ts_' || $asset]) // first registration var['grace_expiry_ts_' || $asset] = timestamp + $grace_period; } $drawer_key = trigger.address || '_' || $drawer || '_' || $symbol || '_' || $asset; 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 || '_' || $asset] += $amount; $desc_hash = var['desc_choice_' || $asset || '_' || trigger.address]; if ($desc_hash) var['desc_support_' || $asset || '_' || $desc_hash] += $amount; if ($initial_desc_hash){ if (!var['desc_' || $initial_desc_hash]){ var['desc_' || $initial_desc_hash] = $description; var['decimals_' || $initial_desc_hash] = $decimals; } var['desc_choice_' || $asset || '_' || trigger.address] = $initial_desc_hash; var['desc_support_' || $asset || '_' || $initial_desc_hash] = $amount; var['current_desc_' || $asset] = $initial_desc_hash; response['message'] = "Your description is now the current"; } }" } ] } ] } } ]
Technical information
Fees:
13,163 bytes
(352 headers, 12811 payload)
Level:5464514
Witnessed level:5464505
Main chain index:5321619
Latest included mc index:5321618
Status:stable/confirmed/final