Пример #1
0
    def test_getStorageAt(self):
        key = bytes.fromhex(
            "c987d4506fb6824639f9a9e3b8834584f5165e94680501d1b0044071cd36c3b3")
        id1 = Identity.create_from_key(key)
        acc1 = Address.create_from_identity(id1, full_shard_id=0)
        created_addr = "0x8531eb33bba796115f56ffa1b7df1ea3acdd8cdd00000000"

        with ClusterContext(1, acc1) as clusters, jrpc_server_context(
                clusters[0].master):
            master = clusters[0].master
            slaves = clusters[0].slave_list

            branch = Branch.create(2, 0)
            tx = create_contract_with_storage_transaction(
                shard_state=slaves[0].shards[branch].state,
                key=id1.get_key(),
                from_address=acc1,
                to_full_shard_id=acc1.full_shard_id,
            )
            self.assertTrue(slaves[0].add_tx(tx))

            _, block = call_async(master.get_next_block_to_mine(address=acc1))
            self.assertTrue(
                call_async(clusters[0].get_shard(0).add_block(block)))

            for using_eth_endpoint in (True, False):
                if using_eth_endpoint:
                    req = lambda k: send_request("eth_getStorageAt",
                                                 created_addr[:-8], k, "0x0")
                else:
                    req = lambda k: send_request("getStorageAt", created_addr,
                                                 k)

                # first storage
                response = req("0x0")
                # equals 1234
                self.assertEqual(
                    response,
                    "0x00000000000000000000000000000000000000000000000000000000000004d2",
                )

                # mapping storage
                k = sha3_256(
                    bytes.fromhex(acc1.recipient.hex().zfill(64) +
                                  "1".zfill(64)))
                response = req("0x" + k.hex())
                self.assertEqual(
                    response,
                    "0x000000000000000000000000000000000000000000000000000000000000162e",
                )

                # doesn't exist
                response = req("0x3")
                self.assertEqual(
                    response,
                    "0x0000000000000000000000000000000000000000000000000000000000000000",
                )
Пример #2
0
def calculate_merkle_root(item_list):
    """ Using ETH2.0 SSZ style hash tree
    """
    if len(item_list) == 0:
        sha_tree = [bytes(32)]
    else:
        sha_tree = [sha3_256(item.serialize()) for item in item_list]

    zbytes = bytes(32)
    while len(sha_tree) != 1:
        if len(sha_tree) % 2 != 0:
            sha_tree.append(zbytes)
        sha_tree = [
            sha3_256(sha_tree[i] + sha_tree[i + 1])
            for i in range(0, len(sha_tree), 2)
        ]
        zbytes = sha3_256(zbytes + zbytes)
    return sha3_256(sha_tree[0] + len(item_list).to_bytes(8, "big"))
Пример #3
0
    def test_getWork_and_submitWork(self):
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_key=0)

        with ClusterContext(
            1, acc1, remote_mining=True, shard_size=1, small_coinbase=True
        ) as clusters, jrpc_server_context(clusters[0].master):
            master = clusters[0].master
            slaves = clusters[0].slave_list

            branch = Branch.create(1, 0)
            tx = create_transfer_transaction(
                shard_state=slaves[0].shards[branch].state,
                key=id1.get_key(),
                from_address=acc1,
                to_address=acc1,
                value=0,
                gas_price=12,
            )
            self.assertTrue(slaves[0].add_tx(tx))

            for shard_id in ["0x0", None]:  # shard, then root
                resp = send_request("getWork", shard_id)
                self.assertEqual(resp[1:], ["0x1", "0xa"])  # height and diff

                header_hash_hex = resp[0]
                if shard_id is not None:  # shard 0
                    miner_address = Address.create_from(
                        master.env.quark_chain_config.shards[1].COINBASE_ADDRESS
                    )
                else:  # root
                    miner_address = Address.create_from(
                        master.env.quark_chain_config.ROOT.COINBASE_ADDRESS
                    )
                _, block = call_async(
                    master.get_next_block_to_mine(
                        address=miner_address, prefer_root=shard_id is None
                    )
                )
                self.assertEqual(
                    header_hash_hex[2:], block.header.get_hash_for_mining().hex()
                )
                # solve it and submit
                work = MiningWork(bytes.fromhex(resp[0][2:]), 1, 10)
                solver = DoubleSHA256(work)
                nonce = solver.mine(0, 10000).nonce
                mixhash = "0x" + sha3_256(b"").hex()
                resp = send_request(
                    "submitWork", shard_id, header_hash_hex, hex(nonce), mixhash
                )
                self.assertTrue(resp)

            # show progress on shard 0
            self.assertEqual(
                clusters[0].get_shard_state(1 | 0).get_tip().header.height, 1
            )
Пример #4
0
def gen_address():
    sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
    print(
        colorify(
            "A new address has been generated for you, your private key is: ",
            "grey"))
    print(sk.to_string().hex())
    address = sha3_256(sk.verifying_key.to_string())[-20:].hex()
    print(colorify("Address is:", "grey") + " 0x{}".format(address))
    return address
Пример #5
0
    def create_minor_block(self, root_block: RootBlock, full_shard_id: int,
                           evm_state: EvmState) -> MinorBlock:
        """ Create genesis block for shard.
        Genesis block's hash_prev_root_block is set to the genesis root block.
        Genesis state will be committed to the given evm_state.
        Based on ALLOC, genesis_token will be added to initial accounts.
        """
        branch = Branch(full_shard_id)
        shard_config = self._qkc_config.shards[full_shard_id]
        genesis = shard_config.GENESIS

        for address_hex, alloc_amount in genesis.ALLOC.items():
            address = Address.create_from(bytes.fromhex(address_hex))
            check(
                self._qkc_config.get_full_shard_id_by_full_shard_key(
                    address.full_shard_key) == full_shard_id)
            evm_state.full_shard_key = address.full_shard_key
            for k, v in alloc_amount.items():
                evm_state.delta_token_balance(address.recipient,
                                              token_id_encode(k), v)

        evm_state.commit()

        meta = MinorBlockMeta(
            hash_merkle_root=bytes.fromhex(genesis.HASH_MERKLE_ROOT),
            hash_evm_state_root=evm_state.trie.root_hash,
        )

        local_fee_rate = 1 - self._qkc_config.reward_tax_rate  # type: Fraction
        coinbase_tokens = {
            self._qkc_config.genesis_token:
            shard_config.COINBASE_AMOUNT * local_fee_rate.numerator //
            local_fee_rate.denominator
        }

        coinbase_address = Address.create_empty_account(full_shard_id)

        header = MinorBlockHeader(
            version=genesis.VERSION,
            height=genesis.HEIGHT,
            branch=branch,
            hash_prev_minor_block=bytes.fromhex(genesis.HASH_PREV_MINOR_BLOCK),
            hash_prev_root_block=root_block.header.get_hash(),
            evm_gas_limit=genesis.GAS_LIMIT,
            hash_meta=sha3_256(meta.serialize()),
            coinbase_amount_map=TokenBalanceMap(coinbase_tokens),
            coinbase_address=coinbase_address,
            create_time=genesis.TIMESTAMP,
            difficulty=genesis.DIFFICULTY,
            extra_data=bytes.fromhex(genesis.EXTRA_DATA),
        )
        return (
            MinorBlock(header=header, meta=meta, tx_list=[]),
            TokenBalanceMap(coinbase_tokens),
        )
Пример #6
0
    def _encode_node(self, node, put_in_db=True):
        if node == BLANK_NODE:
            return BLANK_NODE
        # assert isinstance(node, list)
        rlpnode = rlp_encode(node)
        if len(rlpnode) < 32:
            return node

        hashkey = utils.sha3_256(rlpnode)
        if put_in_db:
            self.db.put(hashkey, rlpnode)
        return hashkey
Пример #7
0
        async def go():
            work, _ = await miner.get_work(now=now)
            self.assertEqual(work.height, 0)
            self.assertEqual(work.difficulty, 5)
            # submitted block doesn't exist
            res = await miner.submit_work(b"lolwut", 0, sha3_256(b""))
            self.assertFalse(res)

            solver = DoubleSHA256(work)
            sol = solver.mine(100, 200).nonce
            self.assertGreater(sol, 100)  # ensure non-solution is tried
            non_sol = sol - 1
            # invalid pow proof
            res = await miner.submit_work(work.hash, non_sol, sha3_256(b""))
            self.assertFalse(res)
            # valid submission, also check internal state afterwards
            res = await miner.submit_work(work.hash, sol, sha3_256(b""))
            self.assertTrue(res)
            self.assertEqual(miner.work_map, {})
            self.assertEqual(len(self.added_blocks), 1)
            self.assertIsNone(miner.current_work)
Пример #8
0
        async def go():
            for i in range(42, 100):
                work, _ = await miner.get_work(EMPTY_ADDR, now=now)
                self.assertEqual(work.height, 0)

                # remote guardian: diff 1000 -> 1, any number should work
                # mimic the sign process of the remote guardian server
                block.header.nonce = i
                block.header.mixhash = sha3_256(b"")
                block.header.sign_with_private_key(priv)
                signature = block.header.signature

                # reset the signature to the default value
                block.header.signature = bytes(65)
                # submit the signature through the submit work
                res = await miner.submit_work(work.hash, i, sha3_256(b""),
                                              signature)
                self.assertTrue(res)
                res = await miner.submit_work(work.hash, i, sha3_256(b""),
                                              bytes(65))
                self.assertFalse(res)
Пример #9
0
def validate_seal(
    block_header: Union[RootBlockHeader, MinorBlockHeader],
    consensus_type: ConsensusType,
) -> None:
    if consensus_type == ConsensusType.POW_ETHASH:
        nonce_bytes = block_header.nonce.to_bytes(8, byteorder="big")
        if not check_pow(
                block_header.height,
                block_header.get_hash_for_mining(),
                block_header.mixhash,
                nonce_bytes,
                block_header.difficulty,
        ):
            raise ValueError("invalid pow proof")
    elif consensus_type == ConsensusType.POW_SHA3SHA3:
        nonce_bytes = block_header.nonce.to_bytes(8, byteorder="big")
        target = (2**256 // (block_header.difficulty or 1) - 1).to_bytes(
            32, byteorder="big")
        h = sha3_256(sha3_256(block_header.get_hash_for_mining() +
                              nonce_bytes))
        if not h < target:
            raise ValueError("invalid pow proof")
Пример #10
0
 def sender(self):
     if not self._sender:
         if self.r >= secpk1n or self.s >= secpk1n or self.r == 0 or self.s == 0:
             raise InvalidTransaction("Invalid signature values!")
         if self.version == 0:
             pub = ecrecover_to_pub(self.hash_unsigned, self.v, self.r,
                                    self.s)
         if self.version == 1:
             pub = ecrecover_to_pub(self.hash_typed, self.v, self.r, self.s)
         if pub == b"\x00" * 64:
             raise InvalidTransaction(
                 "Invalid signature (zero privkey cannot sign)")
         self._sender = sha3_256(pub)[-20:]
     return self._sender
Пример #11
0
 def __init__(self,
              hash=b'\x00' * 32,
              number=0,
              timestamp=0,
              difficulty=1,
              gas_limit=3141592,
              gas_used=0,
              uncles_hash=sha3_256(rlp.encode([]))):
     self.hash = hash
     self.number = number
     self.timestamp = timestamp
     self.difficulty = difficulty
     self.gas_limit = gas_limit
     self.gas_used = gas_used
     self.uncles_hash = uncles_hash
Пример #12
0
    def create_minor_block(self, root_block: RootBlock, shard_id: int,
                           evm_state: EvmState) -> MinorBlock:
        """ Create genesis block for shard.
        Genesis block's hash_prev_root_block is set to the genesis root block.
        Genesis state will be committed to the given evm_state.
        """
        branch = Branch.create(self._qkc_config.SHARD_SIZE, shard_id)
        shard_config = self._qkc_config.SHARD_LIST[shard_id]
        genesis = shard_config.GENESIS

        for address_hex, amount_in_wei in genesis.ALLOC.items():
            address = Address.create_from(bytes.fromhex(address_hex))
            check(
                address.get_shard_id(self._qkc_config.SHARD_SIZE) == shard_id)
            evm_state.full_shard_id = address.full_shard_id
            evm_state.delta_balance(address.recipient, amount_in_wei)

        evm_state.commit()

        meta = MinorBlockMeta(
            hash_merkle_root=bytes.fromhex(genesis.HASH_MERKLE_ROOT),
            hash_evm_state_root=evm_state.trie.root_hash,
        )

        local_fee_rate = 1 - self._qkc_config.reward_tax_rate  # type: Fraction
        coinbase_amount = (shard_config.COINBASE_AMOUNT *
                           local_fee_rate.numerator //
                           local_fee_rate.denominator)
        coinbase_address = Address.create_empty_account(shard_id)

        header = MinorBlockHeader(
            version=genesis.VERSION,
            height=genesis.HEIGHT,
            branch=branch,
            hash_prev_minor_block=bytes.fromhex(genesis.HASH_PREV_MINOR_BLOCK),
            hash_prev_root_block=root_block.header.get_hash(),
            evm_gas_limit=genesis.GAS_LIMIT,
            hash_meta=sha3_256(meta.serialize()),
            coinbase_amount=coinbase_amount,
            coinbase_address=coinbase_address,
            create_time=genesis.TIMESTAMP,
            difficulty=genesis.DIFFICULTY,
            extra_data=bytes.fromhex(genesis.EXTRA_DATA),
        )
        return MinorBlock(header=header, meta=meta, tx_list=[])
Пример #13
0
    def test_getWork_and_submitWork(self):
        id1 = Identity.create_random_identity()
        acc1 = Address.create_from_identity(id1, full_shard_id=0)

        with ClusterContext(1, acc1, remote_mining=True,
                            shard_size=1) as clusters, jrpc_server_context(
                                clusters[0].master):
            master = clusters[0].master
            slaves = clusters[0].slave_list

            branch = Branch.create(1, 0)
            tx = create_transfer_transaction(
                shard_state=slaves[0].shards[branch].state,
                key=id1.get_key(),
                from_address=acc1,
                to_address=acc1,
                value=0,
                gas_price=12,
            )
            self.assertTrue(slaves[0].add_tx(tx))

            for shard_id in ["0x0", None]:  # shard, then root
                resp = send_request("getWork", shard_id)
                self.assertEqual(resp[1:], ["0x1", "0xa"])  # height and diff

                header_hash_hex = resp[0]
                _, block = call_async(
                    master.get_next_block_to_mine(address=acc1))
                self.assertEqual(header_hash_hex[2:],
                                 block.header.get_hash_for_mining().hex())
                # solve it and submit
                solver = DoubleSHA256(block)
                mined = solver.mine(0, 1000)
                self.assertTrue(mined)
                nonce_found = "0x" + solver.nonce_found.hex()
                mixhash = "0x" + sha3_256(b"").hex()
                resp = send_request("submitWork", shard_id, header_hash_hex,
                                    nonce_found, mixhash)
                # FIXME: also verify root chain block addition after fixing https://github.com/QuarkChain/pyquarkchain/issues/130
                if shard_id is not None:
                    self.assertTrue(resp)
Пример #14
0
 def sender(self):
     if not self._sender:
         if self.r >= secpk1n or self.s >= secpk1n or self.r == 0 or self.s == 0:
             raise InvalidTransaction("Invalid signature values!")
         if self.version == 0:
             pub = ecrecover_to_pub(self.hash_unsigned, self.v, self.r,
                                    self.s)
         if self.version == 1:
             pub = ecrecover_to_pub(self.hash_typed, self.v, self.r, self.s)
         if self.version == 2:
             v = 35 - 27 + self.network_id * 2
             if self.v < v:
                 raise InvalidTransaction(
                     "Invalid signature (wrong v with tx version = 2)")
             v = self.v - v
             pub = ecrecover_to_pub(self.hash_unsigned, v, self.r, self.s)
         if pub == b"\x00" * 64:
             raise InvalidTransaction(
                 "Invalid signature (zero privkey cannot sign)")
         self._sender = sha3_256(pub)[-20:]
     return self._sender
def main():
    args = parse_args()
    result = []
    while True:
        identity = Identity.create_random_identity()
        address = Address.create_from_identity(identity)
        if args.shard > -1:
            # Follow the same algorithm in testnet web
            fullShard = int.from_bytes(
                sha3_256(address.recipient.hex().encode("utf-8"))[:4], "big")
            shard = fullShard & (args.shard_size - 1)
            if shard != args.shard:
                continue
            address = Address.create_from_identity(identity, fullShard)
        result.append({
            "address": address.to_hex(),
            "key": identity.get_key().hex()
        })
        args.num_accounts -= 1
        if args.num_accounts == 0:
            break

    print(json.dumps(result, indent=4))
Пример #16
0
 def hash_unsigned(self):
     return sha3_256(
         rlp.encode(unsigned_tx_from_tx(self), UnsignedTransaction))
Пример #17
0
def sha3(seed):
    return sha3_256(seed)
Пример #18
0
 def hash_unsigned(self):
     return sha3_256(rlp.encode(self, UnsignedTransaction))
Пример #19
0
 def get_hash_for_mining(self):
     return sha3_256(self.serialize_without(["nonce", "mixhash"]))
Пример #20
0
 def get_hash(self):
     return sha3_256(self.serialize())
Пример #21
0
 def _update_root_hash(self):
     val = rlp_encode(self.root_node)
     key = utils.sha3_256(val)
     self.db.put(key, val)
     self._root_hash = key
Пример #22
0
    def create_minor_block(
            self, root_block: RootBlock, full_shard_id: int,
            evm_state: EvmState) -> Tuple[MinorBlock, TokenBalanceMap]:
        """ Create genesis block for shard.
        Genesis block's hash_prev_root_block is set to the genesis root block.
        Genesis state will be committed to the given evm_state.
        Based on ALLOC, genesis_token will be added to initial accounts.
        """
        branch = Branch(full_shard_id)
        shard_config = self._qkc_config.shards[full_shard_id]
        genesis = shard_config.GENESIS

        for address_hex, alloc_data in genesis.ALLOC.items():
            address = Address.create_from(bytes.fromhex(address_hex))
            check(
                self._qkc_config.get_full_shard_id_by_full_shard_key(
                    address.full_shard_key) == full_shard_id)
            evm_state.full_shard_key = address.full_shard_key
            recipient = address.recipient
            if "code" in alloc_data:
                code = decode_hex(remove_0x_head(alloc_data["code"]))
                evm_state.set_code(recipient, code)
                evm_state.set_nonce(recipient, 1)
            if "storage" in alloc_data:
                for k, v in alloc_data["storage"].items():
                    evm_state.set_storage_data(
                        recipient,
                        big_endian_to_int(decode_hex(k[2:])),
                        big_endian_to_int(decode_hex(v[2:])),
                    )
            # backward compatible:
            # v1: {addr: {QKC: 1234}}
            # v2: {addr: {balances: {QKC: 1234}, code: 0x, storage: {0x12: 0x34}}}
            balances = alloc_data
            if "balances" in alloc_data:
                balances = alloc_data["balances"]
            for k, v in balances.items():
                if k in ("code", "storage"):
                    continue
                evm_state.delta_token_balance(recipient, token_id_encode(k), v)

        evm_state.commit()

        meta = MinorBlockMeta(
            hash_merkle_root=bytes.fromhex(genesis.HASH_MERKLE_ROOT),
            hash_evm_state_root=evm_state.trie.root_hash,
            xshard_tx_cursor_info=XshardTxCursorInfo(root_block.header.height,
                                                     0, 0),
        )

        local_fee_rate = 1 - self._qkc_config.reward_tax_rate  # type: Fraction
        coinbase_tokens = {
            self._qkc_config.genesis_token:
            shard_config.COINBASE_AMOUNT * local_fee_rate.numerator //
            local_fee_rate.denominator
        }

        coinbase_address = Address.create_empty_account(full_shard_id)

        header = MinorBlockHeader(
            version=genesis.VERSION,
            height=genesis.HEIGHT,
            branch=branch,
            hash_prev_minor_block=bytes.fromhex(genesis.HASH_PREV_MINOR_BLOCK),
            hash_prev_root_block=root_block.header.get_hash(),
            evm_gas_limit=genesis.GAS_LIMIT,
            hash_meta=sha3_256(meta.serialize()),
            coinbase_amount_map=TokenBalanceMap(coinbase_tokens),
            coinbase_address=coinbase_address,
            create_time=genesis.TIMESTAMP,
            difficulty=genesis.DIFFICULTY,
            extra_data=bytes.fromhex(genesis.EXTRA_DATA),
        )
        return (
            MinorBlock(header=header, meta=meta, tx_list=[]),
            TokenBalanceMap(coinbase_tokens),
        )
Пример #23
0
def solidity_sha3(types: Iterable, values: Iterable):
    """
    returns 0x hex str
    """
    return "0x{}".format(sha3_256(solidity_pack(types, values)).hex())
Пример #24
0
 def get_hash(self):
     return sha3_256(self.serialize_without(["signature"]))
Пример #25
0
 def hash(self):
     return sha3_256(rlp.encode(self))
Пример #26
0
 def create_from_key(key):
     sk = ecdsa.SigningKey.from_string(key, curve=ecdsa.SECP256k1)
     recipient = sha3_256(sk.verifying_key.to_string())[-20:]
     return Identity(recipient, key)
Пример #27
0
 def test_bloom_bits_in_cstor(self):
     criteria = [[tp] for tp in self.log.topics]
     f = self.filter_gen_with_criteria(criteria)
     # use sha3(b'Hi(address)') to test bits
     expected_indexes = bits_in_number(bloom(sha3_256(b"Hi(address)")))
     self.assertEqual(expected_indexes, bits_in_number(f.bloom_bits[0][0]))
Пример #28
0
 def get_hash_unsigned(self):
     return sha3_256(self.serialize_unsigned())
Пример #29
0
 def create_random_identity():
     sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
     key = sk.to_string()
     recipient = sha3_256(sk.verifying_key.to_string())[-20:]
     return Identity(recipient, key)
Пример #30
0
(
    NODE_TYPE_BLANK,
    NODE_TYPE_LEAF,
    NODE_TYPE_EXTENSION,
    NODE_TYPE_BRANCH
) = tuple(range(4))


def is_key_value_type(node_type):
    return node_type in [NODE_TYPE_LEAF,
                         NODE_TYPE_EXTENSION]


BLANK_NODE = b''
BLANK_ROOT = utils.sha3_256(rlp.encode(b''))


class Trie(object):

    def __init__(self, db, root_hash=BLANK_ROOT):
        """it also present a dictionary like interface

        :param db key value database
        :root: blank or trie node in form of [key, value] or [v0,v1..v15,v]
        """
        self.db = db  # Pass in a database object directly
        self.set_root_hash(root_hash)
        self.deletes = []

    # def __init__(self, dbfile, root_hash=BLANK_ROOT):