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", )
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"))
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 )
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
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), )
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
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)
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)
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")
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
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
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=[])
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)
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))
def hash_unsigned(self): return sha3_256( rlp.encode(unsigned_tx_from_tx(self), UnsignedTransaction))
def sha3(seed): return sha3_256(seed)
def hash_unsigned(self): return sha3_256(rlp.encode(self, UnsignedTransaction))
def get_hash_for_mining(self): return sha3_256(self.serialize_without(["nonce", "mixhash"]))
def get_hash(self): return sha3_256(self.serialize())
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
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), )
def solidity_sha3(types: Iterable, values: Iterable): """ returns 0x hex str """ return "0x{}".format(sha3_256(solidity_pack(types, values)).hex())
def get_hash(self): return sha3_256(self.serialize_without(["signature"]))
def hash(self): return sha3_256(rlp.encode(self))
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)
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]))
def get_hash_unsigned(self): return sha3_256(self.serialize_unsigned())
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)
( 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):