Contract Overview
Balance: 0 Ether
Ether Value: $0
Transactions: 3886 txns
 Latest 25 txns From a total of 3886 Transactions

TxHash Age From To Value [TxFee]
0x66cb018e553593c8c8c4bd708cd0196a59eda9191d94ce30bc244a13bf0d65c07 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001387568
0xac96093e0183a9b9e9d39cf428697c693981469fbf84b9e545d6150d8ed94ee58 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00400869
0x447d1c19a0b32f94d56a106f23af914643008174e06940aaf8a9797815ecaaac1 hr 17 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001386952
0xfa092734398420c2301154106af6db08dba6988fa0e17ef97b70d1f151513d571 hr 18 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.004008074
0xcec8276afdb5fccf9a5778808e8d042b452433afee6defc29cbf81dd15d0fa6c1 hr 30 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001386056
0x77656164a4a7b278b3bf87435b711d1ae59228bde408c546197ba31ed37ee5551 hr 31 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.004007794
0x6b46c869aa0f1ad05b46bb8675d542dbf1ab103691818112998c6ca5edb37f051 hr 42 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001386952
0x5dd9fd73e0cb92b85473f766ef2623138e8a14674dc7639bac997f8a0fd434121 hr 43 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.004218074
0x0a3fa9f3cea3655bb435e450893d96240acd95b6533e0536db4db0602b1ae13a2 hrs 47 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001387848
0x336e37fe84180adbfeaad8e800b1019ff5be7a851808954daac5865230bbf0cf2 hrs 47 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00421897
0xeee781724b5024fc97368ef02859b5ba6aa02ba05fa588bb7649eb037edfe2c13 hrs 42 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001387568
0x5ec54c1a06025b601e293c80a228ca8ea3f0578185d6f7468a93482bb863b2a13 hrs 43 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00400897
0xf90f4893dae77787d5d3ca637240537642c3b02980bc60eb05defe4b755e6d673 hrs 44 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00421897
0x4476e458809e70679e595a8bb2207ac2a855f42b7dcd3c93736059f4fa8a2b314 hrs 56 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001595776
0x9772eea7370cdd4710b6f85972b926de0d24d7786034735a083937b41ca94bca4 hrs 56 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.004217794
0x079367c8255ef5cafcb6c9ca84c7d4f7b76504aaf73f5a5f9a29a75806758b334 hrs 59 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001596952
0x72065221b4f5be78f81175e8ea4d3cfe71f5b809a3861c3c0b7dad8dbdd32c695 hrs ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.004217178
0x933a4f05b5f64d878dfc5be33ece0d9d707f0a8b07a87a683611467d474286e45 hrs 4 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001597848
0x6975d684982a1e3c8744706435d11346c94639545c3bddde5aabd444a4ceaf015 hrs 5 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.004218074
0xa336562a0b19acc0ef78515533c236da0bb0ccadbf299d9e68e12ec8f80a009b5 hrs 8 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001596952
0x207a5f64d68d5bb059ef4b3de67159909b68e34eefdc8ac772f98c3f095d77345 hrs 9 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.00421869
0xa7d404496bb00fea2b2b6029ae8555b639e155ed41f1a7d717b785134262de755 hrs 11 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.004217794
0x12d796b1ac99e9b85d4f5f835bdfda0e1a19395747c3eb43463c11a94de8babc5 hrs 16 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001596952
0x9bca68dd1952f8a5ef2ba8a9843fade1e4fdbb4adb20eeb7324c8bc48a594b075 hrs 16 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.004217794
0x70c803971839493b84f32665e419b2e6eab4e9cba351060d0871fc6b76a485185 hrs 19 mins ago0x6d27d82d7d6f0ae00ba6cdfe53aa9d0097952222  IN   0xd077c09a7e65c4cca490a776d5e395fb4fe7179a0 Ether0.001596672
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 9 Internal Transactions

ParentTxHash Block Age From To Value
0x603100e19aea2398a7c9ea4bcd9b51b322b36632ebe6059ba952446cae58695d65036143 days 7 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x540553e2e2600d0a0a407f8f5d2e10c4feedd90313f7e0474b45ac019b41f34164785797 days 9 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0xa672a6c85f5aa100271ea6a9aa1a746956d27d80d794dee64765d0e0cfa92eaa641778817 days 6 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x89cf13c748b5c9fd0ae092d8bf02e29dd99440baadf50b1ddd5a1c43fecf0e62641777117 days 6 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x74724cf223761f88e3dc74f54775aeac1601f2ad4a4ffe498978fdc7adfa4eee641768517 days 6 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x33f043261aa7d6275a2594f34c517a4f28cc6ba48ecb4b42a86fb44d8e1503bc641765617 days 6 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x9ba7a4b4a54635f5afa48a8160307f417902d6ff298ebabdd1afabb225162a9d641728717 days 8 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x1f0a70876723acec79d0198b70792f9a2a8216b21fc4b99e0836673a18d848fd641191418 days 5 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
0x171fbe1079b6937e91f13e7e994eb785ad6a7d11b62179037e78657c593d0fc6636727525 days 13 hrs ago0xd077c09a7e65c4cca490a776d5e395fb4fe7179a  Contract Creation0 Ether
[ Download CSV Export  ] 
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) SolidityCompiler Bugs.

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



  Contract Source Code   Find Similiar Contracts

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 Switch To Opcodes View
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

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.