def ss58_decode_account_index(address, valid_ss58_format=None, valid_address_type=None): """ Decodes given SS58 encoded address to an AccountIndex Parameters ---------- address valid_ss58_format valid_address_type Returns ------- Decoded int AccountIndex """ if valid_address_type is not None: warnings.warn( "Keyword 'valid_address_type' will be replaced by 'valid_ss58_format'", DeprecationWarning) valid_ss58_format = valid_address_type account_index_bytes = ss58_decode(address, valid_ss58_format) if len(account_index_bytes) == 2: return U8(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 4: return U16(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 8: return U32(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 16: return U64(ScaleBytes('0x{}'.format(account_index_bytes))).decode() else: raise ValueError("Invalid account index length")
def ss58_decode_account_index(address, valid_address_type=42): """ Decodes given SS58 encoded address to an AccountIndex Parameters ---------- address valid_address_type Returns ------- Decoded int AccountIndex """ account_index_bytes = ss58_decode(address, valid_address_type) if len(account_index_bytes) == 2: return U8(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 4: return U16(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 8: return U32(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 16: return U64(ScaleBytes('0x{}'.format(account_index_bytes))).decode() else: raise ValueError("Invalid account index length")
def ss58_decode_account_index(address, valid_address_type=None): account_index_bytes = ss58_decode(address, valid_address_type) if len(account_index_bytes) == 2: return U8(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 4: return U16(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 8: return U32(ScaleBytes('0x{}'.format(account_index_bytes))).decode() if len(account_index_bytes) == 16: return U64(ScaleBytes('0x{}'.format(account_index_bytes))).decode() else: raise ValueError("Invalid account index length")
def _get_address_info(self, address: str) -> dict: """ Returns information associated with provided address """ # Storage key: # xxHash128(System) + xxHash128(Account) storage_key = ( "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9" ) account_id = ss58_decode(address, valid_ss58_format=self.address_type) hashed_address = f"{blake2b(bytes.fromhex(account_id), digest_size=16).digest().hex()}{account_id}" storage_hash = storage_key + hashed_address result = self.network.node_rpc_call("state_getStorageAt", [storage_hash, None])["result"] if not result: return { "nonce": 0, "refcount": 0, "data": { "free": 0, "reserved": 0, "miscFrozen": 0, "feeFrozen": 0 }, } return_decoder = ScaleDecoder.get_decoder_class( "AccountInfo<Index, AccountData>", ScaleBytes(result), metadata=self.metadata, runtime_config=self.runtime_config, ) return return_decoder.decode()
def setUpClass(cls): metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v10_hex)) metadata_decoder.decode() cls.substrate = SubstrateInterface(url='dummy', address_type=2, type_registry_preset='kusama') cls.substrate.get_block_metadata = MagicMock(return_value=metadata_decoder)
def generate_constructor_data(self, name, args: dict = None) -> ScaleBytes: """ Compose the data field used in the "Contracts.instantiate" call, finding the selectors and encoded the args of given constructor Parameters ---------- name args Returns ------- ScaleBytes """ if not args: args = {} for constructor in self.metadata_dict['spec']['constructors']: if name in constructor['name']: data = ScaleBytes(constructor['selector']) for arg in constructor['args']: if arg['name'] not in args: raise ValueError(f"Argument \"{arg['name']}\" is missing") else: data += self.substrate.encode_scale( type_string=self.get_type_string_for_metadata_type(arg['type']['type']), value=args[arg['name']] ) return data raise ValueError(f'Constructor "{name}" not found')
def generate_message_data(self, name, args: dict = None) -> ScaleBytes: """ Compose the data field used in the "Contracts.call" call, finding the selector and encoded the args of provided message name Parameters ---------- name: name of message in contract args: arguments required by message, in format: `{'name': value}` Returns ------- ScaleBytes """ if not args: args = {} for message in self.metadata_dict['spec']['messages']: if name in message['name']: data = ScaleBytes(message['selector']) for arg in message['args']: if arg['name'] not in args: raise ValueError(f"Argument \"{arg['name']}\" is missing") else: data += self.substrate.encode_scale( type_string=self.get_type_string_for_metadata_type(arg['type']['type']), value=args[arg['name']] ) return data raise ValueError(f'Message "{name}" not found')
def diagnose(self, escrow_address: str) -> dict: """ Returns details of all unfinished multisigs from an address """ response = {} prefix = f"0x{helper.get_prefix(escrow_address, self.address_type)}" getkeys_response = self.network.node_rpc_call("state_getKeys", [prefix]) if not getkeys_response.get("result", False): response["status"] = "error getting unfinished escrows" response["details"] = getkeys_response return response for item in getkeys_response["result"]: storage_result = self.network.node_rpc_call( "state_getStorage", [item])["result"] return_decoder = ScaleDecoder.get_decoder_class( "Multisig<BlockNumber, BalanceOf, AccountId>", ScaleBytes(storage_result), metadata=self.metadata, runtime_config=self.runtime_config, ) response[item[178:]] = return_decoder.decode() response["status"] = "unfinised escrows found" return response
async def test_plaintype_call(self): def mocked_request(method, params): if method == 'chain_getRuntimeVersion': return { "jsonrpc": "2.0", "result": { "specVersion": 2023 }, "id": 1 } if method == 'state_getStorageAt': return { "jsonrpc": "2.0", "result": '0x0800000000000000482d7c0900000000020000000100000000000000000000000000020000', "id": 1 } metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v12_hex)) metadata_decoder.decode() self.substrate.get_block_metadata = MagicMock( return_value=metadata_decoder) self.substrate.rpc_request = MagicMock(side_effect=mocked_request) response = await self.substrate.get_runtime_state( module='System', storage_function='Events') self.assertEqual(len(response['result']), 2) self.assertEqual(response['result'][0]['module_id'], 'System') self.assertEqual(response['result'][0]['event_id'], 'ExtrinsicSuccess') self.assertEqual(response['result'][1]['module_id'], 'System') self.assertEqual(response['result'][1]['event_id'], 'ExtrinsicSuccess')
def sync_block_account_id(self): db_session = self.session blocks = Block.query(db_session).filter( Block.account_index.is_(None)).all() for block in blocks: log = Log.query(db_session).filter(Log.block_id == block.id).filter( Log.type == 'PreRuntime').first() if log: data = log.data.get("value").get("data") if data: if data[0:2] != "01" and data[0:2] != "00": continue res = RawBabePreDigest(ScaleBytes("0x{}".format(data))) if data[0:2] == "01" and len(data) == 34: res.decode() block.account_index = res.value.get("Secondary").get( "authorityIndex") elif data[0:2] == "00": res.decode(check_remaining=False) block.account_index = res.value.get("Primary").get( "authorityIndex") else: raise "error log data ".format(data) block.save(db_session) print("...................", block.id, block.account_index) else: print("...................", "Blocks not found") db_session.commit()
def test_iterate_map(self): def mocked_request(method, params): if method == 'chain_getRuntimeVersion': return { "jsonrpc": "2.0", "result": {"specVersion": 2023}, "id": 1 } elif method == 'state_getPairs': return { "jsonrpc": "2.0", "result": [ ['0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f', '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d'] ], "id": 1 } self.substrate.rpc_request = MagicMock(side_effect=mocked_request) metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v12_hex)) metadata_decoder.decode() self.substrate.get_block_metadata = MagicMock(return_value=metadata_decoder) all_bonded_stash_ctrls = self.substrate.iterate_map( module='Staking', storage_function='Bonded', block_hash='0x7d56e0ff8d3c57f77ea6a1eeef1cd2c0157a7b24d5a1af0f802ca242617922bf' ) self.assertEqual(all_bonded_stash_ctrls, [[ '0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f', '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' ]])
def get_storage(self, block_hash, module, function, params=None, return_scale_type=None, hasher=None, spec_version_id='default', metadata=None): """ Retrieves the storage for given given module, function and optional paramaters at given block :param metadata: :param spec_version_id: :param hasher: Hashing method used to determine storage key, defaults to 'Twox64Concat' if not provided :param return_scale_type: Scale type string to interprete result :param block_hash: :param module: :param function: :param params: :return: """ storage_hash = self.generate_storage_hash(module, function, params, hasher) response = self.__rpc_request("state_getStorageAt", [storage_hash, block_hash]) if 'result' in response: if return_scale_type and response.get('result'): obj = ScaleDecoder.get_decoder_class( return_scale_type, ScaleBytes(response.get('result')), metadata=metadata ) return obj.decode() else: return response.get('result') else: raise SubstrateRequestException("Error occurred during retrieval of events")
def get_events(self, block_hash: str) -> list: """ Returns events broadcasted within the provided block """ # Storage key: # xxHash128(System) + xxHash128(Events) storage_hash = ( "0x26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7" ) system_pallet = [ p for p in self.metadata.pallets if p["name"] == "System" ][0] event_storage_function = [ s for s in system_pallet["storage"]["entries"] if s["name"] == "Events" ][0] result = self.network.node_rpc_call( "state_getStorageAt", [storage_hash, block_hash])["result"] return_decoder = self.runtime_config.create_scale_object( event_storage_function.get_value_type_string(), ScaleBytes(result), metadata=self.metadata, ) return return_decoder.decode()
def setUpClass(cls): cls.kusama_substrate = SubstrateInterface( url=settings.KUSAMA_NODE_URL, ss58_format=2, type_registry_preset='kusama') cls.polkadot_substrate = SubstrateInterface( url=settings.POLKADOT_NODE_URL, ss58_format=0, type_registry_preset='polkadot') cls.substrate_v13 = SubstrateInterface(url=settings.POLKADOT_NODE_URL, ss58_format=0, type_registry_preset='polkadot') module_path = os.path.dirname(__file__) cls.metadata_fixture_dict = load_type_registry_file( os.path.join(module_path, 'fixtures', 'metadata_hex.json')) cls.metadata_v13_obj = cls.substrate_v13.runtime_config.create_scale_object( 'MetadataVersioned', data=ScaleBytes(cls.metadata_fixture_dict['V13'])) cls.metadata_v13_obj.decode() cls.substrate_v13.init_runtime() cls.substrate_v13.metadata_decoder = cls.metadata_v13_obj # Create new keypair mnemonic = Keypair.generate_mnemonic() cls.keypair = Keypair.create_from_mnemonic(mnemonic)
def test_get_contract_event_type(self): contract_metadata = ContractMetadata.create_from_file( metadata_file=os.path.join(os.path.dirname(__file__), 'constracts', 'ink', 'erc20.json'), substrate=self.substrate ) typ14 = contract_metadata.get_type_string_for_metadata_type(14) logging.debug("typ15 {}".format(typ14)) decoder = ScaleDecoder.get_decoder_class(typ14, ScaleBytes("0x01d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"), self.substrate.runtime_config) evtTransferArgs = decoder.decode() logging.debug("evtTransfer {}".format(evtTransferArgs)) self.assertEqual(evtTransferArgs, '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY') type_data = get_contract_event_type(contract_metadata) logging.debug("type_event_data {}".format(type_data)) decoder = ScaleDecoder.get_decoder_class(type_data, ScaleBytes("0x000001d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0000a0dec5adc9353600000000000000"), self.substrate.runtime_config) evtTransfer1 = decoder.decode() self.assertEqual(evtTransfer1['Transfer']['from'], None) self.assertEqual(evtTransfer1['Transfer']['to'], '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY') self.assertEqual(evtTransfer1['Transfer']['value'], 1000000000000000000000) logging.debug("evtTransfer {}".format(evtTransfer1)) decoder = ScaleDecoder.get_decoder_class(type_data, ScaleBytes("0x0001d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d018eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4810270000000000000000000000000000"), self.substrate.runtime_config) evtTransfer2 = decoder.decode() self.assertEqual(evtTransfer2['Transfer']['from'], '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY') self.assertEqual(evtTransfer2['Transfer']['to'], '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty') self.assertEqual(evtTransfer2['Transfer']['value'], 10000) logging.debug("evtTransfer2 {}".format(evtTransfer2)) decoder = ScaleDecoder.get_decoder_class(type_data, ScaleBytes("0x01d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a4810270000000000000000000000000000"), self.substrate.runtime_config) evtApprove1 = decoder.decode() self.assertEqual(evtApprove1['Approval']['owner'], '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY') self.assertEqual(evtApprove1['Approval']['spender'], '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty') self.assertEqual(evtApprove1['Approval']['value'], 10000) logging.debug("evtApprove1 {}".format(evtApprove1))
def test_sign_and_verify_scale_bytes(self): mnemonic = Keypair.generate_mnemonic() keypair = Keypair.create_from_mnemonic(mnemonic) data = ScaleBytes('0x1234') signature = keypair.sign(data) self.assertTrue(keypair.verify(data, signature))
def test_maptype_call(self): def mocked_request(method, params): if method == 'chain_getRuntimeVersion': return { "jsonrpc": "2.0", "result": { "specVersion": 2023 }, "id": 1 } elif method == 'state_getStorageAt': return { 'jsonrpc': '2.0', 'result': '0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000', 'id': 1 } elif method == 'chain_getHeader': return { "jsonrpc": "2.0", "result": { "digest": { "logs": [] }, "extrinsicsRoot": "0xa94148d938c7b7976abf4272dca95724d7a74da2f3649ec0bd53dc3daaedda44", "number": "0x4abaaa", "parentHash": "0xe1781813275653a970b4260298b3858b36d38e072256dad674f7c786a0cae236", "stateRoot": "0xb6aa468385c82d15b343a676b3488d9f141ac100fc548bb8a546f27a7241c44a" }, "id": 1 } self.substrate.rpc_request = MagicMock(side_effect=mocked_request) metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v12_hex)) metadata_decoder.decode() self.substrate.get_block_metadata = MagicMock( return_value=metadata_decoder) result = self.substrate.query( module='System', storage_function='Account', params=['5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY']) self.assertEqual( result.value, { 'data': { 'feeFrozen': 10000000000000000, 'free': 10000000000000000, 'miscFrozen': 10000000000000000, 'reserved': 0 }, 'nonce': 0, 'refcount': 3 })
def test_iterate_map(self): def mocked_request(method, params): if method == 'chain_getRuntimeVersion': return { "jsonrpc": "2.0", "result": { "specVersion": 2023 }, "id": 1 } elif method == 'state_getPairs': return { "jsonrpc": "2.0", "result": [[ '0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70e535263148daaf49be5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f', '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' ]], "id": 1 } elif method == 'chain_getHeader': return { "jsonrpc": "2.0", "result": { "digest": { "logs": [] }, "extrinsicsRoot": "0xa94148d938c7b7976abf4272dca95724d7a74da2f3649ec0bd53dc3daaedda44", "number": "0x4abaaa", "parentHash": "0xe1781813275653a970b4260298b3858b36d38e072256dad674f7c786a0cae236", "stateRoot": "0xb6aa468385c82d15b343a676b3488d9f141ac100fc548bb8a546f27a7241c44a" }, "id": 1 } self.substrate.rpc_request = MagicMock(side_effect=mocked_request) metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v12_hex)) metadata_decoder.decode() self.substrate.get_block_metadata = MagicMock( return_value=metadata_decoder) all_bonded_stash_ctrls = self.substrate.iterate_map( module='Staking', storage_function='Bonded', block_hash= '0x7d56e0ff8d3c57f77ea6a1eeef1cd2c0157a7b24d5a1af0f802ca242617922bf' ) self.assertEqual(all_bonded_stash_ctrls, [[ '0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f', '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' ]])
def setUpClass(cls): RuntimeConfiguration().update_type_registry( load_type_registry_preset("default")) metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v10_hex)) metadata_decoder.decode() cls.substrate = SubstrateInterface(url='dummy', address_type=2) cls.substrate.get_block_metadata = MagicMock( return_value=metadata_decoder)
def get_metadata(self): """ Returns decoded chain metadata """ raw_metadata = self.network.node_rpc_call("state_getMetadata", [None])["result"] self.raw_metadata = raw_metadata metadata = self.runtime_config.create_scale_object( "MetadataVersioned", data=ScaleBytes(raw_metadata)) metadata.decode() self.runtime_config.add_portable_registry(metadata) return metadata
def test_plaintype_call(self): def mocked_request(method, params): if method == 'chain_getRuntimeVersion': return { "jsonrpc": "2.0", "result": { "specVersion": 2023 }, "id": 1 } elif method == 'state_getStorageAt': return { "jsonrpc": "2.0", "result": '0x0800000000000000482d7c0900000000020000000100000000000000000000000000020000', "id": 1 } elif method == 'chain_getHeader': return { "jsonrpc": "2.0", "result": { "digest": { "logs": [] }, "extrinsicsRoot": "0xa94148d938c7b7976abf4272dca95724d7a74da2f3649ec0bd53dc3daaedda44", "number": "0x4abaaa", "parentHash": "0xe1781813275653a970b4260298b3858b36d38e072256dad674f7c786a0cae236", "stateRoot": "0xb6aa468385c82d15b343a676b3488d9f141ac100fc548bb8a546f27a7241c44a" }, "id": 1 } metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v12_hex)) metadata_decoder.decode() self.substrate.get_block_metadata = MagicMock( return_value=metadata_decoder) self.substrate.rpc_request = MagicMock(side_effect=mocked_request) result = self.substrate.query(module='System', storage_function='Events') self.assertEqual(len(result.value), 2) self.assertEqual(result.value[0]['module_id'], 'System') self.assertEqual(result.value[0]['event_id'], 'ExtrinsicSuccess') self.assertEqual(result.value[1]['module_id'], 'System') self.assertEqual(result.value[1]['event_id'], 'ExtrinsicSuccess')
def get_block_metadata(self, block_hash, decode=True): response = self.__rpc_request("state_getMetadata", [block_hash]) if response.get('result'): if decode: metadata_decoder = MetadataDecoder(ScaleBytes(response.get('result'))) metadata_decoder.decode() return metadata_decoder return response else: raise SubstrateRequestException("Error occurred during retrieval of metadata")
def setUpClass(cls): cls.substrate = SubstrateInterface(url='dummy', ss58_format=42, type_registry_preset='kusama') metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v12_hex)) metadata_decoder.decode() cls.substrate.get_block_metadata = MagicMock(return_value=metadata_decoder) def mocked_request(method, params): if method == 'chain_getRuntimeVersion': return { "jsonrpc": "2.0", "result": {"specVersion": 2023}, "id": 1 } elif method == 'chain_getHeader': return { "jsonrpc": "2.0", "result": { "digest": { "logs": [ ] }, "extrinsicsRoot": "0xa94148d938c7b7976abf4272dca95724d7a74da2f3649ec0bd53dc3daaedda44", "number": "0x4abaaa", "parentHash": "0xe1781813275653a970b4260298b3858b36d38e072256dad674f7c786a0cae236", "stateRoot": "0xb6aa468385c82d15b343a676b3488d9f141ac100fc548bb8a546f27a7241c44a" }, "id": 1 } cls.substrate.rpc_request = MagicMock(side_effect=mocked_request) cls.empty_substrate = SubstrateInterface(url='dummy', ss58_format=42, type_registry_preset='kusama') def mocked_request(method, params): return {'jsonrpc': '2.0', 'result': None, 'id': 1} cls.empty_substrate.rpc_request = MagicMock(side_effect=mocked_request) cls.error_substrate = SubstrateInterface(url='dummy', ss58_format=42, type_registry_preset='kusama') def mocked_request(method, params): return {'jsonrpc': '2.0', 'error': { 'code': -32602, 'message': 'Generic error message' }, 'id': 1} cls.error_substrate.rpc_request = MagicMock(side_effect=mocked_request)
def test_contract_event_decoding(self): contract_event_data = '0x0001d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d018eaf04151687' + \ '736326c9fea17e25fc5287613693c912909cb226aa4794f26a480000a7dcf75015000000000000000000' contract_event_obj = ContractEvent( data=ScaleBytes(contract_event_data), runtime_config=self.substrate.runtime_config, contract_metadata=self.contract_metadata) contract_event_obj.decode() self.assertEqual('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', ss58_encode(contract_event_obj.args[0]['value'], 42)) self.assertEqual('5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty', ss58_encode(contract_event_obj.args[1]['value'], 42)) self.assertEqual(6000000000000000, contract_event_obj.args[2]['value'])
def get_pending_extrinsics(self) -> list: """ Returns decoded pending extrinsics """ decoded_extrinsics = [] extrinsics = self.network.node_rpc_call("author_pendingExtrinsics", [])["result"] for idx, data in enumerate(extrinsics): extrinsic = Extrinsic( data=ScaleBytes(data), metadata=self.metadata, runtime_config=self.runtime_config, ) decoded_extrinsics.append(extrinsic.decode()) return decoded_extrinsics
def get_chain_block(self, block_hash=None, block_id=None, metadata_decoder=None): if block_id: block_hash = self.get_block_hash(block_hash) response = self.__rpc_request("chain_getBlock", [block_hash]).get('result') # Decode extrinsics if metadata_decoder: for idx, extrinsic_data in enumerate(response['block']['extrinsics']): extrinsic_decoder = ExtrinsicsDecoder( data=ScaleBytes(extrinsic_data), metadata=metadata_decoder ) extrinsic_decoder.decode() response['block']['extrinsics'][idx] = extrinsic_decoder return response
def get_block(self, block_hash: str) -> dict: """ Returns the block information associated with provided block hash """ response = self.network.node_rpc_call("chain_getBlock", [block_hash])["result"] response["block"]["header"]["number"] = int( response["block"]["header"]["number"], 16) for idx, data in enumerate(response["block"]["extrinsics"]): extrinsics_decoder = Extrinsic( data=ScaleBytes(data), metadata=self.metadata, runtime_config=self.runtime_config, ) response["block"]["extrinsics"][idx] = extrinsics_decoder.decode() return response
def process_events(self): super().process_events() if self.triggered_events: self.__contract_events = [] for event in self.triggered_events: if event.event_module.name == 'Contracts' and event.event.name == 'ContractExecution': # Create contract event contract_event_obj = ContractEvent( data=ScaleBytes(event.params[1]['value']), runtime_config=self.substrate.runtime_config, contract_metadata=self.contract_metadata) contract_event_obj.decode() self.__contract_events.append(contract_event_obj)
def setUpClass(cls): cls.substrate = SubstrateWSInterface(address_type=42, type_registry_preset='kusama') metadata_decoder = MetadataDecoder(ScaleBytes(metadata_v12_hex)) metadata_decoder.decode() cls.substrate.get_block_metadata = MagicMock( return_value=metadata_decoder) def mocked_request(method, params): if method == 'chain_getRuntimeVersion': return { "jsonrpc": "2.0", "result": { "specVersion": 2023 }, "id": 1 } cls.substrate.rpc_request = MagicMock(side_effect=mocked_request)
def get_block_events(self, block_hash, metadata_decoder=None): response = self.__rpc_request("state_getStorageAt", [STORAGE_HASH_SYSTEM_EVENTS, block_hash]) if response.get('result'): if metadata_decoder: # Process events events_decoder = EventsDecoder( data=ScaleBytes(response.get('result')), metadata=metadata_decoder ) events_decoder.decode() return events_decoder else: return response else: raise SubstrateRequestException("Error occurred during retrieval of events")