ETH Price: $2,028.70 (+3.82%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Grant Token52819342018-03-19 7:07:522905 days ago1521443272IN
0x2E87Fbbf...c07503063
0 ETH0.000340722.1
Grant Token52819292018-03-19 7:05:052905 days ago1521443105IN
0x2E87Fbbf...c07503063
0 ETH0.000372222.1
Grant Token52819212018-03-19 7:03:332905 days ago1521443013IN
0x2E87Fbbf...c07503063
0 ETH0.000403722.1
Set Operating Of...52818632018-03-19 6:50:492905 days ago1521442249IN
0x2E87Fbbf...c07503063
0 ETH0.000175224
Set Financial Of...52818632018-03-19 6:50:492905 days ago1521442249IN
0x2E87Fbbf...c07503063
0 ETH0.000176454

Advanced mode:
Parent Transaction Hash Method Block
From
To
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SuMain

Compiler Version
v0.4.21+commit.dfe3193c

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Etherscan.io on 2018-03-19
*/

pragma solidity ^0.4.21;

/******************************************************************************\
*..................................SU.SQUARES..................................*
*.......................Blockchain.rentable.advertising........................*
*..............................................................................*
* First, I just want to say we are so excited and humbled to get this far and  *
* that you're even reading this. So thank you!                                 *
*                                                                              *
* This file is organized into multiple contracts that separate functionality   *
* into logical parts. The deployed contract, SuMain, is at the bottom and      *
* includes the rest of the file using inheritance.                             *
*                                                                              *
*  - ERC165, ERC721: These interfaces follow the official EIPs                 *
*  - AccessControl: A reusable CEO/CFO/COO access model                        *
*  - PublishInterfaces: An implementation of ERC165                            *
*  - SuNFT: An implementation of ERC721                                        *
*  - SuOperation: The actual square data and the personalize function          *
*  - SuPromo, SuVending: How we sell or grant squares                          *
*..............................................................................*
*............................Su.&.William.Entriken.............................*
*...................................(c) 2018...................................*
\******************************************************************************/

/* AccessControl.sol **********************************************************/

/// @title Reusable three-role access control inspired by CryptoKitties
/// @author William Entriken (https://phor.net)
/// @dev Keep the CEO wallet stored offline, I warned you
contract AccessControl {
    /// @notice The account that can only reassign executive accounts
    address public executiveOfficerAddress;

    /// @notice The account that can collect funds from this contract
    address public financialOfficerAddress;

    /// @notice The account with administrative control of this contract
    address public operatingOfficerAddress;

    function AccessControl() internal {
        executiveOfficerAddress = msg.sender;
    }

    /// @dev Only allowed by executive officer
    modifier onlyExecutiveOfficer() {
        require(msg.sender == executiveOfficerAddress);
        _;
    }

    /// @dev Only allowed by financial officer
    modifier onlyFinancialOfficer() {
        require(msg.sender == financialOfficerAddress);
        _;
    }

    /// @dev Only allowed by operating officer
    modifier onlyOperatingOfficer() {
        require(msg.sender == operatingOfficerAddress);
        _;
    }

    /// @notice Reassign the executive officer role
    /// @param _executiveOfficerAddress new officer address
    function setExecutiveOfficer(address _executiveOfficerAddress)
        external
        onlyExecutiveOfficer
    {
        require(_executiveOfficerAddress != address(0));
        executiveOfficerAddress = _executiveOfficerAddress;
    }

    /// @notice Reassign the financial officer role
    /// @param _financialOfficerAddress new officer address
    function setFinancialOfficer(address _financialOfficerAddress)
        external
        onlyExecutiveOfficer
    {
        require(_financialOfficerAddress != address(0));
        financialOfficerAddress = _financialOfficerAddress;
    }

    /// @notice Reassign the operating officer role
    /// @param _operatingOfficerAddress new officer address
    function setOperatingOfficer(address _operatingOfficerAddress)
        external
        onlyExecutiveOfficer
    {
        require(_operatingOfficerAddress != address(0));
        operatingOfficerAddress = _operatingOfficerAddress;
    }

    /// @notice Collect funds from this contract
    function withdrawBalance() external onlyFinancialOfficer {
        financialOfficerAddress.transfer(address(this).balance);
    }
}

/* ERC165.sol *****************************************************************/

/// @title ERC-165 Standard Interface Detection
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
interface ERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

/* ERC721.sol *****************************************************************/

/// @title ERC-721 Non-Fungible Token Standard
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
contract ERC721 is ERC165 {
    event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);
    event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
    function balanceOf(address _owner) external view returns (uint256);
    function ownerOf(uint256 _tokenId) external view returns (address);
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function approve(address _approved, uint256 _tokenId) external payable;
    function setApprovalForAll(address _operator, bool _approved) external;
    function getApproved(uint256 _tokenId) external view returns (address);
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}

/// @title ERC-721 Non-Fungible Token Standard
interface ERC721TokenReceiver {
	function onERC721Received(address _from, uint256 _tokenId, bytes data) external returns(bytes4);
}

/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
interface ERC721Metadata /* is ERC721 */ {
    function name() external pure returns (string _name);
    function symbol() external pure returns (string _symbol);
    function tokenURI(uint256 _tokenId) external view returns (string);
}

/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
interface ERC721Enumerable /* is ERC721 */ {
    function totalSupply() external view returns (uint256);
    function tokenByIndex(uint256 _index) external view returns (uint256);
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
}

/* PublishInterfaces.sol ******************************************************/

/// @title A reusable contract to comply with ERC-165
/// @author William Entriken (https://phor.net)
contract PublishInterfaces is ERC165 {
    /// @dev Every interface that we support
    mapping(bytes4 => bool) internal supportedInterfaces;

    function PublishInterfaces() internal {
        supportedInterfaces[0x01ffc9a7] = true; // ERC165
    }

    /// @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.
    /// @return `true` if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceID) external view returns (bool) {
        return supportedInterfaces[interfaceID] && (interfaceID != 0xffffffff);
    }
}

/* SuNFT.sol ******************************************************************/

/// @title Compliance with ERC-721 for Su Squares
/// @dev This implementation assumes:
///  - A fixed supply of NFTs, cannot mint or burn
///  - ids are numbered sequentially starting at 1.
///  - NFTs are initially assigned to this contract
///  - This contract does not externally call its own functions
/// @author William Entriken (https://phor.net)
contract SuNFT is ERC165, ERC721, ERC721Metadata, ERC721Enumerable, PublishInterfaces {
    /// @dev The authorized address for each NFT
    mapping (uint256 => address) internal tokenApprovals;

    /// @dev The authorized operators for each address
    mapping (address => mapping (address => bool)) internal operatorApprovals;

    /// @dev Guarantees msg.sender is the owner of _tokenId
    /// @param _tokenId The token to validate belongs to msg.sender
    modifier onlyOwnerOf(uint256 _tokenId) {
        address owner = _tokenOwnerWithSubstitutions[_tokenId];
        // assert(msg.sender != address(this))
        require(msg.sender == owner);
        _;
    }
    
    modifier mustBeOwnedByThisContract(uint256 _tokenId) {
        require(_tokenId >= 1 && _tokenId <= TOTAL_SUPPLY);
        address owner = _tokenOwnerWithSubstitutions[_tokenId];
        require(owner == address(0) || owner == address(this));
        _;
    }
    
    modifier canOperate(uint256 _tokenId) {
        // assert(msg.sender != address(this))
        address owner = _tokenOwnerWithSubstitutions[_tokenId];
        require(msg.sender == owner || operatorApprovals[owner][msg.sender]);
        _;
    }
    
    modifier canTransfer(uint256 _tokenId) {
        // assert(msg.sender != address(this))
        address owner = _tokenOwnerWithSubstitutions[_tokenId];
        require(msg.sender == owner || 
          msg.sender == tokenApprovals[_tokenId] || 
          operatorApprovals[msg.sender][msg.sender]);
        _;
    }
    
    modifier mustBeValidToken(uint256 _tokenId) {
        require(_tokenId >= 1 && _tokenId <= TOTAL_SUPPLY);
        _;
    }
    
    /// @dev This emits when ownership of any NFT changes by any mechanism.
    ///  This event emits when NFTs are created (`from` == 0) and destroyed
    ///  (`to` == 0). Exception: during contract creation, any number of NFTs
    ///  may be created and assigned without emitting Transfer. At the time of
    ///  any transfer, the approved address for that NFT (if any) is reset to none.
    event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);

    /// @dev This emits when the approved address for an NFT is changed or
    ///  reaffirmed. The zero address indicates there is no approved address.
    ///  When a Transfer event emits, this also indicates that the approved
    ///  address for that NFT (if any) is reset to none.
    event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);

    /// @dev This emits when an operator is enabled or disabled for an owner.
    ///  The operator can manage all NFTs of the owner.
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    /// @notice Count all NFTs assigned to an owner
    /// @dev NFTs assigned to the zero address are considered invalid, and this
    ///  function throws for queries about the zero address.
    /// @param _owner An address for whom to query the balance
    /// @return The number of NFTs owned by `_owner`, possibly zero
    function balanceOf(address _owner) external view returns (uint256) {
        require(_owner != address(0));
        return _tokensOfOwnerWithSubstitutions[_owner].length;
    }

    /// @notice Find the owner of an NFT
    /// @param _tokenId The identifier for an NFT
    /// @dev NFTs assigned to zero address are considered invalid, and queries
    ///  about them do throw.
    /// @return The address of the owner of the NFT
    function ownerOf(uint256 _tokenId) 
        external
        view
        mustBeValidToken(_tokenId)
        returns (address _owner)
    {
        _owner = _tokenOwnerWithSubstitutions[_tokenId];
        // Handle substitutions
        if (_owner == address(0)) {
            _owner = address(this);
        }
    }

    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
    ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
    ///  `onERC721Received` on `_to` and throws if the return value is not
    ///  `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    /// @param data Additional data with no specified format, sent in call to `_to`
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable
    {
        _safeTransferFrom(_from, _to, _tokenId, data);
    }
	
    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev This works identically to the other function with an extra data parameter,
    ///  except this function just sets data to ""
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable
    {
        _safeTransferFrom(_from, _to, _tokenId, "");
    }

    /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
    ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
    ///  THEY MAY BE PERMANENTLY LOST
    /// @dev Throws unless `msg.sender` is the current owner, an authorized
    ///  operator, or the approved address for this NFT. Throws if `_from` is
    ///  not the current owner. Throws if `_to` is the zero address. Throws if
    ///  `_tokenId` is not a valid NFT.
    /// @param _from The current owner of the NFT
    /// @param _to The new owner
    /// @param _tokenId The NFT to transfer
    function transferFrom(address _from, address _to, uint256 _tokenId)
        external
        payable
        mustBeValidToken(_tokenId)
        canTransfer(_tokenId)
    {
        address owner = _tokenOwnerWithSubstitutions[_tokenId];
        // Handle substitutions
        if (owner == address(0)) {
            owner = address(this);
        }
        require(owner == _from);
        require(_to != address(0));
        _transfer(_tokenId, _to);
    }

    /// @notice Set or reaffirm the approved address for an NFT
    /// @dev The zero address indicates there is no approved address.
    /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
    ///  operator of the current owner.
    /// @param _approved The new approved NFT controller
    /// @param _tokenId The NFT to approve
    function approve(address _approved, uint256 _tokenId)
        external
        payable
        // assert(mustBeValidToken(_tokenId))
        canOperate(_tokenId)
    {
        address _owner = _tokenOwnerWithSubstitutions[_tokenId];
        // Handle substitutions
        if (_owner == address(0)) {
            _owner = address(this);
        }
        tokenApprovals[_tokenId] = _approved;
        emit Approval(_owner, _approved, _tokenId);
    }

    /// @notice Enable or disable approval for a third party ("operator") to manage
    ///  all your asset.
    /// @dev Emits the ApprovalForAll event
    /// @param _operator Address to add to the set of authorized operators.
    /// @param _approved True if the operators is approved, false to revoke approval
    function setApprovalForAll(address _operator, bool _approved) external {
        operatorApprovals[msg.sender][_operator] = _approved;
        emit ApprovalForAll(msg.sender, _operator, _approved);
    }

    /// @notice Get the approved address for a single NFT
    /// @dev Throws if `_tokenId` is not a valid NFT
    /// @param _tokenId The NFT to find the approved address for
    /// @return The approved address for this NFT, or the zero address if there is none
    function getApproved(uint256 _tokenId)
        external
        view
        mustBeValidToken(_tokenId)
        returns (address)
    {
        return tokenApprovals[_tokenId];        
    }

    /// @notice Query if an address is an authorized operator for another address
    /// @param _owner The address that owns the NFTs
    /// @param _operator The address that acts on behalf of the owner
    /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
    function isApprovedForAll(address _owner, address _operator) external view returns (bool) {
        return operatorApprovals[_owner][_operator];
    }
    
    // COMPLIANCE WITH ERC721Metadata //////////////////////////////////////////

    /// @notice A descriptive name for a collection of NFTs in this contract
    function name() external pure returns (string) {
        return "Su Squares";
    }

    /// @notice An abbreviated name for NFTs in this contract
    function symbol() external pure returns (string) {
        return "SU";
    }

    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
    ///  3986. The URI may point to a JSON file that conforms to the "ERC721
    ///  Metadata JSON Schema".
    function tokenURI(uint256 _tokenId) 
        external
        view
        mustBeValidToken(_tokenId)
        returns (string _tokenURI)
    {
        _tokenURI = "https://tenthousandsu.com/erc721/00000.json";
        bytes memory _tokenURIBytes = bytes(_tokenURI);
        _tokenURIBytes[33] = byte(48+(_tokenId / 10000) % 10);
        _tokenURIBytes[34] = byte(48+(_tokenId / 1000) % 10);
        _tokenURIBytes[35] = byte(48+(_tokenId / 100) % 10);
        _tokenURIBytes[36] = byte(48+(_tokenId / 10) % 10);
        _tokenURIBytes[37] = byte(48+(_tokenId / 1) % 10);
        
    }

    // COMPLIANCE WITH ERC721Enumerable ////////////////////////////////////////

    /// @notice Count NFTs tracked by this contract
    /// @return A count of valid NFTs tracked by this contract, where each one of
    ///  them has an assigned and queryable owner not equal to the zero address
    function totalSupply() external view returns (uint256) {
        return TOTAL_SUPPLY;
    }

    /// @notice Enumerate valid NFTs
    /// @dev Throws if `_index` >= `totalSupply()`.
    /// @param _index A counter less than `totalSupply()`
    /// @return The token identifier for the `_index`th NFT,
    ///  (sort order not specified)
    function tokenByIndex(uint256 _index) external view returns (uint256) {
        require(_index < TOTAL_SUPPLY);
        return _index + 1;
    }

    /// @notice Enumerate NFTs assigned to an owner
    /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
    ///  `_owner` is the zero address, representing invalid NFTs.
    /// @param _owner An address where we are interested in NFTs owned by them
    /// @param _index A counter less than `balanceOf(_owner)`
    /// @return The token identifier for the `_index`th NFT assigned to `_owner`,
    ///   (sort order not specified)
    function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _tokenId) {
        require(_owner != address(0));
        require(_index < _tokensOfOwnerWithSubstitutions[_owner].length);
        _tokenId = _tokensOfOwnerWithSubstitutions[_owner][_index];
        // Handle substitutions
        if (_owner == address(this)) {
            if (_tokenId == 0) {
                _tokenId = _index + 1;
            }
        }
    }

    // INTERNAL INTERFACE //////////////////////////////////////////////////////

    /// @dev Actually do a transfer, does NO precondition checking
    function _transfer(uint256 _tokenId, address _to) internal {
        // Here are the preconditions we are not checking:
        // assert(canTransfer(_tokenId))
        // assert(mustBeValidToken(_tokenId))
        require(_to != address(0));

        // Find the FROM address
        address fromWithSubstitution = _tokenOwnerWithSubstitutions[_tokenId];
        address from = fromWithSubstitution;
        if (fromWithSubstitution == address(0)) {
            from = address(this);
        }

        // Take away from the FROM address
        // The Entriken algorithm for deleting from an indexed, unsorted array
        uint256 indexToDeleteWithSubstitution = _ownedTokensIndexWithSubstitutions[_tokenId];
        uint256 indexToDelete;
        if (indexToDeleteWithSubstitution == 0) {
            indexToDelete = _tokenId - 1;
        } else {
            indexToDelete = indexToDeleteWithSubstitution - 1;
        }
        if (indexToDelete != _tokensOfOwnerWithSubstitutions[from].length - 1) {
            uint256 lastNftWithSubstitution = _tokensOfOwnerWithSubstitutions[from][_tokensOfOwnerWithSubstitutions[from].length - 1];
            uint256 lastNft = lastNftWithSubstitution;
            if (lastNftWithSubstitution == 0) {
                // assert(from ==  address(0) || from == address(this));
                lastNft = _tokensOfOwnerWithSubstitutions[from].length;
            }
            _tokensOfOwnerWithSubstitutions[from][indexToDelete] = lastNft;
            _ownedTokensIndexWithSubstitutions[lastNft] = indexToDelete + 1;
        }
        delete _tokensOfOwnerWithSubstitutions[from][_tokensOfOwnerWithSubstitutions[from].length - 1]; // get gas back
        _tokensOfOwnerWithSubstitutions[from].length--;
        // Right now _ownedTokensIndexWithSubstitutions[_tokenId] is invalid, set it below based on the new owner

        // Give to the TO address
        _tokensOfOwnerWithSubstitutions[_to].push(_tokenId);
        _ownedTokensIndexWithSubstitutions[_tokenId] = (_tokensOfOwnerWithSubstitutions[_to].length - 1) + 1;

        // External processing
        _tokenOwnerWithSubstitutions[_tokenId] = _to;
        tokenApprovals[_tokenId] = address(0);
        emit Transfer(from, _to, _tokenId);
    }
    
    // PRIVATE STORAGE AND FUNCTIONS ///////////////////////////////////////////

    uint256 private constant TOTAL_SUPPLY = 10000; // SOLIDITY ISSUE #3356 make this immutable

    bytes4 private constant ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,uint256,bytes)"));
    
    /// @dev The owner of each NFT
    ///  If value == address(0), NFT is owned by address(this)
    ///  If value != address(0), NFT is owned by value
    ///  assert(This contract never assigns awnerhip to address(0) or destroys NFTs)
    ///  See commented out code in constructor, saves hella gas
    mapping (uint256 => address) private _tokenOwnerWithSubstitutions;

    /// @dev The list of NFTs owned by each address
    ///  Nomenclature: this[key][index] = value
    ///  If key != address(this) or value != 0, then value represents an NFT
    ///  If key == address(this) and value == 0, then index + 1 is the NFT
    ///  assert(0 is not a valid NFT)
    ///  See commented out code in constructor, saves hella gas
    mapping (address => uint256[]) private _tokensOfOwnerWithSubstitutions;
    
    /// @dev (Location + 1) of each NFT in its owner's list
    ///  Nomenclature: this[key] = value
    ///  If value != 0, _tokensOfOwnerWithSubstitutions[owner][value - 1] = nftId
    ///  If value == 0, _tokensOfOwnerWithSubstitutions[owner][key - 1] = nftId
    ///  assert(2**256-1 is not a valid NFT)
    ///  See commented out code in constructor, saves hella gas
    mapping (uint256 => uint256) private _ownedTokensIndexWithSubstitutions;

    // Due to implementation choices (no mint, no burn, contiguous NFT ids), it
    // is not necessary to keep an array of NFT ids nor where each NFT id is
    // located in that array.
    // address[] private nftIds;
    // mapping (uint256 => uint256) private nftIndexOfId;
    
    function SuNFT() internal {
        // Publish interfaces with ERC-165
        supportedInterfaces[0x6466353c] = true; // ERC721
        supportedInterfaces[0x5b5e139f] = true; // ERC721Metadata
        supportedInterfaces[0x780e9d63] = true; // ERC721Enumerable
        
        // The effect of substitution makes storing address(this), address(this)
        // ..., address(this) for a total of TOTAL_SUPPLY times unnecessary at
        // deployment time
        // for (uint256 i = 1; i <= TOTAL_SUPPLY; i++) {
        //     _tokenOwnerWithSubstitutions[i] = address(this);
        // }

        // The effect of substitution makes storing 1, 2, ..., TOTAL_SUPPLY
        // unnecessary at deployment time
        _tokensOfOwnerWithSubstitutions[address(this)].length = TOTAL_SUPPLY;
        // for (uint256 i = 0; i < TOTAL_SUPPLY; i++) {
        //     _tokensOfOwnerWithSubstitutions[address(this)][i] = i + 1;
        // }
        // for (uint256 i = 1; i <= TOTAL_SUPPLY; i++) {
        //     _ownedTokensIndexWithSubstitutions[i] = i - 1;
        // }
    }
    
    /// @dev Actually perform the safeTransferFrom
    function _safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data)
        private
        mustBeValidToken(_tokenId)
        canTransfer(_tokenId)
    {
        address owner = _tokenOwnerWithSubstitutions[_tokenId];
        // Handle substitutions
        if (owner == address(0)) {
            owner = address(this);
        }
        require(owner == _from);
        require(_to != address(0));
        _transfer(_tokenId, _to);
        
        // Do the callback after everything is done to avoid reentrancy attack
        uint256 codeSize;
        assembly { codeSize := extcodesize(_to) }
        if (codeSize == 0) {
            return;
        }
        bytes4 retval = ERC721TokenReceiver(_to).onERC721Received(_from, _tokenId, data);
        require(retval == ERC721_RECEIVED);
    }    
}

/* SuOperation.sol ************************************************************/

/// @title The features that square owners can use
/// @author William Entriken (https://phor.net)
/// @dev See SuMain contract documentation for detail on how contracts interact.
contract SuOperation is SuNFT {
    /// @dev The personalization of a square has changed
    event Personalized(uint256 _nftId);
    
    /// @dev The main SuSquare struct. The owner may set these properties, subject
    ///  subject to certain rules. The actual 10x10 image is rendered on our
    ///  website using this data.
    struct SuSquare {
        /// @dev This increments on each update
        uint256 version;
        
        /// @dev A 10x10 pixel image, stored 8-bit RGB values from left-to-right
        ///  and top-to-bottom order (normal English reading order). So it is
        ///  exactly 300 bytes. Or it is an empty array.
        ///  So the first byte is the red channel for the top-left pixel, then
        ///  the blue, then the green, and then next is the red channel for the
        ///  pixel to the right of the first pixel.
        bytes rgbData;

        /// @dev The title of this square, at most 64 bytes,
        string title;

        /// @dev The URL of this square, at most 100 bytes, or empty string
        string href;
    }

    /// @notice All the Su Squares that ever exist or will exist. Each Su Square
    ///  represents a square on our webpage in a 100x100 grid. The squares are
    ///  arranged in left-to-right, top-to-bottom order. In other words, normal
    ///  English reading order. So suSquares[1] is the top-left location and
    ///  suSquares[100] is the top-right location. And suSquares[101] is
    ///  directly below suSquares[1]. 
    /// @dev There is no suSquares[0] -- that is an unused array index.
    SuSquare[10001] public suSquares;
    
    /// @notice Update the contents of your square, the first 3 personalizations
    ///  for a square are free then cost 10 finney (0.01 ether) each
    /// @param _squareId The top-left is 1, to its right is 2, ..., top-right is
    ///  100 and then 101 is below 1... the last one at bottom-right is 10000
    /// @param _squareId A 10x10 image for your square, in 8-bit RGB words
    ///  ordered like the squares are ordered. See Imagemagick's command
    ///  convert -size 10x10 -depth 8 in.rgb out.png
    /// @param _title A description of your square (max 64 bytes UTF-8)
    /// @param _href A hyperlink for your square (max 96 bytes)
    function personalizeSquare(
        uint256 _squareId,
        bytes _rgbData,
        string _title,
        string _href
    )
        external
        onlyOwnerOf(_squareId)
        payable
    {
        require(bytes(_title).length <= 64);
        require(bytes(_href).length <= 96);
        require(_rgbData.length == 300);
        suSquares[_squareId].version++;
        suSquares[_squareId].rgbData = _rgbData;
        suSquares[_squareId].title = _title;
        suSquares[_squareId].href = _href;
        if (suSquares[_squareId].version > 3) {
            require(msg.value == 10 finney);
        }
        emit Personalized(_squareId);
    }
}

/* SuPromo.sol ****************************************************************/

/// @title A limited pre-sale and promotional giveaway.
/// @author William Entriken (https://phor.net)
/// @dev See SuMain contract documentation for detail on how contracts interact.
contract SuPromo is AccessControl, SuNFT {
    uint256 constant PROMO_CREATION_LIMIT = 5000;

    /// @notice How many promo squares were granted
    uint256 public promoCreatedCount;

    /// @notice BEWARE, this does not use a safe transfer mechanism!
    ///  You must manually check the receiver can accept NFTs
    function grantToken(uint256 _tokenId, address _newOwner)
        external
        onlyOperatingOfficer
        mustBeValidToken(_tokenId)
        mustBeOwnedByThisContract(_tokenId)
    {
        require(promoCreatedCount < PROMO_CREATION_LIMIT);
        promoCreatedCount++;
        _transfer(_tokenId, _newOwner);
    }
}

/* SuVending.sol **************************************************************/

/// @title A token vending machine
/// @author William Entriken (https://phor.net)
/// @dev See SuMain contract documentation for detail on how contracts interact.
contract SuVending is SuNFT {
    uint256 constant SALE_PRICE = 500 finney; // 0.5 ether

    /// @notice The price is always 0.5 ether, and you can buy any available square
    ///  Be sure you are calling this from a regular account (not a smart contract)
    ///  or if you are calling from a smart contract, make sure it can use
    ///  ERC-721 non-fungible tokens
    function purchase(uint256 _nftId)
        external
        payable
        mustBeValidToken(_nftId)
        mustBeOwnedByThisContract(_nftId)
    {
        require(msg.value == SALE_PRICE);
        _transfer(_nftId, msg.sender);
    }
}

/* SuMain.sol *****************************************************************/

/// @title The features that deed owners can use
/// @author William Entriken (https://phor.net)
/// @dev See SuMain contract documentation for detail on how contracts interact.
contract SuMain is AccessControl, SuNFT, SuOperation, SuVending, SuPromo {
    function SuMain() public {
    }
}

Contract Security Audit

Contract ABI

API
[{"constant":true,"inputs":[],"name":"executiveOfficerAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"promoCreatedCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_approved","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_newOwner","type":"address"}],"name":"grantToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_operatingOfficerAddress","type":"address"}],"name":"setOperatingOfficer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"_tokenId","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"_owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"operatingOfficerAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_squareId","type":"uint256"},{"name":"_rgbData","type":"bytes"},{"name":"_title","type":"string"},{"name":"_href","type":"string"}],"name":"personalizeSquare","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"financialOfficerAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"_tokenURI","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_financialOfficerAddress","type":"address"}],"name":"setFinancialOfficer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_executiveOfficerAddress","type":"address"}],"name":"setExecutiveOfficer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_nftId","type":"uint256"}],"name":"purchase","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"suSquares","outputs":[{"name":"version","type":"uint256"},{"name":"rgbData","type":"bytes"},{"name":"title","type":"string"},{"name":"href","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_nftId","type":"uint256"}],"name":"Personalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]

606060405234156200001057600080fd5b60008054600160a060020a03191633600160a060020a039081169190911782557f28b0ef64f7e82d3b26f3fd404bd0151552f792965f39c29ae82c0a78df67af9c805460ff1990811660019081179092557fd1937f36823354dfe8fc4fecdaaf31c1d82bafb512cc0f14d076e0ce399f798680548216831790557fcca39824a677cee72cd3539fc56c0e5a676a28b60617ea00a9d38305722c8b6480548216831790557f785e4d925c4778965a1107f0c202069d496d641ab5dd08a13bd2b783950e105f805490911690911790553016815260076020526040902061271090620000fb908262000102565b5062000152565b8154818355818115116200012957600083815260209020620001299181019083016200012e565b505050565b6200014f91905b808211156200014b576000815560010162000135565b5090565b90565b61196780620001626000396000f3006060604052600436106101685763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166215be71811461016d57806301ffc9a71461019c57806305e45546146101d057806306fdde03146101f5578063081812fc1461027f578063095ea7b314610295578063133252a6146102ae57806318160ddd146102d057806323b872dd146102e35780632aad292e146103005780632f745c591461031f57806342842e0e146103415780634f6ccce71461035e5780635fd8c710146103745780636352211e146103875780636bfa5edc1461039d57806370a08231146103b057806376f14c98146103cf57806395d89b41146103fe578063a22cb46514610411578063abe088a714610435578063b88d4fde14610448578063c87b56dd14610474578063d978a0d31461048a578063e985e9c5146104a9578063ec13df6b146104ce578063efef39a1146104ed578063ffa6ab44146104f8575b600080fd5b341561017857600080fd5b61018061065f565b604051600160a060020a03909116815260200160405180910390f35b34156101a757600080fd5b6101bc600160e060020a03196004351661066e565b604051901515815260200160405180910390f35b34156101db57600080fd5b6101e36106a7565b60405190815260200160405180910390f35b341561020057600080fd5b6102086106ae565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561024457808201518382015260200161022c565b50505050905090810190601f1680156102715780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561028a57600080fd5b6101806004356106f0565b6102ac600160a060020a0360043516602435610732565b005b34156102b957600080fd5b6102ac600435600160a060020a036024351661082d565b34156102db57600080fd5b6101e36108f7565b6102ac600160a060020a03600435811690602435166044356108fd565b341561030b57600080fd5b6102ac600160a060020a03600435166109ff565b341561032a57600080fd5b6101e3600160a060020a0360043516602435610a5e565b6102ac600160a060020a0360043581169060243516604435610af5565b341561036957600080fd5b6101e3600435610b14565b341561037f57600080fd5b6102ac610b2b565b341561039257600080fd5b610180600435610b81565b34156103a857600080fd5b610180610bcb565b34156103bb57600080fd5b6101e3600160a060020a0360043516610bda565b6102ac600480359060248035808201929081013591604435808201929081013591606435908101910135610c0d565b341561040957600080fd5b610208610d55565b341561041c57600080fd5b6102ac600160a060020a03600435166024351515610d96565b341561044057600080fd5b610180610e06565b6102ac600160a060020a0360048035821691602480359091169160443591606435908101910135610e15565b341561047f57600080fd5b610208600435610e50565b341561049557600080fd5b6102ac600160a060020a0360043516610fee565b34156104b457600080fd5b6101bc600160a060020a036004358116906024351661104d565b34156104d957600080fd5b6102ac600160a060020a036004351661107b565b6102ac6004356110da565b341561050357600080fd5b61050e600435611180565b60405180858152602001806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015610559578082015183820152602001610541565b50505050905090810190601f1680156105865780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b838110156105bc5780820151838201526020016105a4565b50505050905090810190601f1680156105e95780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b8381101561061f578082015183820152602001610607565b50505050905090810190601f16801561064c5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b600054600160a060020a031681565b600160e060020a0319811660009081526003602052604081205460ff1680156106a15750600160e060020a031980831614155b92915050565b619c4d5481565b6106b6611871565b60408051908101604052600a81527f5375205371756172657300000000000000000000000000000000000000000000602082015290505b90565b6000816001811015801561070657506127108111155b151561071157600080fd5b600083815260046020526040902054600160a060020a031691505b50919050565b6000818152600660205260408120548290600160a060020a039081169033168114806107845750600160a060020a038082166000908152600560209081526040808320339094168352929052205460ff165b151561078f57600080fd5b600084815260066020526040902054600160a060020a031692508215156107b4573092505b60008481526004602052604090819020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388811691821790925591908516907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259087905190815260200160405180910390a35050505050565b60025433600160a060020a0390811691161461084857600080fd5b816001811015801561085c57506127108111155b151561086757600080fd5b8260006001821015801561087d57506127108211155b151561088857600080fd5b50600081815260066020526040902054600160a060020a03168015806108bf575030600160a060020a031681600160a060020a0316145b15156108ca57600080fd5b619c4d5461138890106108dc57600080fd5b619c4d805460010190556108f0858561137c565b5050505050565b61271090565b6000816001811015801561091357506127108111155b151561091e57600080fd5b6000838152600660205260409020548390600160a060020a03908116903316811480610964575060008281526004602052604090205433600160a060020a039081169116145b8061098f5750600160a060020a033316600090815260056020908152604080832090915290205460ff165b151561099a57600080fd5b600085815260066020526040902054600160a060020a031693508315156109bf573093505b600160a060020a03848116908816146109d757600080fd5b600160a060020a03861615156109ec57600080fd5b6109f6858761137c565b50505050505050565b60005433600160a060020a03908116911614610a1a57600080fd5b600160a060020a0381161515610a2f57600080fd5b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6000600160a060020a0383161515610a7557600080fd5b600160a060020a0383166000908152600760205260409020548210610a9957600080fd5b600160a060020a0383166000908152600760205260409020805483908110610abd57fe5b906000526020600020900154905030600160a060020a031683600160a060020a031614156106a1578015156106a15750600101919050565b610b0f8383836020604051908101604052600081526115eb565b505050565b60006127108210610b2457600080fd5b5060010190565b60015433600160a060020a03908116911614610b4657600080fd5b600154600160a060020a039081169030163180156108fc0290604051600060405180830381858888f193505050501515610b7f57600080fd5b565b60008160018110158015610b9757506127108111155b1515610ba257600080fd5b600083815260066020526040902054600160a060020a0316915081151561072c57503092915050565b600254600160a060020a031681565b6000600160a060020a0382161515610bf157600080fd5b50600160a060020a031660009081526007602052604090205490565b6000878152600660205260409020548790600160a060020a039081169033168114610c3757600080fd5b6040851115610c4557600080fd5b6060831115610c5357600080fd5b61012c8714610c6157600080fd5b6009896127118110610c6f57fe5b6004020180546001019055878760098b6127118110610c8a57fe5b600402016001019190610c9e929190611883565b50858560098b6127118110610caf57fe5b600402016002019190610cc3929190611883565b50838360098b6127118110610cd457fe5b600402016003019190610ce8929190611883565b50600360098a6127118110610cf957fe5b60040201541115610d1757662386f26fc100003414610d1757600080fd5b7f95820ed330d949e85d003e7c553aa060e3cdffc1f8af4eb8c9cf988dca7878328960405190815260200160405180910390a1505050505050505050565b610d5d611871565b60408051908101604052600281527f53550000000000000000000000000000000000000000000000000000000000006020820152905090565b33600160a060020a0390811660008181526005602090815260408083209487168084529490915290819020805460ff19168515151790557f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190849051901515815260200160405180910390a35050565b600154600160a060020a031681565b6108f085858585858080601f0160208091040260200160405190810160405281815292919060208401838380828437506115eb945050505050565b610e58611871565b610e60611871565b8260018110158015610e7457506127108111155b1515610e7f57600080fd5b60606040519081016040908152602b82527f68747470733a2f2f74656e74686f7573616e6473752e636f6d2f65726337323160208301527f2f30303030302e6a736f6e000000000000000000000000000000000000000000908201529250829150600a61271085040660300160f860020a0282602181518110610efe57fe5b906020010190600160f860020a031916908160001a905350600a6103e885040660300160f860020a0282602281518110610f3457fe5b906020010190600160f860020a031916908160001a905350600a606485040660300160f860020a0282602381518110610f6957fe5b906020010190600160f860020a031916908160001a905350600a8085040660300160f860020a0282602481518110610f9d57fe5b906020010190600160f860020a031916908160001a905350600a840660300160f860020a0282602581518110610fcf57fe5b906020010190600160f860020a031916908160001a9053505050919050565b60005433600160a060020a0390811691161461100957600080fd5b600160a060020a038116151561101e57600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60005433600160a060020a0390811691161461109657600080fd5b600160a060020a03811615156110ab57600080fd5b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b80600181101580156110ee57506127108111155b15156110f957600080fd5b8160006001821015801561110f57506127108211155b151561111a57600080fd5b50600081815260066020526040902054600160a060020a0316801580611151575030600160a060020a031681600160a060020a0316145b151561115c57600080fd5b346706f05b59d3b200001461117057600080fd5b61117a843361137c565b50505050565b600981612711811061118e57fe5b60040201600091509050806000015490806001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112365780601f1061120b57610100808354040283529160200191611236565b820191906000526020600020905b81548152906001019060200180831161121957829003601f168201915b505050505090806002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112d45780601f106112a9576101008083540402835291602001916112d4565b820191906000526020600020905b8154815290600101906020018083116112b757829003601f168201915b505050505090806003018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113725780601f1061134757610100808354040283529160200191611372565b820191906000526020600020905b81548152906001019060200180831161135557829003601f168201915b5050505050905084565b60008080808080600160a060020a038716151561139857600080fd5b600088815260066020526040902054600160a060020a031695508594508415156113c0573094505b60008881526008602052604090205493508315156113e3576001880392506113ea565b6001840392505b600160a060020a0385166000908152600760205260409020546000190183146114b557600160a060020a03851660009081526007602052604090208054600019810190811061143557fe5b9060005260206000209001549150819050816000141561146a5750600160a060020a0384166000908152600760205260409020545b600160a060020a038516600090815260076020526040902080548291908590811061149157fe5b60009182526020808320909101929092558281526008909152604090206001840190555b600160a060020a0385166000908152600760205260409020805460001981019081106114dd57fe5b60009182526020808320909101829055600160a060020a03871682526007905260409020805490611512906000198301611901565b50600160a060020a038716600090815260076020526040902080546001810161153b8382611901565b5060009182526020808320919091018a9055600160a060020a03808a16808452600783526040808520548d8652600885528186205560068452808520805473ffffffffffffffffffffffffffffffffffffffff19908116841790915560049094529384902080549093169092559091908716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908b905190815260200160405180910390a35050505050505050565b6000806000846001811015801561160457506127108111155b151561160f57600080fd5b6000868152600660205260409020548690600160a060020a03908116903316811480611655575060008281526004602052604090205433600160a060020a039081169116145b806116805750600160a060020a033316600090815260056020908152604080832090915290205460ff165b151561168b57600080fd5b600088815260066020526040902054600160a060020a031695508515156116b0573095505b600160a060020a03868116908b16146116c857600080fd5b600160a060020a03891615156116dd57600080fd5b6116e7888a61137c565b883b94508415156116f757611865565b88600160a060020a031663f0b9e5ba8b8a8a6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561178f578082015183820152602001611777565b50505050905090810190601f1680156117bc5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15156117dc57600080fd5b5af115156117e957600080fd5b5050506040518051905093506040517f6f6e455243373231526563656976656428616464726573732c75696e7432353681527f2c627974657329000000000000000000000000000000000000000000000000006020820152602701604051908190039020600160e060020a031985811691161461186557600080fd5b50505050505050505050565b60206040519081016040526000815290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118c45782800160ff198235161785556118f1565b828001600101855582156118f1579182015b828111156118f15782358255916020019190600101906118d6565b506118fd929150611921565b5090565b815481835581811511610b0f57600083815260209020610b0f9181019083015b6106ed91905b808211156118fd57600081556001016119275600a165627a7a723058201ea9aaee21e636445f4dc5d5326f064b32923cb04128721c5842d5c66670a72f0029

Deployed Bytecode

0x6060604052600436106101685763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166215be71811461016d57806301ffc9a71461019c57806305e45546146101d057806306fdde03146101f5578063081812fc1461027f578063095ea7b314610295578063133252a6146102ae57806318160ddd146102d057806323b872dd146102e35780632aad292e146103005780632f745c591461031f57806342842e0e146103415780634f6ccce71461035e5780635fd8c710146103745780636352211e146103875780636bfa5edc1461039d57806370a08231146103b057806376f14c98146103cf57806395d89b41146103fe578063a22cb46514610411578063abe088a714610435578063b88d4fde14610448578063c87b56dd14610474578063d978a0d31461048a578063e985e9c5146104a9578063ec13df6b146104ce578063efef39a1146104ed578063ffa6ab44146104f8575b600080fd5b341561017857600080fd5b61018061065f565b604051600160a060020a03909116815260200160405180910390f35b34156101a757600080fd5b6101bc600160e060020a03196004351661066e565b604051901515815260200160405180910390f35b34156101db57600080fd5b6101e36106a7565b60405190815260200160405180910390f35b341561020057600080fd5b6102086106ae565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561024457808201518382015260200161022c565b50505050905090810190601f1680156102715780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561028a57600080fd5b6101806004356106f0565b6102ac600160a060020a0360043516602435610732565b005b34156102b957600080fd5b6102ac600435600160a060020a036024351661082d565b34156102db57600080fd5b6101e36108f7565b6102ac600160a060020a03600435811690602435166044356108fd565b341561030b57600080fd5b6102ac600160a060020a03600435166109ff565b341561032a57600080fd5b6101e3600160a060020a0360043516602435610a5e565b6102ac600160a060020a0360043581169060243516604435610af5565b341561036957600080fd5b6101e3600435610b14565b341561037f57600080fd5b6102ac610b2b565b341561039257600080fd5b610180600435610b81565b34156103a857600080fd5b610180610bcb565b34156103bb57600080fd5b6101e3600160a060020a0360043516610bda565b6102ac600480359060248035808201929081013591604435808201929081013591606435908101910135610c0d565b341561040957600080fd5b610208610d55565b341561041c57600080fd5b6102ac600160a060020a03600435166024351515610d96565b341561044057600080fd5b610180610e06565b6102ac600160a060020a0360048035821691602480359091169160443591606435908101910135610e15565b341561047f57600080fd5b610208600435610e50565b341561049557600080fd5b6102ac600160a060020a0360043516610fee565b34156104b457600080fd5b6101bc600160a060020a036004358116906024351661104d565b34156104d957600080fd5b6102ac600160a060020a036004351661107b565b6102ac6004356110da565b341561050357600080fd5b61050e600435611180565b60405180858152602001806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015610559578082015183820152602001610541565b50505050905090810190601f1680156105865780820380516001836020036101000a031916815260200191505b50848103835286818151815260200191508051906020019080838360005b838110156105bc5780820151838201526020016105a4565b50505050905090810190601f1680156105e95780820380516001836020036101000a031916815260200191505b50848103825285818151815260200191508051906020019080838360005b8381101561061f578082015183820152602001610607565b50505050905090810190601f16801561064c5780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b600054600160a060020a031681565b600160e060020a0319811660009081526003602052604081205460ff1680156106a15750600160e060020a031980831614155b92915050565b619c4d5481565b6106b6611871565b60408051908101604052600a81527f5375205371756172657300000000000000000000000000000000000000000000602082015290505b90565b6000816001811015801561070657506127108111155b151561071157600080fd5b600083815260046020526040902054600160a060020a031691505b50919050565b6000818152600660205260408120548290600160a060020a039081169033168114806107845750600160a060020a038082166000908152600560209081526040808320339094168352929052205460ff165b151561078f57600080fd5b600084815260066020526040902054600160a060020a031692508215156107b4573092505b60008481526004602052604090819020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388811691821790925591908516907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259087905190815260200160405180910390a35050505050565b60025433600160a060020a0390811691161461084857600080fd5b816001811015801561085c57506127108111155b151561086757600080fd5b8260006001821015801561087d57506127108211155b151561088857600080fd5b50600081815260066020526040902054600160a060020a03168015806108bf575030600160a060020a031681600160a060020a0316145b15156108ca57600080fd5b619c4d5461138890106108dc57600080fd5b619c4d805460010190556108f0858561137c565b5050505050565b61271090565b6000816001811015801561091357506127108111155b151561091e57600080fd5b6000838152600660205260409020548390600160a060020a03908116903316811480610964575060008281526004602052604090205433600160a060020a039081169116145b8061098f5750600160a060020a033316600090815260056020908152604080832090915290205460ff165b151561099a57600080fd5b600085815260066020526040902054600160a060020a031693508315156109bf573093505b600160a060020a03848116908816146109d757600080fd5b600160a060020a03861615156109ec57600080fd5b6109f6858761137c565b50505050505050565b60005433600160a060020a03908116911614610a1a57600080fd5b600160a060020a0381161515610a2f57600080fd5b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6000600160a060020a0383161515610a7557600080fd5b600160a060020a0383166000908152600760205260409020548210610a9957600080fd5b600160a060020a0383166000908152600760205260409020805483908110610abd57fe5b906000526020600020900154905030600160a060020a031683600160a060020a031614156106a1578015156106a15750600101919050565b610b0f8383836020604051908101604052600081526115eb565b505050565b60006127108210610b2457600080fd5b5060010190565b60015433600160a060020a03908116911614610b4657600080fd5b600154600160a060020a039081169030163180156108fc0290604051600060405180830381858888f193505050501515610b7f57600080fd5b565b60008160018110158015610b9757506127108111155b1515610ba257600080fd5b600083815260066020526040902054600160a060020a0316915081151561072c57503092915050565b600254600160a060020a031681565b6000600160a060020a0382161515610bf157600080fd5b50600160a060020a031660009081526007602052604090205490565b6000878152600660205260409020548790600160a060020a039081169033168114610c3757600080fd5b6040851115610c4557600080fd5b6060831115610c5357600080fd5b61012c8714610c6157600080fd5b6009896127118110610c6f57fe5b6004020180546001019055878760098b6127118110610c8a57fe5b600402016001019190610c9e929190611883565b50858560098b6127118110610caf57fe5b600402016002019190610cc3929190611883565b50838360098b6127118110610cd457fe5b600402016003019190610ce8929190611883565b50600360098a6127118110610cf957fe5b60040201541115610d1757662386f26fc100003414610d1757600080fd5b7f95820ed330d949e85d003e7c553aa060e3cdffc1f8af4eb8c9cf988dca7878328960405190815260200160405180910390a1505050505050505050565b610d5d611871565b60408051908101604052600281527f53550000000000000000000000000000000000000000000000000000000000006020820152905090565b33600160a060020a0390811660008181526005602090815260408083209487168084529490915290819020805460ff19168515151790557f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190849051901515815260200160405180910390a35050565b600154600160a060020a031681565b6108f085858585858080601f0160208091040260200160405190810160405281815292919060208401838380828437506115eb945050505050565b610e58611871565b610e60611871565b8260018110158015610e7457506127108111155b1515610e7f57600080fd5b60606040519081016040908152602b82527f68747470733a2f2f74656e74686f7573616e6473752e636f6d2f65726337323160208301527f2f30303030302e6a736f6e000000000000000000000000000000000000000000908201529250829150600a61271085040660300160f860020a0282602181518110610efe57fe5b906020010190600160f860020a031916908160001a905350600a6103e885040660300160f860020a0282602281518110610f3457fe5b906020010190600160f860020a031916908160001a905350600a606485040660300160f860020a0282602381518110610f6957fe5b906020010190600160f860020a031916908160001a905350600a8085040660300160f860020a0282602481518110610f9d57fe5b906020010190600160f860020a031916908160001a905350600a840660300160f860020a0282602581518110610fcf57fe5b906020010190600160f860020a031916908160001a9053505050919050565b60005433600160a060020a0390811691161461100957600080fd5b600160a060020a038116151561101e57600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60005433600160a060020a0390811691161461109657600080fd5b600160a060020a03811615156110ab57600080fd5b6000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b80600181101580156110ee57506127108111155b15156110f957600080fd5b8160006001821015801561110f57506127108211155b151561111a57600080fd5b50600081815260066020526040902054600160a060020a0316801580611151575030600160a060020a031681600160a060020a0316145b151561115c57600080fd5b346706f05b59d3b200001461117057600080fd5b61117a843361137c565b50505050565b600981612711811061118e57fe5b60040201600091509050806000015490806001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112365780601f1061120b57610100808354040283529160200191611236565b820191906000526020600020905b81548152906001019060200180831161121957829003601f168201915b505050505090806002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112d45780601f106112a9576101008083540402835291602001916112d4565b820191906000526020600020905b8154815290600101906020018083116112b757829003601f168201915b505050505090806003018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113725780601f1061134757610100808354040283529160200191611372565b820191906000526020600020905b81548152906001019060200180831161135557829003601f168201915b5050505050905084565b60008080808080600160a060020a038716151561139857600080fd5b600088815260066020526040902054600160a060020a031695508594508415156113c0573094505b60008881526008602052604090205493508315156113e3576001880392506113ea565b6001840392505b600160a060020a0385166000908152600760205260409020546000190183146114b557600160a060020a03851660009081526007602052604090208054600019810190811061143557fe5b9060005260206000209001549150819050816000141561146a5750600160a060020a0384166000908152600760205260409020545b600160a060020a038516600090815260076020526040902080548291908590811061149157fe5b60009182526020808320909101929092558281526008909152604090206001840190555b600160a060020a0385166000908152600760205260409020805460001981019081106114dd57fe5b60009182526020808320909101829055600160a060020a03871682526007905260409020805490611512906000198301611901565b50600160a060020a038716600090815260076020526040902080546001810161153b8382611901565b5060009182526020808320919091018a9055600160a060020a03808a16808452600783526040808520548d8652600885528186205560068452808520805473ffffffffffffffffffffffffffffffffffffffff19908116841790915560049094529384902080549093169092559091908716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908b905190815260200160405180910390a35050505050505050565b6000806000846001811015801561160457506127108111155b151561160f57600080fd5b6000868152600660205260409020548690600160a060020a03908116903316811480611655575060008281526004602052604090205433600160a060020a039081169116145b806116805750600160a060020a033316600090815260056020908152604080832090915290205460ff165b151561168b57600080fd5b600088815260066020526040902054600160a060020a031695508515156116b0573095505b600160a060020a03868116908b16146116c857600080fd5b600160a060020a03891615156116dd57600080fd5b6116e7888a61137c565b883b94508415156116f757611865565b88600160a060020a031663f0b9e5ba8b8a8a6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561178f578082015183820152602001611777565b50505050905090810190601f1680156117bc5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15156117dc57600080fd5b5af115156117e957600080fd5b5050506040518051905093506040517f6f6e455243373231526563656976656428616464726573732c75696e7432353681527f2c627974657329000000000000000000000000000000000000000000000000006020820152602701604051908190039020600160e060020a031985811691161461186557600080fd5b50505050505050505050565b60206040519081016040526000815290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118c45782800160ff198235161785556118f1565b828001600101855582156118f1579182015b828111156118f15782358255916020019190600101906118d6565b506118fd929150611921565b5090565b815481835581811511610b0f57600083815260209020610b0f9181019083015b6106ed91905b808211156118fd57600081556001016119275600a165627a7a723058201ea9aaee21e636445f4dc5d5326f064b32923cb04128721c5842d5c66670a72f0029

Swarm Source

bzzr://1ea9aaee21e636445f4dc5d5326f064b32923cb04128721c5842d5c66670a72f

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.