Address Contract Partially Verified
Address
0x4Fece400c0d3DB0937162AB44BAB34445626eCfe
Balance
0 ETH
Nonce
1
Code Size
8746 bytes
Creator
0x2EFde486...d86F at tx 0x301e24df...1e7c60
Indexed Transactions
0
Contract Bytecode
8746 bytes
0x6060604052600436106101be5763ffffffff60e060020a60003504166306fdde0381146101c3578063081812fc1461024d578063095ea7b31461027f5780630b3464c3146102a35780631038a54e146102d457806314572dff146102f357806318160ddd146103065780631d6c0dfa1461031957806323b872dd1461032f5780632f745c591461035757806333bebb771461037957806340c10f19146103a157806342842e0e146103c35780634f558e79146103eb5780634f6ccce714610415578063532e48491461042b5780635aa4470f146104495780636352211e146104685780636a1af8b81461047e57806370a08231146104c957806373b31190146104e85780638462151c1461055557806395d89b41146105c75780639dc29fac146105da578063a22cb465146105fc578063a4482f4114610620578063a9059cbb1461063c578063b65c2b401461065e578063b88d4fde14610671578063c87b56dd146106dd578063cc0e97c9146106f3578063d847057614610706578063e81f35fd1461071c578063e985e9c514610732578063ea79f33d14610757578063f21f80d014610783578063f84ddf0b1461079c578063fce87fb0146107af575b600080fd5b34156101ce57600080fd5b6101d66107c2565b60405160208082528190810183818151815260200191508051906020019080838360005b838110156102125780820151838201526020016101fa565b50505050905090810190601f16801561023f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561025857600080fd5b61026360043561086b565b604051600160a060020a03909116815260200160405180910390f35b341561028a57600080fd5b6102a1600160a060020a0360043516602435610886565b005b34156102ae57600080fd5b6102c2600160a060020a0360043516610982565b60405190815260200160405180910390f35b34156102df57600080fd5b6102c2600160a060020a03600435166109c3565b34156102fe57600080fd5b6102a16109d5565b341561031157600080fd5b6102c2610a59565b341561032457600080fd5b6102a1600435610a5f565b341561033a57600080fd5b6102a1600160a060020a0360043581169060243516604435610ada565b341561036257600080fd5b6102c2600160a060020a0360043516602435610b17565b341561038457600080fd5b6102a1600160a060020a0360043581169060243516604435610b65565b34156103ac57600080fd5b6102a1600160a060020a0360043516602435610c1d565b34156103ce57600080fd5b6102a1600160a060020a0360043581169060243516604435610c61565b34156103f657600080fd5b610401600435610c98565b604051901515815260200160405180910390f35b341561042057600080fd5b6102c2600435610cb5565b341561043657600080fd5b6102a16004803560248101910135610ceb565b341561045457600080fd5b6102a1600160a060020a0360043516610d12565b341561047357600080fd5b610263600435610d5c565b341561048957600080fd5b6102a160043561ffff6024358116906044351663ffffffff60643581169060843581169060a4351667ffffffffffffffff60c43581169060e43516610d86565b34156104d457600080fd5b6102c2600160a060020a0360043516610f79565b34156104f357600080fd5b6104fe600435610fac565b60405161ffff978816815295909616602086015263ffffffff93841660408087019190915292841660608601529216608084015267ffffffffffffffff91821660a0840152921660c082015260e001905180910390f35b341561056057600080fd5b610574600160a060020a036004351661103d565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156105b357808201518382015260200161059b565b505050509050019250505060405180910390f35b34156105d257600080fd5b6101d66110c0565b34156105e557600080fd5b6102a1600160a060020a0360043516602435611133565b341561060757600080fd5b6102a1600160a060020a03600435166024351515611173565b341561062b57600080fd5b6102a163ffffffff60043516611204565b341561064757600080fd5b6102a1600160a060020a0360043516602435611267565b341561066957600080fd5b6102a1611311565b341561067c57600080fd5b6102a1600160a060020a036004803582169160248035909116916044359160849060643590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061135295505050505050565b34156106e857600080fd5b6101d6600435611391565b34156106fe57600080fd5b610263611461565b341561071157600080fd5b6102c2600435611470565b341561072757600080fd5b6102a1600435611482565b341561073d57600080fd5b610401600160a060020a03600435811690602435166114a2565b341561076257600080fd5b61076a6114d0565b60405163ffffffff909116815260200160405180910390f35b341561078e57600080fd5b6102a16004356024356114f4565b34156107a757600080fd5b6102c261153c565b34156107ba57600080fd5b6101d6611542565b6107ca612114565b60058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108605780601f1061083557610100808354040283529160200191610860565b820191906000526020600020905b81548152906001019060200180831161084357829003601f168201915b505050505090505b90565b600090815260026020526040902054600160a060020a031690565b600061089182610d5c565b9050600160a060020a0383811690821614156108ac57600080fd5b80600160a060020a031633600160a060020a031614806108d157506108d181336114a2565b15156108dc57600080fd5b60006108e78361086b565b600160a060020a03161415806109055750600160a060020a03831615155b1561097d5760008281526002602052604090819020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0386811691821790925591908316907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a35b505050565b600160a060020a0381166000908152600e60205260408120548015156109ab57600091506109bd565b60008181526010602052604090205491505b50919050565b600e6020526000908152604090205481565b600c5433600160a060020a0390811691161480610a00575060005433600160a060020a039081169116145b1515610a0b57600080fd5b600c8054600163ffffffff74010000000000000000000000000000000000000000808404821692909201160277ffffffff000000000000000000000000000000000000000019909116179055565b60095490565b8033600160a060020a0316610a7382610d5c565b600160a060020a031614610a8657600080fd5b600160a060020a0333166000818152600e6020526040908190208490557f120a390cb4dcd5b400add7dd5a2fc0f7fe657034e6484e3f3667582369856b849084905190815260200160405180910390a25050565b80610ae533826115e0565b1515610af057600080fd5b610afb84848461163f565b1515610b0657600080fd5b610b118484846116e5565b50505050565b6000610b2283610f79565b8210610b2d57600080fd5b600160a060020a0383166000908152600760205260409020805483908110610b5157fe5b906000526020600020900154905092915050565b600c5433600160a060020a0390811691161480610b90575060005433600160a060020a039081169116145b1515610b9b57600080fd5b600160a060020a0383161515610bb057600080fd5b600160a060020a0382161515610bc557600080fd5b610bcf838261177e565b610bd9838261182d565b610be382826119cb565b81600160a060020a031683600160a060020a03166000805160206121df8339815191528360405190815260200160405180910390a3505050565b600c5433600160a060020a0390811691161480610c48575060005433600160a060020a039081169116145b1515610c5357600080fd5b610c5d8282611a92565b5050565b80610c6c33826115e0565b1515610c7757600080fd5b610c8284848461163f565b1515610c8d57600080fd5b610b11848484611b11565b600090815260016020526040902054600160a060020a0316151590565b6000610cbf610a59565b8210610cca57600080fd5b6009805483908110610cd857fe5b9060005260206000209001549050919050565b60005433600160a060020a03908116911614610d0657600080fd5b61097d600b8383612126565b60005433600160a060020a03908116911614610d2d57600080fd5b600c805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600081815260016020526040812054600160a060020a0316801515610d8057600080fd5b92915050565b600c5433600160a060020a0390811691161480610db1575060005433600160a060020a039081169116145b1515610dbc57600080fd5b60e0604051908101604090815261ffff808a168352881660208084019190915263ffffffff8089168385015287811660608501528616608084015267ffffffffffffffff80861660a0850152841660c084015260008b8152600f909152208151815461ffff191661ffff919091161781556020820151815461ffff91909116620100000263ffff0000199091161781556040820151815463ffffffff919091166401000000000267ffffffff00000000199091161781556060820151815463ffffffff9190911668010000000000000000026bffffffff0000000000000000199091161781556080820151815463ffffffff919091166c01000000000000000000000000026fffffffff0000000000000000000000001990911617815560a0820151815467ffffffffffffffff919091167001000000000000000000000000000000000277ffffffffffffffff000000000000000000000000000000001990911617815560c0820151815467ffffffffffffffff9190911678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff909116179055505050505050505050565b6000600160a060020a0382161515610f9057600080fd5b50600160a060020a031660009081526003602052604090205490565b600f6020526000908152604090205461ffff808216916201000081049091169063ffffffff64010000000082048116916801000000000000000081048216916c010000000000000000000000008204169067ffffffffffffffff7001000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041687565b611045612114565b6007600083600160a060020a0316600160a060020a031681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156110b457602002820191906000526020600020905b8154815260200190600101908083116110a0575b50505050509050919050565b6110c8612114565b60068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108605780601f1061083557610100808354040283529160200191610860565b600c5433600160a060020a039081169116148061115e575060005433600160a060020a039081169116145b151561116957600080fd5b610c5d8282611b41565b33600160a060020a031682600160a060020a03161415151561119457600080fd5b33600160a060020a0390811660008181526004602090815260408083209487168084529490915290819020805460ff19168515151790557f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190849051901515815260200160405180910390a35050565b60005433600160a060020a0390811691161461121f57600080fd5b600c805463ffffffff909216740100000000000000000000000000000000000000000277ffffffff000000000000000000000000000000000000000019909216919091179055565b8033600160a060020a031661127b82610d5c565b600160a060020a03161461128e57600080fd5b61129933848461163f565b15156112a457600080fd5b600160a060020a03831615156112b957600080fd5b6112c3338361177e565b6112cd338361182d565b6112d783836119cb565b82600160a060020a031633600160a060020a03166000805160206121df8339815191528460405190815260200160405180910390a3505050565b600c5433600160a060020a039081169116148061133c575060005433600160a060020a039081169116145b151561134757600080fd5b600d80546001019055565b8161135d33826115e0565b151561136857600080fd5b61137385858561163f565b151561137e57600080fd5b61138a85858585611c5a565b5050505050565b611399612114565b6113a282610c98565b15156113ad57600080fd5b610d80600b8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156114465780601f1061141b57610100808354040283529160200191611446565b820191906000526020600020905b81548152906001019060200180831161142957829003601f168201915b5050506000868152601060205260409020549150611c929050565b600c54600160a060020a031681565b60106020526000908152604090205481565b60005433600160a060020a0390811691161461149d57600080fd5b600d55565b600160a060020a03918216600090815260046020908152604080832093909416825291909152205460ff1690565b600c5474010000000000000000000000000000000000000000900463ffffffff1681565b600c5433600160a060020a039081169116148061151f575060005433600160a060020a039081169116145b151561152a57600080fd5b60009182526010602052604090912055565b600d5481565b600b8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156115d85780601f106115ad576101008083540402835291602001916115d8565b820191906000526020600020905b8154815290600101906020018083116115bb57829003601f168201915b505050505081565b6000806115ec83610d5c565b905080600160a060020a031684600160a060020a03161480611627575083600160a060020a031661161c8461086b565b600160a060020a0316145b80611637575061163781856114a2565b949350505050565b600c546000908190600160a060020a0316151561165f57600191506116dd565b50600c54600160a060020a03168063f7ebc39a86868660405160e060020a63ffffffff8616028152600160a060020a0393841660048201529190921660248201526044810191909152606401602060405180830381600087803b15156116c457600080fd5b5af115156116d157600080fd5b50505060405180519250505b509392505050565b806116f033826115e0565b15156116fb57600080fd5b600160a060020a038416151561171057600080fd5b600160a060020a038316151561172557600080fd5b61172f848361177e565b611739848361182d565b61174383836119cb565b82600160a060020a031684600160a060020a03166000805160206121df8339815191528460405190815260200160405180910390a350505050565b81600160a060020a031661179182610d5c565b600160a060020a0316146117a457600080fd5b600081815260026020526040902054600160a060020a031615610c5d57600081815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff19169055600160a060020a038416907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259084905190815260200160405180910390a35050565b600080600061183c8585611e6e565b600084815260086020908152604080832054600160a060020a038916845260079092529091205490935061187790600163ffffffff611f0416565b600160a060020a03861660009081526007602052604090208054919350908390811061189f57fe5b6000918252602080832090910154600160a060020a03881683526007909152604090912080549192508291859081106118d457fe5b6000918252602080832090910192909255600160a060020a038716815260079091526040812080548490811061190657fe5b6000918252602080832090910192909255600160a060020a038716815260079091526040902080549061193d9060001983016121a4565b506000848152600860209081526040808320839055838352808320869055600160a060020a0388168352600e90915290205484141561138a57600160a060020a0385166000818152600e60205260408082208290557f120a390cb4dcd5b400add7dd5a2fc0f7fe657034e6484e3f3667582369856b8491905190815260200160405180910390a25050505050565b60006119d78383611f16565b50600160a060020a03821660009081526007602052604090208054908160018101611a0283826121a4565b506000918252602080832091909101849055838252600881526040808320849055600160a060020a0386168352600e909152902054151561097d57600160a060020a0383166000818152600e6020526040908190208490557f120a390cb4dcd5b400add7dd5a2fc0f7fe657034e6484e3f3667582369856b849084905190815260200160405180910390a2505050565b600160a060020a0382161515611aa757600080fd5b611ab182826119cb565b600160a060020a03821660006000805160206121df8339815191528360405190815260200160405180910390a3600980546000838152600a6020526040902081905560018101611b0183826121a4565b5060009182526020909120015550565b80611b1c33826115e0565b1515611b2757600080fd5b610b11848484602060405190810160405260008152611352565b6000806000611b50858561177e565b611b5a858561182d565b6000600160a060020a0386166000805160206121df8339815191528660405190815260200160405180910390a36000848152600a6020526040902054600954909350611bad90600163ffffffff611f0416565b9150600982815481101515611bbe57fe5b906000526020600020900154905080600984815481101515611bdc57fe5b60009182526020822001919091556009805484908110611bf857fe5b6000918252602090912001556009805490611c179060001983016121a4565b506000848152600a6020908152604080832083905583835280832086905586835260109091529020541561138a5750505060009081526010602052604081205550565b81611c6533826115e0565b1515611c7057600080fd5b611c7b858585610ada565b611c8785858585611fa6565b151561138a57600080fd5b611c9a612114565b6000611ca4612114565b600080611caf612114565b611cb7612114565b60006064965086604051805910611ccb5750595b818152601f19601f830116810160200160405290509550600094505b8815611d4a57600a89069350600a890498508360300160f860020a02868680600101975081518110611d1557fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611ce7565b6000199094019389925084835101600101604051805910611d685750595b818152601f19601f830116810160200160405290509150600090505b8251811015611def57828181518110611d9957fe5b016020015160f860020a900460f860020a02828281518110611db757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611d84565b5060005b848111611e61578581860381518110611e0857fe5b016020015160f860020a900460f860020a02828451830181518110611e2957fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101611df3565b5098975050505050505050565b81600160a060020a0316611e8182610d5c565b600160a060020a031614611e9457600080fd5b600160a060020a038216600090815260036020526040902054611ebe90600163ffffffff611f0416565b600160a060020a03909216600090815260036020908152604080832094909455918152600190915220805473ffffffffffffffffffffffffffffffffffffffff19169055565b600082821115611f1057fe5b50900390565b600081815260016020526040902054600160a060020a031615611f3857600080fd5b6000818152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388169081179091558452600390915290912054611f86916120f6565b600160a060020a0390921660009081526003602052604090209190915550565b600080611fb28561210c565b1515611fc157600191506120ed565b84600160a060020a031663f0b9e5ba8786866040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612040578082015183820152602001612028565b50505050905090810190601f16801561206d5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b151561208d57600080fd5b5af1151561209a57600080fd5b50505060405180517fffffffff0000000000000000000000000000000000000000000000000000000081167ff0b9e5ba000000000000000000000000000000000000000000000000000000001493509150505b50949350505050565b60008282018381101561210557fe5b9392505050565b6000903b1190565b60206040519081016040526000815290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106121675782800160ff19823516178555612194565b82800160010185558215612194579182015b82811115612194578235825591602001919060010190612179565b506121a09291506121c4565b5090565b81548183558181151161097d5760008381526020902061097d9181019083015b61086891905b808211156121a057600081556001016121ca5600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a7230582017bfcef20c0dcc7aa0b7d98abedad0970445dcced96cd76799df1f4fc0358e930029
Verified Source Code Partial Match
Compiler: v0.4.21+commit.dfe3193c
EVM: byzantium
Optimization: Yes (200 runs)
ETHero.sol 911 lines
pragma solidity ^0.4.21;
// The contract uses code from zeppelin-solidity library
// licensed under MIT license
// https://github.com/OpenZeppelin/zeppelin-solidity
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
/**
* @title ERC721 Non-Fungible Token Standard basic interface
* @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721Basic {
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) public view returns (uint256 _balance);
function ownerOf(uint256 _tokenId) public view returns (address _owner);
function exists(uint256 _tokenId) public view returns (bool _exists);
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 _data) public;
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721Enumerable is ERC721Basic {
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);
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721Metadata is ERC721Basic {
function name() public view returns (string _name);
function symbol() public view returns (string _symbol);
function tokenURI(uint256 _tokenId) public view returns (string);
}
/**
* @title ERC-721 Non-Fungible Token Standard, full implementation interface
* @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
}
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
contract ERC721Receiver {
/**
* @dev Magic value to be returned upon successful reception of an NFT
* Equals to `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`,
* which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
*/
bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba;
/**
* @notice Handle the receipt of an NFT
* @dev The ERC721 smart contract calls this function on the recipient
* after a `safetransfer`. This function MAY throw to revert and reject the
* transfer. This function MUST use 50,000 gas or less. Return of other
* than the magic value MUST result in the transaction being reverted.
* Note: the contract address is always the message sender.
* @param _from The sending address
* @param _tokenId The NFT identifier which is being transfered
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
*/
function onERC721Received(address _from, uint256 _tokenId, bytes _data) public returns(bytes4);
}
/**
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract ERC721BasicToken is ERC721Basic {
using SafeMath for uint256;
// Equals to `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
// which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
bytes4 constant ERC721_RECEIVED = 0xf0b9e5ba;
// Mapping from token ID to owner
mapping (uint256 => address) internal tokenOwner;
// Mapping from token ID to approved address
mapping (uint256 => address) internal tokenApprovals;
// Mapping from owner to number of owned token
mapping (address => uint256) internal ownedTokensCount;
// Mapping from owner to operator approvals
mapping (address => mapping (address => bool)) internal operatorApprovals;
/**
* @dev Guarantees msg.sender is owner of the given token
* @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender
*/
modifier onlyOwnerOf(uint256 _tokenId) {
require(ownerOf(_tokenId) == msg.sender);
_;
}
/**
* @dev Checks msg.sender can transfer a token, by being owner, approved, or operator
* @param _tokenId uint256 ID of the token to validate
*/
modifier canTransfer(uint256 _tokenId) {
require(isApprovedOrOwner(msg.sender, _tokenId));
_;
}
/**
* @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 Returns whether the specified token exists
* @param _tokenId uint256 ID of the token to query the existance of
* @return whether the token exists
*/
function exists(uint256 _tokenId) public view returns (bool) {
address owner = tokenOwner[_tokenId];
return owner != address(0);
}
/**
* @dev Approves another address to transfer the given token ID
* @dev The zero address indicates there is no approved address.
* @dev There can only be one approved address per token at a given time.
* @dev 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));
if (getApproved(_tokenId) != address(0) || _to != address(0)) {
tokenApprovals[_tokenId] = _to;
emit Approval(owner, _to, _tokenId);
}
}
/**
* @dev Gets the approved address for a token ID, or zero if no address set
* @param _tokenId uint256 ID of the token to query the approval of
* @return address currently approved for a the given token ID
*/
function getApproved(uint256 _tokenId) public view returns (address) {
return tokenApprovals[_tokenId];
}
/**
* @dev Sets or unsets the approval of a given operator
* @dev 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
* @dev Usage of this method is discouraged, use `safeTransferFrom` whenever possible
* @dev 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 canTransfer(_tokenId) {
require(_from != address(0));
require(_to != address(0));
clearApproval(_from, _tokenId);
removeTokenFrom(_from, _tokenId);
addTokenTo(_to, _tokenId);
emit Transfer(_from, _to, _tokenId);
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* @dev 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,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* @dev 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
canTransfer(_tokenId)
{
safeTransferFrom(_from, _to, _tokenId, "");
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* @dev 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,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* @dev 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 _data
)
public
canTransfer(_tokenId)
{
transferFrom(_from, _to, _tokenId);
require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data));
}
/**
* @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
* @dev 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 by the msg.sender
*/
function _mint(address _to, uint256 _tokenId) internal {
require(_to != address(0));
addTokenTo(_to, _tokenId);
emit Transfer(address(0), _to, _tokenId);
}
/**
* @dev Internal function to burn a specific token
* @dev Reverts if the token does not exist
* @param _tokenId uint256 ID of the token being burned by the msg.sender
*/
function _burn(address _owner, uint256 _tokenId) internal {
clearApproval(_owner, _tokenId);
removeTokenFrom(_owner, _tokenId);
emit Transfer(_owner, address(0), _tokenId);
}
/**
* @dev Internal function to clear current approval of a given token ID
* @dev Reverts if the given address is not indeed the owner of the token
* @param _owner owner of the token
* @param _tokenId uint256 ID of the token to be transferred
*/
function clearApproval(address _owner, uint256 _tokenId) internal {
require(ownerOf(_tokenId) == _owner);
if (tokenApprovals[_tokenId] != address(0)) {
tokenApprovals[_tokenId] = address(0);
emit Approval(_owner, address(0), _tokenId);
}
}
/**
* @dev Internal function to add a token ID to the list of a given address
* @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 addTokenTo(address _to, uint256 _tokenId) internal {
require(tokenOwner[_tokenId] == address(0));
tokenOwner[_tokenId] = _to;
ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
}
/**
* @dev Internal function to remove a token ID from the list of a given address
* @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 removeTokenFrom(address _from, uint256 _tokenId) internal {
require(ownerOf(_tokenId) == _from);
ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
tokenOwner[_tokenId] = address(0);
}
/**
* 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 _user address to check
* @return whether the target address is a contract
*/
function _isContract(address _user) internal view returns (bool) {
uint size;
assembly { size := extcodesize(_user) }
return size > 0;
}
/**
* @dev Internal function to invoke `onERC721Received` on a target address
* @dev 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 checkAndCallSafeTransfer(
address _from,
address _to,
uint256 _tokenId,
bytes _data
)
internal
returns (bool)
{
if (!_isContract(_to)) {
return true;
}
bytes4 retval = ERC721Receiver(_to).onERC721Received(_from, _tokenId, _data);
return (retval == ERC721_RECEIVED);
}
}
contract Owned {
address owner;
modifier onlyOwner {
require(msg.sender == owner);
_;
}
/// @dev Contract constructor
function Owned() public {
owner = msg.sender;
}
}
contract HeroLogicInterface {
function isTransferAllowed(address _from, address _to, uint256 _tokenId) public view returns (bool);
}
contract ETHero is Owned, ERC721, ERC721BasicToken {
struct HeroData {
uint16 fieldA;
uint16 fieldB;
uint32 fieldC;
uint32 fieldD;
uint32 fieldE;
uint64 fieldF;
uint64 fieldG;
}
// Token name
string internal name_;
// Token symbol
string internal symbol_;
// Mapping from owner to list of owned token IDs
mapping (address => uint256[]) internal ownedTokens;
// Mapping from token ID to index of the owner tokens list
mapping(uint256 => uint256) internal ownedTokensIndex;
// Array with all token ids, used for enumeration
uint256[] internal allTokens;
// Mapping from token id to position in the allTokens array
mapping(uint256 => uint256) internal allTokensIndex;
// Prefix for token URIs
string public tokenUriPrefix = "https://eth.town/hero-image/";
// Interchangeable logic contract
address public logicContract;
// Incremental uniqueness index for the genome
uint32 public uniquenessIndex = 0;
// Last token ID
uint256 public lastTokenId = 0;
// Users' active heroes
mapping(address => uint256) public activeHero;
// Hero data
mapping(uint256 => HeroData) public heroData;
// Genomes
mapping(uint256 => uint256) public genome;
event ActiveHeroChanged(address indexed _from, uint256 _tokenId);
modifier onlyLogicContract {
require(msg.sender == logicContract || msg.sender == owner);
_;
}
/**
* @dev Constructor function
*/
function ETHero() public {
name_ = "ETH.TOWN Hero";
symbol_ = "HERO";
}
/**
* @dev Sets the token's interchangeable logic contract
*/
function setLogicContract(address _logicContract) external onlyOwner {
logicContract = _logicContract;
}
/**
* @dev Gets the token name
* @return string representing the token name
*/
function name() public view returns (string) {
return name_;
}
/**
* @dev Gets the token symbol
* @return string representing the token symbol
*/
function symbol() public view returns (string) {
return symbol_;
}
/**
* @dev Internal function to check if transferring a specific token is allowed
* @param _from transfer from
* @param _to transfer to
* @param _tokenId token to transfer
*/
function _isTransferAllowed(address _from, address _to, uint256 _tokenId) internal view returns (bool) {
if (logicContract == address(0)) {
return true;
}
HeroLogicInterface logic = HeroLogicInterface(logicContract);
return logic.isTransferAllowed(_from, _to, _tokenId);
}
/**
* @dev Appends uint (in decimal) to a string
* @param _str The prefix string
* @param _value The uint to append
* @return resulting string
*/
function _appendUintToString(string _str, uint _value) internal pure returns (string) {
uint maxLength = 100;
bytes memory reversed = new bytes(maxLength);
uint i = 0;
while (_value != 0) {
uint remainder = _value % 10;
_value = _value / 10;
reversed[i++] = byte(48 + remainder);
}
i--;
bytes memory inStrB = bytes(_str);
bytes memory s = new bytes(inStrB.length + i + 1);
uint j;
for (j = 0; j < inStrB.length; j++) {
s[j] = inStrB[j];
}
for (j = 0; j <= i; j++) {
s[j + inStrB.length] = reversed[i - j];
}
return string(s);
}
/**
* @dev Returns an URI for a given token ID
* @dev Throws if the token ID does not exist
* @param _tokenId uint256 ID of the token to query
*/
function tokenURI(uint256 _tokenId) public view returns (string) {
require(exists(_tokenId));
return _appendUintToString(tokenUriPrefix, genome[_tokenId]);
}
/**
* @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));
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 allTokens.length;
}
/**
* @dev Gets the token ID at a given index of all the tokens in this contract
* @dev 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());
return allTokens[_index];
}
/**
* @dev Internal function to add a token ID to the list of a given address
* @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 addTokenTo(address _to, uint256 _tokenId) internal {
super.addTokenTo(_to, _tokenId);
uint256 length = ownedTokens[_to].length;
ownedTokens[_to].push(_tokenId);
ownedTokensIndex[_tokenId] = length;
if (activeHero[_to] == 0) {
activeHero[_to] = _tokenId;
emit ActiveHeroChanged(_to, _tokenId);
}
}
/**
* @dev Internal function to remove a token ID from the list of a given address
* @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 removeTokenFrom(address _from, uint256 _tokenId) internal {
super.removeTokenFrom(_from, _tokenId);
uint256 tokenIndex = ownedTokensIndex[_tokenId];
uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
uint256 lastToken = ownedTokens[_from][lastTokenIndex];
ownedTokens[_from][tokenIndex] = lastToken;
ownedTokens[_from][lastTokenIndex] = 0;
// Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
// be zero. Then we can make sure that we will remove _tokenId from the ownedTokens list since we are first swapping
// the lastToken to the first position, and then dropping the element placed in the last position of the list
ownedTokens[_from].length--;
ownedTokensIndex[_tokenId] = 0;
ownedTokensIndex[lastToken] = tokenIndex;
// If a hero is removed from its owner, it no longer can be their active hero
if (activeHero[_from] == _tokenId) {
activeHero[_from] = 0;
emit ActiveHeroChanged(_from, 0);
}
}
/**
* @dev Internal function to mint a new token
* @dev 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 by the msg.sender
*/
function _mint(address _to, uint256 _tokenId) internal {
require(_to != address(0));
addTokenTo(_to, _tokenId);
emit Transfer(address(0), _to, _tokenId);
allTokensIndex[_tokenId] = allTokens.length;
allTokens.push(_tokenId);
}
/**
* @dev External function to mint a new token
* @dev 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 by the msg.sender
*/
function mint(address _to, uint256 _tokenId) external onlyLogicContract {
_mint(_to, _tokenId);
}
/**
* @dev Internal function to burn a specific token
* @dev Reverts if the token does not exist
* @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 {
clearApproval(_owner, _tokenId);
removeTokenFrom(_owner, _tokenId);
emit Transfer(_owner, address(0), _tokenId);
// Reorg all tokens array
uint256 tokenIndex = allTokensIndex[_tokenId];
uint256 lastTokenIndex = allTokens.length.sub(1);
uint256 lastToken = allTokens[lastTokenIndex];
allTokens[tokenIndex] = lastToken;
allTokens[lastTokenIndex] = 0;
allTokens.length--;
allTokensIndex[_tokenId] = 0;
allTokensIndex[lastToken] = tokenIndex;
// Clear genome data
if (genome[_tokenId] != 0) {
genome[_tokenId] = 0;
}
}
/**
* @dev External function to burn a specific token
* @dev Reverts if the token does not exist
* @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) external onlyLogicContract {
_burn(_owner, _tokenId);
}
/**
* @dev Transfers the ownership of a given token ID to another address
* @dev Usage of this method is discouraged, use `safeTransferFrom` whenever possible
* @dev 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 canTransfer(_tokenId) {
require(_isTransferAllowed(_from, _to, _tokenId));
super.transferFrom(_from, _to, _tokenId);
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* @dev 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,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* @dev 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
canTransfer(_tokenId)
{
require(_isTransferAllowed(_from, _to, _tokenId));
super.safeTransferFrom(_from, _to, _tokenId);
}
/**
* @dev Safely transfers the ownership of a given token ID to another address
* @dev 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,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* @dev 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 _data)
public
canTransfer(_tokenId)
{
require(_isTransferAllowed(_from, _to, _tokenId));
super.safeTransferFrom(_from, _to, _tokenId, _data);
}
/**
* @dev Allows to transfer a token to another owner
* @param _to transfer to
* @param _tokenId token to transfer
*/
function transfer(address _to, uint256 _tokenId) external onlyOwnerOf(_tokenId) {
require(_isTransferAllowed(msg.sender, _to, _tokenId));
require(_to != address(0));
clearApproval(msg.sender, _tokenId);
removeTokenFrom(msg.sender, _tokenId);
addTokenTo(_to, _tokenId);
emit Transfer(msg.sender, _to, _tokenId);
}
/**
* @dev Sets the specified token as user's active Hero
* @param _tokenId the hero token to set as active
*/
function setActiveHero(uint256 _tokenId) external onlyOwnerOf(_tokenId) {
activeHero[msg.sender] = _tokenId;
emit ActiveHeroChanged(msg.sender, _tokenId);
}
/**
* @dev Queries list of tokens owned by a specific address
* @param _owner the address to get tokens of
*/
function tokensOfOwner(address _owner) external view returns (uint256[]) {
return ownedTokens[_owner];
}
/**
* @dev Gets the genome of the active hero
* @param _owner the address to get hero of
*/
function activeHeroGenome(address _owner) public view returns (uint256) {
uint256 tokenId = activeHero[_owner];
if (tokenId == 0) {
return 0;
}
return genome[tokenId];
}
/**
* @dev Increments uniqueness index. Overflow intentionally allowed.
*/
function incrementUniquenessIndex() external onlyLogicContract {
uniquenessIndex ++;
}
/**
* @dev Increments lastTokenId
*/
function incrementLastTokenId() external onlyLogicContract {
lastTokenId ++;
}
/**
* @dev Allows (re-)setting the uniqueness index
* @param _uniquenessIndex new value
*/
function setUniquenessIndex(uint32 _uniquenessIndex) external onlyOwner {
uniquenessIndex = _uniquenessIndex;
}
/**
* @dev Allows (re-)setting lastTokenId
* @param _lastTokenId new value
*/
function setLastTokenId(uint256 _lastTokenId) external onlyOwner {
lastTokenId = _lastTokenId;
}
/**
* @dev Allows setting hero data for a hero
* @param _tokenId hero to set data for
* @param _fieldA data to set
* @param _fieldB data to set
* @param _fieldC data to set
* @param _fieldD data to set
* @param _fieldE data to set
* @param _fieldF data to set
* @param _fieldG data to set
*/
function setHeroData(
uint256 _tokenId,
uint16 _fieldA,
uint16 _fieldB,
uint32 _fieldC,
uint32 _fieldD,
uint32 _fieldE,
uint64 _fieldF,
uint64 _fieldG
) external onlyLogicContract {
heroData[_tokenId] = HeroData(
_fieldA,
_fieldB,
_fieldC,
_fieldD,
_fieldE,
_fieldF,
_fieldG
);
}
/**
* @dev Allows setting hero genome
* @param _tokenId token to set data for
* @param _genome genome data to set
*/
function setGenome(uint256 _tokenId, uint256 _genome) external onlyLogicContract {
genome[_tokenId] = _genome;
}
/**
* @dev Allows the admin to forcefully transfer a token from one address to another
* @param _from transfer from
* @param _to transfer to
* @param _tokenId token to transfer
*/
function forceTransfer(address _from, address _to, uint256 _tokenId) external onlyLogicContract {
require(_from != address(0));
require(_to != address(0));
clearApproval(_from, _tokenId);
removeTokenFrom(_from, _tokenId);
addTokenTo(_to, _tokenId);
emit Transfer(_from, _to, _tokenId);
}
/**
* @dev External function to set the token URI prefix for all tokens
* @param _uriPrefix prefix string to assign
*/
function setTokenUriPrefix(string _uriPrefix) external onlyOwner {
tokenUriPrefix = _uriPrefix;
}
}
Read Contract
activeHero 0x1038a54e → uint256
activeHeroGenome 0x0b3464c3 → uint256
balanceOf 0x70a08231 → uint256
exists 0x4f558e79 → bool
genome 0xd8470576 → uint256
getApproved 0x081812fc → address
heroData 0x73b31190 → uint16, uint16, uint32, uint32, uint32, uint64, uint64
isApprovedForAll 0xe985e9c5 → bool
lastTokenId 0xf84ddf0b → uint256
logicContract 0xcc0e97c9 → address
name 0x06fdde03 → string
ownerOf 0x6352211e → address
symbol 0x95d89b41 → string
tokenByIndex 0x4f6ccce7 → uint256
tokenOfOwnerByIndex 0x2f745c59 → uint256
tokenURI 0xc87b56dd → string
tokenUriPrefix 0xfce87fb0 → string
tokensOfOwner 0x8462151c → uint256[]
totalSupply 0x18160ddd → uint256
uniquenessIndex 0xea79f33d → uint32
Write Contract 18 functions
These functions modify contract state and require a wallet transaction to execute.
approve 0x095ea7b3
address _to
uint256 _tokenId
burn 0x9dc29fac
address _owner
uint256 _tokenId
forceTransfer 0x33bebb77
address _from
address _to
uint256 _tokenId
incrementLastTokenId 0xb65c2b40
No parameters
incrementUniquenessIndex 0x14572dff
No parameters
mint 0x40c10f19
address _to
uint256 _tokenId
safeTransferFrom 0x42842e0e
address _from
address _to
uint256 _tokenId
safeTransferFrom 0xb88d4fde
address _from
address _to
uint256 _tokenId
bytes _data
setActiveHero 0x1d6c0dfa
uint256 _tokenId
setApprovalForAll 0xa22cb465
address _to
bool _approved
setGenome 0xf21f80d0
uint256 _tokenId
uint256 _genome
setHeroData 0x6a1af8b8
uint256 _tokenId
uint16 _fieldA
uint16 _fieldB
uint32 _fieldC
uint32 _fieldD
uint32 _fieldE
uint64 _fieldF
uint64 _fieldG
setLastTokenId 0xe81f35fd
uint256 _lastTokenId
setLogicContract 0x5aa4470f
address _logicContract
setTokenUriPrefix 0x532e4849
string _uriPrefix
setUniquenessIndex 0xa4482f41
uint32 _uniquenessIndex
transfer 0xa9059cbb
address _to
uint256 _tokenId
transferFrom 0x23b872dd
address _from
address _to
uint256 _tokenId
Recent Transactions
No transactions found for this address