[
"autonomous agent",
{
"getters": "{
//DIMENSIONS
$x = ()=>params.x; //Current canvas height
$y = ()=>params.y; //Current canvas width
//TOKENS
$rt = ()=>"Bx0MWol5P4jWKfqkl38KkGOgaKKA/Jwxz4k1if1V2T4="; //Asset id of red token
$gt = ()=>"PuQix92btvdVs8hYu0PDZ0iUNN6JcDpETgSQcnhEhZw="; //Asset id of green token
$bt = ()=>"UHkxLRnDP6WCrIzoqnqYr+bKwuyvP/JIamop6K6uGx4="; //Asset id of blue token
$vt = ()=>"c8QUsXz0oYki50q7J8ylE3k47PDAss1U5YTgDlZlR6M="; //Asset id of varnish token
//BALANCES
$r = ()=>balance[$rt()] OTHERWISE 0; //Current red paint amount in use
$g = ()=>var[$gt()] OTHERWISE 0; //Current green paint amount in use
$b = ()=>var[$bt()] OTHERWISE 0; //Current blue paint amount in use
$v = ()=>balance[$vt()] OTHERWISE 0; //Varnish balance of instance
//$rt = ()=>var[$patternAddress()]["rt"]; //Asset id of red token
//$gt = ()=>var[$patternAddress()]["gt"]; //Asset id of green token
//$bt = ()=>var[$patternAddress()]["bt"]; //Asset id of blue token
//$vt = ()=>var[$patternAddress()]["vt"]; //Asset id of varnish token
$shares = ()=>var["shares"] OTHERWISE 0; //A share allows its holder to receive a proportional amount of painting when a painting is scrapped
$patternAddress = ()=>{
$base = definition[this_address][1].base_aa;
return $base OTHERWISE this_address;
};
$name = ()=>params.name; //Canvas name
$sharesOf = ($address)=>var["shares_" || $address];
$immortalizeCost = ()=>max($v()*2, (params.immortalizeCost OTHERWISE 0));
$isImmortalized = ()=>var["immortalized"];
$getTokenId = ()=>var["tokenId"];
$getUpdatedPixels = ()=>var["lifetime_updates"] OTHERWISE 0;
$getMemo = ()=>var["memo"];
$getOwner = ()=>params.owner;
$canDraw = ($address)=>{
if (NOT params.whitelist)
return true;
return in_data_feed[[oracles=params.whitelist, feed_name=this_address, feed_value=$address]];
};
}",
"init": "{
$METHOD = trigger.data.method;
$PATTERN_ADDRESS = $patternAddress();
$SIZE_X = params.x;
$SIZE_Y = params.y;
//$TOKEN_RED = var[$PATTERN_ADDRESS]["rt"];
//$TOKEN_GREEN = var[$PATTERN_ADDRESS]["gt"];
//$TOKEN_BLUE = var[$PATTERN_ADDRESS]["bt"];
//$TOKEN_VARNISH = var[$PATTERN_ADDRESS]["vt"];
$TOKEN_RED = $rt();
$TOKEN_GREEN = $gt();
$TOKEN_BLUE = $bt();
$TOKEN_VARNISH = $vt();
$R = $r();
$G = $g();
$B = $b();
$VARNISH = balance[$TOKEN_VARNISH];
$SHARES = $shares();
$SHARES_OF_CALLER = $sharesOf(trigger.address);
$IMMORTALIZED = $isImmortalized();
$IS_ALLOWED_TO_DRAW = $canDraw(trigger.address);
$OWNER = $getOwner();
response["method"] = $METHOD;
response["who"] = trigger.address;
}",
"messages": {
"cases": [
{
"if": "{this_address != $patternAddress()}",
"messages": {
"cases": [
{
"if": "{$METHOD == "paint"}",
"init": "{
require(NOT $IMMORTALIZED, "This canvas has been immortalized and is now read-only");
require($IS_ALLOWED_TO_DRAW, "You are not allowed to draw on this canvas");
$red = trigger.output[[asset=$TOKEN_RED]] OTHERWISE 0;
$green = trigger.output[[asset=$TOKEN_GREEN]] OTHERWISE 0;
$blue = trigger.output[[asset=$TOKEN_BLUE]] OTHERWISE 0;
$varnish = trigger.output[[asset=$TOKEN_VARNISH]] OTHERWISE 0;
$area = length(trigger.data.x);
$color = trigger.data.color;
require($area == length(trigger.data.y), "x and y arrays must be of the same size");
require(is_integer($color[0]) AND $color[0] >= 0 AND $color[0] <= 255, "Invalid color component (red)");
require(is_integer($color[1]) AND $color[1] >= 0 AND $color[1] <= 255, "Invalid color (green)");
require(is_integer($color[2]) AND $color[2] >= 0 AND $color[2] <= 255, "Invalid color (blue)");
require($area <= 40, "You can paint at most 40 pixels per call");
require($red >= $area * $color[0], "Not enough red paint");
require($green >= $area * $color[1], "Not enough green paint");
require($blue >= $area * $color[2], "Not enough blue paint");
require($varnish >= floor($VARNISH / ($SIZE_X*$SIZE_Y)) * $area, "You need at least " || floor($VARNISH / ($SIZE_X*$SIZE_Y) * $area || " varnish to edit this painting"));
response["area"] = $area;
response["color"] = json_stringify([$red, $green, $blue]);
response["varnish"] = $varnish;
response["pixels"] = json_stringify({x: trigger.data.x, y: trigger.data.y});
}",
"messages": [
{
"app": "state",
"state": "{
foreach(trigger.data.x, 40, ($xx, $i)=>{
require(is_integer($xx) AND $xx >= 0 AND $xx <= $SIZE_X, "Invalid pixel X coordination");
require(is_integer(trigger.data.y[$i]) AND trigger.data.y[$i] >= 0 AND trigger.data.y[$i] <= $SIZE_Y, "Invalid pixel Y coordinate");
var["p_" || $xx || "_" || trigger.data.y[$i]] = [$red, $green, $blue];
});
$created_shares = $red+$green+$blue; //A share is created per modified pixel
//Non-redeemable balances are updated
var["shares"] += $created_shares; //shares are added to the share pool
var["shares_" || trigger.address] += $created_shares; //shares are credited to the artist
var["lifetime_updates"] += $area;
}"
}
]
},
{
"if": "{$METHOD == "stake"}",
"init": "{
require($IS_ALLOWED_TO_DRAW, "Only allowed painters can stake varnish");
require(NOT $IMMORTALIZED, "This canvas has been immortalized and is now read-only");
require(trigger.output[[asset!=base]].asset == $TOKEN_VARNISH, "You can only stake varnish");
response["amount"] = trigger.output[[asset!=base]];
}",
"messages": [
{
"app": "state",
"state": "{}"
}
]
},
{
"if": "{$METHOD == "claim"}",
"init": "{
require($IMMORTALIZED, "You cannot claim anything until the canvas has been immortalized");
require($SHARES_OF_CALLER > 0, "You don't have any shares");
$share_percent = floor($SHARES_OF_CALLER/$SHARES);
$claimed_red = floor($share_percent * $R);
$claimed_green = floor($share_percent * $G);
$claimed_blue = floor($share_percent * $B);
$claimed_varnish =floor($share_percent * $VARNISH);
response["red"] = $claimed_red;
response["green"] = $claimed_green;
response["blue"] = $claimed_blue;
response["varnish"] = $claimed_varnish;
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "{$TOKEN_RED}",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{$claimed_red}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$TOKEN_GREEN}",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{$claimed_green}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$TOKEN_BLUE}",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{$claimed_blue}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$TOKEN_VARNISH}",
"outputs": [
{
"address": "{trigger.address}",
"amount": "{$claimed_varnish}"
}
]
}
},
{
"app": "state",
"state": "{
var["shares_" || trigger.address] = 0;
var["shares"] -= $SHARES_OF_CALLER;
}"
}
]
},
{
"if": "{$METHOD == "immortalize"}",
"init": "{
require(NOT $IMMORTALIZED, "This canvas has already been immortalized!");
$vpayment = trigger.output[[asset=$TOKEN_VARNISH]];
$requiredVarnish = max(balance[$TOKEN_VARNISH]*2 - $vpayment, (params.immortalizeCost OTHERWISE 0));
require($vpayment >= $requiredVarnish, "You need to send at least " || $requiredVarnish || " varnish to immortalize the canvas");
response["at"] = timestamp;
response["for"] = $vpayment;
response["memo"] = trigger.data.memo;
}",
"messages": [
{
"app": "state",
"state": "{
var["immortalized"] = timestamp;
var["immortalizedBy"] = trigger.address;
var["immortalizedFor"] = $vpayment;
var["memo"] = trigger.data.memo;
}"
}
]
}
]
}
}
]
}
}
]