Skip to content

Instantly share code, notes, and snippets.

@sherlock-shi-x
Forked from lychees/sponsorToken.sol
Last active March 22, 2018 12:04
Show Gist options
  • Select an option

  • Save sherlock-shi-x/a5d2483023caf4429f642c93e0b1f8ae to your computer and use it in GitHub Desktop.

Select an option

Save sherlock-shi-x/a5d2483023caf4429f642c93e0b1f8ae to your computer and use it in GitHub Desktop.

Revisions

  1. sherlock-shi-x revised this gist Feb 21, 2018. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions sponsorToken.sol
    Original file line number Diff line number Diff line change
    @@ -128,6 +128,11 @@ contract SponsorToken is ERC721{
    balanceOfToken[parentOfItem[_tokenId]] += r;
    msg.sender.transfer(t - r);
    }

    function withdrawAll() public {
    require(msg.sender == owner);
    owner.transfer(this.balance);
    }

    /* Buying */
    function calculateNextPrice (uint256 _price) public view returns (uint256 _nextPrice) {
  2. sherlock-shi-x revised this gist Feb 21, 2018. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion sponsorToken.sol
    Original file line number Diff line number Diff line change
    @@ -83,7 +83,6 @@ contract SponsorToken is ERC721{
    mapping (uint256 => address) private approvedOfItem;
    mapping (uint256 => address) private creatorOfItem;
    mapping (uint256 => uint256) private parentOfItem;
    mapping (address => uint256) private balanceOfAccount;
    mapping (uint256 => uint256) private balanceOfToken;
    mapping (uint256 => uint256) private freeOfItem;

  3. sherlock-shi-x revised this gist Feb 21, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion sponsorToken.sol
    Original file line number Diff line number Diff line change
    @@ -301,7 +301,7 @@ contract SponsorToken is ERC721{
    return size > 0;
    }

    function changePrice(uint256 _itemId, uint256 _price) {
    function changePrice(uint256 _itemId, uint256 _price) onlyOwner(_itemId) public {
    require(now >= freeOfItem[_itemId]);
    priceOfItem[_itemId] = _price;
    }
  4. sherlock-shi-x revised this gist Feb 21, 2018. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions sponsorToken.sol
    Original file line number Diff line number Diff line change
    @@ -118,16 +118,15 @@ contract SponsorToken is ERC721{
    uint256 t = balanceOfToken[_tokenId];
    uint256 r = t / 20;
    balanceOfToken[_tokenId] = 0;
    balanceOfToken[parentOfItem[_tokenId]] + r;
    balanceOfToken[parentOfItem[_tokenId]] += r;
    msg.sender.transfer(t - r);
    }

    function withdrawAmountFromToken (uint256 _tokenId, uint256 t) onlyCreator(_tokenId) public {
    require(msg.sender == creatorOfItem[_tokenId]);
    if (t > balanceOfToken[_tokenId]) t = balanceOfToken[_tokenId];
    uint256 r = t / 20;
    balanceOfToken[_tokenId] = 0;
    balanceOfToken[parentOfItem[_tokenId]] + r;
    balanceOfToken[parentOfItem[_tokenId]] += r;
    msg.sender.transfer(t - r);
    }

  5. @lychees lychees revised this gist Feb 21, 2018. 1 changed file with 27 additions and 27 deletions.
    54 changes: 27 additions & 27 deletions sponsorToken.sol
    Original file line number Diff line number Diff line change
    @@ -84,7 +84,7 @@ contract SponsorToken is ERC721{
    mapping (uint256 => address) private creatorOfItem;
    mapping (uint256 => uint256) private parentOfItem;
    mapping (address => uint256) private balanceOfAccount;
    mapping (address => uint256) private ethOfAccount;
    mapping (uint256 => uint256) private balanceOfToken;
    mapping (uint256 => uint256) private freeOfItem;

    function SponsorToken () public {
    @@ -113,30 +113,31 @@ contract SponsorToken is ERC721{
    }

    /* Withdraw */
    function withdraw () onlyOwner(0) {
    creatorOfItem[0].transfer(this.balance);
    }

    function withdrawAll () public {
    uint256 t = ethOfAccount[msg.sender];
    ethOfAccount[msg.sender] = 0;
    msg.sender.transfer(t);

    function withdrawAllFromToken (uint256 _tokenId) onlyCreator(_tokenId) public {
    uint256 t = balanceOfToken[_tokenId];
    uint256 r = t / 20;
    balanceOfToken[_tokenId] = 0;
    balanceOfToken[parentOfItem[_tokenId]] + r;
    msg.sender.transfer(t - r);
    }

    function withdrawAmount (uint256 _amount) public {
    if (_amount > ethOfAccount[msg.sender]) _amount = ethOfAccount[msg.sender];
    ethOfAccount[msg.sender] -= _amount;
    msg.sender.transfer(_amount);
    function withdrawAmountFromToken (uint256 _tokenId, uint256 t) onlyCreator(_tokenId) public {
    require(msg.sender == creatorOfItem[_tokenId]);
    if (t > balanceOfToken[_tokenId]) t = balanceOfToken[_tokenId];
    uint256 r = t / 20;
    balanceOfToken[_tokenId] = 0;
    balanceOfToken[parentOfItem[_tokenId]] + r;
    msg.sender.transfer(t - r);
    }

    /* Buying */
    function calculateNextPrice (uint256 _price) public view returns (uint256 _nextPrice) {
    return _price.mul(115).div(98);
    return _price.mul(117).div(98);
    }

    function calculateDevCut (uint256 _price) public view returns (uint256 _devCut) {
    return _price.mul(5).div(100); // 5%
    return _price.div(20); // 5%
    }

    function buy (uint256 _itemId) payable public {
    @@ -163,11 +164,10 @@ contract SponsorToken is ERC721{
    uint256 devCut = calculateDevCut(price);

    // Transfer payment to old owner minus the developer's cut.
    ethOfAccount[oldOwner] += price.sub(devCut);
    devCut = devCut.div(5);
    ethOfAccount[creatorOfItem[parentOfItem[_itemId]]] += devCut;
    ethOfAccount[ownerOfItem[parentOfItem[_itemId]]] += devCut;
    ethOfAccount[creatorOfItem[_itemId]] += devCut.mul(3);
    oldOwner.transfer(price.sub(devCut));
    uint256 shareHolderCut = devCut.div(20);
    ownerOfItem[parentOfItem[_itemId]].transfer(shareHolderCut);
    balanceOfToken[_itemId] += devCut.sub(shareHolderCut);

    if (excess > 0) {
    newOwner.transfer(excess);
    @@ -208,16 +208,16 @@ contract SponsorToken is ERC721{
    return creatorOfItem[_itemId];
    }

    function parentOf (uint256 _itemId) public view returns (uint256 _parent) {
    return parentOfItem[_itemId];
    function parentOf (uint256 _tokenId) public view returns (uint256 _parent) {
    return parentOfItem[_tokenId];
    }

    function freeOf (uint256 _itemId) public view returns (uint256 _free) {
    return freeOfItem[_itemId];
    function freeOf (uint256 _tokenId) public view returns (uint256 _free) {
    return freeOfItem[_tokenId];
    }

    function ethOf (address _user) public view returns (uint256 _eth) {
    return ethOfAccount[_user];
    function balanceFromToken (uint256 _tokenId) public view returns (uint256 _balance) {
    return balanceOfToken[_tokenId];
    }

    function tokensOf (address _owner) public view returns (uint256[] _tokenIds) {
    @@ -312,7 +312,7 @@ contract SponsorToken is ERC721{
    creatorOfItem[counter] = ownerOfItem[counter] = msg.sender;
    priceOfItem[counter] = _price;
    parentOfItem[counter] = _parent;
    freeOfItem[counter] = now + _frozen;
    freeOfItem[counter] = now + _frozen;
    counter += 1;
    }
    }
  6. @lychees lychees revised this gist Feb 21, 2018. 1 changed file with 9 additions and 6 deletions.
    15 changes: 9 additions & 6 deletions sponsorToken.sol
    Original file line number Diff line number Diff line change
    @@ -76,7 +76,6 @@ contract SponsorToken is ERC721{
    event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);

    address private owner;
    mapping (address => bool) private admins;

    uint256 counter;
    mapping (uint256 => address) private ownerOfItem;
    @@ -90,7 +89,11 @@ contract SponsorToken is ERC721{

    function SponsorToken () public {
    owner = msg.sender;
    admins[owner] = true;
    creatorOfItem[counter] = ownerOfItem[counter] = msg.sender;
    priceOfItem[counter] = 1 ether;
    parentOfItem[counter] = 0;
    freeOfItem[counter] = now + 120;
    counter += 1;
    }

    /* Modifiers */
    @@ -115,8 +118,10 @@ contract SponsorToken is ERC721{
    }

    function withdrawAll () public {
    uint256 t = ethOfAccount[msg.sender];
    ethOfAccount[msg.sender] = 0;
    msg.sender.transfer(ethOfAccount[msg.sender]);
    msg.sender.transfer(t);

    }

    function withdrawAmount (uint256 _amount) public {
    @@ -277,9 +282,6 @@ contract SponsorToken is ERC721{
    }

    /* Read */
    function isAdmin (address _admin) public view returns (bool _isAdmin) {
    return admins[_admin];
    }

    function priceOf (uint256 _itemId) public view returns (uint256 _price) {
    return priceOfItem[_itemId];
    @@ -306,6 +308,7 @@ contract SponsorToken is ERC721{
    }

    function issueToken(uint256 _price, uint256 _frozen, uint256 _parent) public {
    require(_parent <= counter);
    creatorOfItem[counter] = ownerOfItem[counter] = msg.sender;
    priceOfItem[counter] = _price;
    parentOfItem[counter] = _parent;
  7. @lychees lychees renamed this gist Feb 21, 2018. 1 changed file with 27 additions and 36 deletions.
    63 changes: 27 additions & 36 deletions gistfile1.txt → sponsorToken.sol
    Original file line number Diff line number Diff line change
    @@ -84,7 +84,8 @@ contract SponsorToken is ERC721{
    mapping (uint256 => address) private approvedOfItem;
    mapping (uint256 => address) private creatorOfItem;
    mapping (uint256 => uint256) private parentOfItem;
    mapping (address => uint256) private ethOfAccount;
    mapping (address => uint256) private balanceOfAccount;
    mapping (address => uint256) private ethOfAccount;
    mapping (uint256 => uint256) private freeOfItem;

    function SponsorToken () public {
    @@ -93,40 +94,34 @@ contract SponsorToken is ERC721{
    }

    /* Modifiers */
    modifier onlyOwner() {
    require(owner == msg.sender);
    modifier onlyOwner(uint256 _tokenId) {
    require(ownerOfItem[_tokenId] == msg.sender);
    _;
    }

    modifier onlyAdmins() {
    require(admins[msg.sender]);
    modifier onlyCreator(uint256 _tokenId) {
    require(creatorOfItem[_tokenId] == msg.sender);
    _;
    }
    }

    /* Owner */
    function setOwner (address _owner) onlyOwner() public {
    owner = _owner;
    }

    function addAdmin (address _admin) onlyOwner() public {
    admins[_admin] = true;
    }

    function removeAdmin (address _admin) onlyOwner() public {
    delete admins[_admin];
    function setCreator (address _creator, uint _tokenId) onlyCreator(_tokenId) public {
    creatorOfItem[_tokenId] = _creator;
    }

    /* Withdraw */
    /*
    NOTICE: These functions withdraw the developer's cut which is left
    in the contract by `buy`. User funds are immediately sent to the old
    owner in `buy`, no user funds are left in the contract.
    */
    function withdrawAll () onlyAdmins() public {
    msg.sender.transfer(this.balance);
    function withdraw () onlyOwner(0) {
    creatorOfItem[0].transfer(this.balance);
    }

    function withdrawAll () public {
    ethOfAccount[msg.sender] = 0;
    msg.sender.transfer(ethOfAccount[msg.sender]);
    }

    function withdrawAmount (uint256 _amount) onlyAdmins() public {
    function withdrawAmount (uint256 _amount) public {
    if (_amount > ethOfAccount[msg.sender]) _amount = ethOfAccount[msg.sender];
    ethOfAccount[msg.sender] -= _amount;
    msg.sender.transfer(_amount);
    }

    @@ -139,12 +134,6 @@ contract SponsorToken is ERC721{
    return _price.mul(5).div(100); // 5%
    }

    /*
    Buy a country directly from the contract for the calculated price
    which ensures that the owner gets a profit. All countries that
    have been listed can be bought by this method. User funds are sent
    directly to the previous owner and are never stored in the contract.
    */
    function buy (uint256 _itemId) payable public {
    require(priceOf(_itemId) > 0);
    require(ownerOf(_itemId) != address(0));
    @@ -169,8 +158,11 @@ contract SponsorToken is ERC721{
    uint256 devCut = calculateDevCut(price);

    // Transfer payment to old owner minus the developer's cut.
    oldOwner.transfer(price.sub(devCut));
    creatorOfItem[_itemId].transfer(devCut/2);
    ethOfAccount[oldOwner] += price.sub(devCut);
    devCut = devCut.div(5);
    ethOfAccount[creatorOfItem[parentOfItem[_itemId]]] += devCut;
    ethOfAccount[ownerOfItem[parentOfItem[_itemId]]] += devCut;
    ethOfAccount[creatorOfItem[_itemId]] += devCut.mul(3);

    if (excess > 0) {
    newOwner.transfer(excess);
    @@ -308,9 +300,8 @@ contract SponsorToken is ERC721{
    return size > 0;
    }

    function changePrice(uint256 _itemId, uint256 _price) public {
      require(msg.sender == ownerOfItem[_itemId]);
    require(now >= freeOfItem[_itemId]);
    function changePrice(uint256 _itemId, uint256 _price) {
    require(now >= freeOfItem[_itemId]);
    priceOfItem[_itemId] = _price;
    }

  8. @lychees lychees revised this gist Feb 21, 2018. 1 changed file with 3 additions and 4 deletions.
    7 changes: 3 additions & 4 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -84,8 +84,7 @@ contract SponsorToken is ERC721{
    mapping (uint256 => address) private approvedOfItem;
    mapping (uint256 => address) private creatorOfItem;
    mapping (uint256 => uint256) private parentOfItem;
    mapping (address => uint256) private balanceOfAccount;
    mapping (address => uint256) private ethOfAccount;
    mapping (address => uint256) private ethOfAccount;
    mapping (uint256 => uint256) private freeOfItem;

    function SponsorToken () public {
    @@ -309,8 +308,8 @@ contract SponsorToken is ERC721{
    return size > 0;
    }

    function changePrice(uint256 _itemId, uint256 _price) {
    require(ownerOfItem[_itemId] == creatorOfItem[_itemId]);
    function changePrice(uint256 _itemId, uint256 _price) public {
      require(msg.sender == ownerOfItem[_itemId]);
    require(now >= freeOfItem[_itemId]);
    priceOfItem[_itemId] = _price;
    }
  9. @lychees lychees revised this gist Feb 21, 2018. 1 changed file with 26 additions and 7 deletions.
    33 changes: 26 additions & 7 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -67,7 +67,7 @@ contract ERC721 {
    // function supportsInterface(bytes4 _interfaceID) external view returns (bool);
    }

    contract CryptoLike is ERC721{
    contract SponsorToken is ERC721{
    using SafeMath for uint256;

    event Bought (uint256 indexed _itemId, address indexed _owner, uint256 _price);
    @@ -83,8 +83,12 @@ contract CryptoLike is ERC721{
    mapping (uint256 => uint256) private priceOfItem;
    mapping (uint256 => address) private approvedOfItem;
    mapping (uint256 => address) private creatorOfItem;
    mapping (uint256 => uint256) private parentOfItem;
    mapping (address => uint256) private balanceOfAccount;
    mapping (address => uint256) private ethOfAccount;
    mapping (uint256 => uint256) private freeOfItem;

    function CryptoLike () public {
    function SponsorToken () public {
    owner = msg.sender;
    admins[owner] = true;
    }
    @@ -177,11 +181,11 @@ contract CryptoLike is ERC721{
    /* ERC721 */

    function name() public view returns (string name) {
    return "cryptolike.io";
    return "sponsortoken.io";
    }

    function symbol() public view returns (string symbol) {
    return "CLI";
    return "SST";
    }

    function totalSupply() public view returns (uint256 _totalSupply) {
    @@ -207,7 +211,19 @@ contract CryptoLike is ERC721{
    function creatorOf (uint256 _itemId) public view returns (address _creator) {
    return creatorOfItem[_itemId];
    }


    function parentOf (uint256 _itemId) public view returns (uint256 _parent) {
    return parentOfItem[_itemId];
    }

    function freeOf (uint256 _itemId) public view returns (uint256 _free) {
    return freeOfItem[_itemId];
    }

    function ethOf (address _user) public view returns (uint256 _eth) {
    return ethOfAccount[_user];
    }

    function tokensOf (address _owner) public view returns (uint256[] _tokenIds) {
    uint256[] memory items = new uint256[](balanceOf(_owner));

    @@ -295,12 +311,15 @@ contract CryptoLike is ERC721{

    function changePrice(uint256 _itemId, uint256 _price) {
    require(ownerOfItem[_itemId] == creatorOfItem[_itemId]);
    require(now >= freeOfItem[_itemId]);
    priceOfItem[_itemId] = _price;
    }

    function issueToken(uint256 price) public {
    function issueToken(uint256 _price, uint256 _frozen, uint256 _parent) public {
    creatorOfItem[counter] = ownerOfItem[counter] = msg.sender;
    priceOfItem[counter] = price;
    priceOfItem[counter] = _price;
    parentOfItem[counter] = _parent;
    freeOfItem[counter] = now + _frozen;
    counter += 1;
    }
    }
  10. @lychees lychees created this gist Feb 21, 2018.
    306 changes: 306 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,306 @@
    pragma solidity ^0.4.20;

    library SafeMath {

    /**
    * @dev Multiplies two numbers, throws on overflow.
    */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
    return 0;
    }
    uint256 c = a * b;
    assert(c / a == b);
    return c;
    }

    /**
    * @dev Integer division of two numbers, truncating the quotient.
    */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
    }

    /**
    * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
    }

    /**
    * @dev Adds two numbers, throws on overflow.
    */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
    }
    }

    /// @title Interface for contracts conforming to ERC-721: Non-Fungible Tokens
    /// @author Dieter Shirley <dete@axiomzen.co> (https://github.com/dete)
    contract ERC721 {
    // Required methods
    function totalSupply() public view returns (uint256 total);
    function balanceOf(address _owner) public view returns (uint256 balance);
    function ownerOf(uint256 _tokenId) public view returns (address owner);
    function approve(address _to, uint256 _tokenId) public;
    function transfer(address _to, uint256 _tokenId) public;
    function transferFrom(address _from, address _to, uint256 _tokenId) public;

    // Events
    event Transfer(address from, address to, uint256 tokenId);
    event Approval(address owner, address approved, uint256 tokenId);

    // Optional
    function name() public view returns (string name);
    function symbol() public view returns (string symbol);
    // function tokensOfOwner(address _owner) external view returns (uint256[] tokenIds);
    // function tokenMetadata(uint256 _tokenId, string _preferredTransport) public view returns (string infoUrl);

    // ERC-165 Compatibility (https://github.com/ethereum/EIPs/issues/165)
    // function supportsInterface(bytes4 _interfaceID) external view returns (bool);
    }

    contract CryptoLike is ERC721{
    using SafeMath for uint256;

    event Bought (uint256 indexed _itemId, address indexed _owner, uint256 _price);
    event Sold (uint256 indexed _itemId, address indexed _owner, uint256 _price);
    event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
    event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);

    address private owner;
    mapping (address => bool) private admins;

    uint256 counter;
    mapping (uint256 => address) private ownerOfItem;
    mapping (uint256 => uint256) private priceOfItem;
    mapping (uint256 => address) private approvedOfItem;
    mapping (uint256 => address) private creatorOfItem;

    function CryptoLike () public {
    owner = msg.sender;
    admins[owner] = true;
    }

    /* Modifiers */
    modifier onlyOwner() {
    require(owner == msg.sender);
    _;
    }

    modifier onlyAdmins() {
    require(admins[msg.sender]);
    _;
    }

    /* Owner */
    function setOwner (address _owner) onlyOwner() public {
    owner = _owner;
    }

    function addAdmin (address _admin) onlyOwner() public {
    admins[_admin] = true;
    }

    function removeAdmin (address _admin) onlyOwner() public {
    delete admins[_admin];
    }

    /* Withdraw */
    /*
    NOTICE: These functions withdraw the developer's cut which is left
    in the contract by `buy`. User funds are immediately sent to the old
    owner in `buy`, no user funds are left in the contract.
    */
    function withdrawAll () onlyAdmins() public {
    msg.sender.transfer(this.balance);
    }

    function withdrawAmount (uint256 _amount) onlyAdmins() public {
    msg.sender.transfer(_amount);
    }

    /* Buying */
    function calculateNextPrice (uint256 _price) public view returns (uint256 _nextPrice) {
    return _price.mul(115).div(98);
    }

    function calculateDevCut (uint256 _price) public view returns (uint256 _devCut) {
    return _price.mul(5).div(100); // 5%
    }

    /*
    Buy a country directly from the contract for the calculated price
    which ensures that the owner gets a profit. All countries that
    have been listed can be bought by this method. User funds are sent
    directly to the previous owner and are never stored in the contract.
    */
    function buy (uint256 _itemId) payable public {
    require(priceOf(_itemId) > 0);
    require(ownerOf(_itemId) != address(0));
    require(msg.value >= priceOf(_itemId));
    require(ownerOf(_itemId) != msg.sender);
    require(!isContract(msg.sender));
    require(msg.sender != address(0));

    address oldOwner = ownerOf(_itemId);
    address newOwner = msg.sender;
    uint256 price = priceOf(_itemId);
    uint256 excess = msg.value.sub(price);

    _transfer(oldOwner, newOwner, _itemId);
    priceOfItem[_itemId] = nextPriceOf(_itemId);

    Bought(_itemId, newOwner, price);
    Sold(_itemId, oldOwner, price);

    // Devevloper's cut which is left in contract and accesed by
    // `withdrawAll` and `withdrawAmountTo` methods.
    uint256 devCut = calculateDevCut(price);

    // Transfer payment to old owner minus the developer's cut.
    oldOwner.transfer(price.sub(devCut));
    creatorOfItem[_itemId].transfer(devCut/2);

    if (excess > 0) {
    newOwner.transfer(excess);
    }
    }

    /* ERC721 */

    function name() public view returns (string name) {
    return "cryptolike.io";
    }

    function symbol() public view returns (string symbol) {
    return "CLI";
    }

    function totalSupply() public view returns (uint256 _totalSupply) {
    return counter;
    }

    function balanceOf (address _owner) public view returns (uint256 _balance) {
    uint256 counter = 0;

    for (uint256 i = 0; i < counter; i++) {
    if (ownerOf(i) == _owner) {
    counter++;
    }
    }

    return counter;
    }

    function ownerOf (uint256 _itemId) public view returns (address _owner) {
    return ownerOfItem[_itemId];
    }

    function creatorOf (uint256 _itemId) public view returns (address _creator) {
    return creatorOfItem[_itemId];
    }

    function tokensOf (address _owner) public view returns (uint256[] _tokenIds) {
    uint256[] memory items = new uint256[](balanceOf(_owner));

    uint256 itemCounter = 0;
    for (uint256 i = 0; i < counter; i++) {
    if (ownerOf(i) == _owner) {
    items[itemCounter] = i;
    itemCounter += 1;
    }
    }

    return items;
    }

    function tokenExists (uint256 _itemId) public view returns (bool _exists) {
    return priceOf(_itemId) > 0;
    }

    function approvedFor(uint256 _itemId) public view returns (address _approved) {
    return approvedOfItem[_itemId];
    }

    function approve(address _to, uint256 _itemId) public {
    require(msg.sender != _to);
    require(tokenExists(_itemId));
    require(ownerOf(_itemId) == msg.sender);

    if (_to == 0) {
    if (approvedOfItem[_itemId] != 0) {
    delete approvedOfItem[_itemId];
    Approval(msg.sender, 0, _itemId);
    }
    } else {
    approvedOfItem[_itemId] = _to;
    Approval(msg.sender, _to, _itemId);
    }
    }

    /* Transferring a country to another owner will entitle the new owner the profits from `buy` */
    function transfer(address _to, uint256 _itemId) public {
    require(msg.sender == ownerOf(_itemId));
    _transfer(msg.sender, _to, _itemId);
    }

    function transferFrom(address _from, address _to, uint256 _itemId) public {
    require(approvedFor(_itemId) == msg.sender);
    _transfer(_from, _to, _itemId);
    }

    function _transfer(address _from, address _to, uint256 _itemId) internal {
    require(tokenExists(_itemId));
    require(ownerOf(_itemId) == _from);
    require(_to != address(0));
    require(_to != address(this));

    ownerOfItem[_itemId] = _to;
    approvedOfItem[_itemId] = 0;

    Transfer(_from, _to, _itemId);
    }

    /* Read */
    function isAdmin (address _admin) public view returns (bool _isAdmin) {
    return admins[_admin];
    }

    function priceOf (uint256 _itemId) public view returns (uint256 _price) {
    return priceOfItem[_itemId];
    }

    function nextPriceOf (uint256 _itemId) public view returns (uint256 _nextPrice) {
    return calculateNextPrice(priceOf(_itemId));
    }

    function allOf (uint256 _itemId) external view returns (address _owner, address _creator, uint256 _price, uint256 _nextPrice) {
    return (ownerOfItem[_itemId], creatorOfItem[_itemId], priceOfItem[_itemId], nextPriceOf(_itemId));
    }

    /* Util */
    function isContract(address addr) internal view returns (bool) {
    uint size;
    assembly { size := extcodesize(addr) } // solium-disable-line
    return size > 0;
    }

    function changePrice(uint256 _itemId, uint256 _price) {
    require(ownerOfItem[_itemId] == creatorOfItem[_itemId]);
    priceOfItem[_itemId] = _price;
    }

    function issueToken(uint256 price) public {
    creatorOfItem[counter] = ownerOfItem[counter] = msg.sender;
    priceOfItem[counter] = price;
    counter += 1;
    }
    }