Definition: [
    "autonomous agent",
    {
        "bounce_fees": {
            "base": 10000
        },
        "init": "{
        if (!$FOREVER_CONSTANT){  // FOREVER CONSTANTS  (the if(!) is trick to be able to create blocks)
            $AA_in_debug_mode = true;
            $owner = 'MYESSCFGDERS3YIEGNZDOG2BI5HKQHLU';
            $domain_creation_fee = 500000;          // 500,000.0 bytes
            $requesting_reputation_fee = 0;            // 10,000.0 bytes
            $reward_pourcentage = 1;                // 1% of the balance for an evalution of an attested address
            $symbolic_reward= 10;                    // for evaluation of not attested address 
            $evaluation_delay = 2*24*60*60*30;        // 30 days
            $default_domain = 'base';
            $default_attestor = '35IT3ZYKEPQSCXG2F7A7KWNRAD3SZXN4'; //'UOYYSPEE7UUW3KJAB5F4Y4AWMYMDDB4Y'; // official attestor
            $mode_uwa = 'uwa'; $mode_twa = 'twa'; $mode_cbwa = 'cbwa'; $mode_crwa = 'crwa';
            $default_mode_of_average = $mode_uwa;
            $message_creation_howto ='set \'creation\' to ['||$mode_uwa||', '||$mode_twa||', '||$mode_cbwa||', '||$mode_crwa||']';
        }
        if (!$TRIGGER_INFO){   // info coming from the triggering transaction
            $input_is_test_mode = trigger.data.testmode otherwise trigger.data.tm otherwise false;
            $user_address = trigger.address;                         // Attested user (if evaluator)
            $evaluated_address = trigger.data.adress otherwise    trigger.data.ad;     
            $domain = trigger.data.domain otherwise    trigger.data.do otherwise $default_domain;           // Evaluation domain
            $attestor_address = trigger.data.attestor otherwise trigger.data.at otherwise $default_attestor;
            $evaluation = trigger.data.evaluation otherwise trigger.data.ev;                             // Evaluation: 0-5 or ?
            $mode_of_average_for_creation = trigger.data.creation otherwise trigger.data.cr otherwise false;
            if ($AA_in_debug_mode){
                $TRIGGER_INFO = 'At the begining there was a user ('||$user_address||') interested in a seller('|| $evaluated_address ||') in a given domain ('|| $domain ||') in the scope of an attestor ('|| $attestor_address ||'), the evaluation is set to ('|| $evaluation ||'), the user could try to initial the test mode ('|| $input_is_test_mode ||'). ';
                
                response['TRIGGER_INFO'] = $TRIGGER_INFO;
            }
        }
        if (!$HASHES){  // hashing to avoid to store the reputation openely in the dag (euh why?)
            $user_address_hash = sha256($user_address);
            $evaluated_address_hash = sha256($evaluated_address);
            $domain_hash = sha256($domain);
            $attestor_hash = sha256($attestor);
            $attested_domain = sha256($domain_hash and $attestor_hash);
            $evaluation_hash = sha256($attested_domain and $evaluated_address_hash and $user_address_hash);
            $reputation_hash = sha256(($attested_domain and $evaluated_address_hash) || 'reputation');
            $evaluation_count_hash = sha256(($attested_domain and $evaluated_address_hash) || 'count');
            // confuse attested address in the dag to avoid to gather information for free 
            // is it even possible ? $evaluated_address_confused = $evaluated_address(2);
            if ($AA_in_debug_mode){
                $HASHES= 'user hash is ('|| $user_address_hash ||') seller ('|| $evaluated_address_hash ||') domain ('|| $domain_hash ||') attestor ('|| $attestor_hash ||') attested_domain ('|| $attested_domain ||'). The evaluation hash for the AD and this pair of user is ('|| $evaluation_hash ||') seller reputation hash is ('|| $reputation_hash ||') number of evaluation for this seller hash is ('|| $evaluation_count_hash ||'). ';
                
                response['HASHES'] = $HASHES;
            }
        }
        if (!$INITIAL_DAG_STATE){ //  aka state variables
            $state_var_is_test_mode = var['is_test_mode'];
            $attested_domain_exist_in_dag = var['coad('||$attested_domain];
            $attested_domain_exist = ($attested_domain_exist_in_dag) ? true:false;
            $balance_in_attestor_scope = var['bo('||$attestor_hash] otherwise 0; 
            $reputation = var['ro('||$reputation_hash] otherwise -1;
            $eval_count = var['eco('||$evaluation_count_hash] otherwise 0;
            $previous_evaluation = var['leo('||$evaluation_hash] otherwise -1;
            $is_re_evaluation = ($previous_evaluation != -1); // this return false if the var doesn't exist
            $mode_of_average= var['moa('||$attested_domain] otherwise $default_mode_of_average;
            
            if ($AA_in_debug_mode){
                $INITIAL_DAG_STATE = 'Is test mode activated to allow unattested user to vote? ('|| $state_var_is_test_mode || '). It is ('|| $attested_domain_exist || '(' || var['coad('||$attested_domain] ||')) that the attested domain exist. The balance for this attestor scope is ('|| $balance_in_attestor_scope || '(' || var['bo('||$attestor_hash] || ')). The reputation of the seller is ('|| $reputation || '(' || var['ro('||$reputation_hash] || ')) with ('|| $eval_count|| '(' || var['eco('||$evaluation_count_hash] ||')) votes. The previous evaluation of the seller from this user is ('|| $previous_evaluation|| '(' || var['le(=)'||$evaluation_hash] ||')) so it is ('|| $is_re_evaluation || ') to says that it is a re-evaluation. ';
                response['INITIAL_DAG_STATE'] = $INITIAL_DAG_STATE;
            }
        }
        if (!$PRELIMINARY_CHECKS){   // Preliminary checks and deductions
            // test mode?
            if ($user_address==$owner)
                $is_test_mode = $input_is_test_mode otherwise $state_var_is_test_mode otherwise false;
            else
                $is_test_mode = var['is_test_mode'] otherwise false;
            // function?
            $is_creating= $mode_of_average_for_creation? true:false;
            $is_requesting = $evaluation == '?';
            $is_contributing = (!$is_requesting) ? $evaluation >= 0 and $evaluation <= 5 : false;
            // attested domain?
            $attested_default_domain = ($domain == $default_domain) and ($attestor_address == $default_attestor);
            // Preliminary checks
            if(!$is_requesting and !$is_contributing)
                bounce('Sorry, You have to specify a \'evaluation\' field in the data section. Use \'0\' to \'5\' to evaluate an address or use \'?\' to request the reputation of an address.'); // (money - bounce fee) is return automatically
            if(!$evaluated_address)
                bounce('Sorry, You have to specify which address you want to find reputation for. Please add an \'address\' field in the data section.');
            // Fee checks
            $fee_received = trigger.output[[asset=base]].amount;
            $is_creation_fee_received = $fee_received > $domain_creation_fee;
            $is_requesting_fee_received = $fee_received > $requesting_reputation_fee;
            if ($AA_in_debug_mode){
                $PRELIMINARY_CHECKS= 'The test mode is set to ('|| $is_test_mode ||') requesting mode to ('|| $is_requesting ||') contributing mode to ('|| $is_contributing ||') this is ('|| $attested_default_domain ||') to say that we will work with the default attested domain. The fee received is ('|| $fee_received ||') ok for creation? ('|| $is_creation_fee_received ||') ok for requesting a reputation? ('|| $is_requesting_fee_received ||'). ';
                response['PRELIMINARY_CHECKS'] = $PRELIMINARY_CHECKS;
            }
        }
        if (!$ATTESTATIONS){ // Attestation checks
            $evaluated_is_attested = attestation[[attestors=$attestor_address, address=$evaluated_address, ifnone=0]];
            $user_is_attested = attestation[[attestors=$attestor_address, address=$user_address, ifnone=0]];
            if ($AA_in_debug_mode){
                $ATTESTATIONS = 'User attestation is ('|| $user_is_attested ||') and seller attestation is ('|| $evaluated_is_attested ||'). ';
                response['ATTESTATIONS'] = $ATTESTATIONS;
            }
        }
        
    }",
        "messages": {
            "cases": [
                {
                    "if": "{$is_requesting}",
                    "init": "{
                    if (!$REQUESTING_CHECKS){ //
                        if (!$attested_domain_exist and !$attested_default_domain)
                            bounce('Sorry, You have requested reputation for a domain-attestor pair that do not exist.');
                        $reputationExists = ($reputation != -1);
                        if (!$reputationExists)
                            bounce('Sorry, the address (user) do not have reputation in this domain-attestor pair yet. Please consider to rate this user once you interacted with him/her.');
                        if (!$is_requesting_fee_received)
                            bounce('Sorry, The fee to request a reputation is '|| $requesting_reputation_fee || 'bytes');
                        if ($AA_in_debug_mode){
                            $REQUESTING_CHECKS = 'User attestation is ('|| $user_is_attested ||') and seller attestation is ('|| $evaluated_is_attested ||'). ';
                            response['REQUESTING_CHECKS'] = $REQUESTING_CHECKS;
                        }
                    }
                    
                    if (!$RETURNING_REPUTATION){ // Respond
                        $reputation_to_show = round($reputation,1);
                        $message_about_reputation ='Reputation for domain \''|| $domain ||'\' is '||$reputation_to_show||'/5 from ' || $eval_count ||  'votes. ';
                        if ($evaluated_is_attested)
                            $message_about_attestation = 'and the address is attested by \''||$attestor_address||'\'). ';
                        else
                            $message_about_attestation = 'BUT the address is NOT attested by \''||$attestor_address||'\')! ';
                        
                        response['message'] = $message_about_reputation || $message_about_attestation;
                        response['domain'] = $domain;
                        response['attestor'] = $attestor_address;
                        response['reputation'] = $reputation_to_show;
                        response['evaluation_count'] = $eval_count;
                        response['attested'] = $evaluated_is_attested;
                        if ($AA_in_debug_mode){
                            $RETURNING_REPUTATION = $message_about_reputation || $message_about_attestation;
                            response['RETURNING_REPUTATION'] = $RETURNING_REPUTATION;
                        }
                    }
                }",
                    "messages": [
                        {
                            "app": "data",
                            "payload": {
                                "message": "{$message}",
                                "domain": "{$domain}",
                                "attestor": "{$attestor_address}",
                                "reputation": "{$reputation}",
                                "evaluation_count": "{$evaluation_count}",
                                "attested": "{$attested}"
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            if (!$FINAL_DAG_STATE){ //
                                $saved_fee = trigger.output[[asset=base]].amount - 1000; // 1000 is the data transfert fee approximation
                                var['bo('||$attestor_hash] += $saved_fee;
                                var['is_test_mode'] = $is_test_mode;
                                if ($AA_in_debug_mode){
                                    $FINAL_DAG_STATE = 'After the requesting, the new balance for this attestor scope is('|| var['bo('||$attestor_hash] ||') bytes, it added ('|| $saved_fee ||') bytes. The test mode will be activated? ('|| $is_test_mode ||'). ';
                                    response['FINAL_DAG_STATE'] = $FINAL_DAG_STATE;
                                }
                            }
                        }"
                        }
                    ]
                },
                {
                    "if": "{$is_creating}",
                    "init": "{
                    if (!$DOMAIN_CREATION){ //
                        // Domain exist? bounce
                        if ($attested_domain_exist)
                            bounce('Sorry, The domain \''||$domain||'\' in the scope of the attestor \''||$attestor_address||'\' already exist. ');
                        // prepare meesages
                        $message_about_creation_requirements = 'In creation mode you should '||$message_creation_howto||' and you should not specify any \'evaluation\'. ';
                        // to much param? bounce
                        if($is_creating or $is_contributing)
                            bounce('Sorry, '|| $message_about_creation_requirements);
                        // check if creation mode ok
                        if(($moa != $mode_uwa) and ($moa != $mode_twa) and ($moa != $mode_cbwa) and ($moa != $mode_crwa))
                            bounce('Sorry, '|| $message_about_creation_requirements);
                        $ok_to_create_domain=true;
                        $message_about_creation = 'The domain \''||$domain||'\' has been created in the scope of the attestor \''||$attestor_address||'\' with the average mode \''||$mode_of_average_for_creation||'\'. ';
                        
                        if ($AA_in_debug_mode){
                            $DOMAIN_CREATION = $message_about_creation;
                            response['DOMAIN_CREATION'] = $DOMAIN_CREATION;
                        }
                    }
                }",
                    "messages": [
                        {
                            "app": "data",
                            "payload": {
                                "domain": "{$domain}",
                                "attestor": "{$attestor_address}"
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            if (!$FINAL_DAG_STATE){ //
                                $saved_fee = trigger.output[[asset=base]].amount - 1000; // 1000 is the data transfert fee approximation
                                var['coad('||$attested_domain]=$user_address_hash;    // creating the var.
                                var['moa('||$attested_domain]=$mode_of_average;
                                var['bo('||$attestor_hash] += $saved_fee;
                                var['is_test_mode'] = $is_test_mode;
                                if ($AA_in_debug_mode){
                                    $FINAL_DAG_STATE = 'After creation of the new, domain the new balance for this attestor scope is('|| var['bo('||$attestor_hash] ||') bytes, it added ('|| $saved_fee ||') bytes. The test mode will be activated? ('|| $is_test_mode ||'). ';
                                    response['FINAL_DAG_STATE'] = $FINAL_DAG_STATE;
                                }
                            }
                        }"
                        }
                    ]
                },
                {
                    "if": "{$is_contributing}",
                    "init": "{
                    if (!$CONTRIBUTION_CHECKING){ //
                        if (!$attested_domain_exist)
                            bounce('Sorry, the domain-attestor pair do not exists. It can be created if you ' || $message_creation_howto || ' but the fee is \''||$domain_creation_fee || '\' bytes, this money will be used to reward the evaluators. '|| $PRELIMINARY_CHECKS);
                        
                        if (!$user_is_attested)
                        {
                            if(!$is_test_mode)
                                bounce('Sorry, to be able to give an evaluation you need to be attested by the following attestor: \''|| $attestor_address || '\' or it will be too easy to pump a reputation.');
                            if($is_test_mode)
                                $message_about_testing ='Normally, a user not attested by the attestor linked to a domain should not be able to vote, but as you are in test mode you will be able to vote. ';
                            else
                                $message_about_testing ='';
                        }
                        if ($AA_in_debug_mode){
                            $CONTRIBUTION_CHECKING = $message_about_testing;
                            response['CONTRIBUTION_CHECKING'] = $CONTRIBUTION_CHECKING;
                        }
                    }
                    
                    if (!$REWARD_COMPUTATION){ // calculating reward
                        if ($evaluated_is_attested){
                            $reward = round($balance_in_attestor_scope* $reward_pourcentage /100);
                            $message_about_the_reward = 'The reward is '||$reward_pourcentage||'% of the attested scope which is '|| $balance_in_attestor_scope ||" bytes. ";
                         }
                         else{ 
                             $reward = $symbolic_reward;
                             $message_about_the_reward = 'The reward is symbolic because you are not attested by '|| $attestor_address||'. ';
                         }
                        if ($AA_in_debug_mode){
                            $REWARD_COMPUTATION = 'The reward will be ('|| $reward ||'). '|| $message_about_the_reward ||'. ';
            
                            response['REWARD_COMPUTATION'] = $REWARD_COMPUTATION;
                        }
                    }
                    
                    if (!$REPUTATION_COMPUTATION){ // compute new reputation
                        $reputation_corrected = ($reputation == -1)? 0: $reputation;
                        if ($mode_of_average)    { // == $mode_uwa) {
                            $total_score=($reputation * $eval_count);
                                    
                            if ($is_re_evaluation){
                                $new_reputation = ($total_score + ($evaluation-$previous_evaluation) / ($eval_count));
                                $message_about_re_evaluation = 'Your evaluation was changed from '||$previous_evaluation||' to '||$evaluation||'. ';
                                $new_eval_count = $eval_count;
                                $message_about_number_of_eval = 'The number of votes for this address is still '||$new_eval_count||'. ';
                            }
                            else{
                                $new_reputation = ($total_score + $evaluation) / ($eval_count+1);
                                $message_about_re_evaluation = '';
                                $new_eval_count = $eval_count+1;
                                $message_about_number_of_eval = '('||$new_eval_count||' votes attested for this address. ';
                            }
                        }
                        $reputation_to_show = round($new_reputation,1);
                        if ($AA_in_debug_mode){
                            $REPUTATION_COMPUTATION = 'the new reputation is ('|| $new_reputation ||'('|| $reputation_to_show ||')). ';
                            response['REPUTATION_COMPUTATION'] = $REPUTATION_COMPUTATION;
                        }
                        
                    }
                    
                    if (!$RESPONSE_CREATION){ // create message
                        
                        $message = $message_about_testing||$message_about_domain||'Thank you for your contribution, a reward of '||$reward||' byte have been sent to you ('||$user_address||'). '|| $message_about_the_reward || 'The new reputation of '||$evaluated_address||' is now ('||$reputation_to_show||'/5). '|| $message_about_re_evaluation || $message_about_number_of_eval;
                        response['message'] = $message;
                        response['domain'] = $domain;
                        response['attestor'] = $attestor_address;
                        response['vote_from'] = $user_address;
                        if ($is_re_evaluation)
                        {
                            response['old_evaluation'] = $previous_evaluation;
                            response['new_evaluation'] = $evaluation;
                        }
                        else
                            response['evaluation'] = $evaluation;
                        response['old_reputation'] = $reputation;
                        response['new_reputation'] = $new_reputation;
                        response['attested'] = $evaluated_is_attested;
                        if ($AA_in_debug_mode){    
                            $RESPONSE_CREATION = 'The message to the user will be ('|| $message ||'). ';
                            response['RESPONSE_CREATION'] = $RESPONSE_CREATION;
                        }
                    }
                }",
                    "messages": [
                        {
                            "app": "payment",
                            "payload": {
                                "asset": "{'base'}",
                                "outputs": [
                                    {
                                        "address": "{trigger.address}",
                                        "amount": "{$reward}"
                                    }
                                ]
                            }
                        },
                        {
                            "app": "state",
                            "state": "{
                            
                            if (!$FINAL_DAG_STATE){ //
                                var['ro('||$reputation_hash] = $new_reputation;
                                var['eco('||$evaluation_count_hash] = $new_eval_count; 
                                var['leo('||$evaluation_hash] = $evaluation;            // last evaluation for later revote
                                var['bo('||$attestor_hash] = $balance_in_attestor_scope - $reward;        // attestor balance
                                var['is_test_mode'] = $is_test_mode;
                                if ($AA_in_debug_mode){
                                    $FINAL_DAG_STATE = 'Finally the state of the DAG is: the new reputation of the seller is ('|| $new_reputation ||') with a number of vote of ('|| $new_eval_count ||'), the last evaluation saved from this user will be ('|| $evaluation ||'). The new balance available in the scope is ('|| var['bo('||$attestor_hash] ||'). The test mode will be activated? ('|| $is_test_mode ||'). ';
                                    response['FINAL_DAG_STATE'] = $FINAL_DAG_STATE;
                                }
                                
                            }    
                        }"
                        }
                    ]
                }
            ]
        }
    }
]