Contract Overview
ETH Balance: 0 Ether
No Of Transactions: 87 txns
  Latest 25 txns from a total Of 87 transactions View All

TxHash Age From To Value [TxFee]
0x787c24904316ecde73d6146c6cf6ed7b47b60ee0fa3273af38cd4730e80fa7a513 hrs 16 mins ago0x000e6dfc6f9f7f701860a5d6e511f6a1bfe4cb9d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.14016276
0x3d00fadf5c121cc11d5ebe564129991e4d0c7e35cfaf6d464bc40995a13144f51 day 7 hrs ago0x9bed7fd11ef2efa7899f757a8d422c1fd028610c  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02306046
0xf859daf428d62323f608c71d7b0ef2fc9fb770147ff69154bd658dc7f6d9ab451 day 11 hrs ago0x9bed7fd11ef2efa7899f757a8d422c1fd028610c  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.00115232
0x191fb9be2fae9800f852fdd0b865dee35347f28455b80a5d70aec3fb2342cde21 day 11 hrs ago0x9bed7fd11ef2efa7899f757a8d422c1fd028610c  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.00115232
0x1d6c6da8cca60e248dc62b09b3f087f6c0038a1513bdaa328c91cb5d883527441 day 11 hrs ago0x9bed7fd11ef2efa7899f757a8d422c1fd028610c  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.00115232
0xac79e806fb65e8b47519888967a7062075bf76ce1974a29714cc1942c03901031 day 11 hrs ago0x9bed7fd11ef2efa7899f757a8d422c1fd028610c  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.00115232
0x1ff57f82855fd44f9ed252779c35c8b56bc1fed87114d91f2c432b751af5fa0e1 day 12 hrs ago0x000e6dfc6f9f7f701860a5d6e511f6a1bfe4cb9d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.00115232
0x199387f56f4b11802369f9a0b025866369a0e918490356e004b36a21a74405481 day 12 hrs ago0x000e6dfc6f9f7f701860a5d6e511f6a1bfe4cb9d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.00115232
0xc47a839ac039302a8951d3d84f43b543bb31547bada1ca1ec5ff3c78c26193951 day 16 hrs ago0x000e6dfc6f9f7f701860a5d6e511f6a1bfe4cb9d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.00115232
0xf9749c3d8cc1ab49008b1be136c081f64d0c5c9b3785baa69f20018d962089774 days 3 hrs ago0x008311788dff04e3c0426a3eb19622b2035ba49d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.06283184
0x69b8af38e57b97a63d581a2ee5daa0c65bfe6492d79e8f0a69b7b67db6d06b134 days 3 hrs ago0x008311788dff04e3c0426a3eb19622b2035ba49d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02336046
0x40dcaf4da7fa4f55feddd1aaa2c7eb7395a860789453d46f6661668dee2674864 days 3 hrs ago0x008311788dff04e3c0426a3eb19622b2035ba49d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02336046
0x688d6254d14bfdaba188e740067a564aee8f088d7025618d3391fa056e1af4334 days 4 hrs ago0x000d91cf263a11f9bfcee3752e5b03fc1196ce98  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02306046
0xe94018f5990957b899e45a4ea72c13c8bd4cd6b62c1b708f2bdf557508dda6d74 days 4 hrs ago0x000d91cf263a11f9bfcee3752e5b03fc1196ce98  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02335918
0x11769eb6ca66d2571d4fd514643352b746f3794aa002fd1064266f7e5526400a4 days 8 hrs ago0xe7901d5298129aa266e74f636ba0ce45be5fe745  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.0230605
0x9462c2c5f12182d5ea509e99ccfe51a4a6d56f5d3eb678db77ee69c87dda625c4 days 8 hrs ago0xe7901d5298129aa266e74f636ba0ce45be5fe745  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.0230605
0x9ee25ac527ce4c4b98ea7118c14bcf7e8091b2a70f3c9e2786d10fe06b01602f4 days 8 hrs ago0xe7901d5298129aa266e74f636ba0ce45be5fe745  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02335922
0x50b7c4ca8ec11f633d06c86b87ab30b1e4df745ababb53ea9af4a8baa7cd6ef14 days 8 hrs ago0x78e5541de8492b78105e2d7693bc007f49861f7d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.0230605
0xfb3d397f6195139fc4abba0f5ccfdf8f348aba8318a09069aa5b68f8612a4ce34 days 8 hrs ago0x78e5541de8492b78105e2d7693bc007f49861f7d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.0230605
0x82990253e2a596419d502770793eebd723a415c497f034b8e7c47b91dc7327c44 days 8 hrs ago0x78e5541de8492b78105e2d7693bc007f49861f7d  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02305922
0x4cf9e979b5aa7bf1bad46c2552da9f99bde527e89cd55c35092da7132260b9fc4 days 9 hrs ago0xaad537ed0a7bed16562b18fbc2b0c30c059e7693  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.0230605
0xb9f509216dec9a065fa8c489de4d79201770398617f3f38ca873d4e6af515eaa4 days 10 hrs ago0xaad537ed0a7bed16562b18fbc2b0c30c059e7693  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.0230605
0xc9bc305334f09156437b23a2e3a3a0d353f0fd7c87745d3cafb171fbff8cfe154 days 10 hrs ago0xaad537ed0a7bed16562b18fbc2b0c30c059e7693  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02335922
0x1b8c6dd9e5fc72d65883308b578bd5dc2835742bebb5875f0a8823ff4d4a5f2e4 days 10 hrs ago0x00174e78f7f9f3640378b507ac01ef0a7e4424c2  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02305918
0xf17159612601dcf74b5eb35669583f445f043672a8696f50fac226cd2c94a2734 days 11 hrs ago0x00174e78f7f9f3640378b507ac01ef0a7e4424c2  IN   0x4ad65661f7390b3719d211f83ad38b1d6591531f0 Ether0.02305922
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
  Latest 25 Internal Txns, Click here to View More View All
ParentTxHash Block Age From To Value
0x787c24904316ecde73d6146c6cf6ed7b47b60ee0fa3273af38cd4730e80fa7a5172175813 hrs 16 mins ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x3d00fadf5c121cc11d5ebe564129991e4d0c7e35cfaf6d464bc40995a13144f517166471 day 7 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0xf9749c3d8cc1ab49008b1be136c081f64d0c5c9b3785baa69f20018d9620897716974474 days 3 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x69b8af38e57b97a63d581a2ee5daa0c65bfe6492d79e8f0a69b7b67db6d06b1316974474 days 3 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x40dcaf4da7fa4f55feddd1aaa2c7eb7395a860789453d46f6661668dee26748616974444 days 3 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x688d6254d14bfdaba188e740067a564aee8f088d7025618d3391fa056e1af43316974064 days 4 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0xe94018f5990957b899e45a4ea72c13c8bd4cd6b62c1b708f2bdf557508dda6d716973994 days 4 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x11769eb6ca66d2571d4fd514643352b746f3794aa002fd1064266f7e5526400a16965544 days 8 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x9462c2c5f12182d5ea509e99ccfe51a4a6d56f5d3eb678db77ee69c87dda625c16965494 days 8 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x9ee25ac527ce4c4b98ea7118c14bcf7e8091b2a70f3c9e2786d10fe06b01602f16965434 days 8 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x50b7c4ca8ec11f633d06c86b87ab30b1e4df745ababb53ea9af4a8baa7cd6ef116965204 days 8 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0xfb3d397f6195139fc4abba0f5ccfdf8f348aba8318a09069aa5b68f8612a4ce316965144 days 8 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x82990253e2a596419d502770793eebd723a415c497f034b8e7c47b91dc7327c416965084 days 8 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x4cf9e979b5aa7bf1bad46c2552da9f99bde527e89cd55c35092da7132260b9fc16961964 days 9 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0xb9f509216dec9a065fa8c489de4d79201770398617f3f38ca873d4e6af515eaa16961904 days 10 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0xc9bc305334f09156437b23a2e3a3a0d353f0fd7c87745d3cafb171fbff8cfe1516961844 days 10 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x1b8c6dd9e5fc72d65883308b578bd5dc2835742bebb5875f0a8823ff4d4a5f2e16960354 days 10 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0xf17159612601dcf74b5eb35669583f445f043672a8696f50fac226cd2c94a27316960204 days 11 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x99424dd5942a73fbe5a99346f59df5bef42bfcef77283a3ecf5225100d718c1a16957544 days 12 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x39e1b42e46ed71cdc8d329ab074fd122230e4d52d8a8009b11d64a6d3419c18916955444 days 13 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x65b88c92d15e7d705e7a5a868b3001c29e5450bae2b3d77a64b93a935baf29ec16794317 days 3 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0xa3c51e65a2349e78f246b8db1f2610c50e9983c9430eebb4aa10507a32a901b516793597 days 3 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x627122ca4a1316a869a926ec507632eb309331ebebaa961a446169eb55b3ca9416793557 days 3 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x3e0cf1e029c7ddd22ea3cc652c5c7aab1c1bb4b79ffa324954691a8eae15e3c216793557 days 3 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
0x68f8f68de167d84a30834b27dcc9ddf2a4586cc4423f3963df63f42ead8adf5216793527 days 3 hrs ago0x4ad65661f7390b3719d211f83ad38b1d6591531f  Contract Creation0 Ether
[ Download CSV Export  ] 
Contract Source Code Verified
Contract Name: ChannelManagerContract
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);
}

contract Utils {
    string constant public contract_version = "0.1._";
    /// @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) constant returns (bool) {
        uint size;

        assembly {
            size := extcodesize(channel)
        }

        return size > 0;
    }
}




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;
    }
}

// for each token a manager will be deployed, to reduce gas usage for manager
// deployment the logic is moved into a library and this contract will work
// only as a proxy/state container.
contract ChannelManagerContract is Utils {
    string constant public contract_version = "0.1._";

    using ChannelManagerLibrary for ChannelManagerLibrary.Data;
    ChannelManagerLibrary.Data data;

    event ChannelNew(
        address netting_channel,
        address participant1,
        address participant2,
        uint settle_timeout
    );

    event ChannelDeleted(
        address caller_address,
        address partner
    );

    function ChannelManagerContract(address token_address) {
        data.token = Token(token_address);
    }

    /// @notice Get all channels
    /// @return All the open channels
    function getChannelsAddresses() constant returns (address[]) {
        return data.all_channels;
    }

    /// @notice Get all participants of all channels
    /// @return All participants in all channels
    function getChannelsParticipants() constant returns (address[]) {
        uint i;
        uint pos;
        address[] memory result;
        NettingChannelContract channel;

        uint open_channels_num = 0;
        for (i = 0; i < data.all_channels.length; i++) {
            if (contractExists(data.all_channels[i])) {
                open_channels_num += 1;
            }
        }
        result = new address[](open_channels_num * 2);

        pos = 0;
        for (i = 0; i < data.all_channels.length; i++) {
            if (!contractExists(data.all_channels[i])) {
                continue;
            }
            channel = NettingChannelContract(data.all_channels[i]);

            var (address1, , address2, ) = channel.addressAndBalance();

            result[pos] = address1;
            pos += 1;
            result[pos] = address2;
            pos += 1;
        }

        return result;
    }

    /// @notice Get all channels that an address participates in.
    /// @param node_address The address of the node
    /// @return The channel's addresses that node_address participates in.
    function nettingContractsByAddress(address node_address) constant returns (address[]) {
        return data.nodeaddress_to_channeladdresses[node_address];
    }

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

    /// @notice Get the address of channel with a partner
    /// @param partner The address of the partner
    /// @return The address of the channel
    function getChannelWith(address partner) constant returns (address) {
        return data.getChannelWith(partner);
    }

    /// @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(address partner, uint settle_timeout) returns (address) {
        address old_channel = getChannelWith(partner);
        if (old_channel != 0) {
            ChannelDeleted(msg.sender, partner);
        }

        address new_channel = data.newChannel(partner, settle_timeout);
        ChannelNew(new_channel, msg.sender, partner, settle_timeout);
        return new_channel;
    }

    function () { revert(); }
}

  Contract ABI  
[{"constant":true,"inputs":[],"name":"getChannelsParticipants","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"partner","type":"address"}],"name":"getChannelWith","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getChannelsAddresses","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"node_address","type":"address"}],"name":"nettingContractsByAddress","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"channel","type":"address"}],"name":"contractExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contract_version","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"partner","type":"address"},{"name":"settle_timeout","type":"uint256"}],"name":"newChannel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"token_address","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":false,"stateMutability":"nonpayable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"netting_channel","type":"address"},{"indexed":false,"name":"participant1","type":"address"},{"indexed":false,"name":"participant2","type":"address"},{"indexed":false,"name":"settle_timeout","type":"uint256"}],"name":"ChannelNew","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"caller_address","type":"address"},{"indexed":false,"name":"partner","type":"address"}],"name":"ChannelDeleted","type":"event"}]

  Contract Creation Code Switch To Opcodes View
6060604052341561000f57600080fd5b604051602080610ce3833981016040528080519060200190919050505b806000800160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505b610c62806100816000396000f3006060604052361561008c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630b74b6201461009f578063238bfba21461010a5780636785b500146101835780636cb30fee146101ee5780637709bc781461027d5780639d76ea58146102ce578063b32c65c814610323578063f26c6aed146103b2575b341561009757600080fd5b5b600080fd5b005b34156100aa57600080fd5b6100b2610434565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156100f65780820151818401525b6020810190506100da565b505050509050019250505060405180910390f35b341561011557600080fd5b610141600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106f5565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561018e57600080fd5b6101966107c3565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156101da5780820151818401525b6020810190506101be565b505050509050019250505060405180910390f35b34156101f957600080fd5b610225600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061085b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102695780820151818401525b60208101905061024d565b505050509050019250505060405180910390f35b341561028857600080fd5b6102b4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610932565b604051808215151515815260200191505060405180910390f35b34156102d957600080fd5b6102e1610946565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032e57600080fd5b610336610973565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103775780820151818401525b60208101905061035b565b50505050905090810190601f1680156103a45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103bd57600080fd5b6103f2600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506109ac565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61043c610c22565b600080610447610c22565b60008060008060009250600096505b6000600101805490508710156104c7576104ad60006001018881548110151561047b57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610932565b156104b9576001830192505b5b8680600101975050610456565b600283026040518059106104d85750595b908082528060200260200182016040525b50945060009550600096505b6000600101805490508710156106e75761054c60006001018881548110151561051a57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610932565b1515610557576106da565b60006001018781548110151561056957fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1693508373ffffffffffffffffffffffffffffffffffffffff16636d2381b36000604051608001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401608060405180830381600087803b151561060457600080fd5b6102c65a03f1151561061557600080fd5b5050506040518051906020018051906020018051906020018051905050925050915081858781518110151561064657fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060018601955080858781518110151561069757fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001860195505b86806001019750506104f5565b8497505b5050505050505090565b6000807335078c2ee5b3c4040c8c8e14fb1e05746ab3735c638a1c00e29091846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15156107a057600080fd5b6102c65a03f415156107b157600080fd5b5050506040518051905090505b919050565b6107cb610c22565b600060010180548060200260200160405190810160405280929190818152602001828054801561085057602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610806575b505050505090505b90565b610863610c22565b600060030160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561092557602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116108db575b505050505090505b919050565b600080823b90506000811191505b50919050565b60008060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b90565b6040805190810160405280600581526020017f302e312e5f00000000000000000000000000000000000000000000000000000081525081565b60008060006109ba856106f5565b915060008273ffffffffffffffffffffffffffffffffffffffff16141515610a74577fda8d2f351e0f7c8c368e631ce8ab15973e7582ece0c347d75a5cff49eb899eb73386604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b60007335078c2ee5b3c4040c8c8e14fb1e05746ab3735c63941583a5909187876000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060206040518083038186803b1515610b2657600080fd5b6102c65a03f41515610b3757600080fd5b5050506040518051905090507f7bd269696a33040df6c111efd58439c9c77909fcbe90f7511065ac277e175dac81338787604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390a18092505b505092915050565b6020604051908101604052806000815250905600a165627a7a72305820997d6137ddea0f03e34ed1a4be3b6d0d6247ebf0e865dee5a5621d9de204055100290000000000000000000000000f114a1e9db192502e7856309cc899952b3db1ed

    Constructor Arguments (ABI-encoded and appended to the ByteCode above)
0000000000000000000000000f114a1e9db192502e7856309cc899952b3db1ed

-----Decoded View---------------
Found 1 constructor arguments :
Arg [0] : 0000000000000000000000000f114a1e9db192502e7856309cc899952b3db1ed


   Library Used
ChannelManagerLibrary : 0x35078c2ee5b3c4040c8c8e14fb1e05746ab3735c

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