Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x9978a912c018ac6d1cebd59109e227e5e051aa861cef2f8128b7f7fced15759c | Register | (pending) | 25 mins ago | IN | 0.001 ETH | (Pending) | |||
Register | 15713604 | 852 days ago | IN | 0.01 ETH | 0.02814463 | ||||
Configure Domain | 14624119 | 1025 days ago | IN | 0 ETH | 0.00164019 | ||||
Configure Domain | 14624097 | 1025 days ago | IN | 0 ETH | 0.00199416 | ||||
Configure Domain | 14624060 | 1025 days ago | IN | 0 ETH | 0.00246 | ||||
Configure Domain | 13885548 | 1139 days ago | IN | 0 ETH | 0.00206962 | ||||
Configure Domain | 13885515 | 1139 days ago | IN | 0 ETH | 0.00254488 | ||||
Configure Domain | 13885504 | 1139 days ago | IN | 0 ETH | 0.00231727 | ||||
Configure Domain | 13885493 | 1139 days ago | IN | 0 ETH | 0.00235691 | ||||
Configure Domain | 13885489 | 1139 days ago | IN | 0 ETH | 0.00209581 | ||||
Configure Domain | 13885412 | 1139 days ago | IN | 0 ETH | 0.00258395 | ||||
Configure Domain | 13885404 | 1139 days ago | IN | 0 ETH | 0.00161937 | ||||
Configure Domain | 13885386 | 1139 days ago | IN | 0 ETH | 0.00161748 | ||||
Transfer | 13462586 | 1206 days ago | IN | 0.04 ETH | 0.00170625 | ||||
Transfer | 13462574 | 1206 days ago | IN | 0.05 ETH | 0.00223593 | ||||
Register | 13004622 | 1277 days ago | IN | 0.05 ETH | 0.20205612 | ||||
Register | 12524765 | 1352 days ago | IN | 0.001 ETH | 0.00707916 | ||||
Register | 11808314 | 1462 days ago | IN | 0.001 ETH | 0.0032 | ||||
Register | 11807014 | 1462 days ago | IN | 0.001 ETH | 0.002475 | ||||
Configure Domain | 11677089 | 1482 days ago | IN | 0 ETH | 0.00169897 | ||||
Configure Domain | 11398308 | 1525 days ago | IN | 0 ETH | 0.00054624 | ||||
Register | 11394233 | 1526 days ago | IN | 0.001 ETH | 0.00622365 | ||||
Register | 11394206 | 1526 days ago | IN | 0.001 ETH | 0.0022393 | ||||
Configure Domain | 11389178 | 1526 days ago | IN | 0 ETH | 0.00095354 | ||||
Register | 11255224 | 1547 days ago | IN | 0.001 ETH | 0.00627626 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
15713604 | 852 days ago | 0.008 ETH | ||||
15713604 | 852 days ago | 0.002 ETH | ||||
13004622 | 1277 days ago | 0.05 ETH | ||||
12524765 | 1352 days ago | 0.001 ETH | ||||
11394233 | 1526 days ago | 0.001 ETH | ||||
11394206 | 1526 days ago | 0.001 ETH | ||||
11255224 | 1547 days ago | 0.001 ETH | ||||
11166787 | 1561 days ago | 0.001 ETH | ||||
10968524 | 1591 days ago | 0.001 ETH | ||||
10911970 | 1600 days ago | 0.001 ETH | ||||
10327829 | 1690 days ago | 0.001 ETH | ||||
10053627 | 1733 days ago | 0.001 ETH | ||||
10041542 | 1734 days ago | 0.001 ETH | ||||
9876789 | 1760 days ago | 0.001 ETH | ||||
9646445 | 1796 days ago | 0.001 ETH | ||||
9505082 | 1817 days ago | 0.001 ETH | ||||
9496721 | 1819 days ago | 0.001 ETH | ||||
9496686 | 1819 days ago | 0.001 ETH | ||||
9491706 | 1819 days ago | 0.001 ETH | ||||
9489865 | 1820 days ago | 0.001 ETH | ||||
9489836 | 1820 days ago | 0.001 ETH | ||||
9464084 | 1824 days ago | 0.01 ETH | ||||
9421033 | 1830 days ago | 0.0000425 ETH | ||||
9421033 | 1830 days ago | 0.0000075 ETH | ||||
9416874 | 1831 days ago | 0.0000425 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
EthRegistrarSubdomainRegistrar
Compiler Version
v0.5.8+commit.23d335f2
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-05-04 */ // File: @ensdomains/ens/contracts/ENS.sol pragma solidity >=0.4.24; interface ENS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external; function setResolver(bytes32 node, address resolver) external; function setOwner(bytes32 node, address owner) external; function setTTL(bytes32 node, uint64 ttl) external; function owner(bytes32 node) external view returns (address); function resolver(bytes32 node) external view returns (address); function ttl(bytes32 node) external view returns (uint64); } // File: @ensdomains/ens/contracts/Deed.sol pragma solidity >=0.4.24; interface Deed { function setOwner(address payable newOwner) external; function setRegistrar(address newRegistrar) external; function setBalance(uint newValue, bool throwOnFailure) external; function closeDeed(uint refundRatio) external; function destroyDeed() external; function owner() external view returns (address); function previousOwner() external view returns (address); function value() external view returns (uint); function creationDate() external view returns (uint); } // File: @ensdomains/ens/contracts/DeedImplementation.sol pragma solidity ^0.5.0; /** * @title Deed to hold ether in exchange for ownership of a node * @dev The deed can be controlled only by the registrar and can only send ether back to the owner. */ contract DeedImplementation is Deed { address payable constant burn = address(0xdead); address payable private _owner; address private _previousOwner; address private _registrar; uint private _creationDate; uint private _value; bool active; event OwnerChanged(address newOwner); event DeedClosed(); modifier onlyRegistrar { require(msg.sender == _registrar); _; } modifier onlyActive { require(active); _; } constructor(address payable initialOwner) public payable { _owner = initialOwner; _registrar = msg.sender; _creationDate = now; active = true; _value = msg.value; } function setOwner(address payable newOwner) external onlyRegistrar { require(newOwner != address(0x0)); _previousOwner = _owner; // This allows contracts to check who sent them the ownership _owner = newOwner; emit OwnerChanged(newOwner); } function setRegistrar(address newRegistrar) external onlyRegistrar { _registrar = newRegistrar; } function setBalance(uint newValue, bool throwOnFailure) external onlyRegistrar onlyActive { // Check if it has enough balance to set the value require(_value >= newValue); _value = newValue; // Send the difference to the owner require(_owner.send(address(this).balance - newValue) || !throwOnFailure); } /** * @dev Close a deed and refund a specified fraction of the bid value * * @param refundRatio The amount*1/1000 to refund */ function closeDeed(uint refundRatio) external onlyRegistrar onlyActive { active = false; require(burn.send(((1000 - refundRatio) * address(this).balance)/1000)); emit DeedClosed(); _destroyDeed(); } /** * @dev Close a deed and refund a specified fraction of the bid value */ function destroyDeed() external { _destroyDeed(); } function owner() external view returns (address) { return _owner; } function previousOwner() external view returns (address) { return _previousOwner; } function value() external view returns (uint) { return _value; } function creationDate() external view returns (uint) { _creationDate; } function _destroyDeed() internal { require(!active); // Instead of selfdestruct(owner), invoke owner fallback function to allow // owner to log an event if desired; but owner should also be aware that // its fallback function can also be invoked by setBalance if (_owner.send(address(this).balance)) { selfdestruct(burn); } } } // File: @ensdomains/ens/contracts/Registrar.sol pragma solidity >=0.4.24; interface Registrar { enum Mode { Open, Auction, Owned, Forbidden, Reveal, NotYetAvailable } event AuctionStarted(bytes32 indexed hash, uint registrationDate); event NewBid(bytes32 indexed hash, address indexed bidder, uint deposit); event BidRevealed(bytes32 indexed hash, address indexed owner, uint value, uint8 status); event HashRegistered(bytes32 indexed hash, address indexed owner, uint value, uint registrationDate); event HashReleased(bytes32 indexed hash, uint value); event HashInvalidated(bytes32 indexed hash, string indexed name, uint value, uint registrationDate); function startAuction(bytes32 _hash) external; function startAuctions(bytes32[] calldata _hashes) external; function newBid(bytes32 sealedBid) external payable; function startAuctionsAndBid(bytes32[] calldata hashes, bytes32 sealedBid) external payable; function unsealBid(bytes32 _hash, uint _value, bytes32 _salt) external; function cancelBid(address bidder, bytes32 seal) external; function finalizeAuction(bytes32 _hash) external; function transfer(bytes32 _hash, address payable newOwner) external; function releaseDeed(bytes32 _hash) external; function invalidateName(string calldata unhashedName) external; function eraseNode(bytes32[] calldata labels) external; function transferRegistrars(bytes32 _hash) external; function acceptRegistrarTransfer(bytes32 hash, Deed deed, uint registrationDate) external; function entries(bytes32 _hash) external view returns (Mode, address, uint, uint, uint); } // File: @ensdomains/ens/contracts/HashRegistrar.sol pragma solidity ^0.5.0; /* Temporary Hash Registrar ======================== This is a simplified version of a hash registrar. It is purporsefully limited: names cannot be six letters or shorter, new auctions will stop after 4 years. The plan is to test the basic features and then move to a new contract in at most 2 years, when some sort of renewal mechanism will be enabled. */ /** * @title Registrar * @dev The registrar handles the auction process for each subnode of the node it owns. */ contract HashRegistrar is Registrar { ENS public ens; bytes32 public rootNode; mapping (bytes32 => Entry) _entries; mapping (address => mapping (bytes32 => Deed)) public sealedBids; uint32 constant totalAuctionLength = 5 days; uint32 constant revealPeriod = 48 hours; uint32 public constant launchLength = 8 weeks; uint constant minPrice = 0.01 ether; uint public registryStarted; struct Entry { Deed deed; uint registrationDate; uint value; uint highestBid; } modifier inState(bytes32 _hash, Mode _state) { require(state(_hash) == _state); _; } modifier onlyOwner(bytes32 _hash) { require(state(_hash) == Mode.Owned && msg.sender == _entries[_hash].deed.owner()); _; } modifier registryOpen() { require(now >= registryStarted && now <= registryStarted + (365 * 4) * 1 days && ens.owner(rootNode) == address(this)); _; } /** * @dev Constructs a new Registrar, with the provided address as the owner of the root node. * * @param _ens The address of the ENS * @param _rootNode The hash of the rootnode. */ constructor(ENS _ens, bytes32 _rootNode, uint _startDate) public { ens = _ens; rootNode = _rootNode; registryStarted = _startDate > 0 ? _startDate : now; } /** * @dev Start an auction for an available hash * * @param _hash The hash to start an auction on */ function startAuction(bytes32 _hash) external { _startAuction(_hash); } /** * @dev Start multiple auctions for better anonymity * * Anyone can start an auction by sending an array of hashes that they want to bid for. * Arrays are sent so that someone can open up an auction for X dummy hashes when they * are only really interested in bidding for one. This will increase the cost for an * attacker to simply bid blindly on all new auctions. Dummy auctions that are * open but not bid on are closed after a week. * * @param _hashes An array of hashes, at least one of which you presumably want to bid on */ function startAuctions(bytes32[] calldata _hashes) external { _startAuctions(_hashes); } /** * @dev Submit a new sealed bid on a desired hash in a blind auction * * Bids are sent by sending a message to the main contract with a hash and an amount. The hash * contains information about the bid, including the bidded hash, the bid amount, and a random * salt. Bids are not tied to any one auction until they are revealed. The value of the bid * itself can be masqueraded by sending more than the value of your actual bid. This is * followed by a 48h reveal period. Bids revealed after this period will be burned and the ether unrecoverable. * Since this is an auction, it is expected that most public hashes, like known domains and common dictionary * words, will have multiple bidders pushing the price up. * * @param sealedBid A sealedBid, created by the shaBid function */ function newBid(bytes32 sealedBid) external payable { _newBid(sealedBid); } /** * @dev Start a set of auctions and bid on one of them * * This method functions identically to calling `startAuctions` followed by `newBid`, * but all in one transaction. * * @param hashes A list of hashes to start auctions on. * @param sealedBid A sealed bid for one of the auctions. */ function startAuctionsAndBid(bytes32[] calldata hashes, bytes32 sealedBid) external payable { _startAuctions(hashes); _newBid(sealedBid); } /** * @dev Submit the properties of a bid to reveal them * * @param _hash The node in the sealedBid * @param _value The bid amount in the sealedBid * @param _salt The sale in the sealedBid */ function unsealBid(bytes32 _hash, uint _value, bytes32 _salt) external { bytes32 seal = shaBid(_hash, msg.sender, _value, _salt); Deed bid = sealedBids[msg.sender][seal]; require(address(bid) != address(0x0)); sealedBids[msg.sender][seal] = Deed(address(0x0)); Entry storage h = _entries[_hash]; uint value = min(_value, bid.value()); bid.setBalance(value, true); Mode auctionState = state(_hash); if (auctionState == Mode.Owned) { // Too late! Bidder loses their bid. Gets 0.5% back. bid.closeDeed(5); emit BidRevealed(_hash, msg.sender, value, 1); } else if (auctionState != Mode.Reveal) { // Invalid phase revert(); } else if (value < minPrice || bid.creationDate() > h.registrationDate - revealPeriod) { // Bid too low or too late, refund 99.5% bid.closeDeed(995); emit BidRevealed(_hash, msg.sender, value, 0); } else if (value > h.highestBid) { // New winner // Cancel the other bid, refund 99.5% if (address(h.deed) != address(0x0)) { Deed previousWinner = h.deed; previousWinner.closeDeed(995); } // Set new winner // Per the rules of a vickery auction, the value becomes the previous highestBid h.value = h.highestBid; // will be zero if there's only 1 bidder h.highestBid = value; h.deed = bid; emit BidRevealed(_hash, msg.sender, value, 2); } else if (value > h.value) { // Not winner, but affects second place h.value = value; bid.closeDeed(995); emit BidRevealed(_hash, msg.sender, value, 3); } else { // Bid doesn't affect auction bid.closeDeed(995); emit BidRevealed(_hash, msg.sender, value, 4); } } /** * @dev Cancel a bid * * @param seal The value returned by the shaBid function */ function cancelBid(address bidder, bytes32 seal) external { Deed bid = sealedBids[bidder][seal]; // If a sole bidder does not `unsealBid` in time, they have a few more days // where they can call `startAuction` (again) and then `unsealBid` during // the revealPeriod to get back their bid value. // For simplicity, they should call `startAuction` within // 9 days (2 weeks - totalAuctionLength), otherwise their bid will be // cancellable by anyone. require(address(bid) != address(0x0) && now >= bid.creationDate() + totalAuctionLength + 2 weeks); // Send the canceller 0.5% of the bid, and burn the rest. bid.setOwner(msg.sender); bid.closeDeed(5); sealedBids[bidder][seal] = Deed(0); emit BidRevealed(seal, bidder, 0, 5); } /** * @dev Finalize an auction after the registration date has passed * * @param _hash The hash of the name the auction is for */ function finalizeAuction(bytes32 _hash) external onlyOwner(_hash) { Entry storage h = _entries[_hash]; // Handles the case when there's only a single bidder (h.value is zero) h.value = max(h.value, minPrice); h.deed.setBalance(h.value, true); trySetSubnodeOwner(_hash, h.deed.owner()); emit HashRegistered(_hash, h.deed.owner(), h.value, h.registrationDate); } /** * @dev The owner of a domain may transfer it to someone else at any time. * * @param _hash The node to transfer * @param newOwner The address to transfer ownership to */ function transfer(bytes32 _hash, address payable newOwner) external onlyOwner(_hash) { require(newOwner != address(0x0)); Entry storage h = _entries[_hash]; h.deed.setOwner(newOwner); trySetSubnodeOwner(_hash, newOwner); } /** * @dev After some time, or if we're no longer the registrar, the owner can release * the name and get their ether back. * * @param _hash The node to release */ function releaseDeed(bytes32 _hash) external onlyOwner(_hash) { Entry storage h = _entries[_hash]; Deed deedContract = h.deed; require(now >= h.registrationDate + 365 days || ens.owner(rootNode) != address(this)); h.value = 0; h.highestBid = 0; h.deed = Deed(0); _tryEraseSingleNode(_hash); deedContract.closeDeed(1000); emit HashReleased(_hash, h.value); } /** * @dev Submit a name 6 characters long or less. If it has been registered, * the submitter will earn 50% of the deed value. * * We are purposefully handicapping the simplified registrar as a way * to force it into being restructured in a few years. * * @param unhashedName An invalid name to search for in the registry. */ function invalidateName(string calldata unhashedName) external inState(keccak256(abi.encode(unhashedName)), Mode.Owned) { require(strlen(unhashedName) <= 6); bytes32 hash = keccak256(abi.encode(unhashedName)); Entry storage h = _entries[hash]; _tryEraseSingleNode(hash); if (address(h.deed) != address(0x0)) { // Reward the discoverer with 50% of the deed // The previous owner gets 50% h.value = max(h.value, minPrice); h.deed.setBalance(h.value/2, false); h.deed.setOwner(msg.sender); h.deed.closeDeed(1000); } emit HashInvalidated(hash, unhashedName, h.value, h.registrationDate); h.value = 0; h.highestBid = 0; h.deed = Deed(0); } /** * @dev Allows anyone to delete the owner and resolver records for a (subdomain of) a * name that is not currently owned in the registrar. If passing, eg, 'foo.bar.eth', * the owner and resolver fields on 'foo.bar.eth' and 'bar.eth' will all be cleared. * * @param labels A series of label hashes identifying the name to zero out, rooted at the * registrar's root. Must contain at least one element. For instance, to zero * 'foo.bar.eth' on a registrar that owns '.eth', pass an array containing * [keccak256('foo'), keccak256('bar')]. */ function eraseNode(bytes32[] calldata labels) external { require(labels.length != 0); require(state(labels[labels.length - 1]) != Mode.Owned); _eraseNodeHierarchy(labels.length - 1, labels, rootNode); } /** * @dev Transfers the deed to the current registrar, if different from this one. * * Used during the upgrade process to a permanent registrar. * * @param _hash The name hash to transfer. */ function transferRegistrars(bytes32 _hash) external onlyOwner(_hash) { address registrar = ens.owner(rootNode); require(registrar != address(this)); // Migrate the deed Entry storage h = _entries[_hash]; h.deed.setRegistrar(registrar); // Call the new registrar to accept the transfer Registrar(registrar).acceptRegistrarTransfer(_hash, h.deed, h.registrationDate); // Zero out the Entry h.deed = Deed(0); h.registrationDate = 0; h.value = 0; h.highestBid = 0; } /** * @dev Accepts a transfer from a previous registrar; stubbed out here since there * is no previous registrar implementing this interface. * * @param hash The sha3 hash of the label to transfer. * @param deed The Deed object for the name being transferred in. * @param registrationDate The date at which the name was originally registered. */ function acceptRegistrarTransfer(bytes32 hash, Deed deed, uint registrationDate) external { hash; deed; registrationDate; // Don't warn about unused variables } function entries(bytes32 _hash) external view returns (Mode, address, uint, uint, uint) { Entry storage h = _entries[_hash]; return (state(_hash), address(h.deed), h.registrationDate, h.value, h.highestBid); } // State transitions for names: // Open -> Auction (startAuction) // Auction -> Reveal // Reveal -> Owned // Reveal -> Open (if nobody bid) // Owned -> Open (releaseDeed or invalidateName) function state(bytes32 _hash) public view returns (Mode) { Entry storage entry = _entries[_hash]; if (!isAllowed(_hash, now)) { return Mode.NotYetAvailable; } else if (now < entry.registrationDate) { if (now < entry.registrationDate - revealPeriod) { return Mode.Auction; } else { return Mode.Reveal; } } else { if (entry.highestBid == 0) { return Mode.Open; } else { return Mode.Owned; } } } /** * @dev Determines if a name is available for registration yet * * Each name will be assigned a random date in which its auction * can be started, from 0 to 8 weeks * * @param _hash The hash to start an auction on * @param _timestamp The timestamp to query about */ function isAllowed(bytes32 _hash, uint _timestamp) public view returns (bool allowed) { return _timestamp > getAllowedTime(_hash); } /** * @dev Returns available date for hash * * The available time from the `registryStarted` for a hash is proportional * to its numeric value. * * @param _hash The hash to start an auction on */ function getAllowedTime(bytes32 _hash) public view returns (uint) { return registryStarted + ((launchLength * (uint(_hash) >> 128)) >> 128); // Right shift operator: a >> b == a / 2**b } /** * @dev Hash the values required for a secret bid * * @param hash The node corresponding to the desired namehash * @param value The bid amount * @param salt A random value to ensure secrecy of the bid * @return The hash of the bid values */ function shaBid(bytes32 hash, address owner, uint value, bytes32 salt) public pure returns (bytes32) { return keccak256(abi.encodePacked(hash, owner, value, salt)); } function _tryEraseSingleNode(bytes32 label) internal { if (ens.owner(rootNode) == address(this)) { ens.setSubnodeOwner(rootNode, label, address(this)); bytes32 node = keccak256(abi.encodePacked(rootNode, label)); ens.setResolver(node, address(0x0)); ens.setOwner(node, address(0x0)); } } function _startAuction(bytes32 _hash) internal registryOpen() { Mode mode = state(_hash); if (mode == Mode.Auction) return; require(mode == Mode.Open); Entry storage newAuction = _entries[_hash]; newAuction.registrationDate = now + totalAuctionLength; newAuction.value = 0; newAuction.highestBid = 0; emit AuctionStarted(_hash, newAuction.registrationDate); } function _startAuctions(bytes32[] memory _hashes) internal { for (uint i = 0; i < _hashes.length; i ++) { _startAuction(_hashes[i]); } } function _newBid(bytes32 sealedBid) internal { require(address(sealedBids[msg.sender][sealedBid]) == address(0x0)); require(msg.value >= minPrice); // Creates a new hash contract with the owner Deed bid = (new DeedImplementation).value(msg.value)(msg.sender); sealedBids[msg.sender][sealedBid] = bid; emit NewBid(sealedBid, msg.sender, msg.value); } function _eraseNodeHierarchy(uint idx, bytes32[] memory labels, bytes32 node) internal { // Take ownership of the node ens.setSubnodeOwner(node, labels[idx], address(this)); node = keccak256(abi.encodePacked(node, labels[idx])); // Recurse if there are more labels if (idx > 0) { _eraseNodeHierarchy(idx - 1, labels, node); } // Erase the resolver and owner records ens.setResolver(node, address(0x0)); ens.setOwner(node, address(0x0)); } /** * @dev Assign the owner in ENS, if we're still the registrar * * @param _hash hash to change owner * @param _newOwner new owner to transfer to */ function trySetSubnodeOwner(bytes32 _hash, address _newOwner) internal { if (ens.owner(rootNode) == address(this)) ens.setSubnodeOwner(rootNode, _hash, _newOwner); } /** * @dev Returns the maximum of two unsigned integers * * @param a A number to compare * @param b A number to compare * @return The maximum of two unsigned integers */ function max(uint a, uint b) internal pure returns (uint) { if (a > b) return a; else return b; } /** * @dev Returns the minimum of two unsigned integers * * @param a A number to compare * @param b A number to compare * @return The minimum of two unsigned integers */ function min(uint a, uint b) internal pure returns (uint) { if (a < b) return a; else return b; } /** * @dev Returns the length of a given string * * @param s The string to measure the length of * @return The length of the input string */ function strlen(string memory s) internal pure returns (uint) { s; // Don't warn about unused variables // Starting here means the LSB will be the byte we care about uint ptr; uint end; assembly { ptr := add(s, 1) end := add(mload(s), ptr) } uint len = 0; for (len; ptr < end; len++) { uint8 b; assembly { b := and(mload(ptr), 0xFF) } if (b < 0x80) { ptr += 1; } else if (b < 0xE0) { ptr += 2; } else if (b < 0xF0) { ptr += 3; } else if (b < 0xF8) { ptr += 4; } else if (b < 0xFC) { ptr += 5; } else { ptr += 6; } } return len; } } // File: openzeppelin-solidity/contracts/introspection/IERC165.sol pragma solidity ^0.5.0; /** * @title IERC165 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md */ interface IERC165 { /** * @notice Query if a contract implements an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721.sol pragma solidity ^0.5.0; /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract IERC721 is IERC165 { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function balanceOf(address owner) public view returns (uint256 balance); function ownerOf(uint256 tokenId) public view returns (address owner); function approve(address to, uint256 tokenId) public; function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; function isApprovedForAll(address owner, address operator) public view returns (bool); function transferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public; } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol pragma solidity ^0.5.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract IERC721Receiver { /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a `safeTransfer`. This function MUST return the function selector, * otherwise the caller will revert the transaction. The selector to be * returned can be obtained as `this.onERC721Received.selector`. This * function MAY throw to revert and reject the transfer. * Note: the ERC721 contract address is always the message sender. * @param operator The address which called `safeTransferFrom` function * @param from The address which previously owned the token * @param tokenId The NFT identifier which is being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) public returns (bytes4); } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: openzeppelin-solidity/contracts/utils/Address.sol pragma solidity ^0.5.0; /** * Utility library of inline functions on addresses */ library Address { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File: openzeppelin-solidity/contracts/introspection/ERC165.sol pragma solidity ^0.5.0; /** * @title ERC165 * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract ERC165 is IERC165 { bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor () internal { _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev internal method for registering an interface */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff); _supportedInterfaces[interfaceId] = true; } } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721.sol pragma solidity ^0.5.0; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721 is ERC165, IERC721 { using SafeMath for uint256; using Address for address; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping (uint256 => address) private _tokenOwner; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to number of owned token mapping (address => uint256) private _ownedTokensCount; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === * bytes4(keccak256('balanceOf(address)')) ^ * bytes4(keccak256('ownerOf(uint256)')) ^ * bytes4(keccak256('approve(address,uint256)')) ^ * bytes4(keccak256('getApproved(uint256)')) ^ * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ * bytes4(keccak256('isApprovedForAll(address,address)')) ^ * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ constructor () public { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); } /** * @dev Gets the balance of the specified address * @param owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address owner) public view returns (uint256) { require(owner != address(0)); return _ownedTokensCount[owner]; } /** * @dev Gets the owner of the specified token ID * @param tokenId uint256 ID of the token to query the owner of * @return owner address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { address owner = _tokenOwner[tokenId]; require(owner != address(0)); return owner; } /** * @dev Approves another address to transfer the given token ID * The zero address indicates there is no approved address. * There can only be one approved address per token at a given time. * Can only be called by the token owner or an approved operator. * @param to address to be approved for the given token ID * @param tokenId uint256 ID of the token to be approved */ function approve(address to, uint256 tokenId) public { address owner = ownerOf(tokenId); require(to != owner); require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev Gets the approved address for a token ID, or zero if no address set * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ function getApproved(uint256 tokenId) public view returns (address) { require(_exists(tokenId)); return _tokenApprovals[tokenId]; } /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf * @param to operator address to set the approval * @param approved representing the status of the approval to be set */ function setApprovalForAll(address to, bool approved) public { require(to != msg.sender); _operatorApprovals[msg.sender][to] = approved; emit ApprovalForAll(msg.sender, to, approved); } /** * @dev Tells whether an operator is approved by a given owner * @param owner owner address which you want to query the approval of * @param operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll(address owner, address operator) public view returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Transfers the ownership of a given token ID to another address * Usage of this method is discouraged, use `safeTransferFrom` whenever possible * Requires the msg sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function transferFrom(address from, address to, uint256 tokenId) public { require(_isApprovedOrOwner(msg.sender, tokenId)); _transferFrom(from, to, tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * * Requires the msg sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { transferFrom(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data)); } /** * @dev Returns whether the specified token exists * @param tokenId uint256 ID of the token to query the existence of * @return whether the token exists */ function _exists(uint256 tokenId) internal view returns (bool) { address owner = _tokenOwner[tokenId]; return owner != address(0); } /** * @dev Returns whether the given spender can transfer a given token ID * @param spender address of the spender to query * @param tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { require(to != address(0)); require(!_exists(tokenId)); _tokenOwner[tokenId] = to; _ownedTokensCount[to] = _ownedTokensCount[to].add(1); emit Transfer(address(0), to, tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { require(ownerOf(tokenId) == owner); _clearApproval(tokenId); _ownedTokensCount[owner] = _ownedTokensCount[owner].sub(1); _tokenOwner[tokenId] = address(0); emit Transfer(owner, address(0), tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * @param tokenId uint256 ID of the token being burned */ function _burn(uint256 tokenId) internal { _burn(ownerOf(tokenId), tokenId); } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { require(ownerOf(tokenId) == from); require(to != address(0)); _clearApproval(tokenId); _ownedTokensCount[from] = _ownedTokensCount[from].sub(1); _ownedTokensCount[to] = _ownedTokensCount[to].add(1); _tokenOwner[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Internal function to invoke `onERC721Received` on a target address * The call is not executed if the target address is not a contract * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) internal returns (bool) { if (!to.isContract()) { return true; } bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); return (retval == _ERC721_RECEIVED); } /** * @dev Private function to clear current approval of a given token ID * @param tokenId uint256 ID of the token to be transferred */ function _clearApproval(uint256 tokenId) private { if (_tokenApprovals[tokenId] != address(0)) { _tokenApprovals[tokenId] = address(0); } } } // File: openzeppelin-solidity/contracts/ownership/Ownable.sol pragma solidity ^0.5.0; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * @notice Renouncing to ownership will leave the contract without an owner. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: @ensdomains/ethregistrar/contracts/BaseRegistrar.sol pragma solidity >=0.4.24; contract BaseRegistrar is ERC721, Ownable { uint constant public GRACE_PERIOD = 90 days; event ControllerAdded(address indexed controller); event ControllerRemoved(address indexed controller); event NameMigrated(uint256 indexed id, address indexed owner, uint expires); event NameRegistered(uint256 indexed id, address indexed owner, uint expires); event NameRenewed(uint256 indexed id, uint expires); // Expiration timestamp for migrated domains. uint public transferPeriodEnds; // The ENS registry ENS public ens; // The namehash of the TLD this registrar owns (eg, .eth) bytes32 public baseNode; // The interim registrar HashRegistrar public previousRegistrar; // A map of addresses that are authorised to register and renew names. mapping(address=>bool) public controllers; // Authorises a controller, who can register and renew domains. function addController(address controller) external; // Revoke controller permission for an address. function removeController(address controller) external; // Set the resolver for the TLD this registrar manages. function setResolver(address resolver) external; // Returns the expiration timestamp of the specified label hash. function nameExpires(uint256 id) external view returns(uint); // Returns true iff the specified name is available for registration. function available(uint256 id) public view returns(bool); /** * @dev Register a name. */ function register(uint256 id, address owner, uint duration) external returns(uint); function renew(uint256 id, uint duration) external returns(uint); /** * @dev Reclaim ownership of a name in ENS, if you own it in the registrar. */ function reclaim(uint256 id, address owner) external; /** * @dev Transfers a registration from the initial registrar. * This function is called by the initial registrar when a user calls `transferRegistrars`. */ function acceptRegistrarTransfer(bytes32 label, Deed deed, uint) external; } // File: contracts/Resolver.sol pragma solidity ^0.5.0; /** * @dev A basic interface for ENS resolvers. */ contract Resolver { function supportsInterface(bytes4 interfaceID) public pure returns (bool); function addr(bytes32 node) public view returns (address); function setAddr(bytes32 node, address addr) public; } // File: contracts/RegistrarInterface.sol pragma solidity ^0.5.0; contract RegistrarInterface { event OwnerChanged(bytes32 indexed label, address indexed oldOwner, address indexed newOwner); event DomainConfigured(bytes32 indexed label); event DomainUnlisted(bytes32 indexed label); event NewRegistration(bytes32 indexed label, string subdomain, address indexed owner, address indexed referrer, uint price); event RentPaid(bytes32 indexed label, string subdomain, uint amount, uint expirationDate); // InterfaceID of these four methods is 0xc1b15f5a function query(bytes32 label, string calldata subdomain) external view returns (string memory domain, uint signupFee, uint rent, uint referralFeePPM); function register(bytes32 label, string calldata subdomain, address owner, address payable referrer, address resolver) external payable; function rentDue(bytes32 label, string calldata subdomain) external view returns (uint timestamp); function payRent(bytes32 label, string calldata subdomain) external payable; } // File: contracts/AbstractSubdomainRegistrar.sol pragma solidity ^0.5.0; contract AbstractSubdomainRegistrar is RegistrarInterface { // namehash('eth') bytes32 constant public TLD_NODE = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae; bool public stopped = false; address public registrarOwner; address public migration; address public registrar; ENS public ens; modifier owner_only(bytes32 label) { require(owner(label) == msg.sender); _; } modifier not_stopped() { require(!stopped); _; } modifier registrar_owner_only() { require(msg.sender == registrarOwner); _; } event DomainTransferred(bytes32 indexed label, string name); constructor(ENS _ens) public { ens = _ens; registrar = ens.owner(TLD_NODE); registrarOwner = msg.sender; } function doRegistration(bytes32 node, bytes32 label, address subdomainOwner, Resolver resolver) internal { // Get the subdomain so we can configure it ens.setSubnodeOwner(node, label, address(this)); bytes32 subnode = keccak256(abi.encodePacked(node, label)); // Set the subdomain's resolver ens.setResolver(subnode, address(resolver)); // Set the address record on the resolver resolver.setAddr(subnode, subdomainOwner); // Pass ownership of the new subdomain to the registrant ens.setOwner(subnode, subdomainOwner); } function supportsInterface(bytes4 interfaceID) public pure returns (bool) { return ( (interfaceID == 0x01ffc9a7) // supportsInterface(bytes4) || (interfaceID == 0xc1b15f5a) // RegistrarInterface ); } function rentDue(bytes32 label, string calldata subdomain) external view returns (uint timestamp) { return 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } /** * @dev Sets the resolver record for a name in ENS. * @param name The name to set the resolver for. * @param resolver The address of the resolver */ function setResolver(string memory name, address resolver) public owner_only(keccak256(bytes(name))) { bytes32 label = keccak256(bytes(name)); bytes32 node = keccak256(abi.encodePacked(TLD_NODE, label)); ens.setResolver(node, resolver); } /** * @dev Configures a domain for sale. * @param name The name to configure. * @param price The price in wei to charge for subdomain registrations * @param referralFeePPM The referral fee to offer, in parts per million */ function configureDomain(string memory name, uint price, uint referralFeePPM) public { configureDomainFor(name, price, referralFeePPM, msg.sender, address(0x0)); } /** * @dev Stops the registrar, disabling configuring of new domains. */ function stop() public not_stopped registrar_owner_only { stopped = true; } /** * @dev Sets the address where domains are migrated to. * @param _migration Address of the new registrar. */ function setMigrationAddress(address _migration) public registrar_owner_only { require(stopped); migration = _migration; } function transferOwnership(address newOwner) public registrar_owner_only { registrarOwner = newOwner; } function owner(bytes32 label) public view returns (address); function configureDomainFor(string memory name, uint price, uint referralFeePPM, address payable _owner, address _transfer) public; } // File: contracts/EthRegistrarSubdomainRegistrar.sol pragma solidity ^0.5.0; /** * @dev Implements an ENS registrar that sells subdomains on behalf of their owners. * * Users may register a subdomain by calling `register` with the name of the domain * they wish to register under, and the label hash of the subdomain they want to * register. They must also specify the new owner of the domain, and the referrer, * who is paid an optional finder's fee. The registrar then configures a simple * default resolver, which resolves `addr` lookups to the new owner, and sets * the `owner` account as the owner of the subdomain in ENS. * * New domains may be added by calling `configureDomain`, then transferring * ownership in the ENS registry to this contract. Ownership in the contract * may be transferred using `transfer`, and a domain may be unlisted for sale * using `unlistDomain`. There is (deliberately) no way to recover ownership * in ENS once the name is transferred to this registrar. * * Critically, this contract does not check one key property of a listed domain: * * - Is the name UTS46 normalised? * * User applications MUST check these two elements for each domain before * offering them to users for registration. * * Applications should additionally check that the domains they are offering to * register are controlled by this registrar, since calls to `register` will * fail if this is not the case. */ contract EthRegistrarSubdomainRegistrar is AbstractSubdomainRegistrar { struct Domain { string name; address payable owner; uint price; uint referralFeePPM; } mapping (bytes32 => Domain) domains; constructor(ENS ens) AbstractSubdomainRegistrar(ens) public { } /** * @dev owner returns the address of the account that controls a domain. * Initially this is a null address. If the name has been * transferred to this contract, then the internal mapping is consulted * to determine who controls it. If the owner is not set, * the owner of the domain in the Registrar is returned. * @param label The label hash of the deed to check. * @return The address owning the deed. */ function owner(bytes32 label) public view returns (address) { if (domains[label].owner != address(0x0)) { return domains[label].owner; } return BaseRegistrar(registrar).ownerOf(uint256(label)); } /** * @dev Transfers internal control of a name to a new account. Does not update * ENS. * @param name The name to transfer. * @param newOwner The address of the new owner. */ function transfer(string memory name, address payable newOwner) public owner_only(keccak256(bytes(name))) { bytes32 label = keccak256(bytes(name)); emit OwnerChanged(label, domains[label].owner, newOwner); domains[label].owner = newOwner; } /** * @dev Configures a domain, optionally transferring it to a new owner. * @param name The name to configure. * @param price The price in wei to charge for subdomain registrations. * @param referralFeePPM The referral fee to offer, in parts per million. * @param _owner The address to assign ownership of this domain to. * @param _transfer The address to set as the transfer address for the name * when the permanent registrar is replaced. Can only be set to a non-zero * value once. */ function configureDomainFor(string memory name, uint price, uint referralFeePPM, address payable _owner, address _transfer) public owner_only(keccak256(bytes(name))) { bytes32 label = keccak256(bytes(name)); Domain storage domain = domains[label]; if (BaseRegistrar(registrar).ownerOf(uint256(label)) != address(this)) { BaseRegistrar(registrar).transferFrom(msg.sender, address(this), uint256(label)); BaseRegistrar(registrar).reclaim(uint256(label), address(this)); } if (domain.owner != _owner) { domain.owner = _owner; } if (keccak256(bytes(domain.name)) != label) { // New listing domain.name = name; } domain.price = price; domain.referralFeePPM = referralFeePPM; emit DomainConfigured(label); } /** * @dev Unlists a domain * May only be called by the owner. * @param name The name of the domain to unlist. */ function unlistDomain(string memory name) public owner_only(keccak256(bytes(name))) { bytes32 label = keccak256(bytes(name)); Domain storage domain = domains[label]; emit DomainUnlisted(label); domain.name = ''; domain.price = 0; domain.referralFeePPM = 0; } /** * @dev Returns information about a subdomain. * @param label The label hash for the domain. * @param subdomain The label for the subdomain. * @return domain The name of the domain, or an empty string if the subdomain * is unavailable. * @return price The price to register a subdomain, in wei. * @return rent The rent to retain a subdomain, in wei per second. * @return referralFeePPM The referral fee for the dapp, in ppm. */ function query(bytes32 label, string calldata subdomain) external view returns (string memory domain, uint price, uint rent, uint referralFeePPM) { bytes32 node = keccak256(abi.encodePacked(TLD_NODE, label)); bytes32 subnode = keccak256(abi.encodePacked(node, keccak256(bytes(subdomain)))); if (ens.owner(subnode) != address(0x0)) { return ('', 0, 0, 0); } Domain storage data = domains[label]; return (data.name, data.price, 0, data.referralFeePPM); } /** * @dev Registers a subdomain. * @param label The label hash of the domain to register a subdomain of. * @param subdomain The desired subdomain label. * @param _subdomainOwner The account that should own the newly configured subdomain. * @param referrer The address of the account to receive the referral fee. */ function register(bytes32 label, string calldata subdomain, address _subdomainOwner, address payable referrer, address resolver) external not_stopped payable { address subdomainOwner = _subdomainOwner; bytes32 domainNode = keccak256(abi.encodePacked(TLD_NODE, label)); bytes32 subdomainLabel = keccak256(bytes(subdomain)); // Subdomain must not be registered already. require(ens.owner(keccak256(abi.encodePacked(domainNode, subdomainLabel))) == address(0)); Domain storage domain = domains[label]; // Domain must be available for registration require(keccak256(bytes(domain.name)) == label); // User must have paid enough require(msg.value >= domain.price); // Send any extra back if (msg.value > domain.price) { msg.sender.transfer(msg.value - domain.price); } // Send any referral fee uint256 total = domain.price; if (domain.referralFeePPM > 0 && referrer != address(0x0) && referrer != domain.owner) { uint256 referralFee = (domain.price * domain.referralFeePPM) / 1000000; referrer.transfer(referralFee); total -= referralFee; } // Send the registration fee if (total > 0) { domain.owner.transfer(total); } // Register the domain if (subdomainOwner == address(0x0)) { subdomainOwner = msg.sender; } doRegistration(domainNode, subdomainLabel, subdomainOwner, Resolver(resolver)); emit NewRegistration(label, subdomain, subdomainOwner, referrer, domain.price); } function rentDue(bytes32 label, string calldata subdomain) external view returns (uint timestamp) { return 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } /** * @dev Migrates the domain to a new registrar. * @param name The name of the domain to migrate. */ function migrate(string memory name) public owner_only(keccak256(bytes(name))) { require(stopped); require(migration != address(0x0)); bytes32 label = keccak256(bytes(name)); Domain storage domain = domains[label]; BaseRegistrar(registrar).approve(migration, uint256(label)); EthRegistrarSubdomainRegistrar(migration).configureDomainFor( domain.name, domain.price, domain.referralFeePPM, domain.owner, address(0x0) ); delete domains[label]; emit DomainTransferred(label, name); } function payRent(bytes32 label, string calldata subdomain) external payable { revert(); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[{"name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"label","type":"bytes32"}],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"migration","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"registrarOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"registrar","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"label","type":"bytes32"},{"name":"subdomain","type":"string"}],"name":"query","outputs":[{"name":"domain","type":"string"},{"name":"price","type":"uint256"},{"name":"rent","type":"uint256"},{"name":"referralFeePPM","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ens","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"label","type":"bytes32"},{"name":"subdomain","type":"string"},{"name":"_subdomainOwner","type":"address"},{"name":"referrer","type":"address"},{"name":"resolver","type":"address"}],"name":"register","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_migration","type":"address"}],"name":"setMigrationAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"label","type":"bytes32"},{"name":"subdomain","type":"string"}],"name":"rentDue","outputs":[{"name":"timestamp","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"resolver","type":"address"}],"name":"setResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"TLD_NODE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"}],"name":"migrate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"label","type":"bytes32"},{"name":"subdomain","type":"string"}],"name":"payRent","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"price","type":"uint256"},{"name":"referralFeePPM","type":"uint256"},{"name":"_owner","type":"address"},{"name":"_transfer","type":"address"}],"name":"configureDomainFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"price","type":"uint256"},{"name":"referralFeePPM","type":"uint256"}],"name":"configureDomain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"}],"name":"unlistDomain","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"newOwner","type":"address"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"ens","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"label","type":"bytes32"},{"indexed":false,"name":"name","type":"string"}],"name":"DomainTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"label","type":"bytes32"},{"indexed":true,"name":"oldOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"label","type":"bytes32"}],"name":"DomainConfigured","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"label","type":"bytes32"}],"name":"DomainUnlisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"label","type":"bytes32"},{"indexed":false,"name":"subdomain","type":"string"},{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"referrer","type":"address"},{"indexed":false,"name":"price","type":"uint256"}],"name":"NewRegistration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"label","type":"bytes32"},{"indexed":false,"name":"subdomain","type":"string"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"expirationDate","type":"uint256"}],"name":"RentPaid","type":"event"}]
Contract Creation Code
608060405260008060006101000a81548160ff02191690831515021790555034801561002a57600080fd5b5060405160208062002c3f8339810180604052602081101561004b57600080fd5b81019080805190602001909291905050508080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be37f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561013457600080fd5b505afa158015610148573d6000803e3d6000fd5b505050506040513d602081101561015e57600080fd5b8101908080519060200190929190505050600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050612a3d80620002026000396000f3fe60806040526004361061012a5760003560e01c8063660b7ad5116100ab578063cb01a9bf1161006f578063cb01a9bf1461088f578063cf77525514610912578063da1fe7d514610a2e578063e34e788914610b0a578063f2fde38b14610bd2578063fbf58b3e14610c235761012a565b8063660b7ad5146105e1578063733ccaba1461068557806375f12b211461076d57806396df35401461079c578063c9c5b5b4146107c75761012a565b80632b20e397116100f25780632b20e397146102e15780632eef3d65146103385780633f15457f146104565780634254b155146104ad5780634732a7dc146105905761012a565b806301ffc9a71461012f57806302571be3146101a157806307da68f51461021c5780631705a3bd146102335780631cb82d791461028a575b600080fd5b34801561013b57600080fd5b506101876004803603602081101561015257600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610d0b565b604051808215151515815260200191505060405180910390f35b3480156101ad57600080fd5b506101da600480360360208110156101c457600080fd5b8101908080359060200190929190505050610d6d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561022857600080fd5b50610231610ecf565b005b34801561023f57600080fd5b50610248610f5e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561029657600080fd5b5061029f610f84565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156102ed57600080fd5b506102f6610faa565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561034457600080fd5b506103c66004803603604081101561035b57600080fd5b81019080803590602001909291908035906020019064010000000081111561038257600080fd5b82018360208201111561039457600080fd5b803590602001918460018302840111640100000000831117156103b657600080fd5b9091929391929390505050610fd0565b6040518080602001858152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156104185780820151818401526020810190506103fd565b50505050905090810190601f1680156104455780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561046257600080fd5b5061046b611269565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61058e600480360360a08110156104c357600080fd5b8101908080359060200190929190803590602001906401000000008111156104ea57600080fd5b8201836020820111156104fc57600080fd5b8035906020019184600183028401116401000000008311171561051e57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061128f565b005b34801561059c57600080fd5b506105df600480360360208110156105b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117ac565b005b3480156105ed57600080fd5b5061066f6004803603604081101561060457600080fd5b81019080803590602001909291908035906020019064010000000081111561062b57600080fd5b82018360208201111561063d57600080fd5b8035906020019184600183028401116401000000008311171561065f57600080fd5b9091929391929390505050611862565b6040518082815260200191505060405180910390f35b34801561069157600080fd5b5061076b600480360360408110156106a857600080fd5b81019080803590602001906401000000008111156106c557600080fd5b8201836020820111156106d757600080fd5b803590602001918460018302840111640100000000831117156106f957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061188e565b005b34801561077957600080fd5b50610782611a00565b604051808215151515815260200191505060405180910390f35b3480156107a857600080fd5b506107b1611a12565b6040518082815260200191505060405180910390f35b3480156107d357600080fd5b5061088d600480360360208110156107ea57600080fd5b810190808035906020019064010000000081111561080757600080fd5b82018360208201111561081957600080fd5b8035906020019184600183028401116401000000008311171561083b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611a39565b005b610910600480360360408110156108a557600080fd5b8101908080359060200190929190803590602001906401000000008111156108cc57600080fd5b8201836020820111156108de57600080fd5b8035906020019184600183028401116401000000008311171561090057600080fd5b9091929391929390505050611eb5565b005b34801561091e57600080fd5b50610a2c600480360360a081101561093557600080fd5b810190808035906020019064010000000081111561095257600080fd5b82018360208201111561096457600080fd5b8035906020019184600183028401116401000000008311171561098657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611eba565b005b348015610a3a57600080fd5b50610b0860048036036060811015610a5157600080fd5b8101908080359060200190640100000000811115610a6e57600080fd5b820183602082011115610a8057600080fd5b80359060200191846001830284011164010000000083111715610aa257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919080359060200190929190505050612335565b005b348015610b1657600080fd5b50610bd060048036036020811015610b2d57600080fd5b8101908080359060200190640100000000811115610b4a57600080fd5b820183602082011115610b5c57600080fd5b80359060200191846001830284011164010000000083111715610b7e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612348565b005b348015610bde57600080fd5b50610c2160048036036020811015610bf557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612422565b005b348015610c2f57600080fd5b50610d0960048036036040811015610c4657600080fd5b8101908080359060200190640100000000811115610c6357600080fd5b820183602082011115610c7557600080fd5b80359060200191846001830284011164010000000083111715610c9757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506124c0565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d66575063c1b15f5a60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166004600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e16576004600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610eca565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8360001c6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e8c57600080fd5b505afa158015610ea0573d6000803e3d6000fd5b505050506040513d6020811015610eb657600080fd5b810190808051906020019092919050505090505b919050565b6000809054906101000a900460ff1615610ee857600080fd5b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f4257600080fd5b60016000806101000a81548160ff021916908315150217905550565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606000806000807f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b886040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600081888860405180838380828437808301925050509250505060405180910390206040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561110857600080fd5b505afa15801561111c573d6000803e3d6000fd5b505050506040513d602081101561113257600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161461118e5760008060006040518060200160405280600081525092919082925081915080905095509550955095505050611260565b6000600460008b8152602001908152602001600020905080600001816002015460008360030154838054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561124a5780601f1061121f5761010080835404028352916020019161124a565b820191906000526020600020905b81548152906001019060200180831161122d57829003601f168201915b5050505050935081915096509650965096505050505b93509350935093565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900460ff16156112a857600080fd5b600083905060007f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b8860405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000878760405180838380828437808301925050509250505060405180910390209050600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be384846040516020018083815260200182815260200192505050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156113df57600080fd5b505afa1580156113f3573d6000803e3d6000fd5b505050506040513d602081101561140957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161461143a57600080fd5b6000600460008b81526020019081526020016000209050898160000160405180828054600181600116156101000203166002900480156114b15780601f1061148f5761010080835404028352918201916114b1565b820191906000526020600020905b81548152906001019060200180831161149d575b50509150506040518091039020146114c857600080fd5b80600201543410156114d957600080fd5b8060020154341115611533573373ffffffffffffffffffffffffffffffffffffffff166108fc826002015434039081150290604051600060405180830381858888f19350505050158015611531573d6000803e3d6000fd5b505b6000816002015490506000826003015411801561157d5750600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614155b80156115d957508160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614155b15611647576000620f42408360030154846002015402816115f657fe5b0490508773ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561163f573d6000803e3d6000fd5b508082039150505b60008111156116bc578160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156116ba573d6000803e3d6000fd5b505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156116f5573394505b61170184848789612600565b8673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168c7ffa38f9920801763ca6e4ee19135fb26a4fa11c0a34f7117455064991a1a3e6588d8d876002015460405180806020018381526020018281038252858582818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060405180910390a45050505050505050505050565b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461180657600080fd5b6000809054906101000a900460ff1661181e57600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90509392505050565b81805190602001203373ffffffffffffffffffffffffffffffffffffffff166118b682610d6d565b73ffffffffffffffffffffffffffffffffffffffff16146118d657600080fd5b60008380519060200120905060007f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b826040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a82866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156119e157600080fd5b505af11580156119f5573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900460ff1681565b7f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b81565b80805190602001203373ffffffffffffffffffffffffffffffffffffffff16611a6182610d6d565b73ffffffffffffffffffffffffffffffffffffffff1614611a8157600080fd5b6000809054906101000a900460ff16611a9957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611af557600080fd5b6000828051906020012090506000600460008381526020019081526020016000209050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460001c6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611be657600080fd5b505af1158015611bfa573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cf77525582600001836002015484600301548560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660006040518663ffffffff1660e01b815260040180806020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015611d795780601f10611d4e57610100808354040283529160200191611d79565b820191906000526020600020905b815481529060010190602001808311611d5c57829003601f168201915b50509650505050505050600060405180830381600087803b158015611d9d57600080fd5b505af1158015611db1573d6000803e3d6000fd5b505050506004600083815260200190815260200160002060008082016000611dd99190612924565b6001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600282016000905560038201600090555050817f8c0dd32279c25300d82425bebe31a5c703918d83d2bb57a1155dfa6cbba61cf8856040518080602001828103825283818151815260200191508051906020019080838360005b83811015611e75578082015181840152602081019050611e5a565b50505050905090810190601f168015611ea25780820380516001836020036101000a031916815260200191505b509250505060405180910390a250505050565b600080fd5b84805190602001203373ffffffffffffffffffffffffffffffffffffffff16611ee282610d6d565b73ffffffffffffffffffffffffffffffffffffffff1614611f0257600080fd5b60008680519060200120905060006004600083815260200190815260200160002090503073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8460001c6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611fb257600080fd5b505afa158015611fc6573d6000803e3d6000fd5b505050506040513d6020811015611fdc57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16146121c557600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd33308560001c6040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1580156120e857600080fd5b505af11580156120fc573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166328ed4f6c8360001c306040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156121ac57600080fd5b505af11580156121c0573d6000803e3d6000fd5b505050505b8473ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461226057848160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b818160000160405180828054600181600116156101000203166002900480156122c05780601f1061229e5761010080835404028352918201916122c0565b820191906000526020600020905b8154815290600101906020018083116122ac575b50509150506040518091039020146122ec57878160000190805190602001906122ea92919061296c565b505b868160020181905550858160030181905550817f1427993bb6b6c16d8953c450c37078c8f41196e2e2db1619cda06620143e2d9160405160405180910390a25050505050505050565b612343838383336000611eba565b505050565b80805190602001203373ffffffffffffffffffffffffffffffffffffffff1661237082610d6d565b73ffffffffffffffffffffffffffffffffffffffff161461239057600080fd5b6000828051906020012090506000600460008381526020019081526020016000209050817f77f7b610de5055c8f704e6a3b12874468f5785f3a7d1007b67a8a4b4c7ed88fc60405160405180910390a26040518060200160405280600081525081600001908051906020019061240792919061296c565b50600081600201819055506000816003018190555050505050565b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461247c57600080fd5b80600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b81805190602001203373ffffffffffffffffffffffffffffffffffffffff166124e882610d6d565b73ffffffffffffffffffffffffffffffffffffffff161461250857600080fd5b6000838051906020012090508273ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16827f06e9c07310f63759634ddbb7257dbb19ca404f90bd6bdef1d3386fab033cebce60405160405180910390a4826004600083815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59238585306040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b1580156126b157600080fd5b505af11580156126c5573d6000803e3d6000fd5b50505050600084846040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a82846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156127a557600080fd5b505af11580156127b9573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663d5fa2b0082856040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561284457600080fd5b505af1158015612858573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c382856040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561290557600080fd5b505af1158015612919573d6000803e3d6000fd5b505050505050505050565b50805460018160011615610100020316600290046000825580601f1061294a5750612969565b601f01602090049060005260206000209081019061296891906129ec565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106129ad57805160ff19168380011785556129db565b828001600101855582156129db579182015b828111156129da5782518255916020019190600101906129bf565b5b5090506129e891906129ec565b5090565b612a0e91905b80821115612a0a5760008160009055506001016129f2565b5090565b9056fea165627a7a72305820ba111398a73297111db3990209a267f2adfa8cfcf6087dc697cff5085b68edfc0029000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b
Deployed Bytecode
0x60806040526004361061012a5760003560e01c8063660b7ad5116100ab578063cb01a9bf1161006f578063cb01a9bf1461088f578063cf77525514610912578063da1fe7d514610a2e578063e34e788914610b0a578063f2fde38b14610bd2578063fbf58b3e14610c235761012a565b8063660b7ad5146105e1578063733ccaba1461068557806375f12b211461076d57806396df35401461079c578063c9c5b5b4146107c75761012a565b80632b20e397116100f25780632b20e397146102e15780632eef3d65146103385780633f15457f146104565780634254b155146104ad5780634732a7dc146105905761012a565b806301ffc9a71461012f57806302571be3146101a157806307da68f51461021c5780631705a3bd146102335780631cb82d791461028a575b600080fd5b34801561013b57600080fd5b506101876004803603602081101561015257600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610d0b565b604051808215151515815260200191505060405180910390f35b3480156101ad57600080fd5b506101da600480360360208110156101c457600080fd5b8101908080359060200190929190505050610d6d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561022857600080fd5b50610231610ecf565b005b34801561023f57600080fd5b50610248610f5e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561029657600080fd5b5061029f610f84565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156102ed57600080fd5b506102f6610faa565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561034457600080fd5b506103c66004803603604081101561035b57600080fd5b81019080803590602001909291908035906020019064010000000081111561038257600080fd5b82018360208201111561039457600080fd5b803590602001918460018302840111640100000000831117156103b657600080fd5b9091929391929390505050610fd0565b6040518080602001858152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156104185780820151818401526020810190506103fd565b50505050905090810190601f1680156104455780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561046257600080fd5b5061046b611269565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61058e600480360360a08110156104c357600080fd5b8101908080359060200190929190803590602001906401000000008111156104ea57600080fd5b8201836020820111156104fc57600080fd5b8035906020019184600183028401116401000000008311171561051e57600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061128f565b005b34801561059c57600080fd5b506105df600480360360208110156105b357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117ac565b005b3480156105ed57600080fd5b5061066f6004803603604081101561060457600080fd5b81019080803590602001909291908035906020019064010000000081111561062b57600080fd5b82018360208201111561063d57600080fd5b8035906020019184600183028401116401000000008311171561065f57600080fd5b9091929391929390505050611862565b6040518082815260200191505060405180910390f35b34801561069157600080fd5b5061076b600480360360408110156106a857600080fd5b81019080803590602001906401000000008111156106c557600080fd5b8201836020820111156106d757600080fd5b803590602001918460018302840111640100000000831117156106f957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061188e565b005b34801561077957600080fd5b50610782611a00565b604051808215151515815260200191505060405180910390f35b3480156107a857600080fd5b506107b1611a12565b6040518082815260200191505060405180910390f35b3480156107d357600080fd5b5061088d600480360360208110156107ea57600080fd5b810190808035906020019064010000000081111561080757600080fd5b82018360208201111561081957600080fd5b8035906020019184600183028401116401000000008311171561083b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611a39565b005b610910600480360360408110156108a557600080fd5b8101908080359060200190929190803590602001906401000000008111156108cc57600080fd5b8201836020820111156108de57600080fd5b8035906020019184600183028401116401000000008311171561090057600080fd5b9091929391929390505050611eb5565b005b34801561091e57600080fd5b50610a2c600480360360a081101561093557600080fd5b810190808035906020019064010000000081111561095257600080fd5b82018360208201111561096457600080fd5b8035906020019184600183028401116401000000008311171561098657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611eba565b005b348015610a3a57600080fd5b50610b0860048036036060811015610a5157600080fd5b8101908080359060200190640100000000811115610a6e57600080fd5b820183602082011115610a8057600080fd5b80359060200191846001830284011164010000000083111715610aa257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919080359060200190929190505050612335565b005b348015610b1657600080fd5b50610bd060048036036020811015610b2d57600080fd5b8101908080359060200190640100000000811115610b4a57600080fd5b820183602082011115610b5c57600080fd5b80359060200191846001830284011164010000000083111715610b7e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612348565b005b348015610bde57600080fd5b50610c2160048036036020811015610bf557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612422565b005b348015610c2f57600080fd5b50610d0960048036036040811015610c4657600080fd5b8101908080359060200190640100000000811115610c6357600080fd5b820183602082011115610c7557600080fd5b80359060200191846001830284011164010000000083111715610c9757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506124c0565b005b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610d66575063c1b15f5a60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff166004600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e16576004600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610eca565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8360001c6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610e8c57600080fd5b505afa158015610ea0573d6000803e3d6000fd5b505050506040513d6020811015610eb657600080fd5b810190808051906020019092919050505090505b919050565b6000809054906101000a900460ff1615610ee857600080fd5b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f4257600080fd5b60016000806101000a81548160ff021916908315150217905550565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606000806000807f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b886040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600081888860405180838380828437808301925050509250505060405180910390206040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be3836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561110857600080fd5b505afa15801561111c573d6000803e3d6000fd5b505050506040513d602081101561113257600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161461118e5760008060006040518060200160405280600081525092919082925081915080905095509550955095505050611260565b6000600460008b8152602001908152602001600020905080600001816002015460008360030154838054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561124a5780601f1061121f5761010080835404028352916020019161124a565b820191906000526020600020905b81548152906001019060200180831161122d57829003601f168201915b5050505050935081915096509650965096505050505b93509350935093565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900460ff16156112a857600080fd5b600083905060007f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b8860405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000878760405180838380828437808301925050509250505060405180910390209050600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166302571be384846040516020018083815260200182815260200192505050604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156113df57600080fd5b505afa1580156113f3573d6000803e3d6000fd5b505050506040513d602081101561140957600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161461143a57600080fd5b6000600460008b81526020019081526020016000209050898160000160405180828054600181600116156101000203166002900480156114b15780601f1061148f5761010080835404028352918201916114b1565b820191906000526020600020905b81548152906001019060200180831161149d575b50509150506040518091039020146114c857600080fd5b80600201543410156114d957600080fd5b8060020154341115611533573373ffffffffffffffffffffffffffffffffffffffff166108fc826002015434039081150290604051600060405180830381858888f19350505050158015611531573d6000803e3d6000fd5b505b6000816002015490506000826003015411801561157d5750600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614155b80156115d957508160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614155b15611647576000620f42408360030154846002015402816115f657fe5b0490508773ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561163f573d6000803e3d6000fd5b508082039150505b60008111156116bc578160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156116ba573d6000803e3d6000fd5b505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156116f5573394505b61170184848789612600565b8673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff168c7ffa38f9920801763ca6e4ee19135fb26a4fa11c0a34f7117455064991a1a3e6588d8d876002015460405180806020018381526020018281038252858582818152602001925080828437600081840152601f19601f82011690508083019250505094505050505060405180910390a45050505050505050505050565b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461180657600080fd5b6000809054906101000a900460ff1661181e57600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90509392505050565b81805190602001203373ffffffffffffffffffffffffffffffffffffffff166118b682610d6d565b73ffffffffffffffffffffffffffffffffffffffff16146118d657600080fd5b60008380519060200120905060007f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b826040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a82866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156119e157600080fd5b505af11580156119f5573d6000803e3d6000fd5b505050505050505050565b6000809054906101000a900460ff1681565b7f93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae60001b81565b80805190602001203373ffffffffffffffffffffffffffffffffffffffff16611a6182610d6d565b73ffffffffffffffffffffffffffffffffffffffff1614611a8157600080fd5b6000809054906101000a900460ff16611a9957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611af557600080fd5b6000828051906020012090506000600460008381526020019081526020016000209050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460001c6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611be657600080fd5b505af1158015611bfa573d6000803e3d6000fd5b50505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663cf77525582600001836002015484600301548560010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660006040518663ffffffff1660e01b815260040180806020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825287818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015611d795780601f10611d4e57610100808354040283529160200191611d79565b820191906000526020600020905b815481529060010190602001808311611d5c57829003601f168201915b50509650505050505050600060405180830381600087803b158015611d9d57600080fd5b505af1158015611db1573d6000803e3d6000fd5b505050506004600083815260200190815260200160002060008082016000611dd99190612924565b6001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600282016000905560038201600090555050817f8c0dd32279c25300d82425bebe31a5c703918d83d2bb57a1155dfa6cbba61cf8856040518080602001828103825283818151815260200191508051906020019080838360005b83811015611e75578082015181840152602081019050611e5a565b50505050905090810190601f168015611ea25780820380516001836020036101000a031916815260200191505b509250505060405180910390a250505050565b600080fd5b84805190602001203373ffffffffffffffffffffffffffffffffffffffff16611ee282610d6d565b73ffffffffffffffffffffffffffffffffffffffff1614611f0257600080fd5b60008680519060200120905060006004600083815260200190815260200160002090503073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e8460001c6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611fb257600080fd5b505afa158015611fc6573d6000803e3d6000fd5b505050506040513d6020811015611fdc57600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff16146121c557600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd33308560001c6040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050600060405180830381600087803b1580156120e857600080fd5b505af11580156120fc573d6000803e3d6000fd5b50505050600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166328ed4f6c8360001c306040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156121ac57600080fd5b505af11580156121c0573d6000803e3d6000fd5b505050505b8473ffffffffffffffffffffffffffffffffffffffff168160010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461226057848160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b818160000160405180828054600181600116156101000203166002900480156122c05780601f1061229e5761010080835404028352918201916122c0565b820191906000526020600020905b8154815290600101906020018083116122ac575b50509150506040518091039020146122ec57878160000190805190602001906122ea92919061296c565b505b868160020181905550858160030181905550817f1427993bb6b6c16d8953c450c37078c8f41196e2e2db1619cda06620143e2d9160405160405180910390a25050505050505050565b612343838383336000611eba565b505050565b80805190602001203373ffffffffffffffffffffffffffffffffffffffff1661237082610d6d565b73ffffffffffffffffffffffffffffffffffffffff161461239057600080fd5b6000828051906020012090506000600460008381526020019081526020016000209050817f77f7b610de5055c8f704e6a3b12874468f5785f3a7d1007b67a8a4b4c7ed88fc60405160405180910390a26040518060200160405280600081525081600001908051906020019061240792919061296c565b50600081600201819055506000816003018190555050505050565b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461247c57600080fd5b80600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b81805190602001203373ffffffffffffffffffffffffffffffffffffffff166124e882610d6d565b73ffffffffffffffffffffffffffffffffffffffff161461250857600080fd5b6000838051906020012090508273ffffffffffffffffffffffffffffffffffffffff166004600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16827f06e9c07310f63759634ddbb7257dbb19ca404f90bd6bdef1d3386fab033cebce60405160405180910390a4826004600083815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166306ab59238585306040518463ffffffff1660e01b8152600401808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019350505050600060405180830381600087803b1580156126b157600080fd5b505af11580156126c5573d6000803e3d6000fd5b50505050600084846040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16631896f70a82846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b1580156127a557600080fd5b505af11580156127b9573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663d5fa2b0082856040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561284457600080fd5b505af1158015612858573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b0fc9c382856040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b15801561290557600080fd5b505af1158015612919573d6000803e3d6000fd5b505050505050505050565b50805460018160011615610100020316600290046000825580601f1061294a5750612969565b601f01602090049060005260206000209081019061296891906129ec565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106129ad57805160ff19168380011785556129db565b828001600101855582156129db579182015b828111156129da5782518255916020019190600101906129bf565b5b5090506129e891906129ec565b5090565b612a0e91905b80821115612a0a5760008160009055506001016129f2565b5090565b9056fea165627a7a72305820ba111398a73297111db3990209a267f2adfa8cfcf6087dc697cff5085b68edfc0029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b
-----Decoded View---------------
Arg [0] : ens (address): 0x314159265dD8dbb310642f98f50C066173C1259b
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000314159265dd8dbb310642f98f50c066173c1259b
Swarm Source
bzzr://ba111398a73297111db3990209a267f2adfa8cfcf6087dc697cff5085b68edfc
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.