Contract 0xd077c09a7e65c4cca490a776d5e395fb4fe7179a

 

TxHash Block Age From To Value [TxFee]
0x8e228d281f38510ad89428f266b2c53457800b11b9f7ebc9a442eb0137cdd9a672591997 mins ago0x276888eff9ee80db0e7801e4b22e25ea6de51f43 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.000892764
0x4756f9c38f594f3c7aec9840cf863bfd212b0504edc3800e050c4405c3c7ecdd72591978 mins ago0x276888eff9ee80db0e7801e4b22e25ea6de51f43 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002712015
0x4cb3e7b6f6c4950049f09eeedb44737881c27daadadbb0d92d8fbfeae6a6a267725913228 mins ago0x276888eff9ee80db0e7801e4b22e25ea6de51f43 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00089316
0xca77f287253e2476d70fa22e8de6fcc42e5579b01a0382b6e30302d1c6b33406725913129 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.000892584
0x7e8dcafb4487a222951ff12123c0a3c433dfcb248319c07293675da03880259c725913029 mins ago0x276888eff9ee80db0e7801e4b22e25ea6de51f43 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002576619
0x0057238b973ed76598e0470371f112bf0fe3913ef940edbbfcd9050995534491725913029 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00089334
0xa80095c05999093966b55b7db2d88b13f1e83c784c89d875bc777b807c0ef757725912630 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002575863
0x6c6b1c835e3574443cbcf2ebfbdd764fe67329e4b3b0ab7f3f13c81fa312ebef725912530 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002712015
0x30385bb34170cc021ef5ac8d9df23227859c769186f4a8ffae706d027984c8d1725912331 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.000892764
0x3a0daf675699f4dc6ddf9c0beb59a27af749a4f01b44110e95ab6d09ce0e133c725912032 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002576619
0x9c5432660e60825a5b4f046d9883fb3cf807495dc2cb43190cfbb0c6ba2bec01725911933 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00089316
0x39351d8df7ce352d6b46e93322864daaa6f9baa5842e3e77029f6bc5670ccf0f725911735 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002576439
0xf0b66bd1f8784b2669ed2999d007fd1dfc90c09d7c0db9cd46d41f89c583f14d725910242 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00089316
0x3709668cd7bdabcf4561f4fad30dfc6a55735c7e7ca064741665131afdbcdb13725910043 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002712015
0x2d331ee0bc82162c673e2f5f60f586b4051db6f64e2065d07347cfa31f52aff2725907849 mins ago0x276888eff9ee80db0e7801e4b22e25ea6de51f43 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.000892008
0xf0d86e625d3753b1c4595e8a791500bfa38797634bddff27ddfd768195de2658725907251 mins ago0x276888eff9ee80db0e7801e4b22e25ea6de51f43 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002712015
0xa559d72cda1b540eced4268610078c60125e480b93211c980ae7f1ab569e22fc725907051 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00089316
0x11dc6f29be968f89ddbff167b6348f23a7083144d0ae280c02333f6e79f61ef9725906752 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002577195
0x75cdb1ac8d5ee5e6e86a29f0017068be8800743e809794fe7e186a6b7ed6a20b725904858 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00089316
0xd80896cef9904d14a31e5dff54c36b7737ff513229f63b463c37d296aa3c99ac725904459 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002577015
0xa6895282f253378ba442f3eb8146f1495cf0c76b2f36e53cc7e8718aface51c672589601 hr 27 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00089334
0x7c5e4c7116016f116249451e75b4d0d185b31eceac48d70e61255abaf0c7d94f72589571 hr 27 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.002577195
0xf59cf369883d60081852637fbe696e568bc68a76b87ddcfda450a467c474fe1672589551 hr 28 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.000892584
0x7fca04f7c1196d8f9f0192b71b200239711991d81c5c6e62860b146a625faa0172589501 hr 30 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.000489744
0xaa88634c4b6b7c8827128e81d8bf0d941d0caaf0d112c03a4c23930ee688daf972589501 hr 30 mins ago0x276888eff9ee80db0e7801e4b22e25ea6de51f43 IN  0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00089316
[ Download CSV Export 

Latest 25 Internal Transaction, Click here to view more Internal Transactions as a result of Contract Execution

Parent TxHash Block Age From To Value
0x2a3f24f4180d709eaf97eb18c95443347d35d25a34cf7bfdad704c845a08ab1472496272 days 5 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0xdec3b19f4ec965c5d2ec3e0d767ce58d59a5448f21f2a1f591658a8319a269cf72205099 days 3 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x92e20779f93b86f7be1c2067ea432a5c86bb1fb738c441279cfc4170e4ef3a54719315215 days 9 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x4aff9596e45d139fb1cd8d3468912b95e71ed623079e87227f8f521932a2cea3719006216 days 34 mins ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x68c4c44c21888e932c619a3a7e09457a8725459a0ad4dee576c148147d32c848715058124 days 1 hr ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x5ee54a664d7295bdf245034988d579fe458574e73409a540b6a7961213c2c041711920230 days 8 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x17208e816758769d29f8bc7752a84de96177a34119d4cfa5a34bcb723337f884711578431 days 1 hr ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x4c08fb8524fa750123d1ae04a3f60398bc6f46c8734c652a946d73c52e863139710564533 days 1 hr ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x00bb2a543802e7b27f6915c25b5ef10ecd450a226e3d37f862f1f2e7387efbd0708333937 days 2 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x7367f1ccae5f2f76540f31c48bda380b0d6f0f6ca46cf71e09938bba41720ea6704991043 days 2 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x2e388b25d31b2950ab6b67b10f065eede8942bb60bc66b5a59a11c152ac9b27c704564643 days 20 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0xecf54d6362540b7b7853b4e54bc362ba89e5c708972cb74a6ebb22a8543ff0e3703864045 days 2 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0xc4c921639d1cec2a65140d81dd64cfe873fc732dd84f8b22e64dae5815ac9bc8701114350 days 27 mins ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x995d2001181e442ead471b742dc1ddcd0ffd69b22bf3e4e587377f6d7e641ce1700483751 days 3 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0xfb1a7347032b18b74f411d5a7e089a7bb4f4a39fdcefa47f47af7577f6153f41696874957 days 7 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x6d94f8be2afe0e170c4baee360aaa219a65ca708d7dd8a7dd65bf41b1fffd998695838059 days 1 hr ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x1c98a6cd25d10c058779e60edef8c16d3714ec0da1bfb0957f087b76ba991f25692888764 days 56 mins ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x4f97a20a2219e01226abe4319020abf82e4664f29a8105468144472111153ac5691707966 days 1 hr ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x0111edc9cc0d06707f64164b2fa314c462a3a23b8c6b5a9c5d2fd8642a02ee6d690445868 days 5 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x9ac706f8ebf55fbbc9d0422152877e094ac0512e08ef393e5a46a93f3a79657f687430573 days 4 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x472a120c14f4263e0bbbc8fc8d95a3feefe8e7550024a5c29f6885a481505b80686226475 days 4 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0xb86240dd6504a21be3f18194ead1f52ff763fccdc4d86fd3c9fbe4877254b38d684356378 days 6 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x39967c6e19e258dca944e484a3318979de07648df240bd035abf1e4af38c4c85683254680 days 2 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0xd55f560e14a63f3e2d0e54123815fdc30223f0ed16ee9c65a8868e3791856904682607181 days 4 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x4a8b53e882630097bce7d6f811e96c22d4b7254c9c78a36e094f91bda4809dbe680157485 days 5 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
[ Download CSV Export 
Warning: The compiled contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) Solidity Compiler Bugs.

Contract Source Code Verified (Exact Match)
Contract Name: DataExchange
Compiler Version: v0.4.24+commit.e67f0147
Optimization Enabled: Yes
Runs (Optimizer):  200


Contract Source Code
pragma solidity ^0.4.24;

/**
 * @title Eliptic curve signature operations
 *
 * @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d
 *
 * TODO Remove this library once solidity supports passing a signature to ecrecover.
 * See https://github.com/ethereum/solidity/issues/864
 *
 */

library ECRecovery {

  /**
   * @dev Recover signer address from a message by using their signature
   * @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address.
   * @param sig bytes signature, the signature is generated using web3.eth.sign()
   */
  function recover(bytes32 hash, bytes sig)
    internal
    pure
    returns (address)
  {
    bytes32 r;
    bytes32 s;
    uint8 v;

    // Check the signature length
    if (sig.length != 65) {
      return (address(0));
    }

    // Divide the signature in r, s and v variables
    // ecrecover takes the signature parameters, and the only way to get them
    // currently is to use assembly.
    // solium-disable-next-line security/no-inline-assembly
    assembly {
      r := mload(add(sig, 32))
      s := mload(add(sig, 64))
      v := byte(0, mload(add(sig, 96)))
    }

    // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
    if (v < 27) {
      v += 27;
    }

    // If the version is correct return the signer address
    if (v != 27 && v != 28) {
      return (address(0));
    } else {
      // solium-disable-next-line arg-overflow
      return ecrecover(hash, v, r, s);
    }
  }

  /**
   * toEthSignedMessageHash
   * @dev prefix a bytes32 value with "\x19Ethereum Signed Message:"
   * @dev and hash the result
   */
  function toEthSignedMessageHash(bytes32 hash)
    internal
    pure
    returns (bytes32)
  {
    // 32 is the length in bytes of hash,
    // enforced by the type signature above
    return keccak256(
      "\x19Ethereum Signed Message:\n32",
      hash
    );
  }
}

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  function totalSupply() public view returns (uint256);
  function balanceOf(address who) public view returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

/**
 * @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 public owner;


  event OwnershipRenounced(address indexed previousOwner);
  event OwnershipTransferred(
    address indexed previousOwner,
    address indexed newOwner
  );


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipRenounced(owner);
    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;
  }
}


/**
 * @title TokenDestructible:
 * @author Remco Bloemen <[email protected]π.com>
 * @dev Base contract that can be destroyed by owner. All funds in contract including
 * listed tokens will be sent to the owner.
 */
contract TokenDestructible is Ownable {

  constructor() public payable { }

  /**
   * @notice Terminate contract and refund to owner
   * @param tokens List of addresses of ERC20 or ERC20Basic token contracts to
   refund.
   * @notice The called token contracts could try to re-enter this contract. Only
   supply token contracts you trust.
   */
  function destroy(address[] tokens) onlyOwner public {

    // Transfer tokens to owner
    for (uint256 i = 0; i < tokens.length; i++) {
      ERC20Basic token = ERC20Basic(tokens[i]);
      uint256 balance = token.balanceOf(this);
      token.transfer(owner, balance);
    }

    // Transfer Eth to owner and terminate contract
    selfdestruct(owner);
  }
}

/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is Ownable {
  event Pause();
  event Unpause();

  bool public paused = false;


  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   */
  modifier whenNotPaused() {
    require(!paused);
    _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   */
  modifier whenPaused() {
    require(paused);
    _;
  }

  /**
   * @dev called by the owner to pause, triggers stopped state
   */
  function pause() onlyOwner whenNotPaused public {
    paused = true;
    emit Pause();
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() onlyOwner whenPaused public {
    paused = false;
    emit Unpause();
  }
}


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

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting '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;
    }

    c = a * b;
    assert(c / a == b);
    return c;
  }

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

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
    c = a + b;
    assert(c >= a);
    return c;
  }
}


/**
 * @title Math
 * @dev Assorted math operations
 */
library Math {
  function max64(uint64 a, uint64 b) internal pure returns (uint64) {
    return a >= b ? a : b;
  }

  function min64(uint64 a, uint64 b) internal pure returns (uint64) {
    return a < b ? a : b;
  }

  function max256(uint256 a, uint256 b) internal pure returns (uint256) {
    return a >= b ? a : b;
  }

  function min256(uint256 a, uint256 b) internal pure returns (uint256) {
    return a < b ? a : b;
  }
}


/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 */
contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) balances;

  uint256 totalSupply_;

  /**
  * @dev total number of tokens in existence
  */
  function totalSupply() public view returns (uint256) {
    return totalSupply_;
  }

  /**
  * @dev transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_to != address(0));
    require(_value <= balances[msg.sender]);

    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param _owner The address to query the the balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function balanceOf(address _owner) public view returns (uint256) {
    return balances[_owner];
  }

}

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender)
    public view returns (uint256);

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

  function approve(address spender, uint256 value) public returns (bool);
  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * @dev https://github.com/ethereum/EIPs/issues/20
 * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract StandardToken is ERC20, BasicToken {

  mapping (address => mapping (address => uint256)) internal allowed;


  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amount of tokens to be transferred
   */
  function transferFrom(
    address _from,
    address _to,
    uint256 _value
  )
    public
    returns (bool)
  {
    require(_to != address(0));
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    emit Transfer(_from, _to, _value);
    return true;
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   *
   * Beware that changing an allowance with this method brings the risk that someone may use both the old
   * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
   * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value) public returns (bool) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param _owner address The address which owns the funds.
   * @param _spender address The address which will spend the funds.
   * @return A uint256 specifying the amount of tokens still available for the spender.
   */
  function allowance(
    address _owner,
    address _spender
   )
    public
    view
    returns (uint256)
  {
    return allowed[_owner][_spender];
  }

  /**
   * @dev Increase the amount of tokens that an owner allowed to a spender.
   *
   * approve should be called when allowed[_spender] == 0. To increment
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _addedValue The amount of tokens to increase the allowance by.
   */
  function increaseApproval(
    address _spender,
    uint _addedValue
  )
    public
    returns (bool)
  {
    allowed[msg.sender][_spender] = (
      allowed[msg.sender][_spender].add(_addedValue));
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   *
   * approve should be called when allowed[_spender] == 0. To decrement
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseApproval(
    address _spender,
    uint _subtractedValue
  )
    public
    returns (bool)
  {
    uint oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue > oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

}


/**
 * @title WIBToken
 * @author Wibson Development Team <[email protected]>
 * @notice Wibson Oficial Token, this is an ERC20 standard compliant token.
 * @dev WIBToken token has an initial supply of 9 billion tokens with 9 decimals.
 */
contract WIBToken is StandardToken {
  string public constant name = "WIBSON"; // solium-disable-line uppercase
  string public constant symbol = "WIB"; // solium-disable-line uppercase
  uint8 public constant decimals = 9; // solium-disable-line uppercase

  // solium-disable-next-line zeppelin/no-arithmetic-operations
  uint256 public constant INITIAL_SUPPLY = 9000000000 * (10 ** uint256(decimals));

  constructor() public {
    totalSupply_ = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
    emit Transfer(address(0), msg.sender, INITIAL_SUPPLY);
  }
}


/**
 * @title DataOrder
 * @author Wibson Development Team <[email protected]>
 * @notice `DataOrder` is the contract between a given buyer and a set of sellers.
 *         This holds the information about the "deal" between them and how the
 *         transaction has evolved.
 */
contract DataOrder is Ownable {
  modifier validAddress(address addr) {
    require(addr != address(0));
    require(addr != address(this));
    _;
  }

  enum OrderStatus {
    OrderCreated,
    NotaryAdded,
    TransactionCompleted
  }

  enum DataResponseStatus {
    DataResponseAdded,
    RefundedToBuyer,
    TransactionCompleted
  }

  // --- Notary Information ---
  struct NotaryInfo {
    uint256 responsesPercentage;
    uint256 notarizationFee;
    string notarizationTermsOfService;
    uint32 addedAt;
  }

  // --- Seller Information ---
  struct SellerInfo {
    address notary;
    string dataHash;
    uint32 createdAt;
    uint32 closedAt;
    DataResponseStatus status;
  }

  address public buyer;
  string public filters;
  string public dataRequest;
  uint256 public price;
  string public termsAndConditions;
  string public buyerURL;
  string public buyerPublicKey;
  uint32 public createdAt;
  uint32 public transactionCompletedAt;
  OrderStatus public orderStatus;

  mapping(address => SellerInfo) public sellerInfo;
  mapping(address => NotaryInfo) internal notaryInfo;

  address[] public sellers;
  address[] public notaries;

  /**
   * @notice Contract's constructor.
   * @param _buyer Buyer address
   * @param _filters Target audience of the order.
   * @param _dataRequest Requested data type (Geolocation, Facebook, etc).
   * @param _price Price per added Data Response.
   * @param _termsAndConditions Copy of the terms and conditions for the order.
   * @param _buyerURL Public URL of the buyer where the data must be sent.
   * @param _buyerPublicKey Public Key of the buyer, which will be used to encrypt the
   *        data to be sent.
   */
  constructor(
    address _buyer,
    string _filters,
    string _dataRequest,
    uint256 _price,
    string _termsAndConditions,
    string _buyerURL,
    string _buyerPublicKey
  ) public validAddress(_buyer) {
    require(bytes(_buyerURL).length > 0);
    require(bytes(_buyerPublicKey).length > 0);

    buyer = _buyer;
    filters = _filters;
    dataRequest = _dataRequest;
    price = _price;
    termsAndConditions = _termsAndConditions;
    buyerURL = _buyerURL;
    buyerPublicKey = _buyerPublicKey;
    orderStatus = OrderStatus.OrderCreated;
    createdAt = uint32(block.timestamp);
    transactionCompletedAt = 0;
  }

  /**
   * @notice Adds a notary to the Data Order.
   * @param notary Notary's address.
   * @param responsesPercentage Percentage of DataResponses to audit per DataOrder.
            Value must be between 0 and 100.
   * @param notarizationFee Fee to be charged per validation done.
   * @param notarizationTermsOfService Notary's terms and conditions for the order.
   * @return true if the Notary was added successfully, reverts otherwise.
   */
  function addNotary(
    address notary,
    uint256 responsesPercentage,
    uint256 notarizationFee,
    string notarizationTermsOfService
  ) public onlyOwner validAddress(notary) returns (bool) {
    require(transactionCompletedAt == 0);
    require(responsesPercentage <= 100);
    require(!hasNotaryBeenAdded(notary));

    notaryInfo[notary] = NotaryInfo(
      responsesPercentage,
      notarizationFee,
      notarizationTermsOfService,
      uint32(block.timestamp)
    );
    notaries.push(notary);
    orderStatus = OrderStatus.NotaryAdded;
    return true;
  }

   /**
    * @notice Adds a new DataResponse.
    * @param seller Address of the Seller.
    * @param notary Notary address that the Seller chooses to use as notary,
    *        this must be one within the allowed notaries and within the
    *         DataOrder's notaries.
    * @param dataHash Hash of the data that must be sent, this is a SHA256.
    * @return true if the DataResponse was added successfully, reverts otherwise.
    */
  function addDataResponse(
    address seller,
    address notary,
    string dataHash
  ) public onlyOwner validAddress(seller) validAddress(notary) returns (bool) {
    require(orderStatus == OrderStatus.NotaryAdded);
    require(transactionCompletedAt == 0);
    require(!hasSellerBeenAccepted(seller));
    require(hasNotaryBeenAdded(notary));

    sellerInfo[seller] = SellerInfo(
      notary,
      dataHash,
      uint32(block.timestamp),
      0,
      DataResponseStatus.DataResponseAdded
    );

    sellers.push(seller);

    return true;
  }

  /**
   * @notice Closes a DataResponse.
   * @dev Once the buyer receives the seller's data and checks that it is valid
   *      or not, he must signal  DataResponse as completed.
   * @param seller Seller address.
   * @param transactionCompleted True, if the seller got paid for his/her data.
   * @return true if DataResponse was successfully closed, reverts otherwise.
   */
  function closeDataResponse(
    address seller,
    bool transactionCompleted
  ) public onlyOwner validAddress(seller) returns (bool) {
    require(orderStatus != OrderStatus.TransactionCompleted);
    require(transactionCompletedAt == 0);
    require(hasSellerBeenAccepted(seller));
    require(sellerInfo[seller].status == DataResponseStatus.DataResponseAdded);

    sellerInfo[seller].status = transactionCompleted
      ? DataResponseStatus.TransactionCompleted
      : DataResponseStatus.RefundedToBuyer;
    sellerInfo[seller].closedAt = uint32(block.timestamp);
    return true;
  }

  /**
   * @notice Closes the Data order.
   * @dev Once the DataOrder is closed it will no longer accept new DataResponses.
   * @return true if the DataOrder was successfully closed, reverts otherwise.
   */
  function close() public onlyOwner returns (bool) {
    require(orderStatus != OrderStatus.TransactionCompleted);
    require(transactionCompletedAt == 0);
    orderStatus = OrderStatus.TransactionCompleted;
    transactionCompletedAt = uint32(block.timestamp);
    return true;
  }

  /**
   * @notice Checks if a DataResponse for a given seller has been accepted.
   * @param seller Seller address.
   * @return true if the DataResponse was accepted, false otherwise.
   */
  function hasSellerBeenAccepted(
    address seller
  ) public view validAddress(seller) returns (bool) {
    return sellerInfo[seller].createdAt != 0;
  }

  /**
   * @notice Checks if the given notary was added to notarize this DataOrder.
   * @param notary Notary address to check.
   * @return true if the Notary was added, false otherwise.
   */
  function hasNotaryBeenAdded(
    address notary
  ) public view validAddress(notary) returns (bool) {
    return notaryInfo[notary].addedAt != 0;
  }

  /**
   * @notice Gets the notary information.
   * @param notary Notary address to get info for.
   * @return Notary information (address, responsesPercentage, notarizationFee,
   *         notarizationTermsOfService, addedAt)
   */
  function getNotaryInfo(
    address notary
  ) public view validAddress(notary) returns (
    address,
    uint256,
    uint256,
    string,
    uint32
  ) {
    require(hasNotaryBeenAdded(notary));
    NotaryInfo memory info = notaryInfo[notary];
    return (
      notary,
      info.responsesPercentage,
      info.notarizationFee,
      info.notarizationTermsOfService,
      uint32(info.addedAt)
    );
  }

  /**
   * @notice Gets the seller information.
   * @param seller Seller address to get info for.
   * @return Seller information (address, notary, dataHash, createdAt, closedAt,
   *         status)
   */
  function getSellerInfo(
    address seller
  ) public view validAddress(seller) returns (
    address,
    address,
    string,
    uint32,
    uint32,
    bytes32
  ) {
    require(hasSellerBeenAccepted(seller));
    SellerInfo memory info = sellerInfo[seller];
    return (
      seller,
      info.notary,
      info.dataHash,
      uint32(info.createdAt),
      uint32(info.closedAt),
      getDataResponseStatusAsString(info.status)
    );
  }

  /**
   * @notice Gets the selected notary for the given seller.
   * @param seller Seller address.
   * @return Address of the notary assigned to the given seller.
   */
  function getNotaryForSeller(
    address seller
  ) public view validAddress(seller) returns (address) {
    require(hasSellerBeenAccepted(seller));
    SellerInfo memory info = sellerInfo[seller];
    return info.notary;
  }

  function getDataResponseStatusAsString(
    DataResponseStatus drs
  ) internal pure returns (bytes32) {
    if (drs == DataResponseStatus.DataResponseAdded) {
      return bytes32("DataResponseAdded");
    }

    if (drs == DataResponseStatus.RefundedToBuyer) {
      return bytes32("RefundedToBuyer");
    }

    if (drs == DataResponseStatus.TransactionCompleted) {
      return bytes32("TransactionCompleted");
    }

    throw; // solium-disable-line security/no-throw
  }

}


/**
 * @title MultiMap
 * @author Wibson Development Team <[email protected]>
 * @notice An address `MultiMap`.
 * @dev `MultiMap` is useful when you need to keep track of a set of addresses.
 */
library MultiMap {

  struct MapStorage {
    mapping(address => uint) addressToIndex;
    address[] addresses;
  }

  /**
   * @notice Retrieves a address from the given `MapStorage` using a index Key.
   * @param self `MapStorage` where the index must be searched.
   * @param index Index to find.
   * @return Address of the given Index.
   */
  function get(
    MapStorage storage self,
    uint index
  ) public view returns (address) {
    require(index < self.addresses.length);
    return self.addresses[index];
  }

  /**
   * @notice Checks if the given address exists in the storage.
   * @param self `MapStorage` where the key must be searched.
   * @param _key Address to find.
   * @return true if `_key` exists in the storage, false otherwise.
   */
  function exist(
    MapStorage storage self,
    address _key
  ) public view returns (bool) {
    if (_key != address(0)) {
      uint targetIndex = self.addressToIndex[_key];
      return targetIndex < self.addresses.length && self.addresses[targetIndex] == _key;
    } else {
      return false;
    }
  }

  /**
   * @notice Inserts a new address within the given storage.
   * @param self `MapStorage` where the key must be inserted.
   * @param _key Address to insert.
   * @return true if `_key` was added, reverts otherwise.
   */
  function insert(
    MapStorage storage self,
    address _key
  ) public returns (bool) {
    require(_key != address(0));
    if (exist(self, _key)) {
      return true;
    }

    self.addressToIndex[_key] = self.addresses.length;
    self.addresses.push(_key);

    return true;
  }

  /**
   * @notice Removes the given index from the storage.
   * @param self MapStorage` where the index lives.
   * @param index Index to remove.
   * @return true if address at `index` was removed, false otherwise.
   */
  function removeAt(MapStorage storage self, uint index) public returns (bool) {
    return remove(self, self.addresses[index]);
  }

  /**
   * @notice Removes the given address from the storage.
   * @param self `MapStorage` where the address lives.
   * @param _key Address to remove.
   * @return true if `_key` was removed, false otherwise.
   */
  function remove(MapStorage storage self, address _key) public returns (bool) {
    require(_key != address(0));
    if (!exist(self, _key)) {
      return false;
    }

    uint currentIndex = self.addressToIndex[_key];

    uint lastIndex = SafeMath.sub(self.addresses.length, 1);
    address lastAddress = self.addresses[lastIndex];
    self.addressToIndex[lastAddress] = currentIndex;
    self.addresses[currentIndex] = lastAddress;

    delete self.addresses[lastIndex];
    delete self.addressToIndex[_key];

    self.addresses.length--;
    return true;
  }

  /**
   * @notice Gets the current length of the Map.
   * @param self `MapStorage` to get the length from.
   * @return The length of the MultiMap.
   */
  function length(MapStorage storage self) public view returns (uint) {
    return self.addresses.length;
  }
}


/**
 * @title CryptoUtils
 * @author Wibson Development Team <[email protected]>
 * @notice Cryptographic utilities used by the Wibson protocol.
 * @dev In order to get the same hashes using `Web3` upon which the signatures
 *      are checked, you must use `web3.utils.soliditySha3` in v1.0 (or the
 *      homonymous function in the `web3-utils` package)
 *      http://web3js.readthedocs.io/en/1.0/web3-utils.html#utils-soliditysha3
 */
library CryptoUtils {

  /**
   * @notice Checks if the signature was created by the signer.
   * @param hash Hash of the data using the `keccak256` algorithm.
   * @param signer Signer address.
   * @param signature Signature over the hash.
   * @return true if `signer` is the one who signed the `hash`, false otherwise.
   */
  function isSignedBy(
    bytes32 hash,
    address signer,
    bytes signature
  ) private pure returns (bool) {
    require(signer != address(0));
    bytes32 prefixedHash = ECRecovery.toEthSignedMessageHash(hash);
    address recovered = ECRecovery.recover(prefixedHash, signature);
    return recovered == signer;
  }

  /**
   * @notice Checks if the notary's signature to be added to the DataOrder is valid.
   * @param order Order address.
   * @param notary Notary address.
   * @param responsesPercentage Percentage of DataResponses to audit per DataOrder.
   * @param notarizationFee Fee to be charged per validation done.
   * @param notarizationTermsOfService Notary terms and conditions for the order.
   * @param notarySignature Off-chain Notary signature.
   * @return true if `notarySignature` is valid, false otherwise.
   */
  function isNotaryAdditionValid(
    address order,
    address notary,
    uint256 responsesPercentage,
    uint256 notarizationFee,
    string notarizationTermsOfService,
    bytes notarySignature
  ) public pure returns (bool) {
    require(order != address(0));
    require(notary != address(0));
    bytes32 hash = keccak256(
      abi.encodePacked(
        order,
        responsesPercentage,
        notarizationFee,
        notarizationTermsOfService
      )
    );

    return isSignedBy(hash, notary, notarySignature);
  }

  /**
   * @notice Checks if the parameters passed correspond to the seller's signature used.
   * @param order Order address.
   * @param seller Seller address.
   * @param notary Notary address.
   * @param dataHash Hash of the data that must be sent, this is a SHA256.
   * @param signature Signature of DataResponse.
   * @return true if arguments are signed by the `seller`, false otherwise.
   */
  function isDataResponseValid(
    address order,
    address seller,
    address notary,
    string dataHash,
    bytes signature
  ) public pure returns (bool) {
    require(order != address(0));
    require(seller != address(0));
    require(notary != address(0));

    bytes memory packed = bytes(dataHash).length > 0
      ? abi.encodePacked(order, notary, dataHash)
      : abi.encodePacked(order, notary);

    bytes32 hash = keccak256(packed);
    return isSignedBy(hash, seller, signature);
  }

  /**
   * @notice Checks if the notary's signature to close the `DataResponse` is valid.
   * @param order Order address.
   * @param seller Seller address.
   * @param notary Notary address.
   * @param wasAudited Indicates whether the data was audited or not.
   * @param isDataValid Indicates the result of the audit, if happened.
   * @param notarySignature Off-chain Notary signature.
   * @return true if `notarySignature` is valid, false otherwise.
   */
  function isNotaryVeredictValid(
    address order,
    address seller,
    address notary,
    bool wasAudited,
    bool isDataValid,
    bytes notarySignature
  ) public pure returns (bool) {
    require(order != address(0));
    require(seller != address(0));
    require(notary != address(0));
    bytes32 hash = keccak256(
      abi.encodePacked(
        order,
        seller,
        wasAudited,
        isDataValid
      )
    );

    return isSignedBy(hash, notary, notarySignature);
  }
}



/**
 * @title DataExchange
 * @author Wibson Development Team <[email protected]>
 * @notice `DataExchange` is the core contract of the Wibson Protocol.
 *         This allows the creation, management, and tracking of DataOrders.
 * @dev This contract also contains some helper methods to access the data
 *      needed by the different parties involved in the Protocol.
 */
contract DataExchange is TokenDestructible, Pausable {
  using SafeMath for uint256;
  using MultiMap for MultiMap.MapStorage;

  event NotaryRegistered(address indexed notary);
  event NotaryUpdated(address indexed notary);
  event NotaryUnregistered(address indexed notary);

  event NewOrder(address indexed orderAddr);
  event NotaryAddedToOrder(address indexed orderAddr, address indexed notary);
  event DataAdded(address indexed orderAddr, address indexed seller);
  event TransactionCompleted(address indexed orderAddr, address indexed seller);
  event RefundedToBuyer(address indexed orderAddr, address indexed buyer);
  event OrderClosed(address indexed orderAddr);

  struct NotaryInfo {
    address addr;
    string name;
    string notaryUrl;
    string publicKey;
  }

  MultiMap.MapStorage openOrders;
  MultiMap.MapStorage allowedNotaries;

  mapping(address => address[]) public ordersBySeller;
  mapping(address => address[]) public ordersByNotary;
  mapping(address => address[]) public ordersByBuyer;
  mapping(address => NotaryInfo) internal notaryInfo;
  // Tracks the orders created by this contract.
  mapping(address => bool) private orders;

  // @dev buyerBalance Keeps track of the buyer's balance per order-seller.
  // TODO: Is there a better way to do this?
  mapping(
    address => mapping(address => mapping(address => uint256))
  ) public buyerBalance;

  // @dev buyerRemainingBudgetForAudits Keeps track of the buyer's remaining
  // budget from the initial one set on the `DataOrder`
  mapping(address => mapping(address => uint256)) public buyerRemainingBudgetForAudits;

  modifier validAddress(address addr) {
    require(addr != address(0));
    require(addr != address(this));
    _;
  }

  modifier isOrderLegit(address order) {
    require(orders[order]);
    _;
  }

  // @dev token A WIBToken implementation of an ERC20 standard token.
  WIBToken token;

  // @dev The minimum for initial budget for audits per `DataOrder`.
  uint256 public minimumInitialBudgetForAudits;

  /**
   * @notice Contract constructor.
   * @param tokenAddress Address of the WIBToken token address.
   * @param ownerAddress Address of the DataExchange owner.
   */
  constructor(
    address tokenAddress,
    address ownerAddress
  ) public validAddress(tokenAddress) validAddress(ownerAddress) {
    require(tokenAddress != ownerAddress);

    token = WIBToken(tokenAddress);
    minimumInitialBudgetForAudits = 0;
    transferOwnership(ownerAddress);
  }

  /**
   * @notice Registers a new notary or replaces an already existing one.
   * @dev At least one notary is needed to enable `DataExchange` operation.
   * @param notary Address of a Notary to add.
   * @param name Name Of the Notary.
   * @param notaryUrl Public URL of the notary where the data must be sent.
   * @param publicKey PublicKey used by the Notary.
   * @return true if the notary was successfully registered, reverts otherwise.
   */
  function registerNotary(
    address notary,
    string name,
    string notaryUrl,
    string publicKey
  ) public onlyOwner whenNotPaused validAddress(notary) returns (bool) {
    bool isNew = notaryInfo[notary].addr == address(0);

    require(allowedNotaries.insert(notary));
    notaryInfo[notary] = NotaryInfo(
      notary,
      name,
      notaryUrl,
      publicKey
    );

    if (isNew) {
      emit NotaryRegistered(notary);
    } else {
      emit NotaryUpdated(notary);
    }
    return true;
  }

  /**
   * @notice Unregisters an existing notary.
   * @param notary Address of a Notary to unregister.
   * @return true if the notary was successfully unregistered, reverts otherwise.
   */
  function unregisterNotary(
    address notary
  ) public onlyOwner whenNotPaused validAddress(notary) returns (bool) {
    require(allowedNotaries.remove(notary));

    emit NotaryUnregistered(notary);
    return true;
  }

  /**
   * @notice Sets the minimum initial budget for audits to be placed by a buyer
   * on DataOrder creation.
   * @dev The initial budget for audit is used as a preventive method to reduce
   *      spam DataOrders in the network.
   * @param _minimumInitialBudgetForAudits The new minimum for initial budget for
   * audits per DataOrder.
   * @return true if the value was successfully set, reverts otherwise.
   */
  function setMinimumInitialBudgetForAudits(
    uint256 _minimumInitialBudgetForAudits
  ) public onlyOwner whenNotPaused returns (bool) {
    minimumInitialBudgetForAudits = _minimumInitialBudgetForAudits;
    return true;
  }

  /**
   * @notice Creates a new DataOrder.
   * @dev The `msg.sender` will become the buyer of the order.
   * @param filters Target audience of the order.
   * @param dataRequest Requested data type (Geolocation, Facebook, etc).
   * @param price Price per added Data Response.
   * @param initialBudgetForAudits The initial budget set for future audits.
   * @param termsAndConditions Buyer's terms and conditions for the order.
   * @param buyerURL Public URL of the buyer where the data must be sent.
   * @param publicKey Public Key of the buyer, which will be used to encrypt the
   *        data to be sent.
   * @return The address of the newly created DataOrder. If the DataOrder could
   *         not be created, reverts.
   */
  function newOrder(
    string filters,
    string dataRequest,
    uint256 price,
    uint256 initialBudgetForAudits,
    string termsAndConditions,
    string buyerURL,
    string publicKey
  ) public whenNotPaused returns (address) {
    require(initialBudgetForAudits >= minimumInitialBudgetForAudits);
    require(token.allowance(msg.sender, this) >= initialBudgetForAudits);

    address newOrderAddr = new DataOrder(
      msg.sender,
      filters,
      dataRequest,
      price,
      termsAndConditions,
      buyerURL,
      publicKey
    );

    token.transferFrom(msg.sender, this, initialBudgetForAudits);
    buyerRemainingBudgetForAudits[msg.sender][newOrderAddr] = initialBudgetForAudits;

    ordersByBuyer[msg.sender].push(newOrderAddr);
    orders[newOrderAddr] = true;

    emit NewOrder(newOrderAddr);
    return newOrderAddr;
  }

  /**
   * @notice Adds a notary to the Data Order.
   * @dev The `msg.sender` must be the buyer.
   * @param orderAddr Order Address to accept notarize.
   * @param notary Notary address.
   * @param responsesPercentage Percentage of `DataResponses` to audit per DataOrder.
   *        Value must be between 0 and 100.
   * @param notarizationFee Fee to be charged per validation done.
   * @param notarizationTermsOfService Notary's terms and conditions for the order.
   * @param notarySignature Notary's signature over the other arguments.
   * @return true if the Notary was added successfully, reverts otherwise.
   */
  function addNotaryToOrder(
    address orderAddr,
    address notary,
    uint256 responsesPercentage,
    uint256 notarizationFee,
    string notarizationTermsOfService,
    bytes notarySignature
  ) public whenNotPaused isOrderLegit(orderAddr) validAddress(notary) returns (bool) {
    DataOrder order = DataOrder(orderAddr);
    address buyer = order.buyer();
    require(msg.sender == buyer);

    require(!order.hasNotaryBeenAdded(notary));
    require(allowedNotaries.exist(notary));

    require(
      CryptoUtils.isNotaryAdditionValid(
        orderAddr,
        notary,
        responsesPercentage,
        notarizationFee,
        notarizationTermsOfService,
        notarySignature
      )
    );

    bool okay = order.addNotary(
      notary,
      responsesPercentage,
      notarizationFee,
      notarizationTermsOfService
    );

    if (okay) {
      openOrders.insert(orderAddr);
      ordersByNotary[notary].push(orderAddr);
      emit NotaryAddedToOrder(order, notary);
    }
    return okay;
  }

  /**
   * @notice Adds a new DataResponse to the given order.
   * @dev 1. The `msg.sender` must be the buyer of the order.
   *      2. The buyer must allow the DataExchange to withdraw the price of the
   *         order.
   * @param orderAddr Order address where the DataResponse must be added.
   * @param seller Address of the Seller.
   * @param notary Notary address that the Seller chose to use as notarizer,
   *        this must be one within the allowed notaries and within the
   *        DataOrder's notaries.
   * @param dataHash Hash of the data that must be sent, this is a SHA256.
   * @param signature Signature of DataResponse.
   * @return true if the DataResponse was set successfully, reverts otherwise.
   */
  function addDataResponseToOrder(
    address orderAddr,
    address seller,
    address notary,
    string dataHash,
    bytes signature
  ) public whenNotPaused isOrderLegit(orderAddr) returns (bool) {
    DataOrder order = DataOrder(orderAddr);
    address buyer = order.buyer();
    require(msg.sender == buyer);
    allDistinct(
      [
        orderAddr,
        buyer,
        seller,
        notary,
        address(this)
      ]
    );
    require(order.hasNotaryBeenAdded(notary));

    require(
      CryptoUtils.isDataResponseValid(
        orderAddr,
        seller,
        notary,
        dataHash,
        signature
      )
    );

    bool okay = order.addDataResponse(
      seller,
      notary,
      dataHash
    );
    require(okay);

    chargeBuyer(order, seller);

    ordersBySeller[seller].push(orderAddr);
    emit DataAdded(order, seller);
    return true;
  }

  /**
   * @notice Closes a DataResponse.
   * @dev Once the buyer receives the seller's data and checks that it is valid
   *      or not, he must close the DataResponse signaling the result.
   *        1. This method requires an offline signature from the notary set in
   *           the DataResponse, which will indicate the audit result or if
   *           the data was not audited at all.
   *             - If the notary did not audit the data or it verifies that it was
   *               valid, funds will be sent to the Seller.
   *             - If the notary signals the data as invalid, funds will be
   *               handed back to the Buyer.
   *             - Otherwise, funds will be locked at the `DataExchange` contract
   *               until the issue is solved.
   *        2. This also works as a pause mechanism in case the system is
   *           working under abnormal scenarios while allowing the parties to keep
   *           exchanging information without losing their funds until the system
   *           is back up.
   *        3. The `msg.sender` must be the buyer or the notary in case the
   *           former does not show up. Only through the notary's signature it is
   *           decided who must receive the funds.
   * @param orderAddr Order address where the DataResponse belongs to.
   * @param seller Seller address.
   * @param wasAudited Indicates whether the data was audited or not.
   * @param isDataValid Indicates the result of the audit, if happened.
   * @param notarySignature Off-chain Notary signature
   * @return true if the DataResponse was successfully closed, reverts otherwise.
   */
  function closeDataResponse(
    address orderAddr,
    address seller,
    bool wasAudited,
    bool isDataValid,
    bytes notarySignature
  ) public whenNotPaused isOrderLegit(orderAddr) returns (bool) {
    DataOrder order = DataOrder(orderAddr);
    address buyer = order.buyer();
    require(order.hasSellerBeenAccepted(seller));

    address notary = order.getNotaryForSeller(seller);
    require(msg.sender == buyer || msg.sender == notary);
    require(
      CryptoUtils.isNotaryVeredictValid(
        orderAddr,
        seller,
        notary,
        wasAudited,
        isDataValid,
        notarySignature
      )
    );
    bool transactionCompleted = !wasAudited || isDataValid;
    require(order.closeDataResponse(seller, transactionCompleted));
    payPlayers(
      order,
      buyer,
      seller,
      notary,
      wasAudited,
      isDataValid
    );

    if (transactionCompleted) {
      emit TransactionCompleted(order, seller);
    } else {
      emit RefundedToBuyer(order, buyer);
    }
    return true;
  }

  /**
   * @notice Closes the DataOrder.
   * @dev Onces the data is closed it will no longer accept new DataResponses.
   *      The `msg.sender` must be the buyer of the order or the owner of the
   *      contract in a emergency case.
   * @param orderAddr Order address to close.
   * @return true if the DataOrder was successfully closed, reverts otherwise.
   */
  function closeOrder(
    address orderAddr
  ) public whenNotPaused isOrderLegit(orderAddr) returns (bool) {
    require(openOrders.exist(orderAddr));
    DataOrder order = DataOrder(orderAddr);
    address buyer = order.buyer();
    require(msg.sender == buyer || msg.sender == owner);

    bool okay = order.close();
    if (okay) {
      // remaining budget for audits go back to buyer.
      uint256 remainingBudget = buyerRemainingBudgetForAudits[buyer][order];
      buyerRemainingBudgetForAudits[buyer][order] = 0;
      require(token.transfer(buyer, remainingBudget));

      openOrders.remove(orderAddr);
      emit OrderClosed(orderAddr);
    }

    return okay;
  }

  /**
   * @notice Gets all the data orders associated with a notary.
   * @param notary Notary address to get orders for.
   * @return A list of DataOrder addresses.
   */
  function getOrdersForNotary(
    address notary
  ) public view validAddress(notary) returns (address[]) {
    return ordersByNotary[notary];
  }

  /**
   * @notice Gets all the data orders associated with a seller.
   * @param seller Seller address to get orders for.
   * @return List of DataOrder addresses.
   */
  function getOrdersForSeller(
    address seller
  ) public view validAddress(seller) returns (address[]) {
    return ordersBySeller[seller];
  }

  /**
   * @notice Gets all the data orders associated with a buyer.
   * @param buyer Buyer address to get orders for.
   * @return List of DataOrder addresses.
   */
  function getOrdersForBuyer(
    address buyer
  ) public view validAddress(buyer) returns (address[]) {
    return ordersByBuyer[buyer];
  }

  /**
   * @notice Gets all the open data orders, that is all the DataOrders that are
   *         still receiving new DataResponses.
   * @return List of DataOrder addresses.
   */
  function getOpenOrders() public view returns (address[]) {
    return openOrders.addresses;
  }

  /**
   * @dev Gets the list of allowed notaries.
   * @return List of notary addresses.
   */
  function getAllowedNotaries() public view returns (address[]) {
    return allowedNotaries.addresses;
  }

  /**
   * @dev Gets information about a give notary.
   * @param notary Notary address to get info for.
   * @return Notary information (address, name, notaryUrl, publicKey, isActive).
   */
  function getNotaryInfo(
    address notary
  ) public view validAddress(notary) returns (address, string, string, string, bool) {
    NotaryInfo memory info = notaryInfo[notary];

    return (
      info.addr,
      info.name,
      info.notaryUrl,
      info.publicKey,
      allowedNotaries.exist(notary)
    );
  }

  /**
   * @dev Requires that five addresses are distinct between themselves and zero.
   * @param addresses array of five addresses to explore.
   */
  function allDistinct(address[5] addresses) private pure {
    for (uint i = 0; i < addresses.length; i++) {
      require(addresses[i] != address(0));
      for (uint j = i + 1; j < addresses.length; j++) { // solium-disable-line zeppelin/no-arithmetic-operations
        require(addresses[i] != addresses[j]);
      }
    }
  }

  /**
   * @dev Charges a buyer the final charges for a given `DataResponse`.
   * @notice 1. Tokens are held in the DataExchange contract until players are paid.
   *         2. This function follows a basic invoice flow:
   *
   *               DataOrder price
   *            + Notarization fee
   *            ------------------
   *                 Total charges
   *            -  Prepaid charges (Minimum between Notarization fee and Buyer remaining budget)
   *            ------------------
   *                 Final charges
   *
   * @param order DataOrder to which the DataResponse applies.
   * @param seller Address of the Seller.
   */
  function chargeBuyer(DataOrder order, address seller) private whenNotPaused {
    address buyer = order.buyer();
    address notary = order.getNotaryForSeller(seller);
    uint256 remainingBudget = buyerRemainingBudgetForAudits[buyer][order];

    uint256 orderPrice = order.price();
    (,, uint256 notarizationFee,,) = order.getNotaryInfo(notary);
    uint256 totalCharges = orderPrice.add(notarizationFee);

    uint256 prePaid = Math.min256(notarizationFee, remainingBudget);
    uint256 finalCharges = totalCharges.sub(prePaid);

    buyerRemainingBudgetForAudits[buyer][order] = remainingBudget.sub(prePaid);
    require(token.transferFrom(buyer, this, finalCharges));

    // Bookkeeping of the available tokens paid by the Buyer and now in control
    // of the DataExchange takes into account the total charges (final + pre-paid)
    buyerBalance[buyer][order][seller] = buyerBalance[buyer][order][seller].add(totalCharges);
  }

  /**
   * @dev Pays the seller, notary and/or buyer according to the notary's veredict.
   * @param order DataOrder to which the payments apply.
   * @param buyer Address of the Buyer.
   * @param seller Address of the Seller.
   * @param notary Address of the Notary.
   * @param wasAudited Indicates whether the data was audited or not.
   * @param isDataValid Indicates the result of the audit, if happened.
   */
  function payPlayers(
    DataOrder order,
    address buyer,
    address seller,
    address notary,
    bool wasAudited,
    bool isDataValid
  ) private whenNotPaused {
    uint256 orderPrice = order.price();
    (,, uint256 notarizationFee,,) = order.getNotaryInfo(notary);
    uint256 totalCharges = orderPrice.add(notarizationFee);

    require(buyerBalance[buyer][order][seller] >= totalCharges);
    buyerBalance[buyer][order][seller] = buyerBalance[buyer][order][seller].sub(totalCharges);

    // if no notarization was done, notarization fee tokens go back to buyer.
    address notarizationFeeReceiver = wasAudited ? notary : buyer;

    // if no notarization was done or data is valid, tokens go to the seller
    address orderPriceReceiver = (!wasAudited || isDataValid) ? seller : buyer;

    require(token.transfer(notarizationFeeReceiver, notarizationFee));
    require(token.transfer(orderPriceReceiver, orderPrice));
  }

}

Contract ABI
[{"constant":true,"inputs":[{"name":"seller","type":"address"}],"name":"getOrdersForSeller","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"},{"name":"","type":"address"}],"name":"buyerBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"ordersByBuyer","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"buyerRemainingBudgetForAudits","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_minimumInitialBudgetForAudits","type":"uint256"}],"name":"setMinimumInitialBudgetForAudits","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"notary","type":"address"}],"name":"getNotaryInfo","outputs":[{"name":"","type":"address"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"string"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"orderAddr","type":"address"},{"name":"seller","type":"address"},{"name":"notary","type":"address"},{"name":"dataHash","type":"string"},{"name":"signature","type":"bytes"}],"name":"addDataResponseToOrder","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"notary","type":"address"}],"name":"getOrdersForNotary","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"orderAddr","type":"address"},{"name":"seller","type":"address"},{"name":"wasAudited","type":"bool"},{"name":"isDataValid","type":"bool"},{"name":"notarySignature","type":"bytes"}],"name":"closeDataResponse","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"orderAddr","type":"address"}],"name":"closeOrder","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"orderAddr","type":"address"},{"name":"notary","type":"address"},{"name":"responsesPercentage","type":"uint256"},{"name":"notarizationFee","type":"uint256"},{"name":"notarizationTermsOfService","type":"string"},{"name":"notarySignature","type":"bytes"}],"name":"addNotaryToOrder","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"buyer","type":"address"}],"name":"getOrdersForBuyer","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAllowedNotaries","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"ordersByNotary","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokens","type":"address[]"}],"name":"destroy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"notary","type":"address"},{"name":"name","type":"string"},{"name":"notaryUrl","type":"string"},{"name":"publicKey","type":"string"}],"name":"registerNotary","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"ordersBySeller","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOpenOrders","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"filters","type":"string"},{"name":"dataRequest","type":"string"},{"name":"price","type":"uint256"},{"name":"initialBudgetForAudits","type":"uint256"},{"name":"termsAndConditions","type":"string"},{"name":"buyerURL","type":"string"},{"name":"publicKey","type":"string"}],"name":"newOrder","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"minimumInitialBudgetForAudits","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"notary","type":"address"}],"name":"unregisterNotary","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"tokenAddress","type":"address"},{"name":"ownerAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"notary","type":"address"}],"name":"NotaryRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"notary","type":"address"}],"name":"NotaryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"notary","type":"address"}],"name":"NotaryUnregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderAddr","type":"address"}],"name":"NewOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderAddr","type":"address"},{"indexed":true,"name":"notary","type":"address"}],"name":"NotaryAddedToOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderAddr","type":"address"},{"indexed":true,"name":"seller","type":"address"}],"name":"DataAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderAddr","type":"address"},{"indexed":true,"name":"seller","type":"address"}],"name":"TransactionCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderAddr","type":"address"},{"indexed":true,"name":"buyer","type":"address"}],"name":"RefundedToBuyer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"orderAddr","type":"address"}],"name":"OrderClosed","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

Contract Creation Code
60806040526000805460a060020a60ff02191690553480156200002157600080fd5b506040516040806200587a83398101604052805160209091015160008054600160a060020a0319163317905581600160a060020a03811615156200006457600080fd5b600160a060020a0381163014156200007b57600080fd5b81600160a060020a03811615156200009257600080fd5b600160a060020a038116301415620000a957600080fd5b600160a060020a038481169084161415620000c357600080fd5b600c8054600160a060020a031916600160a060020a0386161790556000600d55620000f78364010000000062000101810204565b50505050620001a1565b600054600160a060020a031633146200011957600080fd5b6200012d8164010000000062000130810204565b50565b600160a060020a03811615156200014657600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360008054600160a060020a031916600160a060020a0392909216919091179055565b6156c980620001b16000396000f300608060405260043610620001615763ffffffff60e060020a6000350416630636d7ac8114620001665780630aa4b3be14620001dc578063319fa887146200021e578063373dfb1414620002615780633cedd004146200028b5780633f4ba83a14620002ba57806343ca78a214620002d457806352748cfe14620004695780635ac31e68146200051c5780635c975abb146200054057806360909c511462000558578063715018a614620005d65780638456cb5914620005ee5780638da5cb5b146200060657806390e72127146200061e5780639e2d04781462000642578063ac70066514620006fa578063b7915e39146200071e578063c106f2671462000736578063c6786e5a146200075d578063c83abb4014620007b5578063d9ec338a146200089b578063dbe5bab514620008c2578063e0ffe8e314620008da578063e411c71f1462000a3b578063f2fde38b1462000a53578063fdc990641462000a77575b600080fd5b3480156200017357600080fd5b506200018a600160a060020a036004351662000a9b565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015620001c8578181015183820152602001620001ae565b505050509050019250505060405180910390f35b348015620001e957600080fd5b506200020c600160a060020a036004358116906024358116906044351662000b42565b60408051918252519081900360200190f35b3480156200022b57600080fd5b5062000245600160a060020a036004351660243562000b65565b60408051600160a060020a039092168252519081900360200190f35b3480156200026e57600080fd5b506200020c600160a060020a036004358116906024351662000b9d565b3480156200029857600080fd5b50620002a660043562000bba565b604080519115158252519081900360200190f35b348015620002c757600080fd5b50620002d262000bf4565b005b348015620002e157600080fd5b50620002f8600160a060020a036004351662000c6c565b6040518086600160a060020a0316600160a060020a0316815260200180602001806020018060200185151515158152602001848103845288818151815260200191508051906020019080838360005b838110156200036157818101518382015260200162000347565b50505050905090810190601f1680156200038f5780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b83811015620003c4578181015183820152602001620003aa565b50505050905090810190601f168015620003f25780820380516001836020036101000a031916815260200191505b50848103825286518152865160209182019188019080838360005b83811015620004275781810151838201526020016200040d565b50505050905090810190601f168015620004555780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b3480156200047657600080fd5b50604080516020601f606435600481810135928301849004840285018401909552818452620002a694600160a060020a03813581169560248035831696604435909316953695608494920191819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975062000f6a9650505050505050565b3480156200052957600080fd5b506200018a600160a060020a03600435166200146b565b3480156200054d57600080fd5b50620002a662001510565b3480156200056557600080fd5b50604080516020601f608435600481810135928301849004840285018401909552818452620002a694600160a060020a038135811695602480359092169560443515159560643515159536959460a49493910191908190840183828082843750949750620015209650505050505050565b348015620005e357600080fd5b50620002d2620019f3565b348015620005fb57600080fd5b50620002d262001a60565b3480156200061357600080fd5b506200024562001add565b3480156200062b57600080fd5b50620002a6600160a060020a036004351662001aec565b3480156200064f57600080fd5b50604080516020601f608435600481810135928301849004840285018401909552818452620002a694600160a060020a0381358116956024803590921695604435956064359536959460a4949391019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975062001e9e9650505050505050565b3480156200070757600080fd5b506200018a600160a060020a036004351662002510565b3480156200072b57600080fd5b506200018a620025b5565b3480156200074357600080fd5b5062000245600160a060020a03600435166024356200261d565b3480156200076a57600080fd5b5060408051602060048035808201358381028086018501909652808552620002d295369593946024949385019291829185019084908082843750949750620026399650505050505050565b348015620007c257600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552620002a6958335600160a060020a031695369560449491939091019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a999881019791965091820194509250829150840183828082843750949750620027b49650505050505050565b348015620008a857600080fd5b5062000245600160a060020a036004351660243562002a1c565b348015620008cf57600080fd5b506200018a62002a38565b348015620008e757600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526200024594369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020888301358a018035601f8101839004830284018301909452838352979a89359a8a8301359a9199909850606090910196509194509081019250819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375094975062002a9c9650505050505050565b34801562000a4857600080fd5b506200020c62002f1b565b34801562000a6057600080fd5b50620002d2600160a060020a036004351662002f21565b34801562000a8457600080fd5b50620002a6600160a060020a036004351662002f47565b606081600160a060020a038116151562000ab457600080fd5b600160a060020a03811630141562000acb57600080fd5b600160a060020a0383166000908152600560209081526040918290208054835181840281018401909452808452909183018282801562000b3557602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831162000b16575b5050505050915050919050565b600a60209081526000938452604080852082529284528284209052825290205481565b60076020528160005260406000208181548110151562000b8157fe5b600091825260209091200154600160a060020a03169150829050565b600b60209081526000928352604080842090915290825290205481565b60008054600160a060020a0316331462000bd357600080fd5b60005460a060020a900460ff161562000beb57600080fd5b50600d55600190565b600054600160a060020a0316331462000c0c57600080fd5b60005460a060020a900460ff16151562000c2557600080fd5b6000805474ff0000000000000000000000000000000000000000191681556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b339190a1565b60006060806060600062000c7f62003b0e565b86600160a060020a038116151562000c9657600080fd5b600160a060020a03811630141562000cad57600080fd5b600160a060020a03888116600090815260086020908152604091829020825160808101845281549094168452600180820180548551600261010094831615949094026000190190911692909204601f810185900485028301850190955284825291938584019391929183018282801562000d6b5780601f1062000d3f5761010080835404028352916020019162000d6b565b820191906000526020600020905b81548152906001019060200180831162000d4d57829003601f168201915b5050509183525050600282810180546040805160206001841615610100026000190190931694909404601f8101839004830285018301909152808452938101939083018282801562000e015780601f1062000dd55761010080835404028352916020019162000e01565b820191906000526020600020905b81548152906001019060200180831162000de357829003601f168201915b505050918352505060038201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801562000e995780601f1062000e6d5761010080835404028352916020019162000e99565b820191906000526020600020905b81548152906001019060200180831162000e7b57829003601f168201915b5050505050815250509150816000015182602001518360400151846060015160037372ae13d70f65c56e59eb63993605abef1ecb9c416375ce4ef990918e6040518363ffffffff1660e060020a0281526004018083815260200182600160a060020a0316600160a060020a031681526020019250505060206040518083038186803b15801562000f2857600080fd5b505af415801562000f3d573d6000803e3d6000fd5b505050506040513d602081101562000f5457600080fd5b5051939c929b5090995097509095509350505050565b6000805481908190819060a060020a900460ff161562000f8957600080fd5b600160a060020a038916600090815260096020526040902054899060ff16151562000fb357600080fd5b89935083600160a060020a0316637150d8ae6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801562000ff557600080fd5b505af11580156200100a573d6000803e3d6000fd5b505050506040513d60208110156200102157600080fd5b5051925033600160a060020a038416146200103b57600080fd5b6040805160a081018252600160a060020a03808d16825285811660208301528b81169282019290925290891660608201523060808201526200107d9062003098565b83600160a060020a03166343dcbc86896040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b158015620010d957600080fd5b505af1158015620010ee573d6000803e3d6000fd5b505050506040513d60208110156200110557600080fd5b505115156200111357600080fd5b7348819464877341cb7e0bbd91e0c268016ae5e6ad6324c91c1b8b8b8b8b8b6040518663ffffffff1660e060020a0281526004018086600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a0316815260200184600160a060020a0316600160a060020a031681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015620011cf578181015183820152602001620011b5565b50505050905090810190601f168015620011fd5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156200123257818101518382015260200162001218565b50505050905090810190601f168015620012605780820380516001836020036101000a031916815260200191505b5097505050505050505060206040518083038186803b1580156200128357600080fd5b505af415801562001298573d6000803e3d6000fd5b505050506040513d6020811015620012af57600080fd5b50511515620012bd57600080fd5b6040517fffaef25e000000000000000000000000000000000000000000000000000000008152600160a060020a038a8116600483019081528a821660248401526060604484019081528a5160648501528a519288169363ffaef25e938e938e938e939192909160840190602085019080838360005b838110156200134c57818101518382015260200162001332565b50505050905090810190601f1680156200137a5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156200139c57600080fd5b505af1158015620013b1573d6000803e3d6000fd5b505050506040513d6020811015620013c857600080fd5b50519150811515620013d957600080fd5b620013e5848a6200313b565b600160a060020a0389811660008181526005602090815260408083208054600181018255908452918320909101805473ffffffffffffffffffffffffffffffffffffffff19168f86161790555191928716917f96a360ee9d47dddc23543ca7e1b847174c225dc8f968677e1d5b6f35f978108f9190a35060019998505050505050505050565b606081600160a060020a03811615156200148457600080fd5b600160a060020a0381163014156200149b57600080fd5b600160a060020a0383166000908152600660209081526040918290208054835181840281018401909452808452909183018282801562000b3557602002820191906000526020600020908154600160a060020a0316815260019091019060200180831162000b16575050505050915050919050565b60005460a060020a900460ff1681565b60008054819081908190819060a060020a900460ff16156200154157600080fd5b600160a060020a038a166000908152600960205260409020548a9060ff1615156200156b57600080fd5b8a945084600160a060020a0316637150d8ae6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015620015ad57600080fd5b505af1158015620015c2573d6000803e3d6000fd5b505050506040513d6020811015620015d957600080fd5b5051604080517fc081efc1000000000000000000000000000000000000000000000000000000008152600160a060020a038d8116600483015291519296509087169163c081efc1916024808201926020929091908290030181600087803b1580156200164457600080fd5b505af115801562001659573d6000803e3d6000fd5b505050506040513d60208110156200167057600080fd5b505115156200167e57600080fd5b84600160a060020a0316634372df998b6040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b158015620016da57600080fd5b505af1158015620016ef573d6000803e3d6000fd5b505050506040513d60208110156200170657600080fd5b5051925033600160a060020a03851614806200172a575033600160a060020a038416145b15156200173657600080fd5b7348819464877341cb7e0bbd91e0c268016ae5e6ad636c7e02368c8c868d8d8d6040518763ffffffff1660e060020a0281526004018087600160a060020a0316600160a060020a0316815260200186600160a060020a0316600160a060020a0316815260200185600160a060020a0316600160a060020a03168152602001841515151581526020018315151515815260200180602001828103825283818151815260200191508051906020019080838360005b8381101562001803578181015183820152602001620017e9565b50505050905090810190601f168015620018315780820380516001836020036101000a031916815260200191505b5097505050505050505060206040518083038186803b1580156200185457600080fd5b505af415801562001869573d6000803e3d6000fd5b505050506040513d60208110156200188057600080fd5b505115156200188e57600080fd5b881580620018995750875b604080517f96661b04000000000000000000000000000000000000000000000000000000008152600160a060020a038d8116600483015283151560248301529151929450908716916396661b04916044808201926020929091908290030181600087803b1580156200190a57600080fd5b505af11580156200191f573d6000803e3d6000fd5b505050506040513d60208110156200193657600080fd5b505115156200194457600080fd5b6200195485858c868d8d6200360b565b8115620019a15789600160a060020a031685600160a060020a03167fcc3f610635149ab98af5df8f627c661ab8d314e273ae1ab29a88bac48d90b68e60405160405180910390a3620019e2565b83600160a060020a031685600160a060020a03167ff692f1409d5d399fd8f4bd35525ad35edd52de67ca7e2767a65c8e1fe7ec9cf160405160405180910390a35b5060019a9950505050505050505050565b600054600160a060020a0316331462001a0b57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a0316331462001a7857600080fd5b60005460a060020a900460ff161562001a9057600080fd5b6000805474ff0000000000000000000000000000000000000000191660a060020a1781556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff6259190a1565b600054600160a060020a031681565b60008054819081908190819060a060020a900460ff161562001b0d57600080fd5b600160a060020a038616600090815260096020526040902054869060ff16151562001b3757600080fd5b604080517f75ce4ef900000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038916602482015290517372ae13d70f65c56e59eb63993605abef1ecb9c41916375ce4ef9916044808301926020929190829003018186803b15801562001bb257600080fd5b505af415801562001bc7573d6000803e3d6000fd5b505050506040513d602081101562001bde57600080fd5b5051151562001bec57600080fd5b86945084600160a060020a0316637150d8ae6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801562001c2e57600080fd5b505af115801562001c43573d6000803e3d6000fd5b505050506040513d602081101562001c5a57600080fd5b5051935033600160a060020a038516148062001c805750600054600160a060020a031633145b151562001c8c57600080fd5b84600160a060020a03166343d726d66040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801562001ccb57600080fd5b505af115801562001ce0573d6000803e3d6000fd5b505050506040513d602081101562001cf757600080fd5b50519250821562001e9357600160a060020a038481166000818152600b602090815260408083208a861684528252808320805490849055600c54825160e060020a63a9059cbb028152600481019690965260248601829052915190975094169363a9059cbb93604480820194918390030190829087803b15801562001d7b57600080fd5b505af115801562001d90573d6000803e3d6000fd5b505050506040513d602081101562001da757600080fd5b5051151562001db557600080fd5b604080517f7d98ebde00000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038916602482015290517372ae13d70f65c56e59eb63993605abef1ecb9c4191637d98ebde916044808301926020929190829003018186803b15801562001e3057600080fd5b505af415801562001e45573d6000803e3d6000fd5b505050506040513d602081101562001e5c57600080fd5b5050604051600160a060020a038816907fc674f2738d835a5ee10ac4c9fc95355170bec02f7b438d737c8821ca222640f990600090a25b509095945050505050565b6000805481908190819060a060020a900460ff161562001ebd57600080fd5b600160a060020a038a166000908152600960205260409020548a9060ff16151562001ee757600080fd5b89600160a060020a038116151562001efe57600080fd5b600160a060020a03811630141562001f1557600080fd5b8b945084600160a060020a0316637150d8ae6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801562001f5757600080fd5b505af115801562001f6c573d6000803e3d6000fd5b505050506040513d602081101562001f8357600080fd5b5051935033600160a060020a0385161462001f9d57600080fd5b84600160a060020a03166343dcbc868c6040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801562001ff957600080fd5b505af11580156200200e573d6000803e3d6000fd5b505050506040513d60208110156200202557600080fd5b5051156200203257600080fd5b604080517f75ce4ef900000000000000000000000000000000000000000000000000000000815260036004820152600160a060020a038d16602482015290517372ae13d70f65c56e59eb63993605abef1ecb9c41916375ce4ef9916044808301926020929190829003018186803b158015620020ad57600080fd5b505af4158015620020c2573d6000803e3d6000fd5b505050506040513d6020811015620020d957600080fd5b50511515620020e757600080fd5b7348819464877341cb7e0bbd91e0c268016ae5e6ad634ae90a408d8d8d8d8d8d6040518763ffffffff1660e060020a0281526004018087600160a060020a0316600160a060020a0316815260200186600160a060020a0316600160a060020a031681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015620021985781810151838201526020016200217e565b50505050905090810190601f168015620021c65780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620021fb578181015183820152602001620021e1565b50505050905090810190601f168015620022295780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038186803b1580156200224d57600080fd5b505af415801562002262573d6000803e3d6000fd5b505050506040513d60208110156200227957600080fd5b505115156200228757600080fd5b84600160a060020a031663502341738c8c8c8c6040518563ffffffff1660e060020a0281526004018085600160a060020a0316600160a060020a0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156200230f578181015183820152602001620022f5565b50505050905090810190601f1680156200233d5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156200236057600080fd5b505af115801562002375573d6000803e3d6000fd5b505050506040513d60208110156200238c57600080fd5b5051925082156200250057604080517fb57ab3ac00000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038e16602482015290517372ae13d70f65c56e59eb63993605abef1ecb9c419163b57ab3ac916044808301926020929190829003018186803b1580156200241257600080fd5b505af415801562002427573d6000803e3d6000fd5b505050506040513d60208110156200243e57600080fd5b810190808051906020019092919050505050600660008c600160a060020a0316600160a060020a031681526020019081526020016000208c90806001815401808255809150509060018203906000526020600020016000909192909190916101000a815481600160a060020a030219169083600160a060020a03160217905550508a600160a060020a031685600160a060020a03167f83cce77ef1950fd47994e9ab4fa3263f250200e45f9133f74375d8c1fd072fd860405160405180910390a35b50909a9950505050505050505050565b606081600160a060020a03811615156200252957600080fd5b600160a060020a0381163014156200254057600080fd5b600160a060020a0383166000908152600760209081526040918290208054835181840281018401909452808452909183018282801562000b3557602002820191906000526020600020908154600160a060020a0316815260019091019060200180831162000b16575050505050915050919050565b606060036001018054806020026020016040519081016040528092919081815260200182805480156200261257602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311620025f3575b505050505090505b90565b60066020528160005260406000208181548110151562000b8157fe5b6000805481908190600160a060020a031633146200265657600080fd5b600092505b8351831015620027a65783838151811015156200267457fe5b6020908102909101810151604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051919450600160a060020a038516926370a08231926024808401938290030181600087803b158015620026df57600080fd5b505af1158015620026f4573d6000803e3d6000fd5b505050506040513d60208110156200270b57600080fd5b5051600080546040805160e060020a63a9059cbb028152600160a060020a0392831660048201526024810185905290519394509085169263a9059cbb92604480840193602093929083900390910190829087803b1580156200276c57600080fd5b505af115801562002781573d6000803e3d6000fd5b505050506040513d60208110156200279857600080fd5b50506001909201916200265b565b600054600160a060020a0316ff5b600080548190600160a060020a03163314620027cf57600080fd5b60005460a060020a900460ff1615620027e757600080fd5b85600160a060020a0381161515620027fe57600080fd5b600160a060020a0381163014156200281557600080fd5b600160a060020a038781166000818152600860209081526040918290205482517fb57ab3ac0000000000000000000000000000000000000000000000000000000081526003600482015260248101949094529151919093161594507372ae13d70f65c56e59eb63993605abef1ecb9c419263b57ab3ac9260448082019391829003018186803b158015620028a857600080fd5b505af4158015620028bd573d6000803e3d6000fd5b505050506040513d6020811015620028d457600080fd5b50511515620028e257600080fd5b60408051608081018252600160a060020a0389811680835260208084018b81528486018b9052606085018a9052600092835260088252949091208351815473ffffffffffffffffffffffffffffffffffffffff19169316929092178255925180519293919262002959926001850192019062003b40565b50604082015180516200297791600284019160209091019062003b40565b50606082015180516200299591600384019160209091019062003b40565b509050508115620029da57604051600160a060020a038816907f1e59e06fbc9b065c65d072c1f7a2ed1d81154e6e57768747c6c082207dca730890600090a262002a0f565b604051600160a060020a038816907f9db0a73cad02bbf95f84090f7c99969d3a1cf17d5da896752289967f9f80a58490600090a25b5060019695505050505050565b60056020528160005260406000208181548110151562000b8157fe5b6060600180018054806020026020016040519081016040528092919081815260200182805480156200261257602002820191906000526020600020908154600160a060020a03168152600190910190602001808311620025f3575050505050905090565b60008054819060a060020a900460ff161562002ab757600080fd5b600d5486101562002ac757600080fd5b600c54604080517fdd62ed3e00000000000000000000000000000000000000000000000000000000815233600482015230602482015290518892600160a060020a03169163dd62ed3e9160448083019260209291908290030181600087803b15801562002b3357600080fd5b505af115801562002b48573d6000803e3d6000fd5b505050506040513d602081101562002b5f57600080fd5b5051101562002b6d57600080fd5b3389898988888862002b7e62003bc5565b8088600160a060020a0316600160a060020a03168152602001806020018060200187815260200180602001806020018060200186810386528c818151815260200191508051906020019080838360005b8381101562002be857818101518382015260200162002bce565b50505050905090810190601f16801562002c165780820380516001836020036101000a031916815260200191505b5086810385528b5181528b516020918201918d019080838360005b8381101562002c4b57818101518382015260200162002c31565b50505050905090810190601f16801562002c795780820380516001836020036101000a031916815260200191505b5086810384528951815289516020918201918b019080838360005b8381101562002cae57818101518382015260200162002c94565b50505050905090810190601f16801562002cdc5780820380516001836020036101000a031916815260200191505b5086810383528851815288516020918201918a019080838360005b8381101562002d1157818101518382015260200162002cf7565b50505050905090810190601f16801562002d3f5780820380516001836020036101000a031916815260200191505b50868103825287518152875160209182019189019080838360005b8381101562002d7457818101518382015260200162002d5a565b50505050905090810190601f16801562002da25780820380516001836020036101000a031916815260200191505b509c50505050505050505050505050604051809103906000f08015801562002dce573d6000803e3d6000fd5b50600c54604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018a90529051929350600160a060020a03909116916323b872dd916064808201926020929091908290030181600087803b15801562002e4657600080fd5b505af115801562002e5b573d6000803e3d6000fd5b505050506040513d602081101562002e7257600080fd5b5050336000818152600b60209081526040808320600160a060020a0386168085529083528184208b90559383526007825280832080546001818101835591855283852001805473ffffffffffffffffffffffffffffffffffffffff1916861790558484526009909252808320805460ff1916909217909155517fcf6ea478d30b7e2b0d188cd4bc726f7e42c48dd94081b929ae8f03b8743f02d99190a298975050505050505050565b600d5481565b600054600160a060020a0316331462002f3957600080fd5b62002f448162003a4f565b50565b60008054600160a060020a0316331462002f6057600080fd5b60005460a060020a900460ff161562002f7857600080fd5b81600160a060020a038116151562002f8f57600080fd5b600160a060020a03811630141562002fa657600080fd5b604080517f7d98ebde00000000000000000000000000000000000000000000000000000000815260036004820152600160a060020a038516602482015290517372ae13d70f65c56e59eb63993605abef1ecb9c4191637d98ebde916044808301926020929190829003018186803b1580156200302157600080fd5b505af415801562003036573d6000803e3d6000fd5b505050506040513d60208110156200304d57600080fd5b505115156200305b57600080fd5b604051600160a060020a038416907fd2df117cdff329511dba7edac459dd05c2b14dc4c88ea1faf058c15de773b43390600090a250600192915050565b6000805b600582101562003136576000838360058110620030b557fe5b6020020151600160a060020a03161415620030cf57600080fd5b50600181015b60058110156200312a57828160058110620030ec57fe5b6020020151600160a060020a03168383600581106200310757fe5b6020020151600160a060020a031614156200312157600080fd5b600101620030d5565b6001909101906200309c565b505050565b600080600080600080600080600060149054906101000a900460ff161515156200316457600080fd5b89600160a060020a0316637150d8ae6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015620031a357600080fd5b505af1158015620031b8573d6000803e3d6000fd5b505050506040513d6020811015620031cf57600080fd5b5051604080517f4372df99000000000000000000000000000000000000000000000000000000008152600160a060020a038c811660048301529151929a50908c1691634372df99916024808201926020929091908290030181600087803b1580156200323a57600080fd5b505af11580156200324f573d6000803e3d6000fd5b505050506040513d60208110156200326657600080fd5b5051600160a060020a03808a166000908152600b60209081526040808320938f168084529382528083205481517fa035b1fe0000000000000000000000000000000000000000000000000000000081529151959c509a50929363a035b1fe93600480820194918390030190829087803b158015620032e357600080fd5b505af1158015620032f8573d6000803e3d6000fd5b505050506040513d60208110156200330f57600080fd5b5051604080517f43ca78a2000000000000000000000000000000000000000000000000000000008152600160a060020a038a811660048301529151929750908c16916343ca78a29160248082019260009290919082900301818387803b1580156200337957600080fd5b505af11580156200338e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260a0811015620033b857600080fd5b8151602083015160408401516060850180519395929491939183019291640100000000811115620033e857600080fd5b82016020810184811115620033fc57600080fd5b81516401000000008111828201871017156200341757600080fd5b50949a506200343896508b95508a94505063ffffffff62003acd1692505050565b925062003446848762003ae1565b91506200345a838363ffffffff62003afb16565b90506200346e868363ffffffff62003afb16565b600b60008a600160a060020a0316600160a060020a0316815260200190815260200160002060008c600160a060020a0316600160a060020a0316815260200190815260200160002081905550600c60009054906101000a9004600160a060020a0316600160a060020a03166323b872dd8930846040518463ffffffff1660e060020a0281526004018084600160a060020a0316600160a060020a0316815260200183600160a060020a0316600160a060020a031681526020018281526020019350505050602060405180830381600087803b1580156200354d57600080fd5b505af115801562003562573d6000803e3d6000fd5b505050506040513d60208110156200357957600080fd5b505115156200358757600080fd5b600160a060020a038089166000908152600a602090815260408083208e851684528252808320938d1683529290522054620035c9908463ffffffff62003acd16565b600160a060020a039889166000908152600a602090815260408083209d8c1683529c81528c82209b909a16815299909852505050959094209290925550505050565b60008054819081908190819060a060020a900460ff16156200362c57600080fd5b8a600160a060020a031663a035b1fe6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156200366b57600080fd5b505af115801562003680573d6000803e3d6000fd5b505050506040513d60208110156200369757600080fd5b5051604080517f43ca78a2000000000000000000000000000000000000000000000000000000008152600160a060020a038b811660048301529151929750908d16916343ca78a29160248082019260009290919082900301818387803b1580156200370157600080fd5b505af115801562003716573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260a08110156200374057600080fd5b81516020830151604084015160608501805193959294919391830192916401000000008111156200377057600080fd5b820160208101848111156200378457600080fd5b81516401000000008111828201871017156200379f57600080fd5b50949a50620037c096508b95508a94505063ffffffff62003acd1692505050565b925082600a60008c600160a060020a0316600160a060020a0316815260200190815260200160002060008d600160a060020a0316600160a060020a0316815260200190815260200160002060008b600160a060020a0316600160a060020a0316815260200190815260200160002054101515156200383d57600080fd5b600160a060020a03808b166000908152600a602090815260408083208f851684528252808320938d16835292905220546200387f908463ffffffff62003afb16565b600a60008c600160a060020a0316600160a060020a0316815260200190815260200160002060008d600160a060020a0316600160a060020a0316815260200190815260200160002060008b600160a060020a0316600160a060020a031681526020019081526020016000208190555086620038fb5789620038fd565b875b91508615806200390a5750855b62003916578962003918565b885b600c546040805160e060020a63a9059cbb028152600160a060020a03868116600483015260248201899052915193945091169163a9059cbb916044808201926020929091908290030181600087803b1580156200397457600080fd5b505af115801562003989573d6000803e3d6000fd5b505050506040513d6020811015620039a057600080fd5b50511515620039ae57600080fd5b600c546040805160e060020a63a9059cbb028152600160a060020a038481166004830152602482018990529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801562003a0857600080fd5b505af115801562003a1d573d6000803e3d6000fd5b505050506040513d602081101562003a3457600080fd5b5051151562003a4257600080fd5b5050505050505050505050565b600160a060020a038116151562003a6557600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b8181018281101562003adb57fe5b92915050565b600081831062003af2578162003af4565b825b9392505050565b60008282111562003b0857fe5b50900390565b6080604051908101604052806000600160a060020a031681526020016060815260200160608152602001606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062003b8357805160ff191683800117855562003bb3565b8280016001018555821562003bb3579182015b8281111562003bb357825182559160200191906001019062003b96565b5062003bc192915062003bd6565b5090565b604051611aaa8062003bf483390190565b6200261a91905b8082111562003bc1576000815560010162003bdd560060806040523480156200001157600080fd5b5060405162001aaa38038062001aaa83398101604090815281516020830151918301516060840151608085015160a086015160c087015160008054600160a060020a0319163317905594969586019593840194929391820192908201910186600160a060020a03811615156200008657600080fd5b600160a060020a0381163014156200009d57600080fd5b8251600010620000ac57600080fd5b8151600010620000bb57600080fd5b60018054600160a060020a031916600160a060020a038a161790558651620000eb9060029060208a01906200017d565b508551620001019060039060208901906200017d565b50600485905583516200011c9060059060208701906200017d565b508251620001329060069060208601906200017d565b508151620001489060079060208501906200017d565b50506008805468ff00000000ffffffff19164263ffffffff161767ffffffff0000000019169055506200022295505050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620001c057805160ff1916838001178555620001f0565b82800160010185558215620001f0579182015b82811115620001f0578251825591602001919060010190620001d3565b50620001fe92915062000202565b5090565b6200021f91905b80821115620001fe576000815560010162000209565b90565b61187880620002326000396000f3006080604052600436106101485763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632728e28b811461014d5780634372df991461018657806343ca78a2146101c357806343d726d61461029657806343dcbc86146102bf57806350234173146102e0578063600f1f2b1461034c5780636d4b76d51461037a578063715018a6146103925780637150d8ae146103a95780637d4ccb14146103be5780638da5cb5b1461044857806396661b041461045d57806396e8150a14610483578063a035b1fe1461051b578063b1f4ff9014610542578063c081efc114610557578063cee26ed514610578578063cf09e0d014610590578063cf317b7e146105a5578063d778ce3c14610679578063ec9359401461068e578063f2fde38b146106a3578063f678462f146106c4578063ffaef25e146106d9575b600080fd5b34801561015957600080fd5b50610162610748565b6040518082600281111561017257fe5b60ff16815260200191505060405180910390f35b34801561019257600080fd5b506101a7600160a060020a036004351661075d565b60408051600160a060020a039092168252519081900360200190f35b3480156101cf57600080fd5b506101e4600160a060020a03600435166108c0565b6040518086600160a060020a0316600160a060020a03168152602001858152602001848152602001806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561025757818101518382015260200161023f565b50505050905090810190601f1680156102845780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390f35b3480156102a257600080fd5b506102ab610a0c565b604080519115158252519081900360200190f35b3480156102cb57600080fd5b506102ab600160a060020a0360043516610aa7565b3480156102ec57600080fd5b50604080516020601f6064356004818101359283018490048402850184019095528184526102ab94600160a060020a038135169460248035956044359536956084949301918190840183828082843750949750610afd9650505050505050565b34801561035857600080fd5b50610361610c86565b6040805163ffffffff9092168252519081900360200190f35b34801561038657600080fd5b506101a7600435610c9a565b34801561039e57600080fd5b506103a7610cc2565b005b3480156103b557600080fd5b506101a7610d2e565b3480156103ca57600080fd5b506103d3610d3d565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561040d5781810151838201526020016103f5565b50505050905090810190601f16801561043a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561045457600080fd5b506101a7610dcb565b34801561046957600080fd5b506102ab600160a060020a03600435166024351515610dda565b34801561048f57600080fd5b506104a4600160a060020a0360043516610f54565b60408051600160a060020a038716815263ffffffff80861692820192909252908316606082015260208101608082018360028111156104df57fe5b60ff168152602001828103825286818151815260200191508051906020019080838360008381101561025757818101518382015260200161023f565b34801561052757600080fd5b50610530611033565b60408051918252519081900360200190f35b34801561054e57600080fd5b506103d3611039565b34801561056357600080fd5b506102ab600160a060020a0360043516611091565b34801561058457600080fd5b506101a76004356110e7565b34801561059c57600080fd5b506103616110f5565b3480156105b157600080fd5b506105c6600160a060020a0360043516611101565b60408051600160a060020a038089168252871660208083019190915263ffffffff80871660608401528516608083015260a0820184905260c0928201838152875193830193909352865191929160e084019188019080838360005b83811015610639578181015183820152602001610621565b50505050905090810190601f1680156106665780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b34801561068557600080fd5b506103d361129e565b34801561069a57600080fd5b506103d36112f9565b3480156106af57600080fd5b506103a7600160a060020a0360043516611354565b3480156106d057600080fd5b506103d3611377565b3480156106e557600080fd5b50604080516020600460443581810135601f81018490048402850184019095528484526102ab948235600160a060020a03908116956024803590921695369594606494929301919081908401838280828437509497506113d29650505050505050565b60085468010000000000000000900460ff1681565b6000610767611758565b82600160a060020a038116151561077d57600080fd5b600160a060020a03811630141561079357600080fd5b61079c84611091565b15156107a757600080fd5b600160a060020a03848116600090815260096020908152604091829020825160a08101845281549094168452600180820180548551600261010094831615949094026000190190911692909204601f81018590048502830185019095528482529193858401939192918301828280156108615780601f1061083657610100808354040283529160200191610861565b820191906000526020600020905b81548152906001019060200180831161084457829003601f168201915b505050918352505060028281015463ffffffff8082166020850152640100000000820416604084015260609092019168010000000000000000900460ff16908111156108a957fe5b60028111156108b457fe5b90525051949350505050565b6000806000606060006108d1611785565b86600160a060020a03811615156108e757600080fd5b600160a060020a0381163014156108fd57600080fd5b61090688610aa7565b151561091157600080fd5b600160a060020a0388166000908152600a6020908152604091829020825160808101845281548152600180830154828501526002808401805487519381161561010002600019011691909104601f810186900486028301860187528083529295939493860193919290918301828280156109cc5780601f106109a1576101008083540402835291602001916109cc565b820191906000526020600020905b8154815290600101906020018083116109af57829003601f168201915b50505091835250506003919091015463ffffffff1660209182015281519082015160408301516060909301519a9b919a9099509197509095509350505050565b60008054600160a060020a03163314610a2457600080fd5b600260085468010000000000000000900460ff166002811115610a4357fe5b1415610a4e57600080fd5b600854640100000000900463ffffffff1615610a6957600080fd5b506008805468ff00000000000000001916680200000000000000001767ffffffff0000000019166401000000004263ffffffff160217905560015b90565b600081600160a060020a0381161515610abf57600080fd5b600160a060020a038116301415610ad557600080fd5b5050600160a060020a03166000908152600a602052604090206003015463ffffffff16151590565b60008054600160a060020a03163314610b1557600080fd5b84600160a060020a0381161515610b2b57600080fd5b600160a060020a038116301415610b4157600080fd5b600854640100000000900463ffffffff1615610b5c57600080fd5b6064851115610b6a57600080fd5b610b7386610aa7565b15610b7d57600080fd5b60408051608081018252868152602080820187815282840187815263ffffffff42166060850152600160a060020a038b166000908152600a845294909420835181559051600182015592518051929392610bdd92600285019201906117b4565b50606091909101516003909101805463ffffffff191663ffffffff909216919091179055600c8054600181810183556000929092527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c701805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0389161790556008805468ff000000000000000019166801000000000000000083021790555060019695505050505050565b600854640100000000900463ffffffff1681565b600c805482908110610ca857fe5b600091825260209091200154600160a060020a0316905081565b600054600160a060020a03163314610cd957600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600154600160a060020a031681565b6007805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610dc35780601f10610d9857610100808354040283529160200191610dc3565b820191906000526020600020905b815481529060010190602001808311610da657829003601f168201915b505050505081565b600054600160a060020a031681565b60008054600160a060020a03163314610df257600080fd5b82600160a060020a0381161515610e0857600080fd5b600160a060020a038116301415610e1e57600080fd5b600260085468010000000000000000900460ff166002811115610e3d57fe5b1415610e4857600080fd5b600854640100000000900463ffffffff1615610e6357600080fd5b610e6c84611091565b1515610e7757600080fd5b6000600160a060020a038516600090815260096020526040902060029081015468010000000000000000900460ff1690811115610eb057fe5b14610eba57600080fd5b82610ec6576001610ec9565b60025b600160a060020a038516600090815260096020526040902060029081018054909168ff0000000000000000199091169068010000000000000000908490811115610f0f57fe5b0217905550505050600160a060020a03166000908152600960205260409020600201805467ffffffff0000000019166401000000004263ffffffff1602179055600190565b6009602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f8101869004860283018601909652858252600160a060020a03909216949293909290830182828015610ffe5780601f10610fd357610100808354040283529160200191610ffe565b820191906000526020600020905b815481529060010190602001808311610fe157829003601f168201915b5050506002909301549192505063ffffffff8082169164010000000081049091169060ff680100000000000000009091041685565b60045481565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015610dc35780601f10610d9857610100808354040283529160200191610dc3565b600081600160a060020a03811615156110a957600080fd5b600160a060020a0381163014156110bf57600080fd5b5050600160a060020a031660009081526009602052604090206002015463ffffffff16151590565b600b805482908110610ca857fe5b60085463ffffffff1681565b60008060606000806000611113611758565b87600160a060020a038116151561112957600080fd5b600160a060020a03811630141561113f57600080fd5b61114889611091565b151561115357600080fd5b600160a060020a03898116600090815260096020908152604091829020825160a08101845281549094168452600180820180548551600261010094831615949094026000190190911692909204601f810185900485028301850190955284825291938584019391929183018282801561120d5780601f106111e25761010080835404028352916020019161120d565b820191906000526020600020905b8154815290600101906020018083116111f057829003601f168201915b505050918352505060028281015463ffffffff8082166020850152640100000000820416604084015260609092019168010000000000000000900460ff169081111561125557fe5b600281111561126057fe5b8152505091508882600001518360200151846040015185606001516112888760800151611628565b949e939d50919b50995097509095509350505050565b6006805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610dc35780601f10610d9857610100808354040283529160200191610dc3565b6003805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610dc35780601f10610d9857610100808354040283529160200191610dc3565b600054600160a060020a0316331461136b57600080fd5b611374816116db565b50565b6005805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610dc35780601f10610d9857610100808354040283529160200191610dc3565b60008054600160a060020a031633146113ea57600080fd5b83600160a060020a038116151561140057600080fd5b600160a060020a03811630141561141657600080fd5b83600160a060020a038116151561142c57600080fd5b600160a060020a03811630141561144257600080fd5b600160085468010000000000000000900460ff16600281111561146157fe5b1461146b57600080fd5b600854640100000000900463ffffffff161561148657600080fd5b61148f86611091565b1561149957600080fd5b6114a285610aa7565b15156114ad57600080fd5b60a06040519081016040528086600160a060020a031681526020018581526020014263ffffffff168152602001600063ffffffff168152602001600060028111156114f457fe5b9052600160a060020a0387811660009081526009602090815260409091208351815473ffffffffffffffffffffffffffffffffffffffff1916931692909217825582810151805161154b92600185019201906117b4565b50604082015160028083018054606086015163ffffffff9081166401000000000267ffffffff00000000199190951663ffffffff199092169190911716929092178083556080850151929168ff00000000000000001990911690680100000000000000009084908111156115bb57fe5b021790555050600b8054600181810183556000929092527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9018054600160a060020a038a1673ffffffffffffffffffffffffffffffffffffffff1990911617905593505050509392505050565b60008082600281111561163757fe5b141561166457507f44617461526573706f6e736541646465640000000000000000000000000000006116d6565b600182600281111561167257fe5b141561169f57507f526566756e646564546f427579657200000000000000000000000000000000006116d6565b60028260028111156116ad57fe5b141561014857507f5472616e73616374696f6e436f6d706c657465640000000000000000000000005b919050565b600160a060020a03811615156116f057600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6040805160a081018252600080825260606020830181905292820181905291810182905290608082015290565b608060405190810160405280600081526020016000815260200160608152602001600063ffffffff1681525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106117f557805160ff1916838001178555611822565b82800160010185558215611822579182015b82811115611822578251825591602001919060010190611807565b5061182e929150611832565b5090565b610aa491905b8082111561182e57600081556001016118385600a165627a7a7230582090b9454469f2b12ba07c11a2c481de23eda8cd46e7fabdcae09b2ea5d54626870029a165627a7a723058208b119373d135bf2e3226c2a7685f7a2296b836fae440567bb8e62bb5532818d200290000000000000000000000003f17dd476faf0a4855572f0b6ed5115d9bba22ad0000000000000000000000000183b6ffc017ac4f767e460886291d09229a848b


    Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003f17dd476faf0a4855572f0b6ed5115d9bba22ad0000000000000000000000000183b6ffc017ac4f767e460886291d09229a848b

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000003f17dd476faf0a4855572f0b6ed5115d9bba22ad
Arg [1] : 0000000000000000000000000183b6ffc017ac4f767e460886291d09229a848b


   Library Used
CryptoUtils : 0x48819464877341cb7e0bbd91e0c268016ae5e6ad
MultiMap : 0x72ae13d70f65c56e59eb63993605abef1ecb9c41

   Swarm Source:
bzzr://8b119373d135bf2e3226c2a7685f7a2296b836fae440567bb8e62bb5532818d2
Block Age transaction Difficulty GasUsed Reward
Block Age Uncle Number Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.