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

TxHash Age From To Value [TxFee]
0x2ff0d0cf95b52937dd9c840af25bd650b824ba951072836014b22bc181dc141612 days 9 hrs ago0x0021712dae973fb48a772e6eb8ad7620bfb76b47  IN    Contract Creation0 Ether0.07661784
[ 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: NettingChannelLibrary
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 ABI  
[{"constant":false,"inputs":[{"name":"self","type":"NettingChannelLibrary.Data storage"},{"name":"amount","type":"uint256"}],"name":"deposit","outputs":[{"name":"success","type":"bool"},{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"self","type":"NettingChannelLibrary.Data storage"}],"name":"kill","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"contract_version","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"self","type":"NettingChannelLibrary.Data storage"},{"name":"locked_encoded","type":"bytes"},{"name":"merkle_proof","type":"bytes"},{"name":"secret","type":"bytes32"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"self","type":"NettingChannelLibrary.Data storage"},{"name":"nonce","type":"uint64"},{"name":"transferred_amount","type":"uint256"},{"name":"locksroot","type":"bytes32"},{"name":"extra_hash","type":"bytes32"},{"name":"signature","type":"bytes"}],"name":"close","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"self","type":"NettingChannelLibrary.Data storage"}],"name":"settle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"self","type":"NettingChannelLibrary.Data storage"},{"name":"nonce","type":"uint64"},{"name":"transferred_amount","type":"uint256"},{"name":"locksroot","type":"bytes32"},{"name":"extra_hash","type":"bytes32"},{"name":"signature","type":"bytes"}],"name":"updateTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

  Contract Creation Code Switch To Opcodes View
6060604052341561000f57600080fd5b5b61122d8061001f6000396000f30060606040523615610081576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633268a05a146100865780635ef30ac8146100c6578063b32c65c8146100de578063c252246214610162578063c800b0021461020d578063de394e0d1461029e578063f565eb36146102b6575b600080fd5b6100a56004808035906020019091908035906020019091905050610347565b60405180831515151581526020018281526020019250505060405180910390f35b6100dc60048080359060200190919050506105ef565b005b6100e661060d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101275780820151818401525b60208101905061010b565b50505050905090810190601f1680156101545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61020b600480803590602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803560001916906020019091905050610646565b005b61029c600480803590602001909190803567ffffffffffffffff16906020019091908035906020019091908035600019169060200190919080356000191690602001909190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506107d1565b005b6102b460048080359060200190919050506108e6565b005b610345600480803590602001909190803567ffffffffffffffff16906020019091908035906020019091908035600019169060200190919080356000191690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610c49565b005b6000806000806000866001015411151561036057600080fd5b6000866002015414151561037357600080fd5b848660050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231336000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b151561043b57600080fd5b6102c65a03f1151561044c57600080fd5b505050604051805190501015151561046357600080fd5b61046d8633610e48565b9150856006018260ff1660028110151561048357fe5b6006020160005b5090508560050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b151561059057600080fd5b6102c65a03f115156105a157600080fd5b5050506040518051905093506001151584151514156105db57806001015492508483019250828160010181905550600183935093506105e6565b600080809050935093505b50509250929050565b80600081600301541415151561060457600080fd5b6000ff5b5b5050565b6040805190810160405280600581526020017f302e312e5f00000000000000000000000000000000000000000000000000000081525081565b600080600080600080896000816003015411158015610669575060008160020154115b151561067457600080fd5b61067e8b33610e48565b60010395508a6006018660ff1660028110151561069757fe5b6006020160005b5091506000600102826002015460001916141515156106bc57600080fd5b6106c58a610eba565b809550819950829750505050816005016000846000191660001916815260200190815260200160002060009054906101000a900460ff1615151561070857600080fd5b6001826005016000856000191660001916815260200190815260200160002060006101000a81548160ff021916908315150217905550438567ffffffffffffffff161015151561075757600080fd5b87604051808260001916600019168152602001915050604051809103902060001916836000191614151561078a57600080fd5b6107948a8a610eec565b935083600019168260020154600019161415156107b057600080fd5b8682600301600082825401925050819055505b5b5050505050505050505050565b60008060008060008a600201541415156107ea57600080fd5b438a600201819055506107fd8a33610e48565b60ff169250338a60040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506041855114156108d95761085c8989898989611018565b93506108688a85610e48565b60ff16915081831415151561087c57600080fd5b896006018260028110151561088d57fe5b6006020160005b509050888160040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550868160020181600019169055508781600301819055505b5b50505050505050505050565b60008060008060008060008088600081600301541115801561090c575060008160020154115b151561091757600080fd5b894381600001548260020154011115151561093157600080fd5b438b600301819055506109688b8c60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610e48565b99508960010398508a6006018a60ff1660028110151561098457fe5b6006020160005b5093508a6006018960ff166002811015156109a257fe5b6006020160005b50925082600301548460030154846001015401039650826001015484600101540197506109d68789611188565b94506109e38560006111a2565b945084880395506000851115610b0d578a60050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16876000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1515610ae657600080fd5b6102c65a03f11515610af757600080fd5b505050604051805190501515610b0c57600080fd5b5b6000861115610c30578a60050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16886000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1515610c0957600080fd5b6102c65a03f11515610c1a57600080fd5b505050604051805190501515610c2f57600080fd5b5b610c398b6105ef565b5b5b505b50505050505050505050565b6000806000886000816003015411158015610c68575060008160020154115b1515610c7357600080fd5b8943816000015482600201540110151515610c8d57600080fd5b8a60130160009054906101000a900460ff16151515610cab57600080fd5b60018b60130160006101000a81548160ff021916908315150217905550610cd28b33610e48565b93503373ffffffffffffffffffffffffffffffffffffffff168b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515610d3357600080fd5b610d408a8a8a8a8a611018565b94508a60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141515610da057600080fd5b836001039250898b6006018460ff16600281101515610dbb57fe5b6006020160005b5060040160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550878b6006018460ff16600281101515610e0157fe5b6006020160005b506002018160001916905550888b6006018460ff16600281101515610e2957fe5b6006020160005b50600301819055505b5b505b50505050505050505050565b6000808360120160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905060008160ff1614151515610eac57fe5b6001810391505b5092915050565b600080600060488451141515610ecf57600080fd5b6008840151925060288401519150604884015190505b9193909250565b600080600080600060208651811515610f0157fe5b06141515610f0e57600080fd5b856040518082805190602001908083835b602083101515610f4557805182525b602082019150602081019050602083039250610f1f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390209150602092505b84518311151561100b57828501519050806000191682600019161015610fce57818160405180836000191660001916815260200182600019166000191681526020019250505060405180910390209150610fff565b8082604051808360001916600019168152602001826000191660001916815260200192505050604051809103902091505b5b602083019250610f79565b8193505b50505092915050565b60008060008060006041865114151561103057600080fd5b898989308a604051808667ffffffffffffffff1667ffffffffffffffff16780100000000000000000000000000000000000000000000000002815260080185815260200184600019166000191681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c01000000000000000000000000028152601401826000191660001916815260200195505050505050604051809103902093506110eb866111bc565b925092509250600184828585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561116f57600080fd5b50506020604051035194505b5050505095945050505050565b60008183116111975782611199565b815b90505b92915050565b60008183116111b157816111b3565b825b90505b92915050565b6000806000602084015192506040840151915060ff6041850151169050601b8160ff1614806111ee5750601c8160ff16145b15156111f957600080fd5b5b91939092505600a165627a7a72305820629eae857ab6154e89f7fb903ce0d1544c2e959b1f699362da693676ac89a37c0029

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