Latest 12 txns

TxHash Age From To Value [TxFee]
0xf28b6ee20cf20c43b7acf131648b621052e172f434af3858f76111e1c5ef717e39 days 11 hrs ago0x4d307e4ebc9b92fbcfbc9108aeb86cefff1da918  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000413914
0x94dbc4f308b9cdd70338483763533a721a88a25a2971a9fae8c5aa9479f0070c39 days 11 hrs ago0xb73939af7d449d12361ebb4f60141625461456e7  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000345446
0xbd68567f20adfe38e365080c6c636ef8b20c9c8c0fbfbca32ef6f2561879a01c39 days 11 hrs ago0x81100f1eaadc6781412217a2287f3bbcf72ad9d6  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000067918
0xb2754983b81fd417f62bba5dd617de300f13056a76f1aff5730d1cbd713ce88039 days 11 hrs ago0x4d307e4ebc9b92fbcfbc9108aeb86cefff1da918  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000067918
0xf7ea5bfd1b082a9c6ca67f8d14b8ed2ae2d9f9334c8f47716605560b8660aae539 days 11 hrs ago0xb73939af7d449d12361ebb4f60141625461456e7  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000067662
0x823a9918d14938f0608e3425aa9fae2e94c93f989986f689fc22218675d44a6939 days 11 hrs ago0x93611f0b9b577f393d255c0194a3e28f4b90b643  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000067918
0xe035eee7491d9a096ba56e2e34950bff35f289b7bd1cae2fd3d66d4e2012728039 days 11 hrs ago0x93611f0b9b577f393d255c0194a3e28f4b90b643  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000555792
0x89db1dbe40ad0cb72d42584573d469fc9de82d082be2adc043468beccb6cc9b539 days 11 hrs ago0x980dfa039b673412fc16678b5d34e17a51028c91  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000555984
0x248bf6c36f8ad3511a5234f27550961994eb972f5a6f08d2d77536f975bc9e3e39 days 11 hrs ago0x81100f1eaadc6781412217a2287f3bbcf72ad9d6  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.00055592
0x99f933353104473c835d7fd7023c9fb9401e4e900a48c7d4cd024babd90986e539 days 11 hrs ago0x4d307e4ebc9b92fbcfbc9108aeb86cefff1da918  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000555792
0x67c709f206f5d429f9b381ec7218c722ea0ccf966b3bc944040e9d0c54ecc7f239 days 11 hrs ago0xb73939af7d449d12361ebb4f60141625461456e7  IN   0x64eb9cbc8aac7723a7a94b178b7ac4c18d7e62690 Ether0.000570984
0xe2781094a87fc9eb69a556540d7df96a5014ad82dfa11bffe65e34f8e1270f2939 days 11 hrs ago0x90af78e467296d96dbcc60d7f2c8f6a1b370941f  IN    Contract Creation0 Ether0.003492253
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
Contract Source Code Verified (Similar Match)
Note: Displaying Similar Match Verified Source Code At Contract 0xff11c73633b09c825cb2765c234514d70ec1c3c3(Excluding Constructor Arguments if any)
Contract Name: DKG
Compiler Text: v0.4.25+commit.59dbf8f1
Optimization Enabled: Yes
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity ^0.4.24;

/*
    Author: Philipp Schindler
    Source code and documentation available on Github: https://github.com/PhilippSchindler/ethdkg

    Copyright 2018 Philipp Schindler

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

contract DKG {

    struct Node {
        uint256 id;                 // the node's one based id, if id=0 the node has not registered or a dispute was successful
        uint256 deposit;            
        uint256[2] pk;              // the node's public key from group G1 (i.e. g1 * sk)
        uint256[4] bls_pk;          // the node's public key from group G2 (i.e. g2 * sk)
        bytes32 key_distribution_hash;
    }

    event Registration(address node_adr, uint256 id, uint256 deposit, uint256[2] pk, uint256[4] bls_pk);
    event KeySharing(uint256 issuer, uint256[] encrypted_shares, uint256[] public_coefficients);
    event DisputeSuccessful(address bad_issuer_addr);

    uint256 constant g1x = 1;
    uint256 constant g1y = 2;
    uint256 constant g2xx = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
    uint256 constant g2xy = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
    uint256 constant g2yx = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
    uint256 constant g2yy = 8495653923123431417604973247489272438418190587263600148770280649306958101930;

    uint256 constant GROUP_ORDER   = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
    uint256 constant FIELD_MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

    uint256[4] bls_group_pk;
    address[] registered_addresses;
    mapping (address => Node) nodes;

    bool public aborted;       

    uint256 public constant DELTA_INCLUDE = 20;            // needs to be appropriately set for the production system
    uint256 public constant DELTA_CONFIRM = 2;             // needs to be appropriately set for the production system
    uint256 public constant PARTICIPATION_THRESHOLD = 3;   // minimum number of nodes which need to register (inclusive)
    // uint256 public constant PARTICIPATION_LIMIT = 256;  // maximum number of nodes allowed to register (inclusive)

    uint256 public T_CONTRACT_CREATION;     // block number in which the contract instance was created
    uint256 public T_REGISTRATION_END;      // block number of the last block where registration is possible
    uint256 public T_SHARING_END;           // block number of the last block where key sharing is possible
    uint256 public T_DISPUTE_END;           // block number of the last block where dispute is possible.
    uint256 public T_GROUP_KEY_UPLOAD;      // block number of the block in which the group key is uploaded (dynamic)

    constructor() public {
        // potential optimization: could set all this values as constants during compile time 
        // to save gas during deployment and for checking the guard conditions

        T_CONTRACT_CREATION = block.number;
        T_REGISTRATION_END = T_CONTRACT_CREATION + DELTA_CONFIRM + DELTA_INCLUDE;
        T_SHARING_END = T_REGISTRATION_END + DELTA_CONFIRM + DELTA_INCLUDE;
        T_DISPUTE_END = T_SHARING_END + DELTA_CONFIRM + DELTA_INCLUDE;
    }

    function in_registration_phase() 
    public view returns(bool) {
        return block.number <= T_REGISTRATION_END;
    }

    function in_sharing_phase() 
    public view returns(bool) {
        return (T_REGISTRATION_END < block.number) && (block.number <= T_SHARING_END);
    }

    function in_dispute_phase() 
    public view returns(bool) {
        return (T_SHARING_END < block.number) && (block.number <= T_DISPUTE_END);
    }

    function in_finalization_phase()
    public view returns(bool) {
        return (T_DISPUTE_END < block.number) && (T_GROUP_KEY_UPLOAD == 0);
    }

    function registrations_confirmed() 
    public view returns(bool) {
        return T_REGISTRATION_END + DELTA_CONFIRM <= block.number;
    }

    function sharing_confirmed()
    public view returns(bool) {
        return T_SHARING_END + DELTA_CONFIRM <= block.number;
    }

    function dispute_confirmed()
    public view returns(bool) {
        return T_DISPUTE_END + DELTA_CONFIRM <= block.number;
    }

    function group_key_confirmed()
    public view returns(bool) {
        return (T_GROUP_KEY_UPLOAD != 0) && (T_GROUP_KEY_UPLOAD + DELTA_CONFIRM <= block.number);
    }


    function register(uint256[2] pk, uint256[4] bls_pk, uint256[2] sk_knowledge_proof) 
    public payable 
    {
        require(in_registration_phase(), "registration failed (contract is not in registration phase)");
        require(nodes[msg.sender].id == 0, "registration failed (account already registered a public key)");
        require(
            bn128_check_pairing(                                    // ensures that the given pk and bls_pk correspond to each other
                [                                                   // i.e. that pk and bls_pk are of the form
                    pk[0], pk[1],                                   // pk     =  g1 * sk
                    g2xx, g2xy, g2yx, g2yy,                         // bls_pk = -g2 * sk
                    g1x, g1y,                                       // for some secret key sk
                    bls_pk[0], bls_pk[1], bls_pk[2], bls_pk[3]
                ]), 
            "registration failed (bls public key is invalid)"
        );
        require(
            verify_sk_knowledge(pk, sk_knowledge_proof), 
            "registration failed (invalid proof of secret key knowlegde)"
        );

        // add appropriate registration condition(s) here
        // e.g. require a minimum deposit amount or whitelist specific Ethereum accounts

        registered_addresses.push(msg.sender);
        uint256 id = registered_addresses.length;        

        nodes[msg.sender].id = id;
        nodes[msg.sender].deposit = msg.value;
        nodes[msg.sender].pk[0] = pk[0];
        nodes[msg.sender].pk[1] = pk[1];
        nodes[msg.sender].bls_pk[0] = bls_pk[0];
        nodes[msg.sender].bls_pk[1] = bls_pk[1];
        nodes[msg.sender].bls_pk[2] = bls_pk[2];
        nodes[msg.sender].bls_pk[3] = bls_pk[3];

        emit Registration(msg.sender, id, msg.value, pk, bls_pk);
    }

    function share_key(
        uint256[] encrypted_shares,     // Enc_kAB(s_i), each 256 bit
        uint256[] public_coefficients)  // Cj, each 512 bit
    public
    {
        uint256 n = registered_addresses.length;
        uint256 t = (n / 2) + 1;
        uint256 issuer_id = nodes[msg.sender].id;

        require(in_sharing_phase(), "key sharing failed (contract is not in sharing phase)");
        require(issuer_id > 0, "key sharing failed (ethereum account has not registered)");
        require(encrypted_shares.length == n - 1, "key sharing failed (invalid number of encrypted shares provided)");
        require(public_coefficients.length == t * 2 - 2, "key sharing failed (invalid number of commitments provided)");

        // for optimization we only store the hash of the submitted data
        // and emit an event with the actual data
        nodes[msg.sender].key_distribution_hash = keccak256(abi.encodePacked(encrypted_shares, public_coefficients));
        emit KeySharing(issuer_id, encrypted_shares, public_coefficients);
    }

    function dispute_public_coefficient(
        address issuer_addr,             // the node which is accussed to have distributed (at least one) invalid coefficient
        uint256[] encrypted_shares,      // the data from previous KeySharing event
        uint256[] public_coefficients,   // the data from previous KeySharing event
        uint256 invalid_coefficient_idx  // specifies any coefficient which is invalid (used for efficiency)
    ) 
    public
    {
        Node storage issuer = nodes[issuer_addr];
        Node storage verifier = nodes[msg.sender];

        require(in_dispute_phase(), "dispute failed (contract is not in sharing phase)");
        require(issuer.id > 0, "dispute failed/aborted (issuer not registered or slashed)");
        require(verifier.id > 0, "dispute failed/aborted (verifier not registered or slashed)");
        require(issuer.id != verifier.id, "dispute failed (self dispute is not allowed)");
        require(
            issuer.key_distribution_hash == keccak256(abi.encodePacked(encrypted_shares, public_coefficients)),
            "dispute failed (encrypted shares and/or public coefficients not matching)"
        );

        uint256 i = invalid_coefficient_idx * 2;
        require(
            !bn128_is_on_curve([public_coefficients[i], public_coefficients[i + 1]]),
            "dispute failed (coefficient is actually valid)"
        );

        __slash__(issuer_addr);
    }

    function dispute_share(
        address issuer_addr,             // the node which is accussed to have distributed an invalid share
        uint256[] encrypted_shares,      // the data from previous KeyDistribution event
        uint256[] public_coefficients,   // the data from previous KeyDistribution event
        uint256[2] decryption_key,       // shared key between issuer and calling node
        uint256[2] decryption_key_proof) // NIZK proof, showing that decryption key is valid
    public
    {
        Node storage issuer = nodes[issuer_addr];
        Node storage verifier = nodes[msg.sender];

        require(in_dispute_phase(), "dispute failed (contract is not in sharing phase)");
        require(issuer.id > 0, "dispute failed/aborted (issuer not registered or slashed)");
        require(verifier.id > 0, "dispute failed/aborted (verifier not registered or slashed)");
        require(issuer.id != verifier.id, "dispute failed (self dispute is not allowed)");
        require(
            issuer.key_distribution_hash == keccak256(abi.encodePacked(encrypted_shares, public_coefficients)),
            "dispute failed (encrypted shares and/or public coefficients not matching)"
        );
        require(
            verify_decryption_key(decryption_key, decryption_key_proof, verifier.pk, issuer.pk),
            "dispute failed (invalid decryption key or decryption key proof)"
        );

        // compute share index i:
        // the index i is one-based (which is required!) (indepent of the correction below)
        // as the issuer does not provide a share for itself the index has to be corrected
        uint256 i = verifier.id;
        if (i > issuer.id) {
            i--;
        }

        // decryption of the share, (correct for one-based index i to make it zero-based)
        // We currently use a encryption/decryption by xoring the share with the hash of shared key and id as there are 
        // currently no symmetric key encryption primitives available as EVM instructions.
        // This approach can be replaced once such a primitive or an alternative cheap implementation becomes available.
        uint256 share = encrypted_shares[i - 1] ^ uint256(keccak256(abi.encodePacked(decryption_key[0], verifier.id)));
        
        // verify that share is actually invalid
        // evaluate the polynom F(x) for x = i
        uint256 x = i;
        uint256[2] memory Fx = [issuer.pk[0], issuer.pk[1]];
        uint256[2] memory tmp = bn128_multiply([public_coefficients[0], public_coefficients[1], x]);
        Fx = bn128_add([Fx[0], Fx[1], tmp[0], tmp[1]]);

        for (uint256 j = 2; j < public_coefficients.length; j += 2) { 
            x = mulmod(x, i, GROUP_ORDER);
            tmp = bn128_multiply([public_coefficients[j], public_coefficients[j + 1], x]);
            Fx = bn128_add([Fx[0], Fx[1], tmp[0], tmp[1]]);
        }
        // and compare the result (stored in Fx) with g1*si
        uint256[2] memory Fi = bn128_multiply([g1x, g1y, share]);   

        // require that share is actually invalid
        require(Fx[0] != Fi[0] || Fx[1] != Fi[1], "dispute failed (the provided share was valid)");

        __slash__(issuer_addr);
    }

    // compute the group key in the elliptic curve group G1
    // and verify the uploaded bls_group_pk from G2 with the pairing
    // only non-successfully-disputed keys form the group keys
    // calls abort if insufficient valid keys have been registered
    function upload_group_key(uint[4] _bls_group_pk) 
    public returns(bool success)
    {
        require(
            in_finalization_phase(),    
            "group key upload failed (key sharing / disputes not finsished, or group key already uploaded)"
        );

        uint256 n = registered_addresses.length;
        uint256 t = (n / 2) + 1;
        
        Node memory node;
        uint256[2] memory group_pk;
        
        // find first (i.e. lowest index) valid registered node
        uint256 i = 0;
        do {
            node = nodes[registered_addresses[i]];
            i += 1;
        } 
        while((node.id == 0 || node.key_distribution_hash == 0) && i < n);

        if (i == n) {
            // in this case at most one nodes actually shared a valid key
            __abort__();
            return false;
        }
        
        uint256 p = 1;  // number of nodes which provided valid keys
        group_pk = node.pk;
        for ( ; i < registered_addresses.length; i++) {  // sum up all valid pubic keys
            node = nodes[registered_addresses[i]];
            if (node.id != 0 && node.key_distribution_hash != 0) {
                p++;
                group_pk = bn128_add([group_pk[0], group_pk[1], node.pk[0], node.pk[1]]);
            }
        }

        if (p < t) {
            __abort__();
            return false;
        }

        // ensures that the given group_pk and bls_group_pk correspond to each other
        require(
            bn128_check_pairing(                                    
                [                       
                    group_pk[0], group_pk[1],
                    g2xx, g2xy, g2yx, g2yy,
                    g1x, g1y,
                    _bls_group_pk[0], _bls_group_pk[1], _bls_group_pk[2], _bls_group_pk[3]
                ]), 
            "upload of group key failed (the submitted bls_group_pk does not correspond to group_pk)"
        );

        bls_group_pk = _bls_group_pk;
        T_GROUP_KEY_UPLOAD = block.number;
    }

    function __slash__(address addr) 
    private 
    {
        emit DisputeSuccessful(addr);
        nodes[addr].id = 0;
    }

    // checks abort condition and aborts the contract if at least one abort condition is fulfilled
    function abort() 
    public 
    {
        // never abort during registration phase
        require(!in_registration_phase(), "abort failed (cannot abort during registration phase)");

        uint256 n = registered_addresses.length;
        uint256 t = (n / 2) + 1;

        // abort is possible if not enough nodes joined the DKG protocol
        if (n < PARTICIPATION_THRESHOLD) {
            __abort__();
        }

        // abort is possible if less then t nodes actually shared their keys without disputes
        else {
            require(
                T_SHARING_END < block.number, 
                "abort failed (abort is only possible after key sharing phase ended)"
            );
            uint256 p = 0;  // number of nodes with shared their key without disputes
            for (uint256 i = 0; i < n; i++) {
                Node memory node = nodes[registered_addresses[i]];

                // id != 0 ensures not was not slashed
                // hashkey_distribution_hash != 0 ensures that node has shared its key
                if ((node.id != 0) && node.key_distribution_hash != 0)  {
                    p++;
                }                
            }
            require(
                p < t,
                "abort failed (abort is only possible if less than t nodes shared their key successfully)"
            );
            __abort__();
        }
    }

    // move the contract to the aborted state:
    // can e.g. be used to releases all the deposits to be withdrawn from the contract and evenly distribute 
    // slashed deposists are evenly distributed to all other nodes
    function __abort__() 
    private 
    {
        aborted = true;
    }


    // verifies that the sender account knows the private key corresponding to the given public key
    function verify_sk_knowledge(uint[2] public_key, uint[2] proof) 
    public returns (bool)
    {
        uint256[2] memory a = bn128_multiply([g1x, g1y, proof[1]]);
        uint256[2] memory b = bn128_multiply([public_key[0], public_key[1], proof[0]]);
        uint256[2] memory t = bn128_add([a[0], a[1], b[0], b[1]]);
        
        uint256 c = uint256(
            keccak256(abi.encodePacked(g1x, g1y, public_key[0], public_key[1], t[0], t[1], msg.sender)));

        return proof[0] == c;
    }


    // implement the verification procedure for the NIZK DLEQ (discrete logarithm equalty) proof
    function verify_decryption_key(
        uint256[2] decryption_key, 
        uint256[2] correctness_proof, // DLEQ challenge and response      
        uint256[2] verifier_pk,
        uint256[2] issuer_pk) 
    public returns (bool key_valid)
    {
        // equivalent to DLEQ_verify(G1, issuer_pk, verifier_pk, decryption_key, correctness_proof) in python

        uint256[2] memory tmp1;  // two temporary variables
        uint256[2] memory tmp2;

        tmp1 = bn128_multiply([g1x, g1y, correctness_proof[1]]);
        tmp2 = bn128_multiply([verifier_pk[0], verifier_pk[1], correctness_proof[0]]);
        uint256[2] memory a1 = bn128_add([tmp1[0], tmp1[1], tmp2[0], tmp2[1]]);
        
        tmp1 = bn128_multiply([issuer_pk[0], issuer_pk[1], correctness_proof[1]]);
        tmp2 = bn128_multiply([decryption_key[0], decryption_key[1], correctness_proof[0]]);
        uint256[2] memory a2 = bn128_add([tmp1[0], tmp1[1], tmp2[0], tmp2[1]]);

        uint256 challenge_computed = uint256(
            keccak256(abi.encodePacked(a1, a2, g1x, g1y, verifier_pk, issuer_pk, decryption_key)));

        key_valid = correctness_proof[0] == challenge_computed;
    }

    function verify_signature(uint256[4] bls_pk, bytes32 message, uint256[2] signature) 
    public returns (bool signature_valid)
    {
        uint[2] memory h = bn128_map_to_G1(message);
        signature_valid = bn128_check_pairing(                                   
            [                                                  
                signature[0], signature[1],                                  
                g2xx, g2xy, g2yx, g2yy,                        
                h[0], h[1],                                      
                bls_pk[0], bls_pk[1], bls_pk[2], bls_pk[3]
            ]);
    }
    
    function bn128_add(uint256[4] input) 
    public returns (uint256[2] result) {
        // computes P + Q 
        // input: 4 values of 256 bit each
        //  *) x-coordinate of point P
        //  *) y-coordinate of point P
        //  *) x-coordinate of point Q
        //  *) y-coordinate of point Q

        bool success;
        assembly {
            // 0x06     id of precompiled bn256Add contract
            // 0        number of ether to transfer
            // 128      size of call parameters, i.e. 128 bytes total
            // 64       size of call return value, i.e. 64 bytes / 512 bit for a BN256 curve point
            success := call(not(0), 0x06, 0, input, 128, result, 64)
        }
        require(success, "elliptic curve addition failed");
    }

    function bn128_multiply(uint256[3] input) 
    public returns (uint256[2] result) {
        // computes P*x 
        // input: 3 values of 256 bit each
        //  *) x-coordinate of point P
        //  *) y-coordinate of point P
        //  *) scalar x

        bool success;
        assembly {
            // 0x07     id of precompiled bn256ScalarMul contract
            // 0        number of ether to transfer
            // 96       size of call parameters, i.e. 96 bytes total (256 bit for x, 256 bit for y, 256 bit for scalar)
            // 64       size of call return value, i.e. 64 bytes / 512 bit for a BN256 curve point
            success := call(not(0), 0x07, 0, input, 96, result, 64)
        }
        require(success, "elliptic curve multiplication failed");
    }

    function bn128_is_on_curve(uint[2] point) 
    public returns(bool valid) {
        // checks if the given point is a valid point from the first elliptic curve group
        // by trying an addition with the generator point g1

        uint256[4] memory input = [point[0], point[1], g1x, g1y];
        assembly {
            // 0x06     id of precompiled bn256Add contract
            // 0        number of ether to transfer
            // 128      size of call parameters, i.e. 128 bytes total
            // 64       size of call return value, i.e. 64 bytes / 512 bit for a BN256 curve point
            valid := call(not(0), 0x06, 0, input, 128, input, 64)
        }
    }

    function bn128_check_pairing(uint256[12] input) 
    public returns (bool) {
        uint256[1] memory result;
        bool success;
        assembly {
            // 0x08     id of precompiled bn256Pairing contract     (checking the elliptic curve pairings)
            // 0        number of ether to transfer
            // 384       size of call parameters, i.e. 12*256 bits == 384 bytes
            // 32        size of result (one 32 byte boolean!)
            success := call(sub(gas, 2000), 0x08, 0, input, 384, result, 32)
        }
        require(success, "elliptic curve pairing failed");
        return result[0] == 1;
    }


    function bn128_map_to_G1(bytes32 data)
    public returns (uint[2] point) 
    {
        uint256 ctr = 0;
        while (true) {
            uint256 x = uint256(keccak256(abi.encodePacked(ctr, data)));
            bool b = x & 1 == 1;    // extract last bit of the hash
            x >>= 2;                // drop last 2 bits of the hash, a coordinate is a 254 bit number

            if (x < FIELD_MODULUS) { 
                // p...  FIELD_MODULUS
                // z = x**3 + 3 (mod p)
                uint256 z = (bigModExp([32, 32, 32, x, 3, FIELD_MODULUS]) + 3) % FIELD_MODULUS; 

                // y = sqrt(z) = z**((p + 1) / 4) mod p
                uint256 y = bigModExp([32, 32, 32, z, (FIELD_MODULUS + 1) >> 2, FIELD_MODULUS]);

                // checks if y is indeed a square root of z mod p
                if (bigModExp([32, 32, 32, y, 2, FIELD_MODULUS]) == z) {
                    if (b) {
                        y = (FIELD_MODULUS - y);
                    }
                    return [x, y]; 
                }
            }
            ctr++;
        }    
    }

    
    function bigModExp(uint256[6] input) 
    public returns (uint256) {
        // call the precompiled contract to compute the b^e mod m
        // used the following arguments in the given order
        //  - length of the base b
        //  - length of the exponent e
        //  - length of the modulus m
        //  - the base b itself
        //  - the exponent e itself
        //  - the modulus m itself
        // we use 256 bit integers for all of the above values

        bool success;
        uint256[1] memory result;
        assembly {
            // 0x05     id of precompiled bigModExp contract
            // 0        number of ether to transfer
            // 192      size of call parameters, i.e. 192 bytes total (6x 256 bit)
            // 32       size of call return value, i.e. 32 bytes / 256 bit
            success := call(not(0), 0x05, 0, input, 192, result, 32)
        }
        require(success, "bigModExp operation failed");
        return result[0];
    }

}

    Contract ABI  
[{"constant":false,"inputs":[{"name":"encrypted_shares","type":"uint256[]"},{"name":"public_coefficients","type":"uint256[]"}],"name":"share_key","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"T_SHARING_END","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"T_REGISTRATION_END","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DELTA_INCLUDE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"issuer_addr","type":"address"},{"name":"encrypted_shares","type":"uint256[]"},{"name":"public_coefficients","type":"uint256[]"},{"name":"decryption_key","type":"uint256[2]"},{"name":"decryption_key_proof","type":"uint256[2]"}],"name":"dispute_share","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"in_finalization_phase","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PARTICIPATION_THRESHOLD","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"pk","type":"uint256[2]"},{"name":"bls_pk","type":"uint256[4]"},{"name":"sk_knowledge_proof","type":"uint256[2]"}],"name":"register","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"in_sharing_phase","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"abort","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"bls_pk","type":"uint256[4]"},{"name":"message","type":"bytes32"},{"name":"signature","type":"uint256[2]"}],"name":"verify_signature","outputs":[{"name":"signature_valid","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"in_dispute_phase","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"issuer_addr","type":"address"},{"name":"encrypted_shares","type":"uint256[]"},{"name":"public_coefficients","type":"uint256[]"},{"name":"invalid_coefficient_idx","type":"uint256"}],"name":"dispute_public_coefficient","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"group_key_confirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"T_GROUP_KEY_UPLOAD","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DELTA_CONFIRM","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"in_registration_phase","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dispute_confirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"aborted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"input","type":"uint256[3]"}],"name":"bn128_multiply","outputs":[{"name":"result","type":"uint256[2]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"public_key","type":"uint256[2]"},{"name":"proof","type":"uint256[2]"}],"name":"verify_sk_knowledge","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"registrations_confirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"decryption_key","type":"uint256[2]"},{"name":"correctness_proof","type":"uint256[2]"},{"name":"verifier_pk","type":"uint256[2]"},{"name":"issuer_pk","type":"uint256[2]"}],"name":"verify_decryption_key","outputs":[{"name":"key_valid","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"sharing_confirmed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"input","type":"uint256[12]"}],"name":"bn128_check_pairing","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_bls_group_pk","type":"uint256[4]"}],"name":"upload_group_key","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"data","type":"bytes32"}],"name":"bn128_map_to_G1","outputs":[{"name":"point","type":"uint256[2]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"T_DISPUTE_END","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"input","type":"uint256[6]"}],"name":"bigModExp","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"input","type":"uint256[4]"}],"name":"bn128_add","outputs":[{"name":"result","type":"uint256[2]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"T_CONTRACT_CREATION","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"point","type":"uint256[2]"}],"name":"bn128_is_on_curve","outputs":[{"name":"valid","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"node_adr","type":"address"},{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"deposit","type":"uint256"},{"indexed":false,"name":"pk","type":"uint256[2]"},{"indexed":false,"name":"bls_pk","type":"uint256[4]"}],"name":"Registration","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"issuer","type":"uint256"},{"indexed":false,"name":"encrypted_shares","type":"uint256[]"},{"indexed":false,"name":"public_coefficients","type":"uint256[]"}],"name":"KeySharing","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"bad_issuer_addr","type":"address"}],"name":"DisputeSuccessful","type":"event"}]

  Contract Creation Code Switch To Opcodes View
608060405234801561001057600080fd5b5043600781905560168101600855602c8101600955604201600a5561315d8061003a6000396000f3006080604052600436106101955763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166304649712811461019a57806306bd598e1461022a5780630de1553f146102515780630f21e5d8146102665780630f3b00501461027b5780630fd7410c1461035d5780631b177dbd14610386578063294574831461039b5780632d6b113a1461041757806335a063b41461042c5780633b89332e14610441578063628ee84f146104af578063656b9c87146104c4578063708d9fd314610562578063742689c0146105775780637543b80f1461058c5780637753ec49146105a15780637e837ccc146105b657806380b62b70146105cb57806382688f14146105e0578063829f06671461065e5780639da26320146106c15780639fc52bd4146106d6578063add3fa391461077f578063b87cbafc14610794578063b94fdaab146107d9578063ba59a75e1461081b578063d3cf618614610833578063e340727614610848578063e664725b1461088b578063eed6548c146108cd578063f4d7d33d146108e2575b600080fd5b3480156101a657600080fd5b506040805160206004803580820135838102808601850190965280855261022895369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497506109229650505050505050565b005b34801561023657600080fd5b5061023f610cf9565b60408051918252519081900360200190f35b34801561025d57600080fd5b5061023f610cff565b34801561027257600080fd5b5061023f610d05565b34801561028757600080fd5b50604080516020600460248035828101358481028087018601909752808652610228968435600160a060020a031696369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437505060408051808201825295989796818101969550935060029250849150839080828437505060408051808201825294979695818101959450925060029150839083908082843750939650610d0a95505050505050565b34801561036957600080fd5b506103726114b6565b604080519115158252519081900360200190f35b34801561039257600080fd5b5061023f6114cf565b604080518082018252610228913691600491604491908390600290839083908082843750506040805160808181019092529497969581810195945092506004915083908390808284375050604080518082018252949796958181019594509250600291508390839080828437509396506114d495505050505050565b34801561042357600080fd5b5061037261192b565b34801561043857600080fd5b50610228611943565b34801561044d57600080fd5b5060408051608081810190925261037291369160049160849190839081908390829080828437505060408051808201825294978635979096909560608201955093506020019150600290839083908082843750939650611c5595505050505050565b3480156104bb57600080fd5b50610372611d60565b3480156104d057600080fd5b50604080516020600460248035828101358481028087018601909752808652610228968435600160a060020a031696369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a9989019892975090820195509350839250850190849080828437509497505093359450611d789350505050565b34801561056e57600080fd5b506103726121fb565b34801561058357600080fd5b5061023f612219565b34801561059857600080fd5b5061023f61221f565b3480156105ad57600080fd5b50610372612224565b3480156105c257600080fd5b5061037261222d565b3480156105d757600080fd5b5061037261223d565b3480156105ec57600080fd5b5060408051606081810190925261062391369160049160649190839060039083908390808284375093965061224695505050505050565b6040518082600260200280838360005b8381101561064b578181015183820152602001610633565b5050505090500191505060405180910390f35b34801561066a57600080fd5b5060408051808201825261037291369160049160449190839060029083908390808284375050604080518082018252949796958181019594509250600291508390839080828437509396506122e195505050505050565b3480156106cd57600080fd5b50610372612447565b3480156106e257600080fd5b5060408051808201825261037291369160049160449190839060029083908390808284375050604080518082018252949796958181019594509250600291508390839080828437505060408051808201825294979695818101959450925060029150839083908082843750506040805180820182529497969581810195945092506002915083908390808284375093965061245795505050505050565b34801561078b57600080fd5b506103726126f8565b3480156107a057600080fd5b506040805161018081810190925261037291369160049161018491908390600c9083908390808284375093965061270895505050505050565b3480156107e557600080fd5b50604080516080818101909252610372913691600491608491908390819083908290808284375093965061278995505050505050565b34801561082757600080fd5b50610623600435612c6a565b34801561083f57600080fd5b5061023f612e82565b34801561085457600080fd5b506040805160c081810190925261023f91369160049160c491908390600690839083908082843750939650612e8895505050505050565b34801561089757600080fd5b506040805160808181019092526106239136916004916084919083908190839082908082843750939650612f0295505050505050565b3480156108d957600080fd5b5061023f612f72565b3480156108ee57600080fd5b50604080518082018252610372913691600491604491908390600290839083908082843750939650612f7895505050505050565b60045433600090815260056020526040902054600160028304019061094561192b565b15156109c1576040805160e560020a62461bcd02815260206004820152603560248201527f6b65792073686172696e67206661696c65642028636f6e74726163742069732060448201527f6e6f7420696e2073686172696e67207068617365290000000000000000000000606482015290519081900360840190fd5b60008111610a3f576040805160e560020a62461bcd02815260206004820152603860248201527f6b65792073686172696e67206661696c65642028657468657265756d2061636360448201527f6f756e7420686173206e6f742072656769737465726564290000000000000000606482015290519081900360840190fd5b8451600019840114610ac1576040805160e560020a62461bcd02815260206004820152602481018290527f6b65792073686172696e67206661696c65642028696e76616c6964206e756d6260448201527f6572206f6620656e63727970746564207368617265732070726f766964656429606482015290519081900360840190fd5b8351600119600284020114610b46576040805160e560020a62461bcd02815260206004820152603b60248201527f6b65792073686172696e67206661696c65642028696e76616c6964206e756d6260448201527f6572206f6620636f6d6d69746d656e74732070726f7669646564290000000000606482015290519081900360840190fd5b848460405160200180838051906020019060200280838360005b83811015610b78578181015183820152602001610b60565b50505050905001828051906020019060200280838360005b83811015610ba8578181015183820152602001610b90565b50505050905001925050506040516020818303038152906040526040518082805190602001908083835b60208310610bf15780518252601f199092019160209182019101610bd2565b51815160209384036101000a600019018019909216911617905260408051929094018290038220336000908152600583528581206008019190915587835260608383018181528d51918501919091528c517fd3d84113c75efd125afbcf8c5d0ea6cc3f239f23f9ad5521831ec6353fbb34a098508997508d968d965091939185019260808601928881019202908190849084905b83811015610c9d578181015183820152602001610c85565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610cdc578181015183820152602001610cc4565b505050509050019550505050505060405180910390a15050505050565b60095481565b60085481565b601481565b6000806000806000610d1a613023565b610d22613023565b6000610d2c613023565b600160a060020a038e1660009081526005602052604080822033835291209099509750610d57611d60565b1515610dd3576040805160e560020a62461bcd02815260206004820152603160248201527f64697370757465206661696c65642028636f6e7472616374206973206e6f742060448201527f696e2073686172696e6720706861736529000000000000000000000000000000606482015290519081900360840190fd5b8854600010610e52576040805160e560020a62461bcd02815260206004820152603960248201527f64697370757465206661696c65642f61626f727465642028697373756572206e60448201527f6f742072656769737465726564206f7220736c61736865642900000000000000606482015290519081900360840190fd5b8754600010610ed1576040805160e560020a62461bcd02815260206004820152603b60248201527f64697370757465206661696c65642f61626f727465642028766572696669657260448201527f206e6f742072656769737465726564206f7220736c6173686564290000000000606482015290519081900360840190fd5b875489541415610f51576040805160e560020a62461bcd02815260206004820152602c60248201527f64697370757465206661696c6564202873656c6620646973707574652069732060448201527f6e6f7420616c6c6f776564290000000000000000000000000000000000000000606482015290519081900360840190fd5b8c8c60405160200180838051906020019060200280838360005b83811015610f83578181015183820152602001610f6b565b50505050905001828051906020019060200280838360005b83811015610fb3578181015183820152602001610f9b565b50505050905001925050506040516020818303038152906040526040518082805190602001908083835b60208310610ffc5780518252601f199092019160209182019101610fdd565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912060088d01541492506110d0915050576040805160e560020a62461bcd02815260206004820152604960248201527f64697370757465206661696c65642028656e637279707465642073686172657360448201527f20616e642f6f72207075626c696320636f656666696369656e7473206e6f742060648201527f6d61746368696e67290000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b6040805180820191829052611149918d918d9160028d81019182845b8154815260200190600101908083116110ec5750505050508c60020160028060200260405190810160405280929190826002801561113f576020028201915b81548152602001906001019080831161112b575b5050505050612457565b15156111c5576040805160e560020a62461bcd02815260206004820152603f60248201527f64697370757465206661696c65642028696e76616c696420646563727970746960448201527f6f6e206b6579206f722064656372797074696f6e206b65792070726f6f662900606482015290519081900360840190fd5b875489549097508711156111db57600019909601955b8a518854604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b602083106112335780518252601f199092019160209182019101611214565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600190048d6001890381518110151561127557fe5b6020908102909101015160408051808201909152911896508795508060028b0160000154815260200160028b016001015481525093506112ff6060604051908101604052808e60008151811015156112c957fe5b9060200190602002015181526020018e60018151811015156112e757fe5b90602001906020020151815260200187815250612246565b604080516080810190915290935061134490808660005b6020908102919091015182528781015190820152855160408201526060018560015b60200201519052612f02565b9350600291505b8b518210156113df577f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000187860994506113b76060604051908101604052808e8581518110151561139757fe5b9060200190602002015181526020018e856001018151811015156112e757fe5b60408051608081019091529093506113d29080866000611316565b935060028201915061134b565b611405606060405190810160405280600181526020016002815260200188815250612246565b8051855191925014158061142157506020808201519085015114155b151561149d576040805160e560020a62461bcd02815260206004820152602d60248201527f64697370757465206661696c656420287468652070726f76696465642073686160448201527f7265207761732076616c69642900000000000000000000000000000000000000606482015290519081900360840190fd5b6114a68e612fbe565b5050505050505050505050505050565b600043600a541080156114c95750600b54155b90505b90565b600381565b60006114de612224565b151561155a576040805160e560020a62461bcd02815260206004820152603b60248201527f726567697374726174696f6e206661696c65642028636f6e747261637420697360448201527f206e6f7420696e20726567697374726174696f6e207068617365290000000000606482015290519081900360840190fd5b33600090815260056020526040902054156115e5576040805160e560020a62461bcd02815260206004820152603d60248201527f726567697374726174696f6e206661696c656420286163636f756e7420616c7260448201527f6561647920726567697374657265642061207075626c6963206b657929000000606482015290519081900360840190fd5b604080516101808101825285518152602080870151818301527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2828401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60608301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60808301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60a0830152600160c0830152600260e08301528551610100830152850151610120820152908401516101408201526116d79061016081018560035b60200201519052612708565b1515611753576040805160e560020a62461bcd02815260206004820152602f60248201527f726567697374726174696f6e206661696c65642028626c73207075626c69632060448201527f6b657920697320696e76616c6964290000000000000000000000000000000000606482015290519081900360840190fd5b61175d84836122e1565b15156117d9576040805160e560020a62461bcd02815260206004820152603b60248201527f726567697374726174696f6e206661696c65642028696e76616c69642070726f60448201527f6f66206f6620736563726574206b6579206b6e6f776c65676465290000000000606482015290519081900360840190fd5b5060048054600180820183557f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101805473ffffffffffffffffffffffffffffffffffffffff19163390811790915582546000828152600560208181526040808420858155349781018890558b5160028201558b83015160038201558a519881019890985589820151928801929092558882015160068801556060808a0151600790980197909755815185815290810184905280820186905292957f4469beb2ff204caae6761a793ea738c8812d42f6313ca0aa3c02e714b065451595879490938b938b938301918591908190849084905b838110156118e45781810151838201526020016118cc565b5050505090500182600460200280838360005b8381101561190f5781810151838201526020016118f7565b505050509050019550505050505060405180910390a150505050565b6000436008541080156114c957505060095443111590565b60008060008061195161303e565b611959612224565b156119d4576040805160e560020a62461bcd02815260206004820152603560248201527f61626f7274206661696c6564202863616e6e6f742061626f727420647572696e60448201527f6720726567697374726174696f6e207068617365290000000000000000000000606482015290519081900360840190fd5b600454945060028504600101935060038510156119f8576119f3613014565b611c4e565b6009544311611a9d576040805160e560020a62461bcd02815260206004820152604360248201527f61626f7274206661696c6564202861626f7274206973206f6e6c7920706f737360448201527f69626c65206166746572206b65792073686172696e6720706861736520656e6460648201527f6564290000000000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b60009250600091505b84821015611ba35760056000600484815481101515611ac157fe5b600091825260208083209190910154600160a060020a031683528281019390935260409182019020815160a081018352815481526001820154938101939093528151808301808452919284019160028085019182845b815481526020019060010190808311611b175750505091835250506040805160808101918290526020909201919060048481019182845b815481526020019060010190808311611b4e57505050918352505060089190910154602090910152805190915015801590611b8c5750608081015115155b15611b98576001909201915b600190910190611aa6565b838310611c46576040805160e560020a62461bcd02815260206004820152605860248201527f61626f7274206661696c6564202861626f7274206973206f6e6c7920706f737360448201527f69626c65206966206c657373207468616e2074206e6f6465732073686172656460648201527f207468656972206b6579207375636365737366756c6c79290000000000000000608482015290519081900360a40190fd5b611c4e613014565b5050505050565b6000611c5f613023565b611c6884612c6a565b604080516101808101825285518152602080870151818301527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2828401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60608301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60808301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60a0830152835160c08301528381015160e0830152885161010083015288015161012082015290870151610140820152909150611d579061016081018760036116cb565b95945050505050565b6000436009541080156114c9575050600a5443111590565b600160a060020a0384166000908152600560205260408082203383529082209091611da1611d60565b1515611e1d576040805160e560020a62461bcd02815260206004820152603160248201527f64697370757465206661696c65642028636f6e7472616374206973206e6f742060448201527f696e2073686172696e6720706861736529000000000000000000000000000000606482015290519081900360840190fd5b8254600010611e9c576040805160e560020a62461bcd02815260206004820152603960248201527f64697370757465206661696c65642f61626f727465642028697373756572206e60448201527f6f742072656769737465726564206f7220736c61736865642900000000000000606482015290519081900360840190fd5b8154600010611f1b576040805160e560020a62461bcd02815260206004820152603b60248201527f64697370757465206661696c65642f61626f727465642028766572696669657260448201527f206e6f742072656769737465726564206f7220736c6173686564290000000000606482015290519081900360840190fd5b815483541415611f9b576040805160e560020a62461bcd02815260206004820152602c60248201527f64697370757465206661696c6564202873656c6620646973707574652069732060448201527f6e6f7420616c6c6f776564290000000000000000000000000000000000000000606482015290519081900360840190fd5b858560405160200180838051906020019060200280838360005b83811015611fcd578181015183820152602001611fb5565b50505050905001828051906020019060200280838360005b83811015611ffd578181015183820152602001611fe5565b50505050905001925050506040516020818303038152906040526040518082805190602001908083835b602083106120465780518252601f199092019160209182019101612027565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120600887015414925061211a915050576040805160e560020a62461bcd02815260206004820152604960248201527f64697370757465206661696c65642028656e637279707465642073686172657360448201527f20616e642f6f72207075626c696320636f656666696369656e7473206e6f742060648201527f6d61746368696e67290000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b83600202905061216e6040805190810160405280878481518110151561213c57fe5b906020019060200201518152602001878460010181518110151561215c57fe5b90602001906020020151815250612f78565b156121e9576040805160e560020a62461bcd02815260206004820152602e60248201527f64697370757465206661696c65642028636f656666696369656e74206973206160448201527f637475616c6c792076616c696429000000000000000000000000000000000000606482015290519081900360840190fd5b6121f287612fbe565b50505050505050565b6000600b546000141580156114c95750436002600b54011115905090565b600b5481565b600281565b60085443111590565b6000436002600a54011115905090565b60065460ff1681565b61224e613023565b6000604082606085846007600019f190508015156122db576040805160e560020a62461bcd028152602060048201526024808201527f656c6c6970746963206375727665206d756c7469706c69636174696f6e20666160448201527f696c656400000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50919050565b60006122eb613023565b6122f3613023565b6122fb613023565b6000612335606060405190810160405280600181526020016002815260200188600160028110151561232957fe5b60200201519052612246565b60408051606081018252895181526020808b01519082015291955061235f91908101886000612329565b604080516080810190915290935061237a9080866000611316565b87516020808a0151835182850151604080516001818701526002818301526060810196909652608086019390935260a085019190915260c08401526c01000000000000000000000000330260e0840152805160d481850301815260f4909301908190528251939550919282918401908083835b6020831061240c5780518252601f1990920191602091820191016123ed565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912098519098149998505050505050505050565b6000436002600854011115905090565b6000612461613023565b612469613023565b612471613023565b612479613023565b60006124a760606040519081016040528060018152602001600281526020018b600160028110151561232957fe5b6040805160608101909152895181529095506124da90602081018a60015b602090810291909101518252018b6000612329565b604080516080810190915290945061251790808760005b602090810291909101518252888101519082015286516040820152606001866001611338565b60408051606081018252895181526020808b015190820152919450612541919081018b6001612329565b60408051606081019091528b51815290955061256390602081018c60016124c5565b604080516080810190915290945061257e90808760006124f1565b91508282600160028b8b8f6040516020018088600260200280838360005b838110156125b457818101518382015260200161259c565b5050505090500187600260200280838360005b838110156125df5781810151838201526020016125c7565b5050505090500186815260200185815260200184600260200280838360005b838110156126165781810151838201526020016125fe565b5050505090500183600260200280838360005b83811015612641578181015183820152602001612629565b5050505090500182600260200280838360005b8381101561266c578181015183820152602001612654565b505050509050019750505050505050506040516020818303038152906040526040518082805190602001908083835b602083106126ba5780518252601f19909201916020918201910161269b565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209b51909b149c9b505050505050505050505050565b6000436002600954011115905090565b600061271261307b565b600060208261018086600060086107d05a03f1905080151561277e576040805160e560020a62461bcd02815260206004820152601d60248201527f656c6c69707469632063757276652070616972696e67206661696c6564000000604482015290519081900360640190fd5b505160011492915050565b600080600061279661303e565b61279e613023565b6000806127a96114b6565b151561284b576040805160e560020a62461bcd02815260206004820152605d60248201527f67726f7570206b65792075706c6f6164206661696c656420286b65792073686160448201527f72696e67202f206469737075746573206e6f742066696e7369736865642c206f60648201527f722067726f7570206b657920616c72656164792075706c6f6164656429000000608482015290519081900360a40190fd5b6004549550600286046001019450600091505b6005600060048481548110151561287157fe5b600091825260208083209190910154600160a060020a031683528281019390935260409182019020815160a081018352815481526001820154938101939093528151808301808452919284019160028085019182845b8154815260200190600101908083116128c75750505091835250506040805160808101918290526020909201919060048481019182845b8154815260200190600101908083116128fe57505050918352505060089190910154602090910152805190945060019290920191158061294057506080840151155b801561294b57508582105b156129555761285e565b8582141561296e57612965613014565b60009650612c5f565b506040830151915060015b600454821015612ab0576005600060048481548110151561299657fe5b600091825260208083209190910154600160a060020a031683528281019390935260409182019020815160a081018352815481526001820154938101939093528151808301808452919284019160028085019182845b8154815260200190600101908083116129ec5750505091835250506040805160808101918290526020909201919060048481019182845b815481526020019060010190808311612a2357505050918352505060089190910154602090910152805190945015801590612a615750608084015115155b15612aa557604080516080810182528451815260208086015190820152858201805151928201929092529051600192830192612aa292916060830191611338565b92505b600190910190612979565b84811015612ac057612965613014565b604080516101808101825284518152602080860151818301527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2828401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60608301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60808301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60a0830152600160c0830152600260e08301528a516101008301528a015161012082015290890151610140820152612baa9061016081018a60036116cb565b1515612c4c576040805160e560020a62461bcd02815260206004820152605760248201527f75706c6f6164206f662067726f7570206b6579206661696c656420287468652060448201527f7375626d697474656420626c735f67726f75705f706b20646f6573206e6f742060648201527f636f72726573706f6e6420746f2067726f75705f706b29000000000000000000608482015290519081900360a40190fd5b612c59600089600461309a565b5043600b555b505050505050919050565b612c72613023565b6000808080805b6040805160208082018890528183018a9052825180830384018152606090920192839052815191929182918401908083835b60208310612cca5780518252601f199092019160209182019101612cab565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120600481049750600190811614955050506000805160206131128339815191528510159050612e6d57600080516020613112833981519152612d7260c06040519081016040528060208152602001602081526020016020815260200187815260200160038152602001600080516020613112833981519152815250612e88565b600301811515612d7e57fe5b6040805160c081018252602080825280820181905291810191909152919006606082018190527f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52608083015260008051602061311283398151915260a08301529250612de990612e88565b905081612e3460c06040519081016040528060208152602001602081526020016020815260200184815260200160028152602001600080516020613112833981519152815250612e88565b1415612e6d578215612e5157600080516020613112833981519152035b6040805190810160405280858152602001828152509550612e78565b600190940193612c79565b5050505050919050565b600a5481565b600080612e9361307b565b60208160c08660006005600019f19150811515612efa576040805160e560020a62461bcd02815260206004820152601a60248201527f6269674d6f64457870206f7065726174696f6e206661696c6564000000000000604482015290519081900360640190fd5b519392505050565b612f0a613023565b6000604082608085846006600019f190508015156122db576040805160e560020a62461bcd02815260206004820152601e60248201527f656c6c6970746963206375727665206164646974696f6e206661696c65640000604482015290519081900360640190fd5b60075481565b6000612f826130d8565b50604080516080808201835284518252602080860151908301526001828401526002606083015290919082908160006006600019f19392505050565b60408051600160a060020a038316815290517fca3f275f9f6197d1413355ca806679447a484c6932c50cd73388784825f5f5349181900360200190a1600160a060020a0316600090815260056020526040812055565b6006805460ff19166001179055565b60408051808201825290600290829080388339509192915050565b610120604051908101604052806000815260200160008152602001613061613023565b815260200161306e6130d8565b8152600060209091015290565b6020604051908101604052806001906020820280388339509192915050565b82600481019282156130c8579160200282015b828111156130c85782518255916020019190600101906130ad565b506130d49291506130f7565b5090565b6080604051908101604052806004906020820280388339509192915050565b6114cc91905b808211156130d457600081556001016130fd560030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47a165627a7a723058201ab30f68550535e380ef9d2049730483b24cd474dec74f2a9f8e8f0c0262769b0029

   Swarm Source:
bzzr://1ab30f68550535e380ef9d2049730483b24cd474dec74f2a9f8e8f0c0262769b

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward