Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x7e789E2dd1340971De0A9bca35b14AC0939Aa330
Balance 0 ETH
Nonce 1
Code Size 6940 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

6940 bytes
0x6080604052600436106101815760003560e01c80636352211e116100d1578063a22cb4651161008a578063c8c2ed5411610064578063c8c2ed54146107d6578063e66075c2146107eb578063e985e9c514610800578063f01fe6921461083b57610181565b8063a22cb4651461069e578063b88d4fde146106d9578063c87b56dd146107ac57610181565b80636352211e1461054f57806370a08231146105795780637d64bcb4146105ac578063879499f4146105c157806395d89b4114610674578063964585df1461068957610181565b806323b872dd1161013e5780634707d000116101185780634707d000146104095780634f558e79146104445780634f6ccce71461046e5780635ba13abf1461049857610181565b806323b872dd1461034a5780632f745c591461038d57806342842e0e146103c657610181565b806301ffc9a7146101bb57806305d2035b1461020357806306fdde0314610218578063081812fc146102a2578063095ea7b3146102e857806318160ddd14610323575b604051600160e51b62461bcd028152600401808060200182810382526029815260200180611a076029913960400191505060405180910390fd5b3480156101c757600080fd5b506101ef600480360360208110156101de57600080fd5b50356001600160e01b031916610874565b604080519115158252519081900360200190f35b34801561020f57600080fd5b506101ef610897565b34801561022457600080fd5b5061022d6108a7565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561026757818101518382015260200161024f565b50505050905090810190601f1680156102945780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102ae57600080fd5b506102cc600480360360208110156102c557600080fd5b503561093e565b604080516001600160a01b039092168252519081900360200190f35b3480156102f457600080fd5b506103216004803603604081101561030b57600080fd5b506001600160a01b03813516906020013561096e565b005b34801561032f57600080fd5b50610338610a1b565b60408051918252519081900360200190f35b34801561035657600080fd5b506103216004803603606081101561036d57600080fd5b506001600160a01b03813581169160208101359091169060400135610a21565b34801561039957600080fd5b50610338600480360360408110156103b057600080fd5b506001600160a01b038135169060200135610a44565b3480156103d257600080fd5b50610321600480360360608110156103e957600080fd5b506001600160a01b03813581169160208101359091169060400135610ac6565b34801561041557600080fd5b506103216004803603604081101561042c57600080fd5b506001600160a01b0381358116916020013516610ae1565b34801561045057600080fd5b506101ef6004803603602081101561046757600080fd5b5035610c27565b34801561047a57600080fd5b506103386004803603602081101561049157600080fd5b5035610c38565b3480156104a457600080fd5b50610321600480360360408110156104bb57600080fd5b813591908101906040810160208201356401000000008111156104dd57600080fd5b8201836020820111156104ef57600080fd5b8035906020019184602083028401116401000000008311171561051157600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610c9c945050505050565b34801561055b57600080fd5b506102cc6004803603602081101561057257600080fd5b5035610ddd565b34801561058557600080fd5b506103386004803603602081101561059c57600080fd5b50356001600160a01b0316610dff565b3480156105b857600080fd5b50610321610e30565b3480156105cd57600080fd5b50610321600480360360208110156105e457600080fd5b8101906020810181356401000000008111156105ff57600080fd5b82018360208201111561061157600080fd5b8035906020019184600183028401116401000000008311171561063357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610ea2945050505050565b34801561068057600080fd5b5061022d610f05565b34801561069557600080fd5b5061022d610f66565b3480156106aa57600080fd5b50610321600480360360408110156106c157600080fd5b506001600160a01b0381351690602001351515610ff4565b3480156106e557600080fd5b50610321600480360360808110156106fc57600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561073757600080fd5b82018360208201111561074957600080fd5b8035906020019184600183028401116401000000008311171561076b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611078945050505050565b3480156107b857600080fd5b5061022d600480360360208110156107cf57600080fd5b5035611098565b3480156107e257600080fd5b506102cc6111c8565b3480156107f757600080fd5b506102cc6111d7565b34801561080c57600080fd5b506101ef6004803603604081101561082357600080fd5b506001600160a01b03813581169160200135166111e6565b34801561084757600080fd5b506103216004803603604081101561085e57600080fd5b50803590602001356001600160a01b0316611214565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b600d54600160a01b900460ff1681565b60088054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156109335780601f1061090857610100808354040283529160200191610933565b820191906000526020600020905b81548152906001019060200180831161091657829003601f168201915b505050505090505b90565b600061094982611326565b61095257600080fd5b506000908152600260205260409020546001600160a01b031690565b600061097982610ddd565b9050806001600160a01b0316836001600160a01b0316141561099a57600080fd5b336001600160a01b03821614806109b657506109b681336111e6565b6109bf57600080fd5b60008281526002602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60075490565b610a2b3382611343565b610a3457600080fd5b610a3f8383836113a2565b505050565b6000610a4f83610dff565b8210610a8f57604051600160e51b62461bcd02815260040180806020018281038252602c815260200180611a93602c913960400191505060405180910390fd5b6001600160a01b0383166000908152600560205260409020805483908110610ab357fe5b9060005260206000200154905092915050565b610a3f83838360405180602001604052806000815250611078565b600d546001600160a01b03163314610b2d57604051600160e51b62461bcd028152600401808060200182810382526036815260200180611a5d6036913960400191505060405180910390fd5b60408051600160e01b6370a0823102815230600482015290516001600160a01b0384169163a9059cbb91849184916370a0823191602480820192602092909190829003018186803b158015610b8157600080fd5b505afa158015610b95573d6000803e3d6000fd5b505050506040513d6020811015610bab57600080fd5b50516040805163ffffffff851660e01b81526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015610bf757600080fd5b505af1158015610c0b573d6000803e3d6000fd5b505050506040513d6020811015610c2157600080fd5b50505050565b6000610c3282611326565b92915050565b6000610c42610a1b565b8210610c985760408051600160e51b62461bcd02815260206004820152601760248201527f496e646578206973206f7574206f6620626f756e64732e000000000000000000604482015290519081900360640190fd5b5090565b600c546001600160a01b03163314610ce857604051600160e51b62461bcd02815260040180806020018281038252602d815260200180611a30602d913960400191505060405180910390fd5b600d54600160a01b900460ff1615610d3457604051600160e51b62461bcd028152600401808060200182810382526032815260200180611abf6032913960400191505060405180910390fd5b811580610d555750610d55610d5083600163ffffffff6113c116565b611326565b610da95760408051600160e51b62461bcd02815260206004820152601f60248201527f50726576696f757320746f6b656e2049442068617320746f2065786973742e00604482015290519081900360640190fd5b805160005b81811015610c2157610dd5838281518110610dc557fe5b60200260200101518286016113d6565b600101610dae565b6000818152600160205260408120546001600160a01b031680610c3257600080fd5b60006001600160a01b038216610e1457600080fd5b506001600160a01b031660009081526003602052604090205490565b600c546001600160a01b03163314610e7c57604051600160e51b62461bcd02815260040180806020018281038252602d815260200180611a30602d913960400191505060405180910390fd5b600d805474ff00000000000000000000000000000000000000001916600160a01b179055565b600c546001600160a01b03163314610eee57604051600160e51b62461bcd02815260040180806020018281038252602d815260200180611a30602d913960400191505060405180910390fd5b8051610f0190600b906020840190611952565b5050565b60098054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156109335780601f1061090857610100808354040283529160200191610933565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610fec5780601f10610fc157610100808354040283529160200191610fec565b820191906000526020600020905b815481529060010190602001808311610fcf57829003601f168201915b505050505081565b6001600160a01b03821633141561100a57600080fd5b3360008181526004602090815260408083206001600160a01b03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b611083848484610a21565b61108f84848484611405565b610c2157600080fd5b60606110a382611326565b6110f75760408051600160e51b62461bcd02815260206004820152601860248201527f546f6b656e20494420646f6573206e6f742065786973742e0000000000000000604482015290519081900360640190fd5b600b6111028361153e565b60405160200180838054600181600116156101000203166002900480156111605780601f1061113e576101008083540402835291820191611160565b820191906000526020600020905b81548152906001019060200180831161114c575b5050825160208401908083835b6020831061118c5780518252601f19909201916020918201910161116d565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529050919050565b600d546001600160a01b031681565b600c546001600160a01b031681565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b600c546001600160a01b0316331461126057604051600160e51b62461bcd02815260040180806020018281038252602d815260200180611a30602d913960400191505060405180910390fd5b600d54600160a01b900460ff16156112ac57604051600160e51b62461bcd028152600401808060200182810382526032815260200180611abf6032913960400191505060405180910390fd5b8115806112c857506112c8610d5083600163ffffffff6113c116565b61131c5760408051600160e51b62461bcd02815260206004820152601f60248201527f50726576696f757320746f6b656e2049442068617320746f2065786973742e00604482015290519081900360640190fd5b610f0181836113d6565b6000908152600160205260409020546001600160a01b0316151590565b60008061134f83610ddd565b9050806001600160a01b0316846001600160a01b0316148061138a5750836001600160a01b031661137f8461093e565b6001600160a01b0316145b8061139a575061139a81856111e6565b949350505050565b6113ad838383611604565b6113b78382611711565b610a3f8282611806565b6000828211156113d057600080fd5b50900390565b6113e08282611844565b6113ea8282611806565b6007546113fe90600163ffffffff6118f616565b6007555050565b6000611419846001600160a01b031661190f565b6114255750600161139a565b604051600160e11b630a85bd0102815233600482018181526001600160a01b03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b838110156114a257818101518382015260200161148a565b50505050905090810190601f1680156114cf5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156114f157600080fd5b505af1158015611505573d6000803e3d6000fd5b505050506040513d602081101561151b57600080fd5b50516001600160e01b031916600160e11b630a85bd010214915050949350505050565b60608161156657506040805180820190915260018152600160fc1b6003026020820152610892565b818060005b811561157f57600101600a8204915061156b565b6060816040519080825280601f01601f1916602001820160405280156115ac576020820181803883390190505b50905060001982015b84156115fa57600a850660300160f81b828280600190039350815181106115d857fe5b60200101906001600160f81b031916908160001a905350600a850494506115b5565b5095945050505050565b826001600160a01b031661161782610ddd565b6001600160a01b03161461162a57600080fd5b6001600160a01b03821661163d57600080fd5b61164681611915565b6001600160a01b03831660009081526003602052604090205461167090600163ffffffff6113c116565b6001600160a01b0380851660009081526003602052604080822093909355908416815220546116a690600163ffffffff6118f616565b6001600160a01b038084166000818152600360209081526040808320959095558582526001905283812080546001600160a01b031916831790559251849391928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821660009081526005602052604081205461173b90600163ffffffff6113c116565b6000838152600660205260409020549091508082146117d6576001600160a01b038416600090815260056020526040812080548490811061177857fe5b906000526020600020015490508060056000876001600160a01b03166001600160a01b0316815260200190815260200160002083815481106117b657fe5b600091825260208083209091019290925591825260069052604090208190555b6001600160a01b03841660009081526005602052604090208054906117ff9060001983016119cc565b5050505050565b6001600160a01b0390911660009081526005602081815260408084208054868652600684529185208290559282526001810183559183529091200155565b6001600160a01b03821661185757600080fd5b61186081611326565b1561186a57600080fd5b600081815260016020818152604080842080546001600160a01b0319166001600160a01b03881690811790915584526003909152909120546118ab916118f6565b6001600160a01b0383166000818152600360205260408082209390935591518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008282018381101561190857600080fd5b9392505050565b3b151590565b6000818152600260205260409020546001600160a01b03161561194f57600081815260026020526040902080546001600160a01b03191690555b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061199357805160ff19168380011785556119c0565b828001600101855582156119c0579182015b828111156119c05782518255916020019190600101906119a5565b50610c989291506119ec565b815481835581811115610a3f57600083815260209020610a3f9181019083015b61093b91905b80821115610c9857600081556001016119f256fe54686520636f6e74726163742063616e6e6f74207265636569766520455448207061796d656e74732e637265617465436f6e74726f6c206b657920726571756972656420666f7220746869732066756e6374696f6e2e746f6b656e41737369676e6d656e74436f6e74726f6c206b657920726571756972656420666f7220746869732066756e6374696f6e2e496e64657820697320686967686572207468616e206e756d626572206f6620746f6b656e73206f776e65642e546869732063616c6c206f6e6c7920776f726b73207768656e206d696e74696e67206973206e6f742066696e69736865642ea165627a7a72305820881eff59ea96168a047f88d1a174a3522c0147cee065cf96dce362140363964f0029

Verified Source Code Partial Match

Compiler: v0.5.7+commit.6da8b019 EVM: petersburg Optimization: Yes (200 runs)
Cryptostamp.sol 970 lines
/*
 * Crypto stamp
 * Digitalphysical collectible postage stamp
 *
 * Developed by capacity.at
 * for post.at
 */

// File: openzeppelin-solidity/contracts/introspection/IERC165.sol

pragma solidity ^0.5.0;

/**
 * @title IERC165
 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
 */
interface IERC165 {
    /**
     * @notice Query if a contract implements an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @dev Interface identification is specified in ERC-165. This function
     * uses less than 30,000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: openzeppelin-solidity/contracts/token/ERC721/IERC721.sol

pragma solidity ^0.5.0;


/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    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 getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);

    function transferFrom(address from, address to, uint256 tokenId) public;
    function safeTransferFrom(address from, address to, uint256 tokenId) public;

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}

// File: openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol

pragma solidity ^0.5.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a `safeTransfer`. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
    public returns (bytes4);
}

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

pragma solidity ^0.5.0;

/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error
 */
library SafeMath {
    /**
    * @dev Multiplies two unsigned integers, reverts on overflow.
    */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

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

        return c;
    }

    /**
    * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }

    /**
    * @dev Adds two unsigned integers, reverts on overflow.
    */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }

    /**
    * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}

// File: openzeppelin-solidity/contracts/utils/Address.sol

pragma solidity ^0.5.0;

/**
 * Utility library of inline functions on addresses
 */
library Address {
    /**
     * Returns whether the target address is a contract
     * @dev This function will return false if invoked during the constructor of a contract,
     * as the code is not actually created until after the constructor finishes.
     * @param account address of the account to check
     * @return whether the target address is a contract
     */
    function isContract(address account) internal view returns (bool) {
        uint256 size;
        // XXX Currently there is no better way to check if there is a contract in an address
        // than to check the size of the code at that address.
        // See https://ethereum.stackexchange.com/a/14016/36603
        // for more details about how this works.
        // TODO Check this again before the Serenity release, because all addresses will be
        // contracts then.
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }
}

// File: openzeppelin-solidity/contracts/introspection/ERC165.sol

pragma solidity ^0.5.0;


/**
 * @title ERC165
 * @author Matt Condon (@shrugs)
 * @dev Implements ERC165 using a lookup table.
 */
contract ERC165 is IERC165 {
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
    /**
     * 0x01ffc9a7 ===
     *     bytes4(keccak256('supportsInterface(bytes4)'))
     */

    /**
     * @dev a mapping of interface id to whether or not it's supported
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    /**
     * @dev A contract implementing SupportsInterfaceWithLookup
     * implement ERC165 itself
     */
    constructor () internal {
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev implement supportsInterface(bytes4) using a lookup table
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev internal method for registering an interface
     */
    function _registerInterface(bytes4 interfaceId) internal {
        require(interfaceId != 0xffffffff);
        _supportedInterfaces[interfaceId] = true;
    }
}

// File: openzeppelin-solidity/contracts/token/ERC721/ERC721.sol

pragma solidity ^0.5.0;






/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721 is ERC165, IERC721 {
    using SafeMath for uint256;
    using Address for address;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from token ID to owner
    mapping (uint256 => address) private _tokenOwner;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to number of owned token
    mapping (address => uint256) private _ownedTokensCount;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;
    /*
     * 0x80ac58cd ===
     *     bytes4(keccak256('balanceOf(address)')) ^
     *     bytes4(keccak256('ownerOf(uint256)')) ^
     *     bytes4(keccak256('approve(address,uint256)')) ^
     *     bytes4(keccak256('getApproved(uint256)')) ^
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) ^
     *     bytes4(keccak256('isApprovedForAll(address,address)')) ^
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) ^
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
     */

    constructor () public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }

    /**
     * @dev Gets the balance of the specified address
     * @param owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0));
        return _ownedTokensCount[owner];
    }

    /**
     * @dev Gets the owner of the specified token ID
     * @param tokenId uint256 ID of the token to query the owner of
     * @return owner address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(owner != address(0));
        return owner;
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param to address to be approved for the given token ID
     * @param tokenId uint256 ID of the token to be approved
     */
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner);
        require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId));
        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf
     * @param to operator address to set the approval
     * @param approved representing the status of the approval to be set
     */
    function setApprovalForAll(address to, bool approved) public {
        require(to != msg.sender);
        _operatorApprovals[msg.sender][to] = approved;
        emit ApprovalForAll(msg.sender, to, approved);
    }

    /**
     * @dev Tells whether an operator is approved by a given owner
     * @param owner owner address which you want to query the approval of
     * @param operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address
     * Usage of this method is discouraged, use `safeTransferFrom` whenever possible
     * Requires the msg sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
    */
    function transferFrom(address from, address to, uint256 tokenId) public {
        require(_isApprovedOrOwner(msg.sender, tokenId));

        _transferFrom(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     *
     * Requires the msg sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
    */
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data));
    }

    /**
     * @dev Returns whether the specified token exists
     * @param tokenId uint256 ID of the token to query the existence of
     * @return whether the token exists
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        address owner = _tokenOwner[tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer a given token ID
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     *    is an operator of the owner, or is the owner of the token
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Internal function to mint a new token
     * Reverts if the given token ID already exists
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0));
        require(!_exists(tokenId));

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to] = _ownedTokensCount[to].add(1);

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Internal function to burn a specific token
     * Reverts if the token does not exist
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        require(ownerOf(tokenId) == owner);

        _clearApproval(tokenId);

        _ownedTokensCount[owner] = _ownedTokensCount[owner].sub(1);
        _tokenOwner[tokenId] = address(0);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Internal function to burn a specific token
     * Reverts if the token does not exist
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(uint256 tokenId) internal {
        _burn(ownerOf(tokenId), tokenId);
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to transferFrom, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
    */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        require(ownerOf(tokenId) == from);
        require(to != address(0));

        _clearApproval(tokenId);

        _ownedTokensCount[from] = _ownedTokensCount[from].sub(1);
        _ownedTokensCount[to] = _ownedTokensCount[to].add(1);

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Internal function to invoke `onERC721Received` on a target address
     * The call is not executed if the target address is not a contract
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        internal returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }

        bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data);
        return (retval == _ERC721_RECEIVED);
    }

    /**
     * @dev Private function to clear current approval of a given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _clearApproval(uint256 tokenId) private {
        if (_tokenApprovals[tokenId] != address(0)) {
            _tokenApprovals[tokenId] = address(0);
        }
    }
}

// File: openzeppelin-solidity/contracts/token/ERC721/IERC721Enumerable.sol

pragma solidity ^0.5.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract IERC721Enumerable is IERC721 {
    function totalSupply() public view returns (uint256);
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);

    function tokenByIndex(uint256 index) public view returns (uint256);
}

// File: contracts/ERC721EnumerableSimple.sol

pragma solidity ^0.5.0;

/* This is a simplified (and cheaper) version of OpenZeppelin's ERC721Enumerable.
 * ERC721Enumerable's allTokens array and allTokensIndex mapping are eliminated.
 * Side effects: _burn cannot be used any more with this, and creation needs to be
 * in ascending order, starting with 0, and have no holes in the sequence of IDs.
 */




/**
 * @title ERC-721 Non-Fungible Token with optional enumeration extension logic
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721EnumerableSimple is ERC165, ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => uint256[]) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    uint256 internal totalSupply_;

    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;
    /**
     * 0x780e9d63 ===
     *     bytes4(keccak256('totalSupply()')) ^
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
     *     bytes4(keccak256('tokenByIndex(uint256)'))
     */

    /**
     * @dev Constructor function
     */
    constructor () public {
        // register the supported interface to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @dev Gets the token ID at a given index of the tokens list of the requested owner
     * @param owner address owning the tokens list to be accessed
     * @param index uint256 representing the index to be accessed of the requested tokens list
     * @return uint256 token ID at the given index of the tokens list owned by the requested address
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "Index is higher than number of tokens owned.");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev Gets the total amount of tokens stored by the contract
     * @return uint256 representing the total amount of tokens
     */
    function totalSupply() public view returns (uint256) {
        return totalSupply_;
    }


    /**
     * @dev Gets the token ID at a given index of all the tokens in this contract
     * Reverts if the index is greater or equal to the total number of tokens
     * @param index uint256 representing the index to be accessed of the tokens list
     * @return uint256 token ID at the given index of the tokens list
     */
    function tokenByIndex(uint256 index) public view returns (uint256) {
        require(index < totalSupply(), "Index is out of bounds.");
        return index;
    }


    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to transferFrom, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
    */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        super._transferFrom(from, to, tokenId);

        _removeTokenFromOwnerEnumeration(from, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);
    }

    /**
     * @dev Internal function to mint a new token
     * Reverts if the given token ID already exists
     * @param to address the beneficiary that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        super._mint(to, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);

        totalSupply_ = totalSupply_.add(1);
    }

    /**
     * @dev Internal function to burn a specific token
     * Reverts if the token does not exist
     * Deprecated, use _burn(uint256) instead
     * param owner owner of the token to burn
     * param tokenId uint256 ID of the token being burned
     */
    function _burn(address /*owner*/, uint256 /*tokenId*/) internal {
        revert("This token cannot be burned.");
    }

    /**
     * @dev Gets the list of token IDs of the requested owner
     * @param owner address owning the tokens
     * @return uint256[] List of token IDs owned by the requested address
     */
    function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
        return _ownedTokens[owner];
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        _ownedTokensIndex[tokenId] = _ownedTokens[to].length;
        _ownedTokens[to].push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the _ownedTokensIndex mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        _ownedTokens[from].length--;

        // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occcupied by
        // lasTokenId, or just over the end of the array if the token was the last one).
    }
}

// File: openzeppelin-solidity/contracts/token/ERC721/IERC721Metadata.sol

pragma solidity ^0.5.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: openzeppelin-solidity/contracts/token/ERC721/ERC721Metadata.sol

pragma solidity ^0.5.0;




contract ERC721Metadata is ERC165, ERC721, IERC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;
    /**
     * 0x5b5e139f ===
     *     bytes4(keccak256('name()')) ^
     *     bytes4(keccak256('symbol()')) ^
     *     bytes4(keccak256('tokenURI(uint256)'))
     */

    /**
     * @dev Constructor function
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
    }

    /**
     * @dev Gets the token name
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns an URI for a given token ID
     * Throws if the token ID does not exist. May return an empty string.
     * @param tokenId uint256 ID of the token to query
     */
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId));
        return _tokenURIs[tokenId];
    }

    /**
     * @dev Internal function to set the token URI for a given token
     * Reverts if the token ID does not exist
     * @param tokenId uint256 ID of the token to set its URI
     * @param uri string URI to assign
     */
    function _setTokenURI(uint256 tokenId, string memory uri) internal {
        require(_exists(tokenId));
        _tokenURIs[tokenId] = uri;
    }

    /**
     * @dev Internal function to burn a specific token
     * Reverts if the token does not exist
     * Deprecated, use _burn(uint256) instead
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

// File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.5.0;

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
interface IERC20 {
    function transfer(address to, uint256 value) external returns (bool);

    function approve(address spender, uint256 value) external returns (bool);

    function transferFrom(address from, address to, uint256 value) external returns (bool);

    function totalSupply() external view returns (uint256);

    function balanceOf(address who) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: contracts/Cryptostamp.sol

/*
Implements ERC 721 Token standard: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
pragma solidity ^0.5.0;





/* The inheritance is very much the same as OpenZeppelin's ERC721Full,
 * but using a simplified (and cheaper) version of ERC721Enumerable */
contract Cryptostamp is ERC721, ERC721EnumerableSimple, ERC721Metadata("Crypto stamp Edition 1", "CS1") {

    string public uribase;

    address public createControl;

    address public tokenAssignmentControl;

    bool public mintingFinished = false;

    constructor(address _createControl, address _tokenAssignmentControl)
    public
    {
        createControl = _createControl;
        tokenAssignmentControl = _tokenAssignmentControl;
        uribase = "https://test.crypto.post.at/CS1/meta/";
    }

    modifier onlyCreateControl()
    {
        require(msg.sender == createControl, "createControl key required for this function.");
        _;
    }

    modifier onlyTokenAssignmentControl() {
        require(msg.sender == tokenAssignmentControl, "tokenAssignmentControl key required for this function.");
        _;
    }

    modifier requireMinting() {
        require(mintingFinished == false, "This call only works when minting is not finished.");
        _;
    }

    // Issue a new crypto stamp asset, giving it to a specific owner address.
    // As appending the ID into a URI in Solidity is complicated, generate both
    // externally and hand them over to the asset here.
    function create(uint256 _tokenId, address _owner)
    public
    onlyCreateControl
    requireMinting
    {
        // Make sure we do not get any holes in Ids so we can do more optimizations.
        require(_tokenId == 0 || _exists(_tokenId.sub(1)), "Previous token ID has to exist.");
        // _mint already ends up checking if owner != 0 and that tokenId doesn't exist yet.
        _mint(_owner, _tokenId);
    }

    // Batch-issue multiple crypto stamp with adjacent IDs.
    function createMulti(uint256 _tokenIdStart, address[] memory _owners)
    public
    onlyCreateControl
    requireMinting
    {
        // Make sure we do not get any holes in Ids so we can do more optimizations.
        require(_tokenIdStart == 0 || _exists(_tokenIdStart.sub(1)), "Previous token ID has to exist.");
        uint256 addrcount = _owners.length;
        for (uint256 i = 0; i < addrcount; i++) {
            // Make sure this is in sync with what create() does.
            _mint(_owners[i], _tokenIdStart + i);
        }
    }

    // Finish the creation/minting process.
    function finishMinting()
    public
    onlyCreateControl
    {
        mintingFinished = true;
    }

    // Set new base for the token URI.
    function newUriBase(string memory _newUriBase)
    public
    onlyCreateControl
    {
        uribase = _newUriBase;
    }

    // Override ERC721Metadata to create the URI from the base and ID.
    function tokenURI(uint256 _tokenId)
    external view
    returns (string memory)
    {
        require(_exists(_tokenId), "Token ID does not exist.");
        return string(abi.encodePacked(uribase, uint2str(_tokenId)));
    }

    // Returns whether the specified token exists
    function exists(uint256 tokenId) public view returns (bool) {
        return _exists(tokenId);
    }

    // Helper function from Oraclize
    // https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol
    function uint2str(uint256 inp)
    internal pure
    returns (string memory)
    {
        if (inp == 0) return "0";
        uint i = inp;
        uint j = i;
        uint length;
        while (j != 0){
            length++;
            j /= 10;
        }
        bytes memory bstr = new bytes(length);
        uint k = length - 1;
        while (i != 0){
            bstr[k--] = byte(uint8(48 + i % 10));
            i /= 10;
        }
        return string(bstr);
    }

    /*** Make sure currency doesn't get stranded in this contract ***/

    // If this contract gets a balance in some ERC20 contract after it's finished, then we can rescue it.
    function rescueToken(IERC20 _foreignToken, address _to)
    external
    onlyTokenAssignmentControl
    {
        _foreignToken.transfer(_to, _foreignToken.balanceOf(address(this)));
    }

    // Make sure this contract cannot receive ETH.
    function()
    external payable
    {
        revert("The contract cannot receive ETH payments.");
    }
}

Read Contract

balanceOf 0x70a08231 → uint256
createControl 0xe66075c2 → address
exists 0x4f558e79 → bool
getApproved 0x081812fc → address
isApprovedForAll 0xe985e9c5 → bool
mintingFinished 0x05d2035b → bool
name 0x06fdde03 → string
ownerOf 0x6352211e → address
supportsInterface 0x01ffc9a7 → bool
symbol 0x95d89b41 → string
tokenAssignmentControl 0xc8c2ed54 → address
tokenByIndex 0x4f6ccce7 → uint256
tokenOfOwnerByIndex 0x2f745c59 → uint256
tokenURI 0xc87b56dd → string
totalSupply 0x18160ddd → uint256
uribase 0x964585df → string

Write Contract 10 functions

These functions modify contract state and require a wallet transaction to execute.

approve 0x095ea7b3
address to
uint256 tokenId
create 0xf01fe692
uint256 _tokenId
address _owner
createMulti 0x5ba13abf
uint256 _tokenIdStart
address[] _owners
finishMinting 0x7d64bcb4
No parameters
newUriBase 0x879499f4
string _newUriBase
rescueToken 0x4707d000
address _foreignToken
address _to
safeTransferFrom 0x42842e0e
address from
address to
uint256 tokenId
safeTransferFrom 0xb88d4fde
address from
address to
uint256 tokenId
bytes _data
setApprovalForAll 0xa22cb465
address to
bool approved
transferFrom 0x23b872dd
address from
address to
uint256 tokenId

Recent Transactions

No transactions found for this address