Definition: [
"autonomous agent",
{
"bounce_fees": {
"base": 10000
},
"init": "{
$aa_name = "SAAFE"; // Safe Autonomous Agent Forwarding Estate;
$aa_owner = "O7NYCFUL5XIJTYE3O4MKGMGMTN6ATQAJ"; // could withdraw the dust is calculable;
$danaa = "LLAVLVFN3CPBHTAB62NOIZLAMPABR2YF"; // Dynamic Asset Name AA;
// Reconstitute the public key by concataining the 2 given parts
$puk = (trigger.data.puk1 AND trigger.data.puk2)? trigger.data.puk1||trigger.data.puk2 : false;
// Reconstitute the signature by concataining the 2 given parts
$signature = (trigger.data.s1 AND trigger.data.s2)? trigger.data.s1||trigger.data.s2 : false;
// Asset detection
$received_unbase_asset = trigger.output[[asset!=base]].asset;
$received_asset = ($received_unbase_asset != "none")? $received_unbase_asset : "base";
$asset = trigger.data.asset otherwise $received_asset;
$asset_nice_name = var[$danaa][$asset] otherwise $asset;
// Drawer ID
$drawer = sha256($puk||"_"||$asset); // to reduce size of the state var.
// short names for state var.
$dr = "drawer_"||$drawer;
$am = $dr||"_amount";
$as = $dr||"_asset";
$pu = $dr||"_private_user";
$ls = "last_s_"||sha256($puk); // last signature used;
}",
"messages": {
"cases": [
{
"if": "{ $puk AND !($signature or trigger.data.ad) }",
"messages": [
{
"app": "state",
"state": "{
if (!var[$as] and trigger.data.private) // only at the creation, to avoid abuses
var[$pu] = trigger.address;
var[$am] += trigger.output[[asset=$asset]].amount;
var[$as] = $asset;
response['message'] = var[$am]||' '||$asset_nice_name||' are safe under the puk '||$puk;
}"
}
]
},
{
"if": "{ $puk AND $signature AND trigger.data.ad }",
"init": "{
// checking
if (var[$pu])
if (var[$pu] != trigger.address)
bounce ("Not allowed to withdraw from this private drawer!");
if (!var[$as]) bounce ("puk doesn\'t exists with asset!"||$asset_nice_name);
if (var[$ls])
if (var[$ls] == sha256($signature))
bounce ("Cannot use 2 times the same signature in a row!");
$formated_puk = "-----BEGIN PUBLIC KEY-----"||$puk||"-----END PUBLIC KEY-----";
if (!is_valid_sig(trigger.data.ad, $formated_puk, $signature))
bounce ("The 'withdraw address' signed is not the same as the one that was asked to use ! or this signature was not created with private key linked to "||$puk||" !");
// balances
$old_balance = var[$am];
$amount = trigger.data.am otherwise $old_balance;
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "{$asset}",
"outputs": [
{
"address": "{trigger.data.ad}",
"amount": "{$amount}"
}
]
}
},
{
"app": "state",
"state": "{
$new_balance = $old_balance - $amount - 999;
response['message'] = $amount||' of the '||$old_balance||' '||$asset_nice_name||' withdrawn from '||$puk||' to '|| trigger.data.ad;
if ($new_balance < 1000) // cleaning
{
var[$am] = false; var[$as] = false; var[$pu] = false;
}
else // storing last sign to avoid abuse
var[$ls] = sha256($signature); //to reduce size
}"
}
]
},
{
"messages": [
{
"app": "state",
"state": "{
if(!($puk))
bounce ("To store or withdraw, you always have to set at least 'puk1' and 'puk2' to the 2 half of the public key, for which you have the related private key");
if(!($signature))
bounce ("To withdraw, set the puks fields, as well as an 'ad' field set to the Obyte adresse where you want to receive the funds and a 's1' and 's2' field set to <the 2 half signature of a message containing the address 'ad'>.");
}"
}
]
}
]
}
}
]