Contract Overview
ETH Balance: 0 Ether
No Of Transactions: 1 txn
  Latest 1 txn

TxHash Age From To Value [TxFee]
0x8f446b15fcfefb09b5f0d5dd69aa3db152e155e1e7640946b64ff77864644daf12 days 9 hrs ago0x0021712dae973fb48a772e6eb8ad7620bfb76b47  IN    Contract Creation0 Ether0.12268506
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
Contract Source Code Verified
Contract Name: ChannelManagerLibrary
Compiler Version: v0.4.16+commit.d7661dd9
Optimization Enabled: No
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts
pragma solidity ^0.4.11;


interface Token {

    /// @return total amount of tokens
    function totalSupply() constant returns (uint256 supply);

    /// @param _owner The address from which the balance will be retrieved
    /// @return The balance
    function balanceOf(address _owner) constant returns (uint256 balance);

    /// @notice send `_value` token to `_to` from `msg.sender`
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return Whether the transfer was successful or not
    function transfer(address _to, uint256 _value) returns (bool success);

    /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
    /// @param _from The address of the sender
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return Whether the transfer was successful or not
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);

    /// @notice `msg.sender` approves `_spender` to spend `_value` tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @param _value The amount of wei to be approved for transfer
    /// @return Whether the approval was successful or not
    function approve(address _spender, uint256 _value) returns (bool success);

    /// @param _owner The address of the account owning tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @return Amount of remaining tokens allowed to spent
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}



library NettingChannelLibrary {
    string constant public contract_version = "0.1._";

    struct Participant
    {
        address node_address;

        // Total amount of token transferred to this smart contract through the
        // `deposit` function, note that direct token transfer cannot be
        // tracked and will be burned.
        uint256 balance;

        // The latest known merkle root of the pending hash-time locks, used to
        // validate the withdrawn proofs.
        bytes32 locksroot;

        // The latest known transferred_amount from this node to the other
        // participant, used to compute the net balance on settlement.
        uint256 transferred_amount;

        // Value used to order transfers and only accept the latest on calls to
        // update, this will only be relevant after either #182 or #293 is
        // implemented.
        uint64 nonce;

        // A mapping to keep track of locks that have been withdrawn.
        mapping(bytes32 => bool) withdrawn_locks;
    }

    struct Data {
        uint settle_timeout;
        uint opened;
        uint closed;
        uint settled;
        address closing_address;
        Token token;
        Participant[2] participants;
        mapping(address => uint8) participant_index;
        bool updated;
    }


    modifier notSettledButClosed(Data storage self) {
        require(self.settled <= 0 && self.closed > 0);
        _;
    }

    modifier stillTimeout(Data storage self) {
        require(self.closed + self.settle_timeout >= block.number);
        _;
    }

    modifier timeoutOver(Data storage self) {
        require(self.closed + self.settle_timeout <= block.number);
        _;
    }

    modifier channelSettled(Data storage self) {
        require(self.settled != 0);
        _;
    }

    /// @notice Deposit amount to channel.
    /// @dev Deposit an amount to the channel. At least one of the participants
    /// must deposit before the channel is opened.
    /// @param amount The amount to be deposited to the address
    /// @return Success if the transfer was successful
    /// @return The new balance of the invoker
    function deposit(Data storage self, uint256 amount)
        returns (bool success, uint256 balance)
    {
        uint8 index;

        require(self.opened > 0);
        require(self.closed == 0);
        require(self.token.balanceOf(msg.sender) >= amount);

        index = index_or_throw(self, msg.sender);
        Participant storage participant = self.participants[index];

        success = self.token.transferFrom(msg.sender, this, amount);
        if (success == true) {
            balance = participant.balance;
            balance += amount;
            participant.balance = balance;

            return (true, balance);
        }

        return (false, 0);
    }

    /// @notice Close a channel between two parties that was used bidirectionally
    function close(
        Data storage self,
        uint64 nonce,
        uint256 transferred_amount,
        bytes32 locksroot,
        bytes32 extra_hash,
        bytes signature
    ) {
        address transfer_address;
        uint closer_index;
        uint counterparty_index;

        // close can be called only once
        require(self.closed == 0);
        self.closed = block.number;

        // Only a participant can call close
        closer_index = index_or_throw(self, msg.sender);
        self.closing_address = msg.sender;

        // Only the closing party can provide a transfer from the counterparty,
        // and only when this function is called, i.e. this value can not be
        // updated afterwards.

        // An empty value means that the closer never received a transfer, or
        // he is intentionally not providing the latest transfer, in which case
        // the closing party is going to lose the tokens that were transferred
        // to him.
        if (signature.length == 65) {
            transfer_address = recoverAddressFromSignature(
                nonce,
                transferred_amount,
                locksroot,
                extra_hash,
                signature 
            );

            counterparty_index = index_or_throw(self, transfer_address);
            require(closer_index != counterparty_index);

            // update the structure of the counterparty with its data provided
            // by the closing node
            Participant storage counterparty = self.participants[counterparty_index];
            counterparty.nonce = uint64(nonce);
            counterparty.locksroot = locksroot;
            counterparty.transferred_amount = transferred_amount;
        }
    }

    /// @notice Updates counter party transfer after closing.
    function updateTransfer(
        Data storage self,
        uint64 nonce,
        uint256 transferred_amount,
        bytes32 locksroot,
        bytes32 extra_hash,
        bytes signature
    )
        notSettledButClosed(self)
        stillTimeout(self)
    {
        address transfer_address;
        uint8 caller_index;
        uint8 closer_index;

        // updateTransfer can be called by the counter party only once
        require(!self.updated);
        self.updated = true;

        // Only a participant can call updateTransfer (#293 for third parties)
        caller_index = index_or_throw(self, msg.sender);

        // The closer is not allowed to call updateTransfer
        require(self.closing_address != msg.sender);

        // Counter party can only update the closer transfer
        transfer_address = recoverAddressFromSignature(
            nonce,
            transferred_amount,
            locksroot,
            extra_hash,
            signature 
        );
        require(transfer_address == self.closing_address);

        // Update the structure of the closer with its data provided by the
        // counterparty
        closer_index = 1 - caller_index;

        self.participants[closer_index].nonce = nonce;
        self.participants[closer_index].locksroot = locksroot;
        self.participants[closer_index].transferred_amount = transferred_amount;
    }

    function recoverAddressFromSignature(
        uint64 nonce,
        uint256 transferred_amount,
        bytes32 locksroot,
        bytes32 extra_hash,
        bytes signature
    )
        constant internal returns (address)
    {
        bytes32 signed_hash;

        require(signature.length == 65);

        signed_hash = sha3(
            nonce,
            transferred_amount,
            locksroot,
            this,
            extra_hash
        );

        var (r, s, v) = signatureSplit(signature);
        return ecrecover(signed_hash, v, r, s);
    }

    /// @notice Unlock a locked transfer
    /// @dev Unlock a locked transfer
    /// @param locked_encoded The lock
    /// @param merkle_proof The merkle proof
    /// @param secret The secret
    function withdraw(Data storage self, bytes locked_encoded, bytes merkle_proof, bytes32 secret)
        notSettledButClosed(self)
    {
        uint amount;
        uint8 index;
        uint64 expiration;
        bytes32 h;
        bytes32 hashlock;

        // Check if msg.sender is a participant and select the partner (for
        // third party unlock see #541)
        index = 1 - index_or_throw(self, msg.sender);
        Participant storage counterparty = self.participants[index];

        // An empty locksroot means there are no pending locks
        require(counterparty.locksroot != 0);

        (expiration, amount, hashlock) = decodeLock(locked_encoded);

        // A lock can be withdrawn only once per participant
        require(!counterparty.withdrawn_locks[hashlock]);

        counterparty.withdrawn_locks[hashlock] = true;

        // The lock must not have expired, it does not matter how far in the
        // future it would have expired
        require(expiration >= block.number);
        require(hashlock == sha3(secret));

        h = computeMerkleRoot(locked_encoded, merkle_proof);

        require(counterparty.locksroot == h);

        // This implementation allows for each transfer to be set only once, so
        // it's safe to update the transferred_amount in place.
        //
        // Once third parties are allowed to update the counter party transfer
        // (#293, #182) the locksroot may change, if the locksroot change the
        // transferred_amount must be reset and locks must be re-withdrawn, so
        // this is also safe.
        //
        // This may be problematic if an update changes the transferred_amount
        // but not the locksroot, since the locks don't need to be
        // re-withdrawn, the difference in the transferred_amount must be
        // accounted for.
        counterparty.transferred_amount += amount;
    }

    function computeMerkleRoot(bytes lock, bytes merkle_proof)
        internal
        constant
        returns (bytes32)
    {
        require(merkle_proof.length % 32 == 0);

        uint i;
        bytes32 h;
        bytes32 el;

        h = sha3(lock);
        for (i = 32; i <= merkle_proof.length; i += 32) {
            assembly {
                el := mload(add(merkle_proof, i))
            }

            if (h < el) {
                h = sha3(h, el);
            } else {
                h = sha3(el, h);
            }
        }

        return h;
    }

    /// @notice Settles the balance between the two parties
    /// @dev Settles the balances of the two parties fo the channel
    /// @return The participants with netted balances
    function settle(Data storage self)
        notSettledButClosed(self)
        timeoutOver(self)
    {
        uint8 closing_index;
        uint8 counter_index;
        uint256 total_deposit;
        uint256 counter_net;
        uint256 closer_amount;
        uint256 counter_amount;

        self.settled = block.number;

        closing_index = index_or_throw(self, self.closing_address);
        counter_index = 1 - closing_index;

        Participant storage closing_party = self.participants[closing_index];
        Participant storage counter_party = self.participants[counter_index];

        counter_net = (
            counter_party.balance
            + closing_party.transferred_amount
            - counter_party.transferred_amount
        );

        // Direct token transfers done through the token `transfer` function
        // cannot be accounted for, these superfluous tokens will be burned,
        // this is because there is no way to tell which participant (if any)
        // had ownership over the token.
        total_deposit = closing_party.balance + counter_party.balance;

        // When the closing party does not provide the counter party transfer,
        // the `counter_net` may be larger than the `total_deposit`, without
        // the min the token transfer fail and the token is locked.
        counter_amount = min(counter_net, total_deposit);

        // When the counter party does not provide the closing party transfer,
        // then `counter_amount` may be negative and the transfer fails, force
        // the value to 0.
        counter_amount = max(counter_amount, 0);

        // At this point `counter_amount` is between [0,total_deposit], so this
        // is safe.
        closer_amount = total_deposit - counter_amount;

        if (counter_amount > 0) {
            require(self.token.transfer(counter_party.node_address, counter_amount));
        }

        if (closer_amount > 0) {
            require(self.token.transfer(closing_party.node_address, closer_amount));
        }

        kill(self);
    }

    // NOTES:
    //
    // - The EVM is a big-endian, byte addressing machine, with 32bytes/256bits
    //   words.
    // - The Ethereum Contract ABI specifies that variable length types have a
    //   32bytes prefix to define the variable size.
    // - Solidity has additional data types that are narrower than 32bytes
    //   (e.g. uint128 uses a half word).
    // - Solidity uses the *least-significant* bits of the word to store the
    //   values of a narrower type.
    //
    // GENERAL APPROACH:
    //
    // Add to the message pointer the number of bytes required to move the
    // address so that the target data is at the end of the 32bytes word.
    //
    // EXAMPLE:
    //
    // To decode the cmdid, consider this initial state:
    //
    //
    //     v- pointer word start
    //     [ 32 bytes length prefix ][ cmdid ] ----
    //                              ^- pointer word end
    //
    //
    // Because the cmdid has 1 byte length the type uint8 is used, the decoder
    // needs to move the pointer so the cmdid is at the end of the pointer
    // word.
    //
    //
    //             v- pointer word start [moved 1byte ahead]
    //     [ 32 bytes length prefix ][ cmdid ] ----
    //                                       ^- pointer word end
    //
    //
    // Now the data of the cmdid can be loaded to the uint8 variable.
    //
    // REFERENCES:
    // - https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
    // - http://solidity.readthedocs.io/en/develop/assembly.html

    function decodeLock(bytes lock) internal returns (uint64 expiration, uint amount, bytes32 hashlock) {
        require(lock.length == 72);

        // Lock format:
        // [0:8] expiration
        // [8:40] amount
        // [40:72] hashlock
        assembly {
            expiration := mload(add(lock, 8))
            amount := mload(add(lock, 40))
            hashlock := mload(add(lock, 72))
        }
    }

    function signatureSplit(bytes signature) internal returns (bytes32 r, bytes32 s, uint8 v) {
        // The signature format is a compact form of:
        //   {bytes32 r}{bytes32 s}{uint8 v}
        // Compact means, uint8 is not padded to 32 bytes.
        assembly {
            r := mload(add(signature, 32))
            s := mload(add(signature, 64))
            // Here we are loading the last 32 bytes, including 31 bytes
            // of 's'. There is no 'mload8' to do this.
            //
            // 'byte' is not working due to the Solidity parser, so lets
            // use the second best option, 'and'
            v := and(mload(add(signature, 65)), 0xff)
        }

        require(v == 27 || v == 28);
    }

    function index_or_throw(Data storage self, address participant_address) private returns (uint8) {
        uint8 n;
        // Return index of participant, or throw
        n = self.participant_index[participant_address];
        assert(n != 0);
        return n - 1;
    }

    function min(uint a, uint b) constant internal returns (uint) {
        return a > b ? b : a;
    }

    function max(uint a, uint b) constant internal returns (uint) {
        return a > b ? a : b;
    }

    function kill(Data storage self) channelSettled(self) {
        selfdestruct(0x00000000000000000000);
    }
}

contract NettingChannelContract {
    string constant public contract_version = "0.1._";

    using NettingChannelLibrary for NettingChannelLibrary.Data;
    NettingChannelLibrary.Data public data;

    event ChannelNewBalance(address token_address, address participant, uint balance, uint block_number);
    event ChannelClosed(address closing_address, uint block_number);
    event TransferUpdated(address node_address, uint block_number);
    event ChannelSettled(uint block_number);
    event ChannelSecretRevealed(bytes32 secret, address receiver_address);

    modifier settleTimeoutNotTooLow(uint t) {
        assert(t >= 6);
        _;
    }

    function NettingChannelContract(
        address token_address,
        address participant1,
        address participant2,
        uint timeout)
        settleTimeoutNotTooLow(timeout)
    {
        require(participant1 != participant2);

        data.participants[0].node_address = participant1;
        data.participants[1].node_address = participant2;
        data.participant_index[participant1] = 1;
        data.participant_index[participant2] = 2;

        data.token = Token(token_address);
        data.settle_timeout = timeout;
        data.opened = block.number;
    }

    /// @notice Caller makes a deposit into their channel balance.
    /// @param amount The amount caller wants to deposit.
    /// @return True if deposit is successful.
    function deposit(uint256 amount) returns (bool) {
        bool success;
        uint256 balance;

        (success, balance) = data.deposit(amount);

        if (success == true) {
            ChannelNewBalance(data.token, msg.sender, balance, block.number);
        }

        return success;
    }

    /// @notice Get the address and balance of both partners in a channel.
    /// @return The address and balance pairs.
    function addressAndBalance()
        constant
        returns (
        address participant1,
        uint balance1,
        address participant2,
        uint balance2)
    {
        NettingChannelLibrary.Participant storage node1 = data.participants[0];
        NettingChannelLibrary.Participant storage node2 = data.participants[1];

        participant1 = node1.node_address;
        balance1 = node1.balance;
        participant2 = node2.node_address;
        balance2 = node2.balance;
    }

    /// @notice Close the channel. Can only be called by a participant in the channel.
    function close(
        uint64 nonce,
        uint256 transferred_amount,
        bytes32 locksroot,
        bytes32 extra_hash,
        bytes signature
    ) {
        data.close(
            nonce,
            transferred_amount,
            locksroot,
            extra_hash,
            signature
        );
        ChannelClosed(msg.sender, data.closed);
    }

    /// @notice Dispute the state after closing, called by the counterparty (the
    ///         participant who did not close the channel).
    function updateTransfer(
        uint64 nonce,
        uint256 transferred_amount,
        bytes32 locksroot,
        bytes32 extra_hash,
        bytes signature
    ) {
        data.updateTransfer(
            nonce,
            transferred_amount,
            locksroot,
            extra_hash,
            signature
        );
        TransferUpdated(msg.sender, block.number);
    }

    /// @notice Unlock a locked transfer.
    /// @param locked_encoded The locked transfer to be unlocked.
    /// @param merkle_proof The merke_proof for the locked transfer.
    /// @param secret The secret to unlock the locked transfer.
    function withdraw(bytes locked_encoded, bytes merkle_proof, bytes32 secret) {
        // throws if sender is not a participant
        data.withdraw(locked_encoded, merkle_proof, secret);
        ChannelSecretRevealed(secret, msg.sender);
    }

    /// @notice Settle the transfers and balances of the channel and pay out to
    ///         each participant. Can only be called after the channel is closed
    ///         and only after the number of blocks in the settlement timeout
    ///         have passed.
    function settle() {
        data.settle();
        ChannelSettled(data.settled);
    }

    /// @notice Returns the number of blocks until the settlement timeout.
    /// @return The number of blocks until the settlement timeout.
    function settleTimeout() constant returns (uint) {
        return data.settle_timeout;
    }

    /// @notice Returns the address of the token.
    /// @return The address of the token.
    function tokenAddress() constant returns (address) {
        return data.token;
    }

    /// @notice Returns the block number for when the channel was opened.
    /// @return The block number for when the channel was opened.
    function opened() constant returns (uint) {
        return data.opened;
    }

    /// @notice Returns the block number for when the channel was closed.
    /// @return The block number for when the channel was closed.
    function closed() constant returns (uint) {
        return data.closed;
    }

    /// @notice Returns the block number for when the channel was settled.
    /// @return The block number for when the channel was settled.
    function settled() constant returns (uint) {
        return data.settled;
    }

    /// @notice Returns the address of the closing participant.
    /// @return The address of the closing participant.
    function closingAddress() constant returns (address) {
        return data.closing_address;
    }

    function () { revert(); }
}

library ChannelManagerLibrary {
    string constant public contract_version = "0.1._";

    struct Data {
        Token token;

        address[] all_channels;
        mapping(bytes32 => uint) partyhash_to_channelpos;

        mapping(address => address[]) nodeaddress_to_channeladdresses;
        mapping(address => mapping(address => uint)) node_index;
    }

    /// @notice Get the address of channel with a partner
    /// @param partner The address of the partner
    /// @return The address of the channel
    function getChannelWith(Data storage self, address partner) constant returns (address) {
        bytes32 party_hash = partyHash(msg.sender, partner);
        uint channel_pos = self.partyhash_to_channelpos[party_hash];

        if (channel_pos != 0) {
            return self.all_channels[channel_pos - 1];
        }
    }

    /// @notice Create a new payment channel between two parties
    /// @param partner The address of the partner
    /// @param settle_timeout The settle timeout in blocks
    /// @return The address of the newly created NettingChannelContract.
    function newChannel(Data storage self, address partner, uint settle_timeout)
        returns (address)
    {
        address[] storage caller_channels = self.nodeaddress_to_channeladdresses[msg.sender];
        address[] storage partner_channels = self.nodeaddress_to_channeladdresses[partner];

        bytes32 party_hash = partyHash(msg.sender, partner);
        uint channel_pos = self.partyhash_to_channelpos[party_hash];

        address new_channel_address = new NettingChannelContract(
            self.token,
            msg.sender,
            partner,
            settle_timeout
        );

        if (channel_pos != 0) {
            // Check if the channel was settled. Once a channel is settled it
            // kills itself, so address must not have code.
            address settled_channel = self.all_channels[channel_pos - 1];
            require(!contractExists(settled_channel));

            uint caller_pos = self.node_index[msg.sender][partner];
            uint partner_pos = self.node_index[partner][msg.sender];

            // replace the channel address in-place
            self.all_channels[channel_pos - 1] = new_channel_address;
            caller_channels[caller_pos - 1] = new_channel_address;
            partner_channels[partner_pos - 1] = new_channel_address;

        } else {
            self.all_channels.push(new_channel_address);
            caller_channels.push(new_channel_address);
            partner_channels.push(new_channel_address);

            // using the 1-index, 0 is used for the absence of a value
            self.partyhash_to_channelpos[party_hash] = self.all_channels.length;
            self.node_index[msg.sender][partner] = caller_channels.length;
            self.node_index[partner][msg.sender] = partner_channels.length;
        }

        return new_channel_address;
    }

    /// @notice Get the hash of the two addresses
    /// @param address_one address of one party
    /// @param address_two of the other party
    /// @return The sha3 hash of both parties sorted by size of address
    function partyHash(address address_one, address address_two) internal constant returns (bytes32) {
        if (address_one < address_two) {
            return sha3(address_one, address_two);
        } else {
            // The two participants can't be the same here due to this check in
            // the netting channel constructor:
            // https://github.com/raiden-network/raiden/blob/e17d96db375d31b134ae7b4e2ad2c1f905b47857/raiden/smart_contracts/NettingChannelContract.sol#L27
            return sha3(address_two, address_one);
        }
    }

    /// TODO: Find a way to remove this function duplication from Utils.sol here
    ///       At the moment libraries can't inherit so we need to add this here
    ///       explicitly.
    /// @notice Check if a contract exists
    /// @param channel The address to check whether a contract is deployed or not
    /// @return True if a contract exists, false otherwise
    function contractExists(address channel) private constant returns (bool) {
        uint size;

        assembly {
            size := extcodesize(channel)
        }

        return size > 0;
    }
}

  Contract ABI  
[{"constant":true,"inputs":[{"name":"self","type":"ChannelManagerLibrary.Data storage"},{"name":"partner","type":"address"}],"name":"getChannelWith","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"self","type":"ChannelManagerLibrary.Data storage"},{"name":"partner","type":"address"},{"name":"settle_timeout","type":"uint256"}],"name":"newChannel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"contract_version","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]

  Contract Creation Code Switch To Opcodes View
6060604052341561000f57600080fd5b5b611d7e8061001f6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680638a1c00e214610054578063941583a5146100cb578063b32c65c81461014b575b600080fd5b610089600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101cf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610109600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061025b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101536108fd565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101945780820151818401525b602081019050610178565b50505050905090810190601f1680156101c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008060006101de3385610936565b9150846002016000836000191660001916815260200190815260200160002054905060008114151561025257846001016001820381548110151561021e57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250610253565b5b505092915050565b60008060008060008060008060008b60030160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002097508b60030160008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002096506102f9338c610936565b95508b600201600087600019166000191681526020019081526020016000205494508b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16338c8c61034b610abd565b808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050604051809103906000f080151561040457600080fd5b9350600085141515610686578b6001016001860381548110151561042457fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16925061045c83610aa9565b15151561046857600080fd5b8b60040160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205491508b60040160008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050838c6001016001870381548110151561057f57fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508388600184038154811015156105db57fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083876001830381548110151561063757fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506108ea565b8b600101805480600101828161069c9190610acd565b916000526020600020900160005b86909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508780548060010182816106ff9190610acd565b916000526020600020900160005b86909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508680548060010182816107629190610acd565b916000526020600020900160005b86909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508b600101805490508c600201600088600019166000191681526020019081526020016000208190555087805490508c60040160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555086805490508c60040160008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8398505b50505050505050509392505050565b6040805190810160405280600581526020017f302e312e5f00000000000000000000000000000000000000000000000000000081525081565b60008173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161015610a07578282604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014019250505060405180910390209050610aa3565b8183604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014019250505060405180910390209050610aa3565b5b92915050565b600080823b90506000811191505b50919050565b60405161123480610b1f83390190565b815481835581811511610af457818360005260206000209182019101610af39190610af9565b5b505050565b610b1b91905b80821115610b17576000816000905550600101610aff565b5090565b9056006060604052341561000f57600080fd5b604051608080611234833981016040528080519060200190919080519060200190919080519060200190919080519060200190919050505b806006811015151561005557fe5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415151561009057600080fd5b83600060060160006002811015156100a457fe5b6006020160005b5060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826000600601600160028110151561010157fe5b6006020160005b5060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600060120160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff1602179055506002600060120160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908360ff16021790555084600060050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816000800181905550436000600101819055505b5b50505050505b610fc4806102706000396000f300606060405236156100ce576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806311da60b4146100e1578063202ac3bc146100f657806327d120fe146101a357806353af5d1014610236578063597e1fb51461028b5780635e1fc56e146102b45780635f88eade146103475780636d2381b31461037057806373d4a13a146104065780637ebdc478146104b55780638f775839146104de5780639d76ea5814610507578063b32c65c81461055c578063b6b55f25146105eb575b34156100d957600080fd5b5b600080fd5b005b34156100ec57600080fd5b6100f4610626565b005b341561010157600080fd5b6101a1600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091908035600019169060200190919050506106e6565b005b34156101ae57600080fd5b610234600480803567ffffffffffffffff16906020019091908035906020019091908035600019169060200190919080356000191690602001909190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506108cc565b005b341561024157600080fd5b610249610a72565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561029657600080fd5b61029e610a9f565b6040518082815260200191505060405180910390f35b34156102bf57600080fd5b610345600480803567ffffffffffffffff16906020019091908035906020019091908035600019169060200190919080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610aac565b005b341561035257600080fd5b61035a610c57565b6040518082815260200191505060405180910390f35b341561037b57600080fd5b610383610c64565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b341561041157600080fd5b610419610d0c565b604051808881526020018781526020018681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018215151515815260200197505050505050505060405180910390f35b34156104c057600080fd5b6104c8610d89565b6040518082815260200191505060405180910390f35b34156104e957600080fd5b6104f1610d96565b6040518082815260200191505060405180910390f35b341561051257600080fd5b61051a610da3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561056757600080fd5b61056f610dd0565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156105b05780820151818401525b602081019050610594565b50505050905090810190601f1680156105dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156105f657600080fd5b61060c6004808035906020019091905050610e09565b604051808215151515815260200191505060405180910390f35b600073416f9f8fa0f2e133ad7e1ff52a85e4fbc2b0025363de394e0d90916040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082815260200191505060006040518083038186803b151561069357600080fd5b6102c65a03f415156106a457600080fd5b5050507ffe501c6f860c82db0609c0e0e7571f4a08c991e3b653cb35a7f105c84caccb996000600301546040518082815260200191505060405180910390a15b565b600073416f9f8fa0f2e133ad7e1ff52a85e4fbc2b0025363c252246290918585856040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085815260200180602001806020018460001916600019168152602001838103835286818151815260200191508051906020019080838360005b8381101561078b5780820151818401525b60208101905061076f565b50505050905090810190601f1680156107b85780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b838110156107f25780820151818401525b6020810190506107d6565b50505050905090810190601f16801561081f5780820380516001836020036101000a031916815260200191505b50965050505050505060006040518083038186803b151561083f57600080fd5b6102c65a03f4151561085057600080fd5b5050507fa2e2842eefea7e32abccccd9d3fae92608319362c3905ef73de44938c059253681336040518083600019166000191681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b505050565b600073416f9f8fa0f2e133ad7e1ff52a85e4fbc2b0025363f565eb36909187878787876040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808781526020018667ffffffffffffffff1667ffffffffffffffff1681526020018581526020018460001916600019168152602001836000191660001916815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561099d5780820151818401525b602081019050610981565b50505050905090810190601f1680156109ca5780820380516001836020036101000a031916815260200191505b5097505050505050505060006040518083038186803b15156109eb57600080fd5b6102c65a03f415156109fc57600080fd5b5050507f606ec65dd9031d6711dbcc3a0eb7bcf85eae9eb99595b47997b1a50cfc5cef5a3343604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5050505050565b60008060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b90565b6000806002015490505b90565b600073416f9f8fa0f2e133ad7e1ff52a85e4fbc2b0025363c800b002909187878787876040518763ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808781526020018667ffffffffffffffff1667ffffffffffffffff1681526020018581526020018460001916600019168152602001836000191660001916815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610b7d5780820151818401525b602081019050610b61565b50505050905090810190601f168015610baa5780820380516001836020036101000a031916815260200191505b5097505050505050505060006040518083038186803b1515610bcb57600080fd5b6102c65a03f41515610bdc57600080fd5b5050507f770342ee36990141b5b1f4b3b41a184d7968647ac7f0dbfd2d86d566c468027d33600060020154604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5050505050565b6000806001015490505b90565b60008060008060008060006006016000600281101515610c8057fe5b6006020160005b50915060006006016001600281101515610c9d57fe5b6006020160005b5090508160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169550816001015494508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350806001015492505b505090919293565b60008060000154908060010154908060020154908060030154908060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060130160009054906101000a900460ff16905087565b6000806000015490505b90565b6000806003015490505b90565b60008060050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b90565b6040805190810160405280600581526020017f302e312e5f00000000000000000000000000000000000000000000000000000081525081565b60008060008073416f9f8fa0f2e133ad7e1ff52a85e4fbc2b00253633268a05a9091866000604051604001526040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083815260200182815260200192505050604080518083038186803b1515610e8a57600080fd5b6102c65a03f41515610e9b57600080fd5b505050604051805190602001805190508092508193505050600115158215151415610f8d577ffdbb5aee5d86223b95ec2a3ef27bf36cdb0a4ae42a4823bdd7c091f143dbf83d600060050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16338343604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182815260200194505050505060405180910390a15b8192505b50509190505600a165627a7a72305820700c9abf184f63d4c38d9ec174d93b4de116e32faf9096ed4ec0977f8b54fea90029a165627a7a72305820cfa0f4f527ed3a7ac6f2553d1f41a2ea9943facfba16702d253c9d1581729a410029

   Library Used
NettingChannelLibrary : 0x416f9f8fa0f2e133ad7e1ff52a85e4fbc2b00253

   Swarm Source:
bzzr://cfa0f4f527ed3a7ac6f2553d1f41a2ea9943facfba16702d253c9d1581729a41
View All
Block Age txn Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward