Unit ID
qoSDTuBdfFm67PGo7W4Lg92XqhTLYeHAQqC3YuSvzAE=
Received
29.11.2019 09:48:33
Confirmation delay (full node)
2 minutes 7 seconds
Confirmation delay (light node)
5 minutes 30 seconds
Messages
Definition
Definition: [ "autonomous agent", { "init": "{ if (trigger.output[[asset!=base]].asset != 'none') bounce('foreign coins'); $payment_amount = trigger.output[[asset=base]]; $min_reward = 1e5; $coef = 1.5; $overpayment_fee = 1000; $min_delay_before_deadline = 15*60; $period_length = 3600; // $period_length = 3*24*3600; $question = trigger.data.question; $additional_description = trigger.data.description; $question_id = trigger.data.question_id; $outcome = trigger.data.outcome; if ($question AND trigger.data.question_id) bounce("Question and question_id not allowed together"); if (!$question AND !trigger.data.question_id) bounce("No question nor key"); if ($question AND length($question) > 256) bounce("Question cannot be over 256 chars"); if ($question AND contains($question, '_')) bounce('Question cannot contain underscore'); if ($additional_description AND length($additional_description) > 256) bounce("Additional description cannot be over 256 chars"); if ($additional_description AND contains($additional_description, '_')) bounce('Additional description cannot contain underscore'); if ($question_id AND !var[$question_id]) bounce("This question doesn't exist"); if ($outcome AND $outcome != "no" AND $outcome != "yes") bounce("Outcome must be yes or no"); if ($question_id AND !$outcome AND !trigger.data.withdraw) bounce("You must either provide an outcome, commit or withdraw"); }", "messages": { "cases": [ { "if": "{$question}", "init": "{ if ($payment_amount < $min_reward) bounce("Reward must be at least "||$min_reward||" bytes"); $key = "k_"||substring(sha256($question||' '||$additional_description||' '||$payment_amount),0,16); if (var[$key]) bounce("This question already exists"); if (!trigger.data.deadline) bounce("You must specify a deadline"); $deadline = json_parse(trigger.data.deadline); if (!is_integer($deadline)) bounce("Deadline must be an integer"); if ($deadline < timestamp + $min_delay_before_deadline) bounce("Deadline must be at least "||$min_delay_before_deadline||" seconds from now"); }", "messages": [ { "app": "state", "state": "{ var[$key] = "created"; var[$key||"_question"] = $question; var[$key||"_deadline"] = $deadline; var[$key||"_reward"] = $payment_amount; response['your_address'] = trigger.address; response['new_question'] = $question; response['question_id'] = $key; }" } ] }, { "if": "{$outcome AND $question_id}", "init": "{ $key = $question_id; if (var[$key||"_deadline"] > timestamp) bounce("Deadline isn't reached, cannot be graded yet"); if(var[$key||'_outcome']){ // it's a counterstake if(var[$key||'_outcome'] == $outcome) bounce("Question is already graded with this outcome"); if (timestamp - var[$key || '_countdown_start'] > $period_length) bounce('challenging period expired'); $current_outcome = var[$key || '_outcome']; $stake_on_current_outcome = var[$key || '_total_staked_on_' || $current_outcome]; $stake_on_proposed_outcome = var[$key || '_total_staked_on_' || $outcome]; $required_to_challenge = round($coef * $stake_on_current_outcome); $would_override_current_outcome = ($stake_on_proposed_outcome + $amount >= $required_to_challenge); if ($would_override_current_outcome) $excess = $stake_on_proposed_outcome + $amount - $required_to_challenge; } else { if ($payment_amount < var[$key||"_reward"]) bounce("You must stake at least "||$min_reward||" bytes to grade this question"); $excess = $payment_amount - $min_reward; $bInitialStake = true; } }", "messages": [ { "if": "{$excess}", "app": "payment", "payload": { "asset": "base", "outputs": [ { "address": "{trigger.address}", "amount": "{$excess - $overpayment_fee}" } ] } }, { "app": "state", "state": "{ var[$key] = "being_graded"; if ($bInitialStake || $would_override_current_outcome) var[$key||'_outcome'] = $outcome; $accepted_amount = $payment_amount - $excess; var[$key||'_total_staked_on_'||$outcome] += $accepted_amount; var[$key || '_total_staked'] += $accepted_amount; var[$key || '_total_staked_on_' || $outcome || '_by_' || trigger.address] = $accepted_amount; var[$key || '_countdown_start'] = timestamp; if ($bInitialStake){ var[$key || '_initial_reporter'] = trigger.address; response['expected_reward'] = var[$key||"_reward"]; } response['your_address'] = trigger.address; response['your_stake'] = var[$key || '_total_staked_on_' || $outcome || '_by_' || trigger.address]; response['total_staked_on_yes'] = var[$key || '_total_staked_on_yes'] otherwise 0; response['total_staked_on_no'] = var[$key || '_total_staked_on_no'] otherwise 0; response['question_id'] = $key; response['reporting'] = $outcome; }" } ] }, { "if": "{trigger.data.commit AND $question_id}", "init": "{ if (var[$key] == 'committed') bounce('already committed'); if (timestamp - var[$key || '_countdown_start'] <= $period_length) bounce('challenge period is still running'); $outcome = var[$key || '_outcome']; // immediately pay to the initial reporter. Other stakers (if any) will have to manually request withdrawals $address = var[$key || '_initial_reporter']; $initial_reporter_stake = var[$key || '_total_staked_on_' || $outcome || '_by_' || $address]; if ($initial_reporter_stake){ $reward = var[$key||"_reward"]; $total_winning_stake = var[$key || '_total_staked_on_' || $outcome]; $total_stake = var[$key || '_total_staked']; $full_amount = round($initial_reporter_stake / $total_winning_stake * ($total_stake + $rewar)); } }", "messages": [ { "app": "data_feed", "payload": { "{$key}": "{$outcome}" } }, { "if": "{$initial_reporter_stake}", "app": "payment", "payload": { "asset": "base", "outputs": [ { "address": "{$address}", "amount": "{$full_amount}" } ] } }, { "app": "state", "state": "{ var[$key] = 'committed'; var[$pair||"_committed_outcome"] = $outcome; if ($initial_reporter_stake){ var[$key || '_total_staked_on_' || $outcome || '_by_' || $address] = false; response['paid_out_amount'] = $full_amount; response['paid_out_address'] = $address; } response['question_id'] = $key; response['committed_outcome'] = $outcome; }" } ] }, { "if": "{trigger.data.withdraw AND $question_id}", "init": "{ if (var[$key] != 'committed') bounce('not committed yet'); $address = trigger.data.address otherwise trigger.address; // withdrawal can be triggered by anybody $outcome = var[$key || '_outcome']; $my_stake = var[$key || '_total_staked_on_' || $outcome || '_by_' || $address]; if (!$my_stake) bounce("you didn't stake on the winning outcome or you already withdrew"); $reward = var[$key||"_reward"]; $total_winning_stake = var[$key || '_total_staked_on_' || $outcome]; $total_stake = var[$key || '_total_staked']; $full_amount = round($my_stake / $total_winning_stake * ($total_stake + $reward)); }", "messages": [ { "app": "payment", "payload": { "asset": "base", "outputs": [ { "address": "{$address}", "amount": "{$full_amount}" } ] } }, { "app": "state", "state": "{ var[$key || '_total_staked_on_' || $outcome || '_by_' || $address] = false; response['message'] = "paid " || $amount || " bytes"; response['question_id'] = $key; response['paid_out_amount'] = $full_amount; response['paid_out_address'] = $address; }" } ] }, { "if": "{trigger.data.nickname}", "messages": [ { "app": "state", "state": "{ var['nickname_' || trigger.address] = trigger.data.nickname; response['your_address'] = trigger.address; response['nickname'] = trigger.data.nickname; response['message'] = "Nickname changed for " || trigger.data.nickname; }" } ] } ] } } ]
Technical information
Fees:
10,527 bytes
(353 headers, 10174 payload)
Level:1149628
Witnessed level:1149619
Main chain index:1148367
Latest included mc index:1148366
Status:stable/confirmed/final