Contract Overview
Balance: 0 Ether
Ether Value: $0
Transactions: 26463 txns
Misc:
Address Watch: Add To Watch List
Contract Creator: 0x86ef3ec49e3ea47ca1b4446564822cff6020b21aat txn 0x960e7a3d1f60f78f0527fce4a6a519994b87ffb79b059d88b992c9bb0af095cf
Token Balance:
 Latest 25 transactions from a total of 26463 transactions

TxHash Age From To Value [TxFee]
0x4b6db39b8e06c48485107c2f1b44c1f4b66c11f5a88ae8ab548fbf3a8392ae3d17 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.000327819
0x6a69ceee4d29d19c4ac76f435fd87eb8b6975eb303bffa2e54d354b36962a1dd17 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.000437172
0x0dea0008bb72802c63682047905bc3cc9e633d6a1de7187d56849d3983051ff417 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.000327627
0xbe14f3515d38ebe5284093660be5e3d425ea0b78f3c80fe847ac7c5479751a3017 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0004805196
0x792f577c0061236d0a9181b0d098d441a5bafe1d1ecdca3c3b2c3e719263bedf18 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0004806076
0x663d98e8684ed5b4163968fb40032fabcd29ed52eb9afaedfbd48465e2b127fc18 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0004043101
0xa2bc19bedec5907fa39e773d2f8ed498ec968bca527a7fcac2c0084bb95698c042 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.00021833
0xf664e8ccaa140e0c51f943e8ad8a512946efab1a6dc50b06beca145e2236335843 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.000218458
0x6a82a55843a8e237cecfe3de6ecf2b9b66c629e3038b585d86bcf86401606ca844 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002727525
0x94e0f4d35aad794b730f053ca80dcd1f380c01aa503cbd822ffca80738c0aabf48 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.000218418
0x87dcd7e2759b8961be38400aa041287a63b01636d525c7701c18ace61dda29e648 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.00021833
0xfc9887dfb2df99dac075b7082bc6c3605d7b267663081918cd9afbc0f324455948 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002510335
0xd6c4ac69a00627a39614fa5026eda8ccc04f4bb1797e1f84f4697bc40df0c39750 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002293809
0x135d06e691439f2fe28afafd3805394367f67f1cf8486304e5a6af53921f3ed150 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002622552
0x248964b9b32205a8dbd533e095834987db517819d41c097df6f0fa4ebdcd685153 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002949723
0x42cb68c76363da1f4cb59fd4a90342e78c419a9d8ef6b7bad84d268e8fadcb6d58 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002293809
0x47457f7b7a64b8c2ec5980304e05cadf3a06ce43972843fc726b8bd2692dc75c1 hr 1 min ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002404886
0xb5cbc18687cf7d2790798648f91d51d07c21e24c9d0781b4416a2e548e9c821d1 hr 1 min ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002404886
0xf7599d54e929cc9ad77817ef260375cae8ca6e720c853413428c6aed4bd9f9101 hr 2 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002400222
0x468e4d131e1d85b55be63688b23f4f60c57a75f9074917d579f46f31813d37051 hr 14 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0002730725
0xadefa347b0e7252e0185945df8e32e3679404a015a8a8210b284bd4c7955db5a1 hr 23 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.00043666
0x2e8af1843f674f1f59f84d63aba551d3e778f8381dce34d48574a8e8a4d071611 hr 31 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.000546365
0xc9a3c1cd39c37dacb157d263dded3d3cbdff02395110439130951c1ed6c525b81 hr 36 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0005574963
0x4a42113c8c9cfdd7a9a8faa047fb61ebdc2584ef634220a1a95eb174d3608ca31 hr 36 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.0006218757
0xcc1f5167f893468260d1120d5c2a49276a33efa52b2b5289306d513dbcbcead31 hr 40 mins ago0xa83996cace93b2af6c54222a51da5dbda8526172  IN   0xceec7aaa57e3a77c73a9954b9b7d5b32ab6883180 Ether0.000546565
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
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: AttestationLogic
Compiler Text: v0.4.24+commit.e67f0147
Optimization Enabled: No
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity 0.4.24;



/**
 * @dev Pulled from OpenZeppelin: https://git.io/vbaRf
 *   When this is in a public release we will switch to not vendoring this file
 *
 * @title Eliptic curve signature operations
 *
 * @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d
 */

library ECRecovery {

  /**
   * @dev Recover signer address from a message by using his 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) public pure returns (address) {
    bytes32 r;
    bytes32 s;
    uint8 v;

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

    // Extracting these values isn't possible without assembly
    // solhint-disable no-inline-assembly
    // Divide the signature in r, s and v variables
    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 {
      return ecrecover(hash, v, r, s);
    }
  }

}


/**
 * @title SigningLogic is contract implementing signature recovery from typed data signatures
 * @notice Recovers signatures based on the SignTypedData implementation provided by ethSigUtil
 * @dev This contract is inherited by other contracts.
 */
contract SigningLogic {

  // Signatures contain a nonce to make them unique. usedSignatures tracks which signatures
  //  have been used so they can't be replayed
  mapping (bytes32 => bool) public usedSignatures;

  function burnSignatureDigest(bytes32 _signatureDigest, address _sender) internal {
    bytes32 _txDataHash = keccak256(abi.encode(_signatureDigest, _sender));
    require(!usedSignatures[_txDataHash], "Signature not unique");
    usedSignatures[_txDataHash] = true;
  }

  bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256(
    "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
  );

  bytes32 constant ATTESTATION_REQUEST_TYPEHASH = keccak256(
    "AttestationRequest(bytes32 dataHash,bytes32 nonce)"
  );

  bytes32 constant ADD_ADDRESS_TYPEHASH = keccak256(
    "AddAddress(address addressToAdd,bytes32 nonce)"
  );

  bytes32 constant REMOVE_ADDRESS_TYPEHASH = keccak256(
    "RemoveAddress(address addressToRemove,bytes32 nonce)"
  );

  bytes32 constant PAY_TOKENS_TYPEHASH = keccak256(
    "PayTokens(address sender,address receiver,uint256 amount,bytes32 nonce)"
  );

  bytes32 constant RELEASE_TOKENS_FOR_TYPEHASH = keccak256(
    "ReleaseTokensFor(address sender,uint256 amount,bytes32 nonce)"
  );

  bytes32 constant ATTEST_FOR_TYPEHASH = keccak256(
    "AttestFor(address subject,address requester,uint256 reward,bytes32 dataHash,bytes32 requestNonce)"
  );

  bytes32 constant CONTEST_FOR_TYPEHASH = keccak256(
    "ContestFor(address requester,uint256 reward,bytes32 requestNonce)"
  );

  bytes32 constant REVOKE_ATTESTATION_FOR_TYPEHASH = keccak256(
    "RevokeAttestationFor(bytes32 link,bytes32 nonce)"
  );

  bytes32 constant VOTE_FOR_TYPEHASH = keccak256(
    "VoteFor(uint16 choice,address voter,bytes32 nonce,address poll)"
  );

  bytes32 constant LOCKUP_TOKENS_FOR_TYPEHASH = keccak256(
    "LockupTokensFor(address sender,uint256 amount,bytes32 nonce)"
  );

  bytes32 DOMAIN_SEPARATOR;

  constructor (string name, string version, uint256 chainId) public {
    DOMAIN_SEPARATOR = hash(EIP712Domain({
      name: name,
      version: version,
      chainId: chainId,
      verifyingContract: this
    }));
  }

  struct EIP712Domain {
      string  name;
      string  version;
      uint256 chainId;
      address verifyingContract;
  }

  function hash(EIP712Domain eip712Domain) private pure returns (bytes32) {
    return keccak256(abi.encode(
      EIP712DOMAIN_TYPEHASH,
      keccak256(bytes(eip712Domain.name)),
      keccak256(bytes(eip712Domain.version)),
      eip712Domain.chainId,
      eip712Domain.verifyingContract
    ));
  }

  struct AttestationRequest {
      bytes32 dataHash;
      bytes32 nonce;
  }

  function hash(AttestationRequest request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      ATTESTATION_REQUEST_TYPEHASH,
      request.dataHash,
      request.nonce
    ));
  }

  struct AddAddress {
      address addressToAdd;
      bytes32 nonce;
  }

  function hash(AddAddress request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      ADD_ADDRESS_TYPEHASH,
      request.addressToAdd,
      request.nonce
    ));
  }

  struct RemoveAddress {
      address addressToRemove;
      bytes32 nonce;
  }

  function hash(RemoveAddress request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      REMOVE_ADDRESS_TYPEHASH,
      request.addressToRemove,
      request.nonce
    ));
  }

  struct PayTokens {
      address sender;
      address receiver;
      uint256 amount;
      bytes32 nonce;
  }

  function hash(PayTokens request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      PAY_TOKENS_TYPEHASH,
      request.sender,
      request.receiver,
      request.amount,
      request.nonce
    ));
  }

  struct AttestFor {
      address subject;
      address requester;
      uint256 reward;
      bytes32 dataHash;
      bytes32 requestNonce;
  }

  function hash(AttestFor request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      ATTEST_FOR_TYPEHASH,
      request.subject,
      request.requester,
      request.reward,
      request.dataHash,
      request.requestNonce
    ));
  }

  struct ContestFor {
      address requester;
      uint256 reward;
      bytes32 requestNonce;
  }

  function hash(ContestFor request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      CONTEST_FOR_TYPEHASH,
      request.requester,
      request.reward,
      request.requestNonce
    ));
  }

  struct RevokeAttestationFor {
      bytes32 link;
      bytes32 nonce;
  }

  function hash(RevokeAttestationFor request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      REVOKE_ATTESTATION_FOR_TYPEHASH,
      request.link,
      request.nonce
    ));
  }

  struct VoteFor {
      uint16 choice;
      address voter;
      bytes32 nonce;
      address poll;
  }

  function hash(VoteFor request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      VOTE_FOR_TYPEHASH,
      request.choice,
      request.voter,
      request.nonce,
      request.poll
    ));
  }

  struct LockupTokensFor {
    address sender;
    uint256 amount;
    bytes32 nonce;
  }

  function hash(LockupTokensFor request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      LOCKUP_TOKENS_FOR_TYPEHASH,
      request.sender,
      request.amount,
      request.nonce
    ));
  }

  struct ReleaseTokensFor {
    address sender;
    uint256 amount;
    bytes32 nonce;
  }

  function hash(ReleaseTokensFor request) private pure returns (bytes32) {
    return keccak256(abi.encode(
      RELEASE_TOKENS_FOR_TYPEHASH,
      request.sender,
      request.amount,
      request.nonce
    ));
  }

  function generateRequestAttestationSchemaHash(
    bytes32 _dataHash,
    bytes32 _nonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(AttestationRequest(
          _dataHash,
          _nonce
        ))
      )
      );
  }

  function generateAddAddressSchemaHash(
    address _addressToAdd,
    bytes32 _nonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(AddAddress(
          _addressToAdd,
          _nonce
        ))
      )
      );
  }

  function generateRemoveAddressSchemaHash(
    address _addressToRemove,
    bytes32 _nonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(RemoveAddress(
          _addressToRemove,
          _nonce
        ))
      )
      );
  }

  function generatePayTokensSchemaHash(
    address _sender,
    address _receiver,
    uint256 _amount,
    bytes32 _nonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(PayTokens(
          _sender,
          _receiver,
          _amount,
          _nonce
        ))
      )
      );
  }

  function generateAttestForDelegationSchemaHash(
    address _subject,
    address _requester,
    uint256 _reward,
    bytes32 _dataHash,
    bytes32 _requestNonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(AttestFor(
          _subject,
          _requester,
          _reward,
          _dataHash,
          _requestNonce
        ))
      )
      );
  }

  function generateContestForDelegationSchemaHash(
    address _requester,
    uint256 _reward,
    bytes32 _requestNonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(ContestFor(
          _requester,
          _reward,
          _requestNonce
        ))
      )
      );
  }

  function generateRevokeAttestationForDelegationSchemaHash(
    bytes32 _link,
    bytes32 _nonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(RevokeAttestationFor(
          _link,
          _nonce
        ))
      )
      );
  }

  function generateVoteForDelegationSchemaHash(
    uint16 _choice,
    address _voter,
    bytes32 _nonce,
    address _poll
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(VoteFor(
          _choice,
          _voter,
          _nonce,
          _poll
        ))
      )
      );
  }

  function generateLockupTokensDelegationSchemaHash(
    address _sender,
    uint256 _amount,
    bytes32 _nonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(LockupTokensFor(
          _sender,
          _amount,
          _nonce
        ))
      )
      );
  }

  function generateReleaseTokensDelegationSchemaHash(
    address _sender,
    uint256 _amount,
    bytes32 _nonce
  ) internal view returns (bytes32) {
    return keccak256(
      abi.encodePacked(
        "\x19\x01",
        DOMAIN_SEPARATOR,
        hash(ReleaseTokensFor(
          _sender,
          _amount,
          _nonce
        ))
      )
      );
  }

  function recoverSigner(bytes32 _hash, bytes _sig) internal pure returns (address) {
    address signer = ECRecovery.recover(_hash, _sig);
    require(signer != address(0));

    return signer;
  }
}
pragma solidity ^0.4.21;


/**
 * @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 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 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) {
    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 SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
  function safeTransfer(ERC20Basic token, address to, uint256 value) internal {
    assert(token.transfer(to, value));
  }

  function safeTransferFrom(
    ERC20 token,
    address from,
    address to,
    uint256 value
  )
    internal
  {
    assert(token.transferFrom(from, to, value));
  }

  function safeApprove(ERC20 token, address spender, uint256 value) internal {
    assert(token.approve(spender, value));
  }
}


/**
 * @notice TokenEscrowMarketplace is an ERC20 payment channel that enables users to send BLT by exchanging signatures off-chain
 *  Users approve the contract address to transfer BLT on their behalf using the standard ERC20.approve function
 *  After approval, either the user or the contract admin initiates the transfer of BLT into the contract
 *  Once in the contract, users can send payments via a signed message to another user. 
 *  The signature transfers BLT from lockup to the recipient's balance
 *  Users can withdraw funds at any time. Or the admin can release them on the user's behalf
 *  
 *  BLT is stored in the contract by address
 *  
 *  Only the AttestationLogic contract is authorized to release funds once a jobs is complete
 */
contract TokenEscrowMarketplace is SigningLogic {
  using SafeERC20 for ERC20;
  using SafeMath for uint256;

  address public attestationLogic;

  mapping(address => uint256) public tokenEscrow;
  ERC20 public token;

  event TokenMarketplaceWithdrawal(address escrowPayer, uint256 amount);
  event TokenMarketplaceEscrowPayment(address escrowPayer, address escrowPayee, uint256 amount);
  event TokenMarketplaceDeposit(address escrowPayer, uint256 amount);

  /**
   * @notice The TokenEscrowMarketplace constructor initializes the interfaces to the other contracts
   * @dev Some actions are restricted to be performed by the attestationLogic contract.
   *  Signing logic is upgradeable in case the signTypedData spec changes
   * @param _token Address of BLT
   * @param _attestationLogic Address of current attestation logic contract
   */
  constructor(
    ERC20 _token,
    address _attestationLogic
    ) public SigningLogic("Bloom Token Escrow Marketplace", "2", 1) {
    token = _token;
    attestationLogic = _attestationLogic;
  }

  modifier onlyAttestationLogic() {
    require(msg.sender == attestationLogic);
    _;
  }

  /**
   * @notice Lockup tokens for set time period on behalf of user. Must be preceeded by approve
   * @dev Authorized by a signTypedData signature by sender
   *  Sigs can only be used once. They contain a unique nonce
   *  So an action can be repeated, with a different signature
   * @param _sender User locking up their tokens
   * @param _amount Tokens to lock up
   * @param _nonce Unique Id so signatures can't be replayed
   * @param _delegationSig Signed hash of these input parameters so an admin can submit this on behalf of a user
   */
  function moveTokensToEscrowLockupFor(
    address _sender,
    uint256 _amount,
    bytes32 _nonce,
    bytes _delegationSig
    ) external {
      validateLockupTokensSig(
        _sender,
        _amount,
        _nonce,
        _delegationSig
      );
      moveTokensToEscrowLockupForUser(_sender, _amount);
  }

  /**
   * @notice Verify lockup signature is valid
   * @param _sender User locking up their tokens
   * @param _amount Tokens to lock up
   * @param _nonce Unique Id so signatures can't be replayed
   * @param _delegationSig Signed hash of these input parameters so an admin can submit this on behalf of a user
   */
  function validateLockupTokensSig(
    address _sender,
    uint256 _amount,
    bytes32 _nonce,
    bytes _delegationSig
  ) private {
    bytes32 _signatureDigest = generateLockupTokensDelegationSchemaHash(_sender, _amount, _nonce);
    require(_sender == recoverSigner(_signatureDigest, _delegationSig), 'Invalid LockupTokens Signature');
    burnSignatureDigest(_signatureDigest, _sender);
  }

  /**
   * @notice Lockup tokens by user. Must be preceeded by approve
   * @param _amount Tokens to lock up
   */
  function moveTokensToEscrowLockup(uint256 _amount) external {
    moveTokensToEscrowLockupForUser(msg.sender, _amount);
  }

  /**
   * @notice Lockup tokens for set time. Must be preceeded by approve
   * @dev Private function called by appropriate public function
   * @param _sender User locking up their tokens
   * @param _amount Tokens to lock up
   */
  function moveTokensToEscrowLockupForUser(
    address _sender,
    uint256 _amount
    ) private {
    token.safeTransferFrom(_sender, this, _amount);
    addToEscrow(_sender, _amount);
  }

  /**
   * @notice Withdraw tokens from escrow back to requester
   * @dev Authorized by a signTypedData signature by sender
   *  Sigs can only be used once. They contain a unique nonce
   *  So an action can be repeated, with a different signature
   * @param _sender User withdrawing their tokens
   * @param _amount Tokens to withdraw
   * @param _nonce Unique Id so signatures can't be replayed
   * @param _delegationSig Signed hash of these input parameters so an admin can submit this on behalf of a user
   */
  function releaseTokensFromEscrowFor(
    address _sender,
    uint256 _amount,
    bytes32 _nonce,
    bytes _delegationSig
    ) external {
      validateReleaseTokensSig(
        _sender,
        _amount,
        _nonce,
        _delegationSig
      );
      releaseTokensFromEscrowForUser(_sender, _amount);
  }

  /**
   * @notice Verify lockup signature is valid
   * @param _sender User withdrawing their tokens
   * @param _amount Tokens to lock up
   * @param _nonce Unique Id so signatures can't be replayed
   * @param _delegationSig Signed hash of these input parameters so an admin can submit this on behalf of a user
   */
  function validateReleaseTokensSig(
    address _sender,
    uint256 _amount,
    bytes32 _nonce,
    bytes _delegationSig

  ) private {
    bytes32 _signatureDigest = generateReleaseTokensDelegationSchemaHash(_sender, _amount, _nonce);
    require(_sender == recoverSigner(_signatureDigest, _delegationSig), 'Invalid ReleaseTokens Signature');
    burnSignatureDigest(_signatureDigest, _sender);
  }

  /**
   * @notice Release tokens back to payer's available balance if lockup expires
   * @dev Token balance retreived by accountId. Can be different address from the one that deposited tokens
   * @param _amount Tokens to retreive from escrow
   */
  function releaseTokensFromEscrow(uint256 _amount) external {
    releaseTokensFromEscrowForUser(msg.sender, _amount);
  }

  /**
   * @notice Release tokens back to payer's available balance
   * @param _payer User retreiving tokens from escrow
   * @param _amount Tokens to retreive from escrow
   */
  function releaseTokensFromEscrowForUser(
    address _payer,
    uint256 _amount
    ) private {
      subFromEscrow(_payer, _amount);
      token.safeTransfer(_payer, _amount);
      emit TokenMarketplaceWithdrawal(_payer, _amount);
  }

  /**
   * @notice Pay from escrow of payer to available balance of receiever
   * @dev Private function to modify balances on payment
   * @param _payer User with tokens in escrow
   * @param _receiver User receiving tokens
   * @param _amount Tokens being sent
   */
  function payTokensFromEscrow(address _payer, address _receiver, uint256 _amount) private {
    subFromEscrow(_payer, _amount);
    token.safeTransfer(_receiver, _amount);
  }

  /**
   * @notice Pay tokens to receiver from payer's escrow given a valid signature
   * @dev Execution restricted to attestationLogic contract
   * @param _payer User paying tokens from escrow
   * @param _receiver User receiving payment
   * @param _amount Tokens being paid
   * @param _nonce Unique Id for sig to make it one-time-use
   * @param _paymentSig Signed parameters by payer authorizing payment
   */
  function requestTokenPayment(
    address _payer,
    address _receiver,
    uint256 _amount,
    bytes32 _nonce,
    bytes _paymentSig
    ) external onlyAttestationLogic {

    validatePaymentSig(
      _payer,
      _receiver,
      _amount,
      _nonce,
      _paymentSig
    );
    payTokensFromEscrow(_payer, _receiver, _amount);
    emit TokenMarketplaceEscrowPayment(_payer, _receiver, _amount);
  }

  /**
   * @notice Verify payment signature is valid
   * @param _payer User paying tokens from escrow
   * @param _receiver User receiving payment
   * @param _amount Tokens being paid
   * @param _nonce Unique Id for sig to make it one-time-use
   * @param _paymentSig Signed parameters by payer authorizing payment
   */
  function validatePaymentSig(
    address _payer,
    address _receiver,
    uint256 _amount,
    bytes32 _nonce,
    bytes _paymentSig

  ) private {
    bytes32 _signatureDigest = generatePayTokensSchemaHash(_payer, _receiver, _amount, _nonce);
    require(_payer == recoverSigner(_signatureDigest, _paymentSig), 'Invalid Payment Signature');
    burnSignatureDigest(_signatureDigest, _payer);
  }

  /**
   * @notice Helper function to add to escrow balance 
   * @param _from Account address for escrow mapping
   * @param _amount Tokens to lock up
   */
  function addToEscrow(address _from, uint256 _amount) private {
    tokenEscrow[_from] = tokenEscrow[_from].add(_amount);
    emit TokenMarketplaceDeposit(_from, _amount);
  }

  /**
   * Helper function to reduce escrow token balance of user
   */
  function subFromEscrow(address _from, uint256 _amount) private {
    require(tokenEscrow[_from] >= _amount);
    tokenEscrow[_from] = tokenEscrow[_from].sub(_amount);
  }
}

/**
 * @title Initializable
 * @dev The Initializable contract has an initializer address, and provides basic authorization control
 * only while in initialization mode. Once changed to production mode the inializer loses authority
 */
contract Initializable {
  address public initializer;
  bool public initializing;

  event InitializationEnded();

  /**
   * @dev The Initializable constructor sets the initializer to the provided address
   */
  constructor(address _initializer) public {
    initializer = _initializer;
    initializing = true;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyDuringInitialization() {
    require(msg.sender == initializer, 'Method can only be called by initializer');
    require(initializing, 'Method can only be called during initialization');
    _;
  }

  /**
   * @dev Allows the initializer to end the initialization period
   */
  function endInitialization() public onlyDuringInitialization {
    initializing = false;
    emit InitializationEnded();
  }

}


/**
 * @title AttestationLogic allows users to submit attestations given valid signatures
 * @notice Attestation Logic Logic provides a public interface for Bloom and
 *  users to submit attestations.
 */
contract AttestationLogic is Initializable, SigningLogic{
    TokenEscrowMarketplace public tokenEscrowMarketplace;

  /**
   * @notice AttestationLogic constructor sets the implementation address of all related contracts
   * @param _tokenEscrowMarketplace Address of marketplace holding tokens which are
   *  released to attesters upon completion of a job
   */
  constructor(
    address _initializer,
    TokenEscrowMarketplace _tokenEscrowMarketplace
    ) Initializable(_initializer) SigningLogic("Bloom Attestation Logic", "2", 1) public {
    tokenEscrowMarketplace = _tokenEscrowMarketplace;
  }

  event TraitAttested(
    address subject,
    address attester,
    address requester,
    bytes32 dataHash
    );
  event AttestationRejected(address indexed attester, address indexed requester);
  event AttestationRevoked(bytes32 link, address attester);
  event TokenEscrowMarketplaceChanged(address oldTokenEscrowMarketplace, address newTokenEscrowMarketplace);

  /**
   * @notice Function for attester to submit attestation from their own account) 
   * @dev Wrapper for attestForUser using msg.sender
   * @param _subject User this attestation is about
   * @param _requester User requesting and paying for this attestation in BLT
   * @param _reward Payment to attester from requester in BLT
   * @param _requesterSig Signature authorizing payment from requester to attester
   * @param _dataHash Hash of data being attested and nonce
   * @param _requestNonce Nonce in sig signed by subject and requester so they can't be replayed
   * @param _subjectSig Signed authorization from subject with attestation agreement
   */
  function attest(
    address _subject,
    address _requester,
    uint256 _reward,
    bytes _requesterSig,
    bytes32 _dataHash,
    bytes32 _requestNonce,
    bytes _subjectSig // Sig of subject with requester, attester, dataHash, requestNonce
  ) external {
    attestForUser(
      _subject,
      msg.sender,
      _requester,
      _reward,
      _requesterSig,
      _dataHash,
      _requestNonce,
      _subjectSig
    );
  }

  /**
   * @notice Submit attestation for a user in order to pay the gas costs
   * @dev Recover signer of delegation message. If attester matches delegation signature, add the attestation
   * @param _subject user this attestation is about
   * @param _attester user completing the attestation
   * @param _requester user requesting this attestation be completed and paying for it in BLT
   * @param _reward payment to attester from requester in BLT wei
   * @param _requesterSig signature authorizing payment from requester to attester
   * @param _dataHash hash of data being attested and nonce
   * @param _requestNonce Nonce in sig signed by subject and requester so they can't be replayed
   * @param _subjectSig signed authorization from subject with attestation agreement
   * @param _delegationSig signature authorizing attestation on behalf of attester
   */
  function attestFor(
    address _subject,
    address _attester,
    address _requester,
    uint256 _reward,
    bytes _requesterSig,
    bytes32 _dataHash,
    bytes32 _requestNonce,
    bytes _subjectSig, // Sig of subject with dataHash and requestNonce
    bytes _delegationSig
  ) external {
    // Confirm attester address matches recovered address from signature
    validateAttestForSig(_subject, _attester, _requester, _reward, _dataHash, _requestNonce, _delegationSig);
    attestForUser(
      _subject,
      _attester,
      _requester,
      _reward,
      _requesterSig,
      _dataHash,
      _requestNonce,
      _subjectSig
    );
  }

  /**
   * @notice Perform attestation
   * @dev Verify valid certainty level and user addresses
   * @param _subject user this attestation is about
   * @param _attester user completing the attestation
   * @param _requester user requesting this attestation be completed and paying for it in BLT
   * @param _reward payment to attester from requester in BLT wei
   * @param _requesterSig signature authorizing payment from requester to attester
   * @param _dataHash hash of data being attested and nonce
   * @param _requestNonce Nonce in sig signed by subject and requester so they can't be replayed
   * @param _subjectSig signed authorization from subject with attestation agreement
   */
  function attestForUser(
    address _subject,
    address _attester,
    address _requester,
    uint256 _reward,
    bytes _requesterSig,
    bytes32 _dataHash,
    bytes32 _requestNonce,
    bytes _subjectSig
    ) private {
    
    validateSubjectSig(
      _subject,
      _dataHash,
      _requestNonce,
      _subjectSig
    );

    emit TraitAttested(
      _subject,
      _attester,
      _requester,
      _dataHash
    );

    if (_reward > 0) {
      tokenEscrowMarketplace.requestTokenPayment(_requester, _attester, _reward, _requestNonce, _requesterSig);
    }
  }

  /**
   * @notice Function for attester to reject an attestation and receive payment 
   *  without associating the negative attestation with the subject's bloomId
   * @param _requester User requesting and paying for this attestation in BLT
   * @param _reward Payment to attester from requester in BLT
   * @param _requestNonce Nonce in sig signed by requester so it can't be replayed
   * @param _requesterSig Signature authorizing payment from requester to attester
   */
  function contest(
    address _requester,
    uint256 _reward,
    bytes32 _requestNonce,
    bytes _requesterSig
  ) external {
    contestForUser(
      msg.sender,
      _requester,
      _reward,
      _requestNonce,
      _requesterSig
    );
  }

  /**
   * @notice Function for attester to reject an attestation and receive payment 
   *  without associating the negative attestation with the subject's bloomId
   *  Perform on behalf of attester to pay gas fees
   * @param _requester User requesting and paying for this attestation in BLT
   * @param _attester user completing the attestation
   * @param _reward Payment to attester from requester in BLT
   * @param _requestNonce Nonce in sig signed by requester so it can't be replayed
   * @param _requesterSig Signature authorizing payment from requester to attester
   */
  function contestFor(
    address _attester,
    address _requester,
    uint256 _reward,
    bytes32 _requestNonce,
    bytes _requesterSig,
    bytes _delegationSig
  ) external {
    validateContestForSig(
      _attester,
      _requester,
      _reward,
      _requestNonce,
      _delegationSig
    );
    contestForUser(
      _attester,
      _requester,
      _reward,
      _requestNonce,
      _requesterSig
    );
  }

  /**
   * @notice Private function for attester to reject an attestation and receive payment 
   *  without associating the negative attestation with the subject's bloomId
   * @param _attester user completing the attestation
   * @param _requester user requesting this attestation be completed and paying for it in BLT
   * @param _reward payment to attester from requester in BLT wei
   * @param _requestNonce Nonce in sig signed by requester so it can't be replayed
   * @param _requesterSig signature authorizing payment from requester to attester
   */
  function contestForUser(
    address _attester,
    address _requester,
    uint256 _reward,
    bytes32 _requestNonce,
    bytes _requesterSig
    ) private {

    if (_reward > 0) {
      tokenEscrowMarketplace.requestTokenPayment(_requester, _attester, _reward, _requestNonce, _requesterSig);
    }
    emit AttestationRejected(_attester, _requester);
  }

  /**
   * @notice Verify subject signature is valid 
   * @param _subject user this attestation is about
   * @param _dataHash hash of data being attested and nonce
   * param _requestNonce Nonce in sig signed by subject so it can't be replayed
   * @param _subjectSig Signed authorization from subject with attestation agreement
   */
  function validateSubjectSig(
    address _subject,
    bytes32 _dataHash,
    bytes32 _requestNonce,
    bytes _subjectSig
  ) private {
    bytes32 _signatureDigest = generateRequestAttestationSchemaHash(_dataHash, _requestNonce);
    require(_subject == recoverSigner(_signatureDigest, _subjectSig));
    burnSignatureDigest(_signatureDigest, _subject);
  }

  /**
   * @notice Verify attester delegation signature is valid 
   * @param _subject user this attestation is about
   * @param _attester user completing the attestation
   * @param _requester user requesting this attestation be completed and paying for it in BLT
   * @param _reward payment to attester from requester in BLT wei
   * @param _dataHash hash of data being attested and nonce
   * @param _requestNonce nonce in sig signed by subject so it can't be replayed
   * @param _delegationSig signature authorizing attestation on behalf of attester
   */
  function validateAttestForSig(
    address _subject,
    address _attester,
    address _requester,
    uint256 _reward,
    bytes32 _dataHash,
    bytes32 _requestNonce,
    bytes _delegationSig
  ) private {
    bytes32 _delegationDigest = generateAttestForDelegationSchemaHash(_subject, _requester, _reward, _dataHash, _requestNonce);
    require(_attester == recoverSigner(_delegationDigest, _delegationSig), 'Invalid AttestFor Signature');
    burnSignatureDigest(_delegationDigest, _attester);
  }

  /**
   * @notice Verify attester delegation signature is valid 
   * @param _attester user completing the attestation
   * @param _requester user requesting this attestation be completed and paying for it in BLT
   * @param _reward payment to attester from requester in BLT wei
   * @param _requestNonce nonce referenced in TokenEscrowMarketplace so payment sig can't be replayed
   * @param _delegationSig signature authorizing attestation on behalf of attester
   */
  function validateContestForSig(
    address _attester,
    address _requester,
    uint256 _reward,
    bytes32 _requestNonce,
    bytes _delegationSig
  ) private {
    bytes32 _delegationDigest = generateContestForDelegationSchemaHash(_requester, _reward, _requestNonce);
    require(_attester == recoverSigner(_delegationDigest, _delegationSig), 'Invalid ContestFor Signature');
    burnSignatureDigest(_delegationDigest, _attester);
  }

  /**
   * @notice Submit attestation completed prior to deployment of this contract
   * @dev Gives initializer privileges to write attestations during the initialization period without signatures
   * @param _requester user requesting this attestation be completed 
   * @param _attester user completing the attestation
   * @param _subject user this attestation is about
   * @param _dataHash hash of data being attested
   */
  function migrateAttestation(
    address _requester,
    address _attester,
    address _subject,
    bytes32 _dataHash
  ) public onlyDuringInitialization {
    emit TraitAttested(
      _subject,
      _attester,
      _requester,
      _dataHash
    );
  }

  /**
   * @notice Revoke an attestation
   * @dev Link is included in dataHash and cannot be directly connected to a BloomID
   * @param _link bytes string embedded in dataHash to link revocation
   */
  function revokeAttestation(
    bytes32 _link
    ) external {
      revokeAttestationForUser(_link, msg.sender);
  }

  /**
   * @notice Revoke an attestation
   * @dev Link is included in dataHash and cannot be directly connected to a BloomID
   * @param _link bytes string embedded in dataHash to link revocation
   */
  function revokeAttestationFor(
    address _sender,
    bytes32 _link,
    bytes32 _nonce,
    bytes _delegationSig
    ) external {
      validateRevokeForSig(_sender, _link, _nonce, _delegationSig);
      revokeAttestationForUser(_link, _sender);
  }

  /**
   * @notice Verify revocation signature is valid 
   * @param _link bytes string embedded in dataHash to link revocation
   * @param _sender user revoking attestation
   * @param _delegationSig signature authorizing revocation on behalf of revoker
   */
  function validateRevokeForSig(
    address _sender,
    bytes32 _link,
    bytes32 _nonce,
    bytes _delegationSig
  ) private {
    bytes32 _delegationDigest = generateRevokeAttestationForDelegationSchemaHash(_link, _nonce);
    require(_sender == recoverSigner(_delegationDigest, _delegationSig), 'Invalid RevokeFor Signature');
    burnSignatureDigest(_delegationDigest, _sender);
  }

  /**
   * @notice Revoke an attestation
   * @dev Link is included in dataHash and cannot be directly connected to a BloomID
   * @param _link bytes string embedded in dataHash to link revocation
   * @param _sender address identify revoker
   */
  function revokeAttestationForUser(
    bytes32 _link,
    address _sender
    ) private {
      emit AttestationRevoked(_link, _sender);
  }

    /**
   * @notice Set the implementation of the TokenEscrowMarketplace contract by setting a new address
   * @dev Restricted to initializer
   * @param _newTokenEscrowMarketplace Address of new SigningLogic implementation
   */
  function setTokenEscrowMarketplace(TokenEscrowMarketplace _newTokenEscrowMarketplace) external onlyDuringInitialization {
    address oldTokenEscrowMarketplace = tokenEscrowMarketplace;
    tokenEscrowMarketplace = _newTokenEscrowMarketplace;
    emit TokenEscrowMarketplaceChanged(oldTokenEscrowMarketplace, tokenEscrowMarketplace);
  }

}

    Contract ABI  
[{"constant":false,"inputs":[{"name":"_attester","type":"address"},{"name":"_requester","type":"address"},{"name":"_reward","type":"uint256"},{"name":"_requestNonce","type":"bytes32"},{"name":"_requesterSig","type":"bytes"},{"name":"_delegationSig","type":"bytes"}],"name":"contestFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initializing","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_subject","type":"address"},{"name":"_requester","type":"address"},{"name":"_reward","type":"uint256"},{"name":"_requesterSig","type":"bytes"},{"name":"_dataHash","type":"bytes32"},{"name":"_requestNonce","type":"bytes32"},{"name":"_subjectSig","type":"bytes"}],"name":"attest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newTokenEscrowMarketplace","type":"address"}],"name":"setTokenEscrowMarketplace","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_requester","type":"address"},{"name":"_reward","type":"uint256"},{"name":"_requestNonce","type":"bytes32"},{"name":"_requesterSig","type":"bytes"}],"name":"contest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_link","type":"bytes32"}],"name":"revokeAttestation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokenEscrowMarketplace","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_requester","type":"address"},{"name":"_attester","type":"address"},{"name":"_subject","type":"address"},{"name":"_dataHash","type":"bytes32"}],"name":"migrateAttestation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initializer","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_subject","type":"address"},{"name":"_attester","type":"address"},{"name":"_requester","type":"address"},{"name":"_reward","type":"uint256"},{"name":"_requesterSig","type":"bytes"},{"name":"_dataHash","type":"bytes32"},{"name":"_requestNonce","type":"bytes32"},{"name":"_subjectSig","type":"bytes"},{"name":"_delegationSig","type":"bytes"}],"name":"attestFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"endInitialization","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_link","type":"bytes32"},{"name":"_nonce","type":"bytes32"},{"name":"_delegationSig","type":"bytes"}],"name":"revokeAttestationFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"usedSignatures","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_initializer","type":"address"},{"name":"_tokenEscrowMarketplace","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"subject","type":"address"},{"indexed":false,"name":"attester","type":"address"},{"indexed":false,"name":"requester","type":"address"},{"indexed":false,"name":"dataHash","type":"bytes32"}],"name":"TraitAttested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"attester","type":"address"},{"indexed":true,"name":"requester","type":"address"}],"name":"AttestationRejected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"link","type":"bytes32"},{"indexed":false,"name":"attester","type":"address"}],"name":"AttestationRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"oldTokenEscrowMarketplace","type":"address"},{"indexed":false,"name":"newTokenEscrowMarketplace","type":"address"}],"name":"TokenEscrowMarketplaceChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"InitializationEnded","type":"event"}]

  Contract Creation Code Switch To Opcodes View
60806040523480156200001157600080fd5b50604051604080620028d283398101806040528101908080519060200190929190805190602001909291905050506040805190810160405280601781526020017f426c6f6f6d204174746573746174696f6e204c6f6769630000000000000000008152506040805190810160405280600181526020017f3200000000000000000000000000000000000000000000000000000000000000815250600184806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600060146101000a81548160ff021916908315150217905550506200015b6080604051908101604052808581526020018481526020018381526020013073ffffffffffffffffffffffffffffffffffffffff16815250620001b1640100000000026401000000009004565b6002816000191690555050505080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050620003fb565b600060405180807f454950373132446f6d61696e28737472696e67206e616d652c737472696e672081526020017f76657273696f6e2c75696e7432353620636861696e49642c616464726573732081526020017f766572696679696e67436f6e74726163742900000000000000000000000000008152506052019050604051809103902082600001516040518082805190602001908083835b6020831015156200027157805182526020820191506020810190506020830392506200024a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902083602001516040518082805190602001908083835b602083101515620002da5780518252602082019150602081019050602083039250620002b3565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902084604001518560600151604051602001808660001916600019168152602001856000191660001916815260200184600019166000191681526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001955050505050506040516020818303038152906040526040518082805190602001908083835b602083101515620003c75780518252602082019150602081019050602083039250620003a0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050919050565b6124c7806200040b6000396000f3006080604052600436106100c5576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630ca7a56a146100ca5780632599f159146101755780632a5502ad146101a45780633c7367781461025d5780634ae122bb146102a05780634d5e1da6146103135780634e46f6e3146103445780639a43a3141461039b5780639ce110d71461042c5780639f74474514610483578063b397657d14610574578063d0bad1d61461058b578063f978fd6114610602575b600080fd5b3480156100d657600080fd5b50610173600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803560001916906020019092919080359060200190820180359060200191909192939192939080359060200190820180359060200191909192939192939050505061064b565b005b34801561018157600080fd5b5061018a6106d3565b604051808215151515815260200191505060405180910390f35b3480156101b057600080fd5b5061025b600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001919091929391929390803560001916906020019092919080356000191690602001909291908035906020019082018035906020019190919293919293905050506106e6565b005b34801561026957600080fd5b5061029e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610765565b005b3480156102ac57600080fd5b50610311600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035600019169060200190929190803590602001908201803590602001919091929391929390505050610a1e565b005b34801561031f57600080fd5b506103426004803603810190808035600019169060200190929190505050610a64565b005b34801561035057600080fd5b50610359610a71565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103a757600080fd5b5061042a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035600019169060200190929190505050610a97565b005b34801561043857600080fd5b50610441610d0c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561048f57600080fd5b50610572600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190820180359060200191909192939192939080356000191690602001909291908035600019169060200190929190803590602001908201803590602001919091929391929390803590602001908201803590602001919091929391929390505050610d31565b005b34801561058057600080fd5b50610589610df4565b005b34801561059757600080fd5b50610600600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080356000191690602001909291908035600019169060200190929190803590602001908201803590602001919091929391929390505050610fd0565b005b34801561060e57600080fd5b50610631600480360381019080803560001916906020019092919050505061101f565b604051808215151515815260200191505060405180910390f35b61068a8888888886868080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505061103f565b6106c98888888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505061110c565b5050505050505050565b600060149054906101000a900460ff1681565b61075a89338a8a8a8a8080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050898989898080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050611305565b505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610851576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001807f4d6574686f642063616e206f6e6c792062652063616c6c656420627920696e6981526020017f7469616c697a657200000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600060149054906101000a900460ff1615156108fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c656420647572696e6781526020017f20696e697469616c697a6174696f6e000000000000000000000000000000000081525060400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fff80ee77c85d9a66d44e11d38886b3f07748e818eaeb0660b75706962d0f56d581600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b610a5d3386868686868080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505061110c565b5050505050565b610a6e813361158e565b50565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610b81576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001807f4d6574686f642063616e206f6e6c792062652063616c6c656420627920696e6981526020017f7469616c697a657200000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600060149054906101000a900460ff161515610c2b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c656420647572696e6781526020017f20696e697469616c697a6174696f6e000000000000000000000000000000000081525060400191505060405180910390fd5b7f53931139c48182587fa8ce0ac76dd9cd86655899a636bffdce8138a0cdb2c1b582848684604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001826000191660001916815260200194505050505060405180910390a150505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610d728c8c8c8c8a8a88888080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050611605565b610de68c8c8c8c8c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050508b8b8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050611305565b505050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610ede576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001807f4d6574686f642063616e206f6e6c792062652063616c6c656420627920696e6981526020017f7469616c697a657200000000000000000000000000000000000000000000000081525060400191505060405180910390fd5b600060149054906101000a900460ff161515610f88576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001807f4d6574686f642063616e206f6e6c792062652063616c6c656420647572696e6781526020017f20696e697469616c697a6174696f6e000000000000000000000000000000000081525060400191505060405180910390fd5b60008060146101000a81548160ff0219169083151502179055507f0cabb9c05f9eeeadb6765f175642f19876b512ba15100b1391420b714b0c3d0060405160405180910390a1565b61100e85858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050506116d6565b611018848661158e565b5050505050565b60016020528060005260406000206000915054906101000a900460ff1681565b600061104c8585856117a1565b905061105881836118ad565b73ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415156110fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f496e76616c696420436f6e74657374466f72205369676e61747572650000000081525060200191505060405180910390fd5b6111048187611a13565b505050505050565b60008311156112a457600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ed5eb5085878686866040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001836000191660001916815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561123b578082015181840152602081019050611220565b50505050905090810190601f1680156112685780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b15801561128b57600080fd5b505af115801561129f573d6000803e3d6000fd5b505050505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f9a53975728a25417448708f6de6b9c942bbe4461c6647852e0b60c91c3c2fad360405160405180910390a35050505050565b61131188848484611bab565b7f53931139c48182587fa8ce0ac76dd9cd86655899a636bffdce8138a0cdb2c1b588888886604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001826000191660001916815260200194505050505060405180910390a1600085111561158457600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635ed5eb5087898886896040518663ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001836000191660001916815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561151b578082015181840152602081019050611500565b50505050905090810190601f1680156115485780820380516001836020036101000a031916815260200191505b509650505050505050600060405180830381600087803b15801561156b57600080fd5b505af115801561157f573d6000803e3d6000fd5b505050505b5050505050505050565b7f59d1b98a5da8bbc1db92f7d8d2e21c3067da65edbe08f4ae23df11487ee4c8b082826040518083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15050565b60006116148887878787611c0d565b905061162081836118ad565b73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161415156116c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496e76616c696420417474657374466f72205369676e6174757265000000000081525060200191505060405180910390fd5b6116cc8188611a13565b5050505050505050565b60006116e28484611d41565b90506116ee81836118ad565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141515611790576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f496e76616c6964205265766f6b65466f72205369676e6174757265000000000081525060200191505060405180910390fd5b61179a8186611a13565b5050505050565b60006002546117e46060604051908101604052808773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018560001916815250611e33565b60405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183600019166000191681526020018260001916600019168152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831015156118775780518252602082019150602081019050602083039250611852565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090509392505050565b600080737a75cb349d9a9d4c2d3eb8a22cb3090222d8557b6319045a2585856040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180836000191660001916815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561194557808201518184015260208101905061192a565b50505050905090810190601f1680156119725780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561199057600080fd5b505af41580156119a4573d6000803e3d6000fd5b505050506040513d60208110156119ba57600080fd5b81019080805190602001909291905050509050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611a0957600080fd5b8091505092915050565b600082826040516020018083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001925050506040516020818303038152906040526040518082805190602001908083835b602083101515611aa65780518252602082019150602081019050602083039250611a81565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905060016000826000191660001916815260200190815260200160002060009054906101000a900460ff16151515611b73576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206e6f7420756e6971756500000000000000000000000081525060200191505060405180910390fd5b6001806000836000191660001916815260200190815260200160002060006101000a81548160ff021916908315150217905550505050565b6000611bb78484611f9f565b9050611bc381836118ad565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141515611bfc57600080fd5b611c068186611a13565b5050505050565b6000600254611c7660a0604051908101604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff168152602001878152602001866000191681526020018560001916815250612091565b60405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183600019166000191681526020018260001916600019168152602001925050506040516020818303038152906040526040518082805190602001908083835b602083101515611d095780518252602082019150602081019050602083039250611ce4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905095945050505050565b6000600254611d6b604080519081016040528086600019168152602001856000191681525061226f565b60405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183600019166000191681526020018260001916600019168152602001925050506040516020818303038152906040526040518082805190602001908083835b602083101515611dfe5780518252602082019150602081019050602083039250611dd9565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905092915050565b600060405180807f436f6e74657374466f722861646472657373207265717565737465722c75696e81526020017f74323536207265776172642c6279746573333220726571756573744e6f6e636581526020017f2900000000000000000000000000000000000000000000000000000000000000815250604101905060405180910390208260000151836020015184604001516040516020018085600019166000191681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182600019166000191681526020019450505050506040516020818303038152906040526040518082805190602001908083835b602083101515611f6b5780518252602082019150602081019050602083039250611f46565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050919050565b6000600254611fc96040805190810160405280866000191681526020018560001916815250612385565b60405160200180807f190100000000000000000000000000000000000000000000000000000000000081525060020183600019166000191681526020018260001916600019168152602001925050506040516020818303038152906040526040518082805190602001908083835b60208310151561205c5780518252602082019150602081019050602083039250612037565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905092915050565b600060405180807f417474657374466f722861646472657373207375626a6563742c61646472657381526020017f73207265717565737465722c75696e74323536207265776172642c627974657381526020017f33322064617461486173682c6279746573333220726571756573744e6f6e636581526020017f290000000000000000000000000000000000000000000000000000000000000081525060610190506040518091039020826000015183602001518460400151856060015186608001516040516020018087600019166000191681526020018673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018360001916600019168152602001826000191660001916815260200196505050505050506040516020818303038152906040526040518082805190602001908083835b60208310151561223b5780518252602082019150602081019050602083039250612216565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050919050565b600060405180807f5265766f6b654174746573746174696f6e466f722862797465733332206c696e81526020017f6b2c62797465733332206e6f6e6365290000000000000000000000000000000081525060300190506040518091039020826000015183602001516040516020018084600019166000191681526020018360001916600019168152602001826000191660001916815260200193505050506040516020818303038152906040526040518082805190602001908083835b602083101515612351578051825260208201915060208101905060208303925061232c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209050919050565b600060405180807f4174746573746174696f6e52657175657374286279746573333220646174614881526020017f6173682c62797465733332206e6f6e636529000000000000000000000000000081525060320190506040518091039020826000015183602001516040516020018084600019166000191681526020018360001916600019168152602001826000191660001916815260200193505050506040516020818303038152906040526040518082805190602001908083835b6020831015156124675780518252602082019150602081019050602083039250612442565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902090509190505600a165627a7a72305820bff582e58c664569a718e5ba7037128a0b9eb86816de1b987f598c644b6553fc002900000000000000000000000028c7ba752fd214a54ea25f075ab459ab17bd5fd20000000000000000000000000000000000000000000000000000000000000000

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

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000028c7ba752fd214a54ea25f075ab459ab17bd5fd2
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000


   Library Used
ECRecovery : 0x7a75cb349d9a9d4c2d3eb8a22cb3090222d8557b

   Swarm Source:
bzzr://bff582e58c664569a718e5ba7037128a0b9eb86816de1b987f598c644b6553fc

 

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.