Bootstrap Bootstrap
            {
   address: "0x73f7dafa086d58aedd8146f40dd8a86fcf778b8f",
   balance: {
      type: "BigNumber",
      hex: "0x00"
      string: "0"
      ether: "0.0"
   },
   "transactions": [],
   code: "/*
Name: Hot Potatoe
Version: 0.0.3
*/


class HotPotatoe {
name = 'HOT Potatoe';
symbol = 'POTATOE';

decimals = 0;
totalSupply = number('0');

initPrice = number('1' + '000000000000000000'); // 1 ether
admin = '';

PotatoeType = {
idx: number(0),
minter: '',
owner: '',
debtor: '',
price: number(0),
parentIdx: number(-1),
initDate: number(0),
transfers: number(0),
cumulativePrice: number(0),
};

potatoes = []; // array of Potatoe
participants = {}; // mapping (address participant => mapping(uint256 potatoeIdx => string role))


Initialize(minterAddress) {} // event
Mint(potatoeIdx, minter) {} // event
Transfer(potatoeIdx, sender, to) {} // event
Steal(potatoeIdx, stealer) {} // event
Withdrawal(amount) {} // event


constructor() {
this.admin = msg.sender;
}

initialize() {
//require(msg.sender == this.admin, "ONLY_ADMIN");
require(this.potatoes.length == 0, "ONLY_ONCE");
this._mint(msg.sender, -1);

emit('Initialize', [msg.sender]);
}


potatoesCount() {
return [this.potatoes.length];
}

_mint(minter, parentIdx) {
minter = minter.toLowerCase();
const potatoeIdx = this.potatoes.length;

const potatoe = {
idx: potatoeIdx,
minter,
owner: address(this).address,
debtor: minter,
price: this.initPrice,
parentIdx,
initDate: number(block.timestamp),
transfers: number(0),
cumulativePrice: number(0),
};
this.potatoes.push(potatoe);
this._setHolding(minter, potatoeIdx, 'minter+debtor');
this.totalSupply = this.totalSupply.add(1);

emit('Mint', [potatoeIdx, minter]);
}

_nextPrice(currentPrice) {
const rewardPercent = number(150); // 150%
const price = currentPrice.mul(rewardPercent).div(100);
return [price];
}

price(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];
const price = potatoe.price;
return [price];
}

nextPrice(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];
const price = this._nextPrice(potatoe.price)[0];
return [price];
}

owner(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];
const owner = potatoe.owner;
return [owner];
}

debtor(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];
const debtor = potatoe.debtor;
return [debtor];
}

transfer(potatoeIdx, to) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];

const sender = msg.sender.toLowerCase();
require(potatoe.debtor == sender, "ONLY_DEBTOR");

require(address(this) != to, "INVALID_TARGET");
require(address(0) != to, "INVALID_TARGET");

to = to.toLowerCase();
require(potatoe.owner != to, "NO_BACKTRACK_TO_OWNER");
require(potatoe.minter != to, "NO_BACKTRACK_TO_MINTER");

const price = potatoe.price;
require(price.eq(msg.value), "INVALID_POTATOE_PRICE");

const treasureFees = msg.value.mul(1).div(1000); // 0.1% fees for the treasure
const minterFees = msg.value.mul(9).div(1000); // 0.9% fees for the minter
address(potatoe.minter).transfer(minterFees);
address(potatoe.owner).transfer(msg.value.sub(treasureFees).sub(minterFees)); // repay (+bonus-fees) the previous owner

if (potatoe.owner == potatoe.minter) {
this._setHolding(potatoe.owner, potatoeIdx, 'minter+retired');
} else if (potatoe.owner != address(this).address) {
this._setHolding(potatoe.owner, potatoeIdx, 'retired');
}

if (sender == potatoe.minter) {
this._setHolding(sender, potatoeIdx, 'minter+owner');
} else {
this._setHolding(sender, potatoeIdx, 'owner');
}

if (to == potatoe.minter) {
this._setHolding(to, potatoeIdx, 'minter+debtor');
} else {
this._setHolding(to, potatoeIdx, 'debtor');
}

potatoe.owner = sender; // new owner (old debtor)
potatoe.debtor = to; // new debtor
potatoe.transfers = potatoe.transfers.add(1);

if (sender != to) {
potatoe.cumulativePrice = potatoe.cumulativePrice.add(msg.value);
}

const newPrice = this._nextPrice(price)[0];
potatoe.price = newPrice; // new price

emit('Transfer', [potatoeIdx, sender, to]);

this._mint(msg.sender, potatoe.idx);
}

holdings(participantAddress) {
participantAddress = participantAddress.toLowerCase();
require(participantAddress in this.participants, "INVALID_PARTICIPANT");

const result = Object.entries(this.participants[participantAddress]).map((entry => {
const [potatoeIdx, role] = entry;
return potatoeIdx + ':' + role;
})).join(' ');
return [result];
}

_setHolding(participantAddress, potatoeIdx, role) {
participantAddress = participantAddress.toLowerCase();
if (! (participantAddress in this.participants)) {
this.participants[participantAddress] = {};
}
this.participants[participantAddress][potatoeIdx] = role;
}

steal(potatoeIdx) {
require(potatoeIdx in this.potatoes, "INVALID_POTATOE_ID");
const potatoe = this.potatoes[potatoeIdx];

const stealer = msg.sender.toLowerCase();
require(potatoe.owner != stealer, "INVALID_STEALER_OWNER");
require(potatoe.debtor != stealer, "INVALID_STEALER_DEBTOR");

const _stealPrice = this.nextPrice(potatoeIdx)[0];
require(_stealPrice.eq(msg.value), "INVALID_POTATOE_STEAL_PRICE");

potatoe.owner = stealer; // stealer is now the owner => he will not pay the transfer (transfer to himself)
potatoe.debtor = stealer;
potatoe.price = _stealPrice;

potatoe.cumulativePrice = potatoe.cumulativePrice.add(msg.value);

this._setHolding(stealer, potatoeIdx, 'stealer');

emit('Steal', [potatoeIdx, stealer]);
}

withdraw(amount) {
require(msg.sender == this.admin, "ONLY_ADMIN");
address(this.admin).transfer(amount);
emit('Withdrawal', [amount]);
}

}

// Events
HotPotatoe.prototype.Initialize.event = true;
HotPotatoe.prototype.Initialize.inputs = ['address indexed'];

HotPotatoe.prototype.Mint.event = true;
HotPotatoe.prototype.Mint.inputs = ['uint256 indexed', 'address indexed'];

HotPotatoe.prototype.Transfer.event = true;
HotPotatoe.prototype.Transfer.inputs = ['uint256 indexed', 'address indexed', 'address indexed'];

HotPotatoe.prototype.Steal.event = true;
HotPotatoe.prototype.Steal.inputs = ['uint256 indexed', 'address indexed'];

HotPotatoe.prototype.Withdrawal.event = true;
HotPotatoe.prototype.Withdrawal.inputs = ['uint256'];


// Methods
HotPotatoe.prototype._mint.internal = true;

HotPotatoe.prototype._nextPrice.internal = true;

HotPotatoe.prototype.transfer.payable = true;
HotPotatoe.prototype.transfer.inputs = ['uint256', 'address'];

HotPotatoe.prototype.price.view = true;
HotPotatoe.prototype.price.inputs = ['uint256'];
HotPotatoe.prototype.price.outputs = ['uint256'];

HotPotatoe.prototype.potatoesCount.view = true;
HotPotatoe.prototype.potatoesCount.outputs = ['uint256'];

HotPotatoe.prototype.nextPrice.view = true;
HotPotatoe.prototype.nextPrice.inputs = ['uint256'];
HotPotatoe.prototype.nextPrice.outputs = ['uint256'];

HotPotatoe.prototype.owner.view = true;
HotPotatoe.prototype.owner.inputs = ['uint256'];
HotPotatoe.prototype.owner.outputs = ['address'];

HotPotatoe.prototype.debtor.view = true;
HotPotatoe.prototype.debtor.inputs = ['uint256'];
HotPotatoe.prototype.debtor.outputs = ['address'];

HotPotatoe.prototype.holdings.view = true;
HotPotatoe.prototype.holdings.inputs = ['address'];
HotPotatoe.prototype.holdings.outputs = ['string'];

HotPotatoe.prototype._setHolding.internal = true;

HotPotatoe.prototype.steal.payable = true;
HotPotatoe.prototype.steal.inputs = ['uint256'];

HotPotatoe.prototype.withdraw.inputs = ['uint256'];

return HotPotatoe;
"
, codeHash: "0x38bfd1abf92e59c02ef1cf580e5f0310eb66202c827d72430dda08a6f357d703", codeAbi: { 0x06fdde03: { constant: true, "inputs": [], name: "name", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x95d89b41: { constant: true, "inputs": [], name: "symbol", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x313ce567: { constant: true, "inputs": [], name: "decimals", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0x18160ddd: { constant: true, "inputs": [], name: "totalSupply", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xb6add0f4: { constant: true, "inputs": [], name: "initPrice", outputs: [ { name: "", type: "uint256" } ], payable: false, stateMutability: "view", type: "function" }, 0xf851a440: { constant: true, "inputs": [], name: "admin", outputs: [ { name: "", type: "address" } ], payable: false, stateMutability: "view", type: "function" }, 0xaa7b0928: { constant: true, "inputs": [], name: "PotatoeType", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x1b5b0f01: { constant: true, "inputs": [], name: "potatoes", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x6c4470fb: { constant: true, "inputs": [], name: "participants", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0xa8ac9b50: { constant: true, "inputs": [], name: "prototype", outputs: [ { name: "", type: "string" } ], payable: false, stateMutability: "view", type: "function" }, 0x36b14535: { inputs: [ { name: "minterAddress", type: "address", indexed: true } ], name: "Initialize", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xf3cea549: { inputs: [ { name: "potatoeIdx", type: "uint256", indexed: true }, { name: "minter", type: "address", indexed: true } ], name: "Mint", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x0a429aba: { inputs: [ { name: "potatoeIdx", type: "uint256", indexed: true }, { name: "sender", type: "address", indexed: true }, { name: "to", type: "address", indexed: true } ], name: "Transfer", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0xab64b03a: { inputs: [ { name: "potatoeIdx", type: "uint256", indexed: true }, { name: "stealer", type: "address", indexed: true } ], name: "Steal", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x4e70a604: { inputs: [ { name: "amount", type: "uint256", indexed: false } ], name: "Withdrawal", "outputs": [], stateMutability: "nonpayable", type: "event" }, 0x8129fc1c: { "inputs": [], name: "initialize", "outputs": [], stateMutability: "nonpayable", type: "function" }, 0xf469c89c: { "inputs": [], name: "potatoesCount", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x26a49e37: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "price", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0x2821ca71: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "nextPrice", outputs: [ { name: "", type: "uint256" } ], stateMutability: "view", type: "function" }, 0xa123c33e: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "owner", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0x10361897: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "debtor", outputs: [ { name: "", type: "address" } ], stateMutability: "view", type: "function" }, 0xb7760c8f: { inputs: [ { name: "potatoeIdx", type: "uint256" }, { name: "to", type: "address" } ], name: "transfer", "outputs": [], stateMutability: "payable", type: "function" }, 0xdd3ced63: { inputs: [ { name: "participantAddress", type: "address" } ], name: "holdings", outputs: [ { name: "", type: "string" } ], stateMutability: "view", type: "function" }, 0x9bcf5f0c: { inputs: [ { name: "potatoeIdx", type: "uint256" } ], name: "steal", "outputs": [], stateMutability: "payable", type: "function" }, 0x2e1a7d4d: { inputs: [ { name: "amount", type: "uint256" } ], name: "withdraw", "outputs": [], stateMutability: "nonpayable", type: "function" } }, contractName: "HotPotatoe", storage: { prototype: { address: "0x73f7dafa086d58aedd8146f40dd8a86fcf778b8f" }, name: "HOT Potatoe", symbol: "POTATOE", decimals: 0, totalSupply: { type: "BigNumber", hex: "0x01" string: "1" ether: "0.000000000000000001" }, initPrice: { type: "BigNumber", hex: "0x0de0b6b3a7640000" string: "1000000000000000000" ether: "1.0" }, admin: "0x131a190fa22cb867abf58193bf9e7640e9fce682", PotatoeType: { idx: { type: "BigNumber", hex: "0x00" string: "0" ether: "0.0" }, minter: "", owner: "", debtor: "", price: { type: "BigNumber", hex: "0x00" string: "0" ether: "0.0" }, parentIdx: { type: "BigNumber", hex: "-0x01" }, initDate: { type: "BigNumber", hex: "0x00" string: "0" ether: "0.0" }, transfers: { type: "BigNumber", hex: "0x00" string: "0" ether: "0.0" }, cumulativePrice: { type: "BigNumber", hex: "0x00" string: "0" ether: "0.0" } }, potatoes: [ { idx: 0, minter: "0xccf8ba457dcad7ee6a0361c96846a0f79744b113", owner: "0x73f7dafa086d58aedd8146f40dd8a86fcf778b8f", debtor: "0xccf8ba457dcad7ee6a0361c96846a0f79744b113", price: { type: "BigNumber", hex: "0x0de0b6b3a7640000" string: "1000000000000000000" ether: "1.0" }, parentIdx: -1, initDate: { type: "BigNumber", hex: "0x018089715388" string: "1651573347208" ether: "0.000001651573347208" }, transfers: { type: "BigNumber", hex: "0x00" string: "0" ether: "0.0" }, cumulativePrice: { type: "BigNumber", hex: "0x00" string: "0" ether: "0.0" } } ], participants: { 0xccf8ba457dcad7ee6a0361c96846a0f79744b113: { 0: "minter+debtor" } } }, storageHash: "0xb5193f92ac3d5c5c6b4f34b77b9d11cc38fc5d8508236e345904b6556ba232b6", savedOnBlockNumber: { type: "BigNumber", hex: "0x0d" string: "13" ether: "0.000000000000000013" } }