Latest 5 txns

TxHash Age From To Value [TxFee]
0x2782234a31de461bb0e727dc46f1c09f079990cf820ed00a699f2440b44c392d7 days 9 hrs ago0xcb8734a518b3b168eb382d99f09c58674c60b281  IN   0x3b68311f8fd651cc961b49a3a2cdb009ea247e5d0 Ether0.000000001414
0xc666d0712a1a3774a887a9517c56232000ed0620296df04941a2a16c5ec8fc7f7 days 9 hrs ago0xcb8734a518b3b168eb382d99f09c58674c60b281  IN   0x3b68311f8fd651cc961b49a3a2cdb009ea247e5d0 Ether0.000000000903
0x22d77ba6bc2fe6a80c8dceb995eee19ca5b248f8488baf11d383481424bfa6c47 days 9 hrs ago0xcb8734a518b3b168eb382d99f09c58674c60b281  IN   0x3b68311f8fd651cc961b49a3a2cdb009ea247e5d0 Ether0.000000001066
0xe1dddace08d3524fb25db9387b197cc98d4c56417209e93a02e3b151a9c2006c8 days 18 hrs ago0x0011598de1016a350ad719d23586273804076774  IN   0x3b68311f8fd651cc961b49a3a2cdb009ea247e5d0.01 Ether0.000111985
0x52c658a75dc6c100b3936689e4ddd284b5242607c830184ee263758ddc8edd7e8 days 18 hrs ago0x00442c3994155d098f4ffc2e28f76d810ce9209c  IN    Contract Creation0 Ether0.020454775
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
Contract Source Code Verified (Similar Match)
Note: Displaying Similar Match Verified Source Code At Contract 0x0b3d7873de2be11574242ac98f238077acb01a1d(Excluding Constructor Arguments if any)
Contract Name: Wallet
Compiler Text: v0.4.25+commit.59dbf8f1
Optimization Enabled: Yes
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

/**
 *  The Consumer Contract Wallet
 *  Copyright (C) 2018 Token Group Ltd
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

pragma solidity ^0.4.25;

/// @title Oracle converts ERC20 token amounts into equivalent ether amounts based on cryptocurrency exchange rates.
interface IOracle {
    function convert(address, uint) external view returns (bool, uint);
}

/// @title Ownable has an owner address and provides basic authorization control functions.
/// This contract is modified version of the MIT OpenZepplin Ownable contract
/// This contract doesn't allow for multiple changeOwner operations
/// https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol
contract Ownable {
    event TransferredOwnership(address _from, address _to);

    address private _owner;
    bool private _isTransferable;

    /// @dev Constructor sets the original owner of the contract and whether or not it is one time transferable.
    constructor(address _account, bool _transferable) internal {
        _owner = _account;
        _isTransferable = _transferable;
        emit TransferredOwnership(address(0), _account);
    }

    /// @dev Reverts if called by any account other than the owner.
    modifier onlyOwner() {
        require(_isOwner(), "sender is not an owner");
        _;
    }

    /// @dev Allows the current owner to transfer control of the contract to a new address.
    /// @param _account address to transfer ownership to.
    function transferOwnership(address _account) external onlyOwner {
        // Require that the ownership is transferable.
        require(_isTransferable, "ownership is not transferable");
        // Require that the new owner is not the zero address.
        require(_account != address(0), "owner cannot be set to zero address");
        // Set the transferable flag to false.
        _isTransferable = false;
        // Emit the ownership transfer event.
        emit TransferredOwnership(_owner, _account);
        // Set the owner to the provided address.
        _owner = _account;
    }

    /// @dev Allows the current owner to relinquish control of the contract.
    /// @notice Renouncing to ownership will leave the contract without an owner and unusable.
    /// It will not be possible to call the functions with the `onlyOwner` modifier anymore.
    function renounceOwnership() public onlyOwner {
        // Require that the ownership is transferable.
        require(_isTransferable, "ownership is not transferable");
        emit TransferredOwnership(_owner, address(0));
        // note that this could be terminal
        _owner = address(0);
    }

    /// @return the address of the owner.
    function owner() public view returns (address) {
        return _owner;
    }

    /// @return true if the ownership is transferable.
    function isTransferable() public view returns (bool) {
        return _isTransferable;
    }

    /// @return true if sender is the owner of the contract.
    function _isOwner() internal view returns (bool) {
        return msg.sender == _owner;
    }
}

/// @title The Controller interface provides access to an external list of controllers.
interface IController {
    function isController(address) external view returns (bool);
}

/// @title Controller stores a list of controller addresses that can be used for authentication in other contracts.
contract Controller is IController {
    event AddedController(address _sender, address _controller);
    event RemovedController(address _sender, address _controller);

    mapping (address => bool) private _isController;
    uint private _controllerCount;

    /// @dev Constructor initializes the list of controllers with the provided address.
    /// @param _account address to add to the list of controllers.
    constructor(address _account) public {
        _addController(_account);
    }

    /// @dev Checks if message sender is a controller.
    modifier onlyController() {
        require(isController(msg.sender), "sender is not a controller");
        _;
    }

    /// @dev Add a new controller to the list of controllers.
    /// @param _account address to add to the list of controllers.
    function addController(address _account) external onlyController {
        _addController(_account);
    }

    /// @dev Remove a controller from the list of controllers.
    /// @param _account address to remove from the list of controllers.
    function removeController(address _account) external onlyController {
        _removeController(_account);
    }

    /// @return true if the provided account is a controller.
    function isController(address _account) public view returns (bool) {
        return _isController[_account];
    }

    /// @return the current number of controllers.
    function controllerCount() public view returns (uint) {
        return _controllerCount;
    }

    /// @dev Internal-only function that adds a new controller.
    function _addController(address _account) internal {
        require(!_isController[_account], "provided account is already a controller");
        _isController[_account] = true;
        _controllerCount++;
        emit AddedController(msg.sender, _account);
    }

    /// @dev Internal-only function that removes an existing controller.
    function _removeController(address _account) internal {
        require(_isController[_account], "provided account is not a controller");
        require(_controllerCount > 1, "cannot remove the last controller");
        _isController[_account] = false;
        _controllerCount--;
        emit RemovedController(msg.sender, _account);
    }
}

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) public;
    function setResolver(bytes32 node, address resolver) public;
    function setOwner(bytes32 node, address owner) public;
    function setTTL(bytes32 node, uint64 ttl) public;
    function owner(bytes32 node) public view returns (address);
    function resolver(bytes32 node) public view returns (address);
    function ttl(bytes32 node) public view returns (uint64);

}

/**
 * A simple resolver anyone can use; only allows the owner of a node to set its
 * address.
 */
contract PublicResolver {

    bytes4 constant INTERFACE_META_ID = 0x01ffc9a7;
    bytes4 constant ADDR_INTERFACE_ID = 0x3b3b57de;
    bytes4 constant CONTENT_INTERFACE_ID = 0xd8389dc5;
    bytes4 constant NAME_INTERFACE_ID = 0x691f3431;
    bytes4 constant ABI_INTERFACE_ID = 0x2203ab56;
    bytes4 constant PUBKEY_INTERFACE_ID = 0xc8690233;
    bytes4 constant TEXT_INTERFACE_ID = 0x59d1d43c;
    bytes4 constant MULTIHASH_INTERFACE_ID = 0xe89401a1;

    event AddrChanged(bytes32 indexed node, address a);
    event ContentChanged(bytes32 indexed node, bytes32 hash);
    event NameChanged(bytes32 indexed node, string name);
    event ABIChanged(bytes32 indexed node, uint256 indexed contentType);
    event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);
    event TextChanged(bytes32 indexed node, string indexedKey, string key);
    event MultihashChanged(bytes32 indexed node, bytes hash);

    struct PublicKey {
        bytes32 x;
        bytes32 y;
    }

    struct Record {
        address addr;
        bytes32 content;
        string name;
        PublicKey pubkey;
        mapping(string=>string) text;
        mapping(uint256=>bytes) abis;
        bytes multihash;
    }

    ENS ens;

    mapping (bytes32 => Record) records;

    modifier only_owner(bytes32 node) {
        require(ens.owner(node) == msg.sender);
        _;
    }

    /**
     * Constructor.
     * @param ensAddr The ENS registrar contract.
     */
    constructor(ENS ensAddr) public {
        ens = ensAddr;
    }

    /**
     * Sets the address associated with an ENS node.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param addr The address to set.
     */
    function setAddr(bytes32 node, address addr) public only_owner(node) {
        records[node].addr = addr;
        emit AddrChanged(node, addr);
    }

    /**
     * Sets the content hash associated with an ENS node.
     * May only be called by the owner of that node in the ENS registry.
     * Note that this resource type is not standardized, and will likely change
     * in future to a resource type based on multihash.
     * @param node The node to update.
     * @param hash The content hash to set
     */
    function setContent(bytes32 node, bytes32 hash) public only_owner(node) {
        records[node].content = hash;
        emit ContentChanged(node, hash);
    }

    /**
     * Sets the multihash associated with an ENS node.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param hash The multihash to set
     */
    function setMultihash(bytes32 node, bytes hash) public only_owner(node) {
        records[node].multihash = hash;
        emit MultihashChanged(node, hash);
    }

    /**
     * Sets the name associated with an ENS node, for reverse records.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param name The name to set.
     */
    function setName(bytes32 node, string name) public only_owner(node) {
        records[node].name = name;
        emit NameChanged(node, name);
    }

    /**
     * Sets the ABI associated with an ENS node.
     * Nodes may have one ABI of each content type. To remove an ABI, set it to
     * the empty string.
     * @param node The node to update.
     * @param contentType The content type of the ABI
     * @param data The ABI data.
     */
    function setABI(bytes32 node, uint256 contentType, bytes data) public only_owner(node) {
        // Content types must be powers of 2
        require(((contentType - 1) & contentType) == 0);

        records[node].abis[contentType] = data;
        emit ABIChanged(node, contentType);
    }

    /**
     * Sets the SECP256k1 public key associated with an ENS node.
     * @param node The ENS node to query
     * @param x the X coordinate of the curve point for the public key.
     * @param y the Y coordinate of the curve point for the public key.
     */
    function setPubkey(bytes32 node, bytes32 x, bytes32 y) public only_owner(node) {
        records[node].pubkey = PublicKey(x, y);
        emit PubkeyChanged(node, x, y);
    }

    /**
     * Sets the text data associated with an ENS node and key.
     * May only be called by the owner of that node in the ENS registry.
     * @param node The node to update.
     * @param key The key to set.
     * @param value The text data value to set.
     */
    function setText(bytes32 node, string key, string value) public only_owner(node) {
        records[node].text[key] = value;
        emit TextChanged(node, key, key);
    }

    /**
     * Returns the text data associated with an ENS node and key.
     * @param node The ENS node to query.
     * @param key The text data key to query.
     * @return The associated text data.
     */
    function text(bytes32 node, string key) public view returns (string) {
        return records[node].text[key];
    }

    /**
     * Returns the SECP256k1 public key associated with an ENS node.
     * Defined in EIP 619.
     * @param node The ENS node to query
     * @return x, y the X and Y coordinates of the curve point for the public key.
     */
    function pubkey(bytes32 node) public view returns (bytes32 x, bytes32 y) {
        return (records[node].pubkey.x, records[node].pubkey.y);
    }

    /**
     * Returns the ABI associated with an ENS node.
     * Defined in EIP205.
     * @param node The ENS node to query
     * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.
     * @return contentType The content type of the return value
     * @return data The ABI data
     */
    function ABI(bytes32 node, uint256 contentTypes) public view returns (uint256 contentType, bytes data) {
        Record storage record = records[node];
        for (contentType = 1; contentType <= contentTypes; contentType <<= 1) {
            if ((contentType & contentTypes) != 0 && record.abis[contentType].length > 0) {
                data = record.abis[contentType];
                return;
            }
        }
        contentType = 0;
    }

    /**
     * Returns the name associated with an ENS node, for reverse records.
     * Defined in EIP181.
     * @param node The ENS node to query.
     * @return The associated name.
     */
    function name(bytes32 node) public view returns (string) {
        return records[node].name;
    }

    /**
     * Returns the content hash associated with an ENS node.
     * Note that this resource type is not standardized, and will likely change
     * in future to a resource type based on multihash.
     * @param node The ENS node to query.
     * @return The associated content hash.
     */
    function content(bytes32 node) public view returns (bytes32) {
        return records[node].content;
    }

    /**
     * Returns the multihash associated with an ENS node.
     * @param node The ENS node to query.
     * @return The associated multihash.
     */
    function multihash(bytes32 node) public view returns (bytes) {
        return records[node].multihash;
    }

    /**
     * Returns the address associated with an ENS node.
     * @param node The ENS node to query.
     * @return The associated address.
     */
    function addr(bytes32 node) public view returns (address) {
        return records[node].addr;
    }

    /**
     * Returns true if the resolver implements the interface specified by the provided hash.
     * @param interfaceID The ID of the interface to check for.
     * @return True if the contract implements the requested interface.
     */
    function supportsInterface(bytes4 interfaceID) public pure returns (bool) {
        return interfaceID == ADDR_INTERFACE_ID ||
        interfaceID == CONTENT_INTERFACE_ID ||
        interfaceID == NAME_INTERFACE_ID ||
        interfaceID == ABI_INTERFACE_ID ||
        interfaceID == PUBKEY_INTERFACE_ID ||
        interfaceID == TEXT_INTERFACE_ID ||
        interfaceID == MULTIHASH_INTERFACE_ID ||
        interfaceID == INTERFACE_META_ID;
    }
}

/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {

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

        return c;
    }

    /**
    * @dev Subtracts two numbers, 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 numbers, 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 numbers 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;
    }
}

/// @title ERC20 interface is a subset of the ERC20 specification.
interface ERC20 {
    function transfer(address, uint) external returns (bool);
    function balanceOf(address) external view returns (uint);
}


/// @title ERC165 interface specifies a standard way of querying if a contract implements an interface.
interface ERC165 {
    function supportsInterface(bytes4) external view returns (bool);
}


/// @title Resolver returns the controller contract address.
interface IResolver {
    function addr(bytes32) external view returns (address);
}

/// @title Controllable implements access control functionality based on a controller set in ENS.
contract Controllable {
    /// @dev _ENS points to the ENS registry smart contract.
    ENS private _ENS;
    /// @dev Is the registered ENS name of the controller contract.
    bytes32 private _node;

    /// @dev Constructor initializes the controller contract object.
    /// @param _ens is the address of the ENS.
    /// @param _controllerName is the ENS name of the Controller.
    constructor(address _ens, bytes32 _controllerName) internal {
        _ENS = ENS(_ens);
        _node = _controllerName;
    }

    /// @dev Checks if message sender is the controller.
    modifier onlyController() {
        require(_isController(msg.sender), "sender is not a controller");
        _;
    }

    /// @return true if the provided account is the controller.
    function _isController(address _account) internal view returns (bool) {
        return IController(IResolver(_ENS.resolver(_node)).addr(_node)).isController(_account);
    }
}

/// @title Whitelist provides payee-whitelist functionality.
contract Whitelist is Controllable, Ownable {
    event AddedToWhitelist(address _sender, address[] _addresses);
    event SubmittedWhitelistAddition(address[] _addresses, bytes32 _hash);
    event CancelledWhitelistAddition(address _sender);

    event RemovedFromWhitelist(address _sender, address[] _addresses);
    event SubmittedWhitelistRemoval(address[] _addresses, bytes32 _hash);
    event CancelledWhitelistRemoval(address _sender);

    mapping(address => bool) public isWhitelisted;
    address[] private _pendingWhitelistAddition;
    address[] private _pendingWhitelistRemoval;
    bool public submittedWhitelistAddition;
    bool public submittedWhitelistRemoval;
    bool public initializedWhitelist;

    /// @dev Check if the provided addresses contain the owner or the zero-address address.
    modifier hasNoOwnerOrZeroAddress(address[] _addresses) {
        for (uint i = 0; i < _addresses.length; i++) {
            require(_addresses[i] != owner(), "provided whitelist contains the owner address");
            require(_addresses[i] != address(0), "provided whitelist contains the zero address");
        }
        _;
    }

    /// @dev Check that neither addition nor removal operations have already been submitted.
    modifier noActiveSubmission() {
        require(!submittedWhitelistAddition && !submittedWhitelistRemoval, "whitelist operation has already been submitted");
        _;
    }

    /// @dev Getter for pending addition array.
    function pendingWhitelistAddition() external view returns(address[]) {
        return _pendingWhitelistAddition;
    }

    /// @dev Getter for pending removal array.
    function pendingWhitelistRemoval() external view returns(address[]) {
        return _pendingWhitelistRemoval;
    }

    /// @dev Getter for pending addition/removal array hash.
    function pendingWhitelistHash(address[] _pendingWhitelist) public pure returns(bytes32) {
        return keccak256(abi.encodePacked(_pendingWhitelist));
    }

    /// @dev Add initial addresses to the whitelist.
    /// @param _addresses are the Ethereum addresses to be whitelisted.
    function initializeWhitelist(address[] _addresses) external onlyOwner hasNoOwnerOrZeroAddress(_addresses) {
        // Require that the whitelist has not been initialized.
        require(!initializedWhitelist, "whitelist has already been initialized");
        // Add each of the provided addresses to the whitelist.
        for (uint i = 0; i < _addresses.length; i++) {
            isWhitelisted[_addresses[i]] = true;
        }
        initializedWhitelist = true;
        // Emit the addition event.
        emit AddedToWhitelist(msg.sender, _addresses);
    }

    /// @dev Add addresses to the whitelist.
    /// @param _addresses are the Ethereum addresses to be whitelisted.
    function submitWhitelistAddition(address[] _addresses) external onlyOwner noActiveSubmission hasNoOwnerOrZeroAddress(_addresses)  {
        // Require that the whitelist has been initialized.
        require(initializedWhitelist, "whitelist has not been initialized");
        // Set the provided addresses to the pending addition addresses.
        _pendingWhitelistAddition = _addresses;
        // Flag the operation as submitted.
        submittedWhitelistAddition = true;
        // Emit the submission event.
        emit SubmittedWhitelistAddition(_addresses, pendingWhitelistHash(_pendingWhitelistAddition));
    }

    /// @dev Confirm pending whitelist addition.
    function confirmWhitelistAddition(bytes32 _hash) external onlyController {
        // Require that the whitelist addition has been submitted.
        require(submittedWhitelistAddition, "whitelist addition has not been submitted");

        // Require that confirmation hash and the hash of the pending whitelist addition match
        require(_hash == pendingWhitelistHash(_pendingWhitelistAddition), "hash of the pending white list addition do not match");

        // Whitelist pending addresses.
        for (uint i = 0; i < _pendingWhitelistAddition.length; i++) {
            isWhitelisted[_pendingWhitelistAddition[i]] = true;
        }
        // Emit the addition event.
        emit AddedToWhitelist(msg.sender, _pendingWhitelistAddition);
        // Reset pending addresses.
        delete _pendingWhitelistAddition;
        // Reset the submission flag.
        submittedWhitelistAddition = false;
    }

    /// @dev Cancel pending whitelist addition.
    function cancelWhitelistAddition(bytes32 _hash) external onlyController {
        // Require that confirmation hash and the hash of the pending whitelist addition match
        require(_hash == pendingWhitelistHash(_pendingWhitelistAddition), "hash of the pending white list addition does not match");
        // Reset pending addresses.
        delete _pendingWhitelistAddition;
        // Reset the submitted operation flag.
        submittedWhitelistAddition = false;
        // Emit the cancellation event.
        emit CancelledWhitelistAddition(msg.sender);
    }

    /// @dev Remove addresses from the whitelist.
    /// @param _addresses are the Ethereum addresses to be removed.
    function submitWhitelistRemoval(address[] _addresses) external onlyOwner noActiveSubmission {
        // Add the provided addresses to the pending addition list.
        _pendingWhitelistRemoval = _addresses;
        // Flag the operation as submitted.
        submittedWhitelistRemoval = true;
        // Emit the submission event.
        emit SubmittedWhitelistRemoval(_addresses, pendingWhitelistHash(_pendingWhitelistRemoval));
    }

    /// @dev Confirm pending removal of whitelisted addresses.
    function confirmWhitelistRemoval(bytes32 _hash) external onlyController {
        // Require that the pending whitelist is not empty and the operation has been submitted.
        require(submittedWhitelistRemoval, "whitelist removal has not been submitted");
        require(_pendingWhitelistRemoval.length > 0, "pending whitelist removal is empty");
        // Require that confirmation hash and the hash of the pending whitelist removal match
        require(_hash == pendingWhitelistHash(_pendingWhitelistRemoval), "hash of the pending white list removal does not match the confirmed hash");
        // Remove pending addresses.
        for (uint i = 0; i < _pendingWhitelistRemoval.length; i++) {
            isWhitelisted[_pendingWhitelistRemoval[i]] = false;
        }
        // Emit the removal event.
        emit RemovedFromWhitelist(msg.sender, _pendingWhitelistRemoval);
        // Reset pending addresses.
        delete _pendingWhitelistRemoval;
        // Reset the submission flag.
        submittedWhitelistRemoval = false;
    }

    /// @dev Cancel pending removal of whitelisted addresses.
    function cancelWhitelistRemoval(bytes32 _hash) external onlyController {

        // Require that confirmation hash and the hash of the pending whitelist removal match
        require(_hash == pendingWhitelistHash(_pendingWhitelistRemoval), "hash of the pending white list removal do not match");

        // Reset pending addresses.
        delete _pendingWhitelistRemoval;
        // Reset the submitted operation flag.
        submittedWhitelistRemoval = false;
        // Emit the cancellation event.
        emit CancelledWhitelistRemoval(msg.sender);
    }
}


//// @title SpendLimit provides daily spend limit functionality.
contract SpendLimit is Controllable, Ownable {
    event SetSpendLimit(address _sender, uint _amount);
    event SubmittedSpendLimitChange(uint _amount);
    event CancelledSpendLimitChange(address _sender);

    using SafeMath for uint256;

    uint public spendLimit;
    uint private _spendLimitDay;
    uint private _spendAvailable;

    uint public pendingSpendLimit;
    bool public submittedSpendLimit;
    bool public initializedSpendLimit;

    /// @dev Constructor initializes the daily spend limit in wei.
    constructor(uint _spendLimit) internal {
        spendLimit = _spendLimit;
        _spendLimitDay = now;
        _spendAvailable = spendLimit;
    }

    /// @dev Returns the available daily balance - accounts for daily limit reset.
    /// @return amount of ether in wei.
    function spendAvailable() public view returns (uint) {
        if (now > _spendLimitDay + 24 hours) {
            return spendLimit;
        } else {
            return _spendAvailable;
        }
    }

    /// @dev Initialize a daily spend (aka transfer) limit for non-whitelisted addresses.
    /// @param _amount is the daily limit amount in wei.
    function initializeSpendLimit(uint _amount) external onlyOwner {
        // Require that the spend limit has not been initialized.
        require(!initializedSpendLimit, "spend limit has already been initialized");
        // Modify spend limit based on the provided value.
        _modifySpendLimit(_amount);
        // Flag the operation as initialized.
        initializedSpendLimit = true;
        // Emit the set limit event.
        emit SetSpendLimit(msg.sender, _amount);
    }

    /// @dev Set a daily transfer limit for non-whitelisted addresses.
    /// @param _amount is the daily limit amount in wei.
    function submitSpendLimit(uint _amount) external onlyOwner {
        // Require that the spend limit has been initialized.
        require(initializedSpendLimit, "spend limit has not been initialized");
        // Require that the operation has been submitted.
        require(!submittedSpendLimit, "spend limit has already been submitted");
        // Assign the provided amount to pending daily limit change.
        pendingSpendLimit = _amount;
        // Flag the operation as submitted.
        submittedSpendLimit = true;
        // Emit the submission event.
        emit SubmittedSpendLimitChange(_amount);
    }

    /// @dev Confirm pending set daily limit operation.
    function confirmSpendLimit(uint _amount) external onlyController {
        // Require that the operation has been submitted.
        require(submittedSpendLimit, "spend limit has not been submitted");
        // Require that pending and confirmed spend limit are the same
        require(pendingSpendLimit == _amount, "confirmed and submitted spend limits dont match");
        // Modify spend limit based on the pending value.
        _modifySpendLimit(pendingSpendLimit);
        // Emit the set limit event.
        emit SetSpendLimit(msg.sender, pendingSpendLimit);
        // Reset the submission flag.
        submittedSpendLimit = false;
        // Reset pending daily limit.
        pendingSpendLimit = 0;
    }

    /// @dev Cancel pending set daily limit operation.
    function cancelSpendLimit(uint _amount) external onlyController {
        // Require that pending and confirmed spend limit are the same
        require(pendingSpendLimit == _amount, "confirmed and cancelled spend limits dont match");
        // Reset pending daily limit.
        pendingSpendLimit = 0;
        // Reset the submitted operation flag.
        submittedSpendLimit = false;
        // Emit the cancellation event.
        emit CancelledSpendLimitChange(msg.sender);
    }

    // @dev Setter method for the available daily spend limit.
    function _setSpendAvailable(uint _amount) internal {
        _spendAvailable = _amount;
    }

    /// @dev Update available spend limit based on the daily reset.
    function _updateSpendAvailable() internal {
        if (now > _spendLimitDay.add(24 hours)) {
            // Advance the current day by how many days have passed.
            uint extraDays = now.sub(_spendLimitDay).div(24 hours);
            _spendLimitDay = _spendLimitDay.add(extraDays.mul(24 hours));
            // Set the available limit to the current spend limit.
            _spendAvailable = spendLimit;
        }
    }

    /// @dev Modify the spend limit and spend available based on the provided value.
    /// @dev _amount is the daily limit amount in wei.
    function _modifySpendLimit(uint _amount) private {
        // Account for the spend limit daily reset.
        _updateSpendAvailable();
        // Set the daily limit to the provided amount.
        spendLimit = _amount;
        // Lower the available limit if it's higher than the new daily limit.
        if (_spendAvailable > spendLimit) {
            _spendAvailable = spendLimit;
        }
    }
}


//// @title Asset store with extra security features.
contract Vault is Whitelist, SpendLimit, ERC165 {
    event Received(address _from, uint _amount);
    event Transferred(address _to, address _asset, uint _amount);

    using SafeMath for uint256;

    /// @dev Supported ERC165 interface ID.
    bytes4 private constant _ERC165_INTERFACE_ID = 0x01ffc9a7; // solium-disable-line uppercase

    /// @dev ENS points to the ENS registry smart contract.
    ENS private _ENS;
    /// @dev Is the registered ENS name of the oracle contract.
    bytes32 private _node;

    /// @dev Constructor initializes the vault with an owner address and spend limit. It also sets up the oracle and controller contracts.
    /// @param _owner is the owner account of the wallet contract.
    /// @param _transferable indicates whether the contract ownership can be transferred.
    /// @param _ens is the ENS public registry contract address.
    /// @param _oracleName is the ENS name of the Oracle.
    /// @param _controllerName is the ENS name of the controller.
    /// @param _spendLimit is the initial spend limit.
    constructor(address _owner, bool _transferable, address _ens, bytes32 _oracleName, bytes32 _controllerName, uint _spendLimit) SpendLimit(_spendLimit) Ownable(_owner, _transferable) Controllable(_ens, _controllerName) public {
        _ENS = ENS(_ens);
        _node = _oracleName;
    }

    /// @dev Checks if the value is not zero.
    modifier isNotZero(uint _value) {
        require(_value != 0, "provided value cannot be zero");
        _;
    }

    /// @dev Ether can be deposited from any source, so this contract must be payable by anyone.
    function() public payable {
        //TODO question: Why is this check here, is it necessary or are we building into a corner?
        require(msg.data.length == 0);
        emit Received(msg.sender, msg.value);
    }

    /// @dev Returns the amount of an asset owned by the contract.
    /// @param _asset address of an ERC20 token or 0x0 for ether.
    /// @return balance associated with the wallet address in wei.
    function balance(address _asset) external view returns (uint) {
        if (_asset != address(0)) {
            return ERC20(_asset).balanceOf(this);
        } else {
            return address(this).balance;
        }
    }

    /// @dev Transfers the specified asset to the recipient's address.
    /// @param _to is the recipient's address.
    /// @param _asset is the address of an ERC20 token or 0x0 for ether.
    /// @param _amount is the amount of tokens to be transferred in base units.
    function transfer(address _to, address _asset, uint _amount) external onlyOwner isNotZero(_amount) {
        // Checks if the _to address is not the zero-address
        require(_to != address(0), "_to address cannot be set to 0x0");

        // If address is not whitelisted, take daily limit into account.
        if (!isWhitelisted[_to]) {
            // Update the available spend limit.
            _updateSpendAvailable();
            // Convert token amount to ether value.
            uint etherValue;
            bool tokenExists;
            if (_asset != address(0)) {
                (tokenExists, etherValue) = IOracle(PublicResolver(_ENS.resolver(_node)).addr(_node)).convert(_asset, _amount);
            } else {
                etherValue = _amount;
            }

            // If token is supported by our oracle or is ether
            // Check against the daily spent limit and update accordingly
            if (tokenExists || _asset == address(0)) {
                // Require that the value is under remaining limit.
                require(etherValue <= spendAvailable(), "transfer amount exceeds available spend limit");
                // Update the available limit.
                _setSpendAvailable(spendAvailable().sub(etherValue));
            }
        }
        // Transfer token or ether based on the provided address.
        if (_asset != address(0)) {
            require(ERC20(_asset).transfer(_to, _amount), "ERC20 token transfer was unsuccessful");
        } else {
            _to.transfer(_amount);
        }
        // Emit the transfer event.
        emit Transferred(_to, _asset, _amount);
    }

    /// @dev Checks for interface support based on ERC165.
    function supportsInterface(bytes4 interfaceID) external view returns (bool) {
        return interfaceID == _ERC165_INTERFACE_ID;
    }
}


//// @title Asset wallet with extra security features and gas top up management.
contract Wallet is Vault {
    event SetTopUpLimit(address _sender, uint _amount);
    event SubmittedTopUpLimitChange(uint _amount);
    event CancelledTopUpLimitChange(address _sender, uint _amount);

    event ToppedUpGas(address _sender, address _owner, uint _amount);

    using SafeMath for uint256;

    uint constant private MINIMUM_TOPUP_LIMIT = 1 finney; // solium-disable-line uppercase
    uint constant private MAXIMUM_TOPUP_LIMIT = 500 finney; // solium-disable-line uppercase

    uint public topUpLimit;
    uint private _topUpLimitDay;
    uint private _topUpAvailable;

    uint public pendingTopUpLimit;
    bool public submittedTopUpLimit;
    bool public initializedTopUpLimit;

    /// @dev Constructor initializes the wallet top up limit and the vault contract.
    /// @param _owner is the owner account of the wallet contract.
    /// @param _transferable indicates whether the contract ownership can be transferred.
    /// @param _ens is the address of the ENS.
    /// @param _oracleName is the ENS name of the Oracle.
    /// @param _controllerName is the ENS name of the Controller.
    /// @param _spendLimit is the initial spend limit.
    constructor(address _owner, bool _transferable, address _ens, bytes32 _oracleName, bytes32 _controllerName, uint _spendLimit) Vault(_owner, _transferable, _ens, _oracleName, _controllerName, _spendLimit) public {
        _topUpLimitDay = now;
        topUpLimit = MAXIMUM_TOPUP_LIMIT;
        _topUpAvailable = topUpLimit;
    }

    /// @dev Returns the available daily gas top up balance - accounts for daily limit reset.
    /// @return amount of gas in wei.
    function topUpAvailable() external view returns (uint) {
        if (now > _topUpLimitDay + 24 hours) {
            return topUpLimit;
        } else {
            return _topUpAvailable;
        }
    }

    /// @dev Initialize a daily gas top up limit.
    /// @param _amount is the gas top up amount in wei.
    function initializeTopUpLimit(uint _amount) external onlyOwner {
        // Require that the top up limit has not been initialized.
        require(!initializedTopUpLimit, "top up limit has already been initialized");
        // Require that the limit amount is within the acceptable range.
        require(MINIMUM_TOPUP_LIMIT <= _amount && _amount <= MAXIMUM_TOPUP_LIMIT, "top up amount is outside of the min/max range");
        // Modify spend limit based on the provided value.
        _modifyTopUpLimit(_amount);
        // Flag operation as initialized.
        initializedTopUpLimit = true;
        // Emit the set limit event.
        emit SetTopUpLimit(msg.sender, _amount);
    }

    /// @dev Set a daily top up top up limit.
    /// @param _amount is the daily top up limit amount in wei.
    function submitTopUpLimit(uint _amount) external onlyOwner {
        // Require that the top up limit has been initialized.
        require(initializedTopUpLimit, "top up limit has not been initialized");
        // Require that the operation has not been submitted.
        require(!submittedTopUpLimit, "top up limit has already been submitted");
        // Require that the limit amount is within the acceptable range.
        require(MINIMUM_TOPUP_LIMIT <= _amount && _amount <= MAXIMUM_TOPUP_LIMIT, "top up amount is outside of the min/max range");
        // Assign the provided amount to pending daily limit change.
        pendingTopUpLimit = _amount;
        // Flag the operation as submitted.
        submittedTopUpLimit = true;
        // Emit the submission event.
        emit SubmittedTopUpLimitChange(_amount);
    }

    /// @dev Confirm pending set top up limit operation.
    function confirmTopUpLimit(uint _amount) external onlyController {
        // Require that the operation has been submitted.
        require(submittedTopUpLimit, "top up limit has not been submitted");
        // Assert that the pending top up limit amount is within the acceptable range.
        require(MINIMUM_TOPUP_LIMIT <= pendingTopUpLimit && pendingTopUpLimit <= MAXIMUM_TOPUP_LIMIT, "top up amount is outside the min/max range");
        // Assert that confirmed and pending topup limit are the same.
        require(_amount == pendingTopUpLimit, "confirmed and pending topup limit are not same");
        // Modify top up limit based on the pending value.
        _modifyTopUpLimit(pendingTopUpLimit);
        // Emit the set limit event.
        emit SetTopUpLimit(msg.sender, pendingTopUpLimit);
        // Reset pending daily limit.
        pendingTopUpLimit = 0;
        // Reset the submission flag.
        submittedTopUpLimit = false;
    }

    /// @dev Cancel pending set top up limit operation.
    function cancelTopUpLimit(uint _amount) external onlyController {
        // Reset pending daily limit.
        pendingTopUpLimit = 0;
        // Reset the submitted operation flag.
        submittedTopUpLimit = false;
        // Emit the cancellation event.
        emit CancelledTopUpLimitChange(msg.sender, _amount);
    }

    /// @dev Refill owner's gas balance.
    /// @dev Revert if the transaction amount is too large
    /// @param _amount is the amount of ether to transfer to the owner account in wei.
    function topUpGas(uint _amount) external isNotZero(_amount) {
        // Require that the sender is either the owner or a controller.
        require(_isOwner() || _isController(msg.sender), "sender is neither an owner nor a controller");
        // Account for the top up limit daily reset.
        _updateTopUpAvailable();
        // Make sure the available top up amount is not zero.
        require(_topUpAvailable != 0, "available top up limit cannot be zero");
        // Fail if there isn't enough in the daily top up limit to perform topUp
        require(_amount <= _topUpAvailable, "available top up limit less than amount passed in");
        // Reduce the top up amount from available balance and transfer corresponding
        // ether to the owner's account.
        _topUpAvailable = _topUpAvailable.sub(_amount);
        owner().transfer(_amount);
        // Emit the gas top up event.
        emit ToppedUpGas(tx.origin, owner(), _amount);
    }

    /// @dev Modify the top up limit and top up available based on the provided value.
    /// @dev _amount is the daily limit amount in wei.
    function _modifyTopUpLimit(uint _amount) private {
        // Account for the top up limit daily reset.
        _updateTopUpAvailable();
        // Set the daily limit to the provided amount.
        topUpLimit = _amount;
        // Lower the available limit if it's higher than the new daily limit.
        if (_topUpAvailable > topUpLimit) {
            _topUpAvailable = topUpLimit;
        }
    }

    /// @dev Update available top up limit based on the daily reset.
    function _updateTopUpAvailable() private {
        if (now > _topUpLimitDay.add(24 hours)) {
            // Advance the current day by how many days have passed.
            uint extraDays = now.sub(_topUpLimitDay).div(24 hours);
            _topUpLimitDay = _topUpLimitDay.add(extraDays.mul(24 hours));
            // Set the available limit to the current top up limit.
            _topUpAvailable = topUpLimit;
        }
    }
}

    Contract ABI  
[{"constant":true,"inputs":[{"name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"cancelWhitelistAddition","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isTransferable","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"submittedWhitelistAddition","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"confirmTopUpLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pendingWhitelistRemoval","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"submitTopUpLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pendingWhitelistAddition","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"initializedSpendLimit","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"initializeSpendLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"confirmWhitelistAddition","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_addresses","type":"address[]"}],"name":"submitWhitelistRemoval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"initializeTopUpLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pendingTopUpLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"cancelTopUpLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_pendingWhitelist","type":"address[]"}],"name":"pendingWhitelistHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_addresses","type":"address[]"}],"name":"submitWhitelistAddition","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"topUpLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"submittedTopUpLimit","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"topUpAvailable","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"spendLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"initializedWhitelist","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_asset","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pendingSpendLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"confirmWhitelistRemoval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_hash","type":"bytes32"}],"name":"cancelWhitelistRemoval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"submittedSpendLimit","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"submitSpendLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"spendAvailable","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"submittedWhitelistRemoval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_asset","type":"address"}],"name":"balance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"cancelSpendLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"topUpGas","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_account","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"}],"name":"confirmSpendLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_addresses","type":"address[]"}],"name":"initializeWhitelist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initializedTopUpLimit","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_owner","type":"address"},{"name":"_transferable","type":"bool"},{"name":"_ens","type":"address"},{"name":"_oracleName","type":"bytes32"},{"name":"_controllerName","type":"bytes32"},{"name":"_spendLimit","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"SetTopUpLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_amount","type":"uint256"}],"name":"SubmittedTopUpLimitChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"CancelledTopUpLimitChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"},{"indexed":false,"name":"_owner","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"ToppedUpGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_to","type":"address"},{"indexed":false,"name":"_asset","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"Transferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"}],"name":"SetSpendLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_amount","type":"uint256"}],"name":"SubmittedSpendLimitChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"}],"name":"CancelledSpendLimitChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"},{"indexed":false,"name":"_addresses","type":"address[]"}],"name":"AddedToWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_addresses","type":"address[]"},{"indexed":false,"name":"_hash","type":"bytes32"}],"name":"SubmittedWhitelistAddition","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"}],"name":"CancelledWhitelistAddition","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"},{"indexed":false,"name":"_addresses","type":"address[]"}],"name":"RemovedFromWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_addresses","type":"address[]"},{"indexed":false,"name":"_hash","type":"bytes32"}],"name":"SubmittedWhitelistRemoval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_sender","type":"address"}],"name":"CancelledWhitelistRemoval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"_to","type":"address"}],"name":"TransferredOwnership","type":"event"}]

  Contract Creation Code Switch To Opcodes View
608060405234801561001057600080fd5b5060405160c0806139c78339810160408181528251602080850151838601516060870151608088015160a09098015160008054600160a060020a0319908116600160a060020a0380871691909117835560018c90556002805490921690891690811760a060020a60ff02191674010000000000000000000000000000000000000000881515021790915590895294880194909452855194979296919590949293928892889288928892889288928392899289927f850b3df64837d7d518b45f5aa64d104652c3b80eb5b34a8e3d9eb666cb7cdea59281900390910190a150506007819055426008819055600991909155600b8054600160a060020a0390961662010000026201000060b060020a0319909616959095179094555050600c55600e5550506706f05b59d3b20000600d819055600f5550505050505061386e806101596000396000f3006080604052600436106101ed5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301ffc9a78114610234578063100f23fd1461027f5780632121dc751461029957806326d05ab2146102ae578063278ffa13146102c3578063294f4025146102db578063295b3299146103405780633af32abf1461035857806347b55a9d146103795780635658eff01461038e57806358453569146103a35780635adc02ab146103bb5780636137d670146103d35780636ea6f0c3146103f357806370332d851461040b578063715018a614610432578063754628d0146104475780637c9555831461045f5780637fd004fa146104b457806383d02803146104d457806385cd9919146104e95780638da5cb5b146104fe578063a83214591461052f578063aceaf92d14610544578063afa0fd9b14610559578063beabacc81461056e578063c8ecaddb14610598578063cbd2ac68146105ad578063ce0b5bd5146105c5578063d5666590146105dd578063d9ec3018146105f2578063dae37fac1461060a578063de212bf31461061f578063e3d670d714610634578063e4682f0014610655578063e61c51ca1461066d578063f2fde38b14610685578063f3492915146106a6578063f4199bb8146106be578063f9c470a5146106de575b36156101f857600080fd5b6040805133815234602082015281517f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874929181900390910190a1005b34801561024057600080fd5b5061026b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19600435166106f3565b604080519115158252519081900360200190f35b34801561028b57600080fd5b5061029760043561073b565b005b3480156102a557600080fd5b5061026b6108b3565b3480156102ba57600080fd5b5061026b6108d5565b3480156102cf57600080fd5b506102976004356108de565b3480156102e757600080fd5b506102f0610b26565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561032c578181015183820152602001610314565b505050509050019250505060405180910390f35b34801561034c57600080fd5b50610297600435610b88565b34801561036457600080fd5b5061026b600160a060020a0360043516610dbf565b34801561038557600080fd5b506102f0610dd4565b34801561039a57600080fd5b5061026b610e34565b3480156103af57600080fd5b50610297600435610e42565b3480156103c757600080fd5b50610297600435610f6a565b3480156103df57600080fd5b50610297600480356024810191013561122b565b3480156103ff57600080fd5b506102976004356113ea565b34801561041757600080fd5b506104206115ad565b60408051918252519081900360200190f35b34801561043e57600080fd5b506102976115b3565b34801561045357600080fd5b506102976004356116d9565b34801561046b57600080fd5b5060408051602060048035808201358381028086018501909652808552610420953695939460249493850192918291850190849080828437509497506117739650505050505050565b3480156104c057600080fd5b506102976004803560248101910135611820565b3480156104e057600080fd5b50610420611bd3565b3480156104f557600080fd5b5061026b611bd9565b34801561050a57600080fd5b50610513611be2565b60408051600160a060020a039092168252519081900360200190f35b34801561053b57600080fd5b50610420611bf1565b34801561055057600080fd5b50610420611c14565b34801561056557600080fd5b5061026b611c1a565b34801561057a57600080fd5b50610297600160a060020a0360043581169060243516604435611c29565b3480156105a457600080fd5b506104206121be565b3480156105b957600080fd5b506102976004356121c4565b3480156105d157600080fd5b50610297600435612531565b3480156105e957600080fd5b5061026b6126a8565b3480156105fe57600080fd5b506102976004356126b1565b34801561061657600080fd5b5061042061284c565b34801561062b57600080fd5b5061026b61286f565b34801561064057600080fd5b50610420600160a060020a036004351661287d565b34801561066157600080fd5b5061029760043561292a565b34801561067957600080fd5b50610297600435612a3b565b34801561069157600080fd5b50610297600160a060020a0360043516612cdd565b3480156106b257600080fd5b50610297600435612eb7565b3480156106ca57600080fd5b506102976004803560248101910135613060565b3480156106ea57600080fd5b5061026b613372565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1981167f01ffc9a700000000000000000000000000000000000000000000000000000000145b919050565b61074433613380565b1515610788576040805160e560020a62461bcd02815260206004820152601a6024820152600080516020613803833981519152604482015290519081900360640190fd5b6107eb60048054806020026020016040519081016040528092919081815260200182805480156107e157602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116107c3575b5050505050611773565b8114610867576040805160e560020a62461bcd02815260206004820152603660248201527f68617368206f66207468652070656e64696e67207768697465206c697374206160448201527f64646974696f6e20646f6573206e6f74206d6174636800000000000000000000606482015290519081900360840190fd5b61087360046000613709565b6006805460ff191690556040805133815290517f25d73bd719f2f11f571183502cb12c04453b3f963a034d89d1feebf4358f7f309181900360200190a150565b60025474010000000000000000000000000000000000000000900460ff165b90565b60065460ff1681565b6108e733613380565b151561092b576040805160e560020a62461bcd02815260206004820152601a6024820152600080516020613803833981519152604482015290519081900360640190fd5b60115460ff1615156109ad576040805160e560020a62461bcd02815260206004820152602360248201527f746f70207570206c696d697420686173206e6f74206265656e207375626d697460448201527f7465640000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60105466038d7ea4c68000111580156109d057506706f05b59d3b2000060105411155b1515610a4c576040805160e560020a62461bcd02815260206004820152602a60248201527f746f7020757020616d6f756e74206973206f75747369646520746865206d696e60448201527f2f6d61782072616e676500000000000000000000000000000000000000000000606482015290519081900360840190fd5b6010548114610acb576040805160e560020a62461bcd02815260206004820152602e60248201527f636f6e6669726d656420616e642070656e64696e6720746f707570206c696d6960448201527f7420617265206e6f742073616d65000000000000000000000000000000000000606482015290519081900360840190fd5b610ad6601054613540565b60105460408051338152602081019290925280517fb0b775ba506691c666928dfe7120eb5ccedd17f4554dc85ce86eb2b4cc437e369281900390910190a15060006010556011805460ff19169055565b60606005805480602002602001604051908101604052809291908181526020018280548015610b7e57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610b60575b5050505050905090565b610b90613561565b1515610bd4576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b601154610100900460ff161515610c5b576040805160e560020a62461bcd02815260206004820152602560248201527f746f70207570206c696d697420686173206e6f74206265656e20696e6974696160448201527f6c697a6564000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60115460ff1615610cdc576040805160e560020a62461bcd02815260206004820152602760248201527f746f70207570206c696d69742068617320616c7265616479206265656e20737560448201527f626d697474656400000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8066038d7ea4c6800011158015610cfb57506706f05b59d3b200008111155b1515610d77576040805160e560020a62461bcd02815260206004820152602d60248201527f746f7020757020616d6f756e74206973206f757473696465206f66207468652060448201527f6d696e2f6d61782072616e676500000000000000000000000000000000000000606482015290519081900360840190fd5b60108190556011805460ff191660011790556040805182815290517f9312377d84b68703929715872be9f0309065e102db6152de9c0587d9e294216d9181900360200190a150565b60036020526000908152604090205460ff1681565b60606004805480602002602001604051908101604052809291908181526020018280548015610b7e57602002820191906000526020600020908154600160a060020a03168152600190910190602001808311610b60575050505050905090565b600b54610100900460ff1681565b610e4a613561565b1515610e8e576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b600b54610100900460ff1615610f14576040805160e560020a62461bcd02815260206004820152602860248201527f7370656e64206c696d69742068617320616c7265616479206265656e20696e6960448201527f7469616c697a6564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b610f1d81613572565b600b805461ff001916610100179055604080513381526020810183905281517f068f112e5ec923d412be64779fe69e0fcbb6784c6617e94cccc8fd348f2e0f21929181900390910190a150565b6000610f7533613380565b1515610fb9576040805160e560020a62461bcd02815260206004820152601a6024820152600080516020613803833981519152604482015290519081900360640190fd5b60065460ff16151561103b576040805160e560020a62461bcd02815260206004820152602960248201527f77686974656c697374206164646974696f6e20686173206e6f74206265656e2060448201527f7375626d69747465640000000000000000000000000000000000000000000000606482015290519081900360840190fd5b61109c60048054806020026020016040519081016040528092919081815260200182805480156107e157602002820191906000526020600020908154600160a060020a031681526001909101906020018083116107c3575050505050611773565b8214611118576040805160e560020a62461bcd02815260206004820152603460248201527f68617368206f66207468652070656e64696e67207768697465206c697374206160448201527f64646974696f6e20646f206e6f74206d61746368000000000000000000000000606482015290519081900360840190fd5b5060005b6004548110156111775760016003600060048481548110151561113b57fe5b600091825260208083209190910154600160a060020a031683528201929092526040019020805460ff191691151591909117905560010161111c565b7fb2f6cccee7a369e23e293c25aa19bef80af11eb26deba3ea0f2a02783f752e4a3360046040518083600160a060020a0316600160a060020a0316815260200180602001828103825283818154815260200191508054801561120257602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116111e4575b5050935050505060405180910390a161121d60046000613709565b50506006805460ff19169055565b611233613561565b1515611277576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b60065460ff161580156112925750600654610100900460ff16155b151561130e576040805160e560020a62461bcd02815260206004820152602e60248201527f77686974656c697374206f7065726174696f6e2068617320616c72656164792060448201527f6265656e207375626d6974746564000000000000000000000000000000000000606482015290519081900360840190fd5b61131a60058383613727565b506006805461ff00191661010017905560058054604080516020808402820181019092528281527ffbc0e5ca6c7e4858daf0fdb185ef5186203e74ec9c64737e93c0aeaec596e1d193869386936113af939291908301828280156107e157602002820191906000526020600020908154600160a060020a031681526001909101906020018083116107c3575050505050611773565b604080516020808201849052828252918101849052908190606082019086908602808284376040519201829003965090945050505050a15050565b6113f2613561565b1515611436576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b601154610100900460ff16156114bc576040805160e560020a62461bcd02815260206004820152602960248201527f746f70207570206c696d69742068617320616c7265616479206265656e20696e60448201527f697469616c697a65640000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8066038d7ea4c68000111580156114db57506706f05b59d3b200008111155b1515611557576040805160e560020a62461bcd02815260206004820152602d60248201527f746f7020757020616d6f756e74206973206f757473696465206f66207468652060448201527f6d696e2f6d61782072616e676500000000000000000000000000000000000000606482015290519081900360840190fd5b61156081613540565b6011805461ff001916610100179055604080513381526020810183905281517fb0b775ba506691c666928dfe7120eb5ccedd17f4554dc85ce86eb2b4cc437e36929181900390910190a150565b60105481565b6115bb613561565b15156115ff576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b60025474010000000000000000000000000000000000000000900460ff161515611673576040805160e560020a62461bcd02815260206004820152601d60248201527f6f776e657273686970206973206e6f74207472616e7366657261626c65000000604482015290519081900360640190fd5b60025460408051600160a060020a0390921682526000602083015280517f850b3df64837d7d518b45f5aa64d104652c3b80eb5b34a8e3d9eb666cb7cdea59281900390910190a16002805473ffffffffffffffffffffffffffffffffffffffff19169055565b6116e233613380565b1515611726576040805160e560020a62461bcd02815260206004820152601a6024820152600080516020613803833981519152604482015290519081900360640190fd5b60006010556011805460ff19169055604080513381526020810183905281517f25d36a8351febb568fa2c8f5a167990291168552d0f3381a618eb120f42d91f4929181900390910190a150565b60008160405160200180828051906020019060200280838360005b838110156117a657818101518382015260200161178e565b505050509050019150506040516020818303038152906040526040518082805190602001908083835b602083106117ee5780518252601f1990920191602091820191016117cf565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b611828613561565b151561186c576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b60065460ff161580156118875750600654610100900460ff16155b1515611903576040805160e560020a62461bcd02815260206004820152602e60248201527f77686974656c697374206f7065726174696f6e2068617320616c72656164792060448201527f6265656e207375626d6974746564000000000000000000000000000000000000606482015290519081900360840190fd5b8181808060200260200160405190810160405280939291908181526020018383602002808284375060009450505050505b8151811015611a6f57611945611be2565b600160a060020a0316828281518110151561195c57fe5b60209081029091010151600160a060020a031614156119d9576040805160e560020a62461bcd02815260206004820152602d602482015260008051602061382383398151915260448201527f6f776e6572206164647265737300000000000000000000000000000000000000606482015290519081900360840190fd5b81516000908390839081106119ea57fe5b60209081029091010151600160a060020a03161415611a67576040805160e560020a62461bcd02815260206004820152602c602482015260008051602061382383398151915260448201527f7a65726f20616464726573730000000000000000000000000000000000000000606482015290519081900360840190fd5b600101611934565b60065462010000900460ff161515611af7576040805160e560020a62461bcd02815260206004820152602260248201527f77686974656c69737420686173206e6f74206265656e20696e697469616c697a60448201527f6564000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b611b0360048585613727565b506006805460ff1916600117905560048054604080516020808402820181019092528281527f9c80b3b5f68b3e017766d59e8d09b34efe6462b05c398f35cab9e271d9bc3b9c9388938893611b96939291908301828280156107e157602002820191906000526020600020908154600160a060020a031681526001909101906020018083116107c3575050505050611773565b604080516020808201849052828252918101849052908190606082019086908602808284376040519201829003965090945050505050a150505050565b600d5481565b60115460ff1681565b600254600160a060020a031690565b6000600e546201518001421115611c0b5750600d546108d2565b50600f546108d2565b60075481565b60065462010000900460ff1681565b600080611c34613561565b1515611c78576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b82801515611cd0576040805160e560020a62461bcd02815260206004820152601d60248201527f70726f76696465642076616c75652063616e6e6f74206265207a65726f000000604482015290519081900360640190fd5b600160a060020a0386161515611d30576040805160e560020a62461bcd02815260206004820181905260248201527f5f746f20616464726573732063616e6e6f742062652073657420746f20307830604482015290519081900360640190fd5b600160a060020a03861660009081526003602052604090205460ff161515611ffc57611d5a613592565b600160a060020a03851615611f3b57600b54600c54604080517f0178b8bf00000000000000000000000000000000000000000000000000000000815260048101929092525162010000909204600160a060020a031691630178b8bf916024808201926020929091908290030181600087803b158015611dd857600080fd5b505af1158015611dec573d6000803e3d6000fd5b505050506040513d6020811015611e0257600080fd5b5051600c54604080517f3b3b57de000000000000000000000000000000000000000000000000000000008152600481019290925251600160a060020a0390921691633b3b57de916024808201926020929091908290030181600087803b158015611e6b57600080fd5b505af1158015611e7f573d6000803e3d6000fd5b505050506040513d6020811015611e9557600080fd5b5051604080517f67c6e39c000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301526024820188905282519316926367c6e39c926044808401939192918290030181600087803b158015611eff57600080fd5b505af1158015611f13573d6000803e3d6000fd5b505050506040513d6040811015611f2957600080fd5b50805160209091015193509150611f3f565b8392505b8180611f525750600160a060020a038516155b15611ffc57611f5f61284c565b831115611fdc576040805160e560020a62461bcd02815260206004820152602d60248201527f7472616e7366657220616d6f756e74206578636565647320617661696c61626c60448201527f65207370656e64206c696d697400000000000000000000000000000000000000606482015290519081900360840190fd5b611ffc611ff784611feb61284c565b9063ffffffff61360d16565b61362b565b600160a060020a038516156121345784600160a060020a031663a9059cbb87866040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b15801561208757600080fd5b505af115801561209b573d6000803e3d6000fd5b505050506040513d60208110156120b157600080fd5b5051151561212f576040805160e560020a62461bcd02815260206004820152602560248201527f455243323020746f6b656e207472616e736665722077617320756e737563636560448201527f737366756c000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b61216c565b604051600160a060020a0387169085156108fc029086906000818181858888f1935050505015801561216a573d6000803e3d6000fd5b505b60408051600160a060020a0380891682528716602082015280820186905290517fd1ba4ac2e2a11b5101f6cb4d978f514a155b421e8ec396d2d9abaf0bb02917ee9181900360600190a1505050505050565b600a5481565b60006121cf33613380565b1515612213576040805160e560020a62461bcd02815260206004820152601a6024820152600080516020613803833981519152604482015290519081900360640190fd5b600654610100900460ff16151561229a576040805160e560020a62461bcd02815260206004820152602860248201527f77686974656c6973742072656d6f76616c20686173206e6f74206265656e207360448201527f75626d6974746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60055460001061231a576040805160e560020a62461bcd02815260206004820152602260248201527f70656e64696e672077686974656c6973742072656d6f76616c20697320656d7060448201527f7479000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b61237b60058054806020026020016040519081016040528092919081815260200182805480156107e157602002820191906000526020600020908154600160a060020a031681526001909101906020018083116107c3575050505050611773565b821461241d576040805160e560020a62461bcd02815260206004820152604860248201527f68617368206f66207468652070656e64696e67207768697465206c697374207260448201527f656d6f76616c20646f6573206e6f74206d617463682074686520636f6e66697260648201527f6d65642068617368000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b5060005b60055481101561247c5760006003600060058481548110151561244057fe5b600091825260208083209190910154600160a060020a031683528201929092526040019020805460ff1916911515919091179055600101612421565b7fd218c430fa348f4ce67791021b6b89c0c3eacd4ead1d8f5b83c60038ec28249b3360056040518083600160a060020a0316600160a060020a0316815260200180602001828103825283818154815260200191508054801561250757602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116124e9575b5050935050505060405180910390a161252260056000613709565b50506006805461ff0019169055565b61253a33613380565b151561257e576040805160e560020a62461bcd02815260206004820152601a6024820152600080516020613803833981519152604482015290519081900360640190fd5b6125df60058054806020026020016040519081016040528092919081815260200182805480156107e157602002820191906000526020600020908154600160a060020a031681526001909101906020018083116107c3575050505050611773565b811461265b576040805160e560020a62461bcd02815260206004820152603360248201527f68617368206f66207468652070656e64696e67207768697465206c697374207260448201527f656d6f76616c20646f206e6f74206d6174636800000000000000000000000000606482015290519081900360840190fd5b61266760056000613709565b6006805461ff00191690556040805133815290517f60bb946c4a1cccc534339b65c28159eda759452dae3765f17933d4b374f2ba379181900360200190a150565b600b5460ff1681565b6126b9613561565b15156126fd576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b600b54610100900460ff161515612783576040805160e560020a62461bcd028152602060048201526024808201527f7370656e64206c696d697420686173206e6f74206265656e20696e697469616c60448201527f697a656400000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600b5460ff1615612804576040805160e560020a62461bcd02815260206004820152602660248201527f7370656e64206c696d69742068617320616c7265616479206265656e2073756260448201527f6d69747465640000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600a819055600b805460ff191660011790556040805182815290517ff7155f467a69de148f41fc3c39089f07e9bff6d91519f3d69d46936643d5197a9181900360200190a150565b6000600854620151800142111561286657506007546108d2565b506009546108d2565b600654610100900460ff1681565b6000600160a060020a0382161561292257604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038416916370a082319160248083019260209291908290030181600087803b1580156128ef57600080fd5b505af1158015612903573d6000803e3d6000fd5b505050506040513d602081101561291957600080fd5b50519050610736565b503031610736565b61293333613380565b1515612977576040805160e560020a62461bcd02815260206004820152601a6024820152600080516020613803833981519152604482015290519081900360640190fd5b600a5481146129f6576040805160e560020a62461bcd02815260206004820152602f60248201527f636f6e6669726d656420616e642063616e63656c6c6564207370656e64206c6960448201527f6d69747320646f6e74206d617463680000000000000000000000000000000000606482015290519081900360840190fd5b6000600a55600b805460ff191690556040805133815290517f54921a39614b43b6ccca341733f54619b8708667dc2036e8ea7f41031fca3b3f9181900360200190a150565b80801515612a93576040805160e560020a62461bcd02815260206004820152601d60248201527f70726f76696465642076616c75652063616e6e6f74206265207a65726f000000604482015290519081900360640190fd5b612a9b613561565b80612aaa5750612aaa33613380565b1515612b26576040805160e560020a62461bcd02815260206004820152602b60248201527f73656e646572206973206e65697468657220616e206f776e6572206e6f72206160448201527f20636f6e74726f6c6c6572000000000000000000000000000000000000000000606482015290519081900360840190fd5b612b2e613630565b600f541515612bad576040805160e560020a62461bcd02815260206004820152602560248201527f617661696c61626c6520746f70207570206c696d69742063616e6e6f7420626560448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600f54821115612c2d576040805160e560020a62461bcd02815260206004820152603160248201527f617661696c61626c6520746f70207570206c696d6974206c657373207468616e60448201527f20616d6f756e742070617373656420696e000000000000000000000000000000606482015290519081900360840190fd5b600f54612c40908363ffffffff61360d16565b600f55612c4b611be2565b600160a060020a03166108fc839081150290604051600060405180830381858888f19350505050158015612c83573d6000803e3d6000fd5b507f611b7c0d84fda988026215bef9b3e4d81cbceced7e679be6d5e044b588467c0e32612cae611be2565b60408051600160a060020a03938416815291909216602082015280820185905290519081900360600190a15050565b612ce5613561565b1515612d29576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b60025474010000000000000000000000000000000000000000900460ff161515612d9d576040805160e560020a62461bcd02815260206004820152601d60248201527f6f776e657273686970206973206e6f74207472616e7366657261626c65000000604482015290519081900360640190fd5b600160a060020a0381161515612e23576040805160e560020a62461bcd02815260206004820152602360248201527f6f776e65722063616e6e6f742062652073657420746f207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6002805474ff000000000000000000000000000000000000000019811690915560408051600160a060020a039283168152918316602083015280517f850b3df64837d7d518b45f5aa64d104652c3b80eb5b34a8e3d9eb666cb7cdea59281900390910190a16002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b612ec033613380565b1515612f04576040805160e560020a62461bcd02815260206004820152601a6024820152600080516020613803833981519152604482015290519081900360640190fd5b600b5460ff161515612f86576040805160e560020a62461bcd02815260206004820152602260248201527f7370656e64206c696d697420686173206e6f74206265656e207375626d69747460448201527f6564000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600a548114613005576040805160e560020a62461bcd02815260206004820152602f60248201527f636f6e6669726d656420616e64207375626d6974746564207370656e64206c6960448201527f6d69747320646f6e74206d617463680000000000000000000000000000000000606482015290519081900360840190fd5b613010600a54613572565b600a5460408051338152602081019290925280517f068f112e5ec923d412be64779fe69e0fcbb6784c6617e94cccc8fd348f2e0f219281900390910190a150600b805460ff191690556000600a55565b600061306a613561565b15156130ae576040805160e560020a62461bcd02815260206004820152601660248201526000805160206137e3833981519152604482015290519081900360640190fd5b8282808060200260200160405190810160405280939291908181526020018383602002808284375060009450505050505b815181101561321a576130f0611be2565b600160a060020a0316828281518110151561310757fe5b60209081029091010151600160a060020a03161415613184576040805160e560020a62461bcd02815260206004820152602d602482015260008051602061382383398151915260448201527f6f776e6572206164647265737300000000000000000000000000000000000000606482015290519081900360840190fd5b815160009083908390811061319557fe5b60209081029091010151600160a060020a03161415613212576040805160e560020a62461bcd02815260206004820152602c602482015260008051602061382383398151915260448201527f7a65726f20616464726573730000000000000000000000000000000000000000606482015290519081900360840190fd5b6001016130df565b60065462010000900460ff16156132a1576040805160e560020a62461bcd02815260206004820152602660248201527f77686974656c6973742068617320616c7265616479206265656e20696e69746960448201527f616c697a65640000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600092505b838310156132fd576001600360008787878181106132c057fe5b60209081029290920135600160a060020a0316835250810191909152604001600020805460ff1916911515919091179055600192909201916132a6565b6006805462ff0000191662010000179055604080513380825260208083018481529383018890527fb2f6cccee7a369e23e293c25aa19bef80af11eb26deba3ea0f2a02783f752e4a93919289928992606083019085908502808284376040519201829003965090945050505050a15050505050565b601154610100900460ff1681565b60008054600154604080517f0178b8bf000000000000000000000000000000000000000000000000000000008152600481019290925251600160a060020a0390921691630178b8bf9160248082019260209290919082900301818787803b1580156133ea57600080fd5b505af11580156133fe573d6000803e3d6000fd5b505050506040513d602081101561341457600080fd5b5051600154604080517f3b3b57de000000000000000000000000000000000000000000000000000000008152600481019290925251600160a060020a0390921691633b3b57de916024808201926020929091908290030181600087803b15801561347d57600080fd5b505af1158015613491573d6000803e3d6000fd5b505050506040513d60208110156134a757600080fd5b5051604080517fb429afeb000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163b429afeb9160248083019260209291908290030181600087803b15801561350e57600080fd5b505af1158015613522573d6000803e3d6000fd5b505050506040513d602081101561353857600080fd5b505192915050565b613548613630565b600d819055600f5481101561355e57600d54600f555b50565b600254600160a060020a0316331490565b61357a613592565b600781905560095481101561355e5760075460095550565b6008546000906135ab906201518063ffffffff61369f16565b42111561355e576135da620151806135ce6008544261360d90919063ffffffff16565b9063ffffffff6136b816565b90506136016135f2826201518063ffffffff6136db16565b6008549063ffffffff61369f16565b60085560075460095550565b6000808383111561361d57600080fd5b5050808203805b5092915050565b600955565b600e54600090613649906201518063ffffffff61369f16565b42111561355e5761366c620151806135ce600e544261360d90919063ffffffff16565b9050613693613684826201518063ffffffff6136db16565b600e549063ffffffff61369f16565b600e55600d54600f5550565b6000828201838110156136b157600080fd5b9392505050565b6000808083116136c757600080fd5b82848115156136d257fe5b04949350505050565b6000808315156136ee5760009150613624565b508282028284828115156136fe57fe5b04146136b157600080fd5b508054600082559060005260206000209081019061355e9190613797565b828054828255906000526020600020908101928215613787579160200282015b8281111561378757815473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03843516178255602090920191600190910190613747565b506137939291506137b1565b5090565b6108d291905b80821115613793576000815560010161379d565b6108d291905b8082111561379357805473ffffffffffffffffffffffffffffffffffffffff191681556001016137b7560073656e646572206973206e6f7420616e206f776e65720000000000000000000073656e646572206973206e6f74206120636f6e74726f6c6c657200000000000070726f76696465642077686974656c69737420636f6e7461696e732074686520a165627a7a72305820d56b1cfcfbffa7679e6e73354e232690c53f95cdc8b2648c909e0aabaeb5e3c000290000000000000000000000003f48a7c43c9fd56ea666b4937970cad7f9a70fe80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000112234455c3a32fd11230c42e7bccd4a84e02010641c0900086ccfffea93c7d8b16693544f9f4ce389c6aeaa13ba5df602aa73147f2ce995617d2816b426c5c8698c5ec2952f7a34bb10f38326f74933d58936970000000000000000000000000000000000000000000000056bc75e2d63100000

   Swarm Source:
bzzr://d56b1cfcfbffa7679e6e73354e232690c53f95cdc8b2648c909e0aabaeb5e3c0

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward