def serialize_formatting_hook(self, obj_dict): if self.account: obj_dict['attributes']['account'] = self.account.serialize() if obj_dict['attributes'].get('address'): obj_dict['attributes']['address_id'] = obj_dict['attributes']['address'].replace('0x', '') obj_dict['attributes']['address'] = ss58_encode(obj_dict['attributes']['address'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) for item in obj_dict['attributes'].get('params', []): # SS58 format Addresses public keys if item['type'] in ['Address', 'AccountId'] and item['value']: self.format_address(item) elif item['type'] in ['Vec<Address>', 'Vec<AccountId>', 'Vec<<Lookup as StaticLookup>::Source>'] and item['value']: for idx, vec_item in enumerate(item['value']): item['value'][idx] = { 'name': idx, 'type': 'Address', 'value': ss58_encode(vec_item.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE), 'orig_value': vec_item.replace('0x', '') } elif item['type'] == 'Box<Proposal>': for proposal_param in item['value'].get('call_args', []): if proposal_param['type'] == 'Address': self.format_address(proposal_param) return obj_dict
def serialize_item(self, item): return { 'type': 'balancetransfer', 'id': '{}-{}'.format(item.block_id, item.event_idx), 'attributes': { 'block_id': item.block_id, 'event_idx': '{}-{}'.format(item.block_id, item.event_idx), 'sender': ss58_encode(item.attributes[0]['value'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE), 'sender_id': item.attributes[0]['value'].replace('0x', ''), 'destination': ss58_encode(item.attributes[1]['value'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE), 'destination_id': item.attributes[1]['value'].replace('0x', ''), 'value': item.attributes[2]['value'], 'fee': item.attributes[3]['value'] } }
def serialize_item(self, item): return { 'type': 'balancetransfer', 'id': item.extrinsic_hash, 'attributes': { 'block_id': item.block_id, 'extrinsic_hash': item.extrinsic_hash, 'extrinsic_idx': item.extrinsic_idx, 'sender': ss58_encode(item.address, SUBSTRATE_ADDRESS_TYPE), 'sender_id': item.address, 'destination': ss58_encode(item.params[0]['value'], SUBSTRATE_ADDRESS_TYPE), 'destination_id': item.params[0]['value'].replace('0x', ''), 'value': item.params[1]['value'], 'success': item.success, 'error': item.error, } }
def serialize_formatting_hook(self, obj_dict): if self.validator_stash_account: obj_dict['attributes'][ 'validator_stash_account'] = self.validator_stash_account.serialize( ) obj_dict['attributes']['validator_stash_id'] = self.validator_stash if self.validator_stash: obj_dict['attributes']['validator_stash'] = ss58_encode( self.validator_stash.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) else: obj_dict['attributes']['validator_stash'] = None obj_dict['attributes'][ 'validator_controller_id'] = self.validator_controller if self.validator_controller: obj_dict['attributes']['validator_controller'] = ss58_encode( self.validator_controller.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) else: obj_dict['attributes']['validator_controller'] = None obj_dict['attributes']['validator_session_id'] = self.validator_session if self.validator_session: obj_dict['attributes']['validator_session'] = ss58_encode( self.validator_session.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) else: obj_dict['attributes']['validator_session'] = None return obj_dict
def serialize_formatting_hook(self, obj_dict): if self.nominator_stash_account: obj_dict['attributes'][ 'nominator_stash_account'] = self.nominator_stash_account.serialize( ) else: obj_dict['attributes']['nominator_stash_account'] = { 'type': 'account', 'id': self.nominator_stash.replace('0x', ''), 'attributes': { 'id': self.nominator_stash.replace('0x', ''), 'address': ss58_encode(self.nominator_stash.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) } } if self.nominator_controller: obj_dict['attributes'][ 'nominator_controller_id'] = self.nominator_controller obj_dict['attributes']['nominator_controller'] = ss58_encode( self.nominator_controller.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) return obj_dict
def serialize_formatting_hook(self, obj_dict): for item in obj_dict['attributes']['attributes']: if item['type'] in ['AccountId', 'AuthorityId', 'Address' ] and item['value']: # SS58 format AccountId public keys item['orig_value'] = item['value'].replace('0x', '') item['value'] = ss58_encode(item['value'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) elif item['type'] in ['AccountIndex'] and item['value']: # SS58 format Account index item['orig_value'] = item['value'] item['value'] = ss58_encode_account_index( item['value'], SUBSTRATE_ADDRESS_TYPE) elif item['type'] in ['AuthorityList'] and item['value']: for idx, vec_item in enumerate(item['value']): item['value'][idx]['AuthorityId'] = { 'name': 'AuthorityId', 'type': 'Address', 'value': ss58_encode(vec_item['AuthorityId'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE), 'orig_value': vec_item['AuthorityId'].replace('0x', '') } elif item['type'] == 'Vec<IdentificationTuple>': for idx, vec_item in enumerate(item['value']): item['value'][idx]['validatorId'] = { 'name': 'validatorId', 'type': 'Address', 'value': ss58_encode(vec_item['validatorId'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE), 'orig_value': vec_item['validatorId'].replace('0x', '') } for other_idx, other_item in enumerate( vec_item['exposure']['others']): item['value'][idx]['exposure']['others'][other_idx][ 'who'] = { 'name': 'validatorId', 'type': 'Address', 'value': ss58_encode( other_item['who'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE), 'orig_value': other_item['who'].replace('0x', '') } return obj_dict
def serialize_item(self, item): sender = Account.query(self.session).get( item.attributes[0]['value'].replace('0x', '')) if sender: sender_data = sender.serialize() else: sender_data = { 'type': 'account', 'id': item.attributes[0]['value'].replace('0x', ''), 'attributes': { 'id': item.attributes[0]['value'].replace('0x', ''), 'address': ss58_encode(item.attributes[0]['value'].replace('0x', ''), settings.SUBSTRATE_ADDRESS_TYPE) } } destination = Account.query(self.session).get( item.attributes[1]['value'].replace('0x', '')) if destination: destination_data = destination.serialize() else: destination_data = { 'type': 'account', 'id': item.attributes[1]['value'].replace('0x', ''), 'attributes': { 'id': item.attributes[1]['value'].replace('0x', ''), 'address': ss58_encode(item.attributes[1]['value'].replace('0x', ''), settings.SUBSTRATE_ADDRESS_TYPE) } } # Some networks don't have fees if len(item.attributes) == 4: fee = item.attributes[3]['value'] else: fee = 0 return { 'type': 'balancetransfer', 'id': '{}-{}'.format(item.block_id, item.event_idx), 'attributes': { 'block_id': item.block_id, 'event_idx': '{}-{}'.format(item.block_id, item.event_idx), 'sender': sender_data, 'destination': destination_data, 'value': item.attributes[2]['value'], 'fee': fee } }
def serialize_formatting_hook(self, obj_dict): obj_dict['attributes']['nominator_stash_id'] = self.nominator_stash obj_dict['attributes']['nominator_stash'] = ss58_encode(self.nominator_stash.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) if self.nominator_controller: obj_dict['attributes']['nominator_controller_id'] = self.nominator_controller obj_dict['attributes']['nominator_controller'] = ss58_encode(self.nominator_controller.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) return obj_dict
def serialize_formatting_hook(self, obj_dict): obj_dict['attributes']['proposed_by_address'] = ss58_encode( self.proposed_by_account_id.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE ) obj_dict['attributes']['beneficiary_address'] = ss58_encode( self.beneficiary_account_id.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE ) return obj_dict
def on_get(self, req, resp): resp.status = falcon.HTTP_200 page = int(req.params.get('page') if req.params.get('page') else 1) pageSize = int( req.params.get('page_size') if req.params.get('page_size') else 10) extrinsics = Extrinsic.latest_extrinsics(self.session, page, pageSize) result = [] for extrinsic in extrinsics: extrinsicId = '{}-{}'.format(extrinsic.block_id, extrinsic.extrinsic_idx) fromAddr = ss58_encode(extrinsic.address.replace('0x', '')) hash = "0x{}".format(extrinsic.extrinsic_hash) timestamp = extrinsic.datetime.strftime( "%Y-%m-%d %H:%M:%S" ) if extrinsic.datetime is not None else None blockId = extrinsic.block_id success = extrinsic.success # print(extrinsic); # timestamp = time.mktime(extrinsic.datetime.timetuple()) params = json.loads(extrinsic.params) for param in params: name = param.get('name') if name == 'dest': toAddr = ss58_encode(param.get('value').replace('0x', '')) elif name == 'value': coin = param.get('value') / 1000000000000000 # 转换为单位 Unit result.append({ "extrinsic_id": extrinsicId, "block_id": blockId, "from": fromAddr, "to": toAddr, "hash": hash, "timestamp": timestamp, "coin": coin, "result": success }) count = Extrinsic.query(self.session).filter( and_(Extrinsic.module_id == "balances", Extrinsic.call_id == "transfer")).count() resp.media = { 'status': 'success', 'data': { "result": result, "count": count } }
def sequencing_hook(self, db_session, parent_block_data, parent_sequenced_block_data): for account_audit in AccountAudit.query(db_session).filter_by(block_id=self.block.id).order_by('event_idx'): try: account = Account.query(db_session).filter_by(id=account_audit.account_id).one() if account_audit.type_id == ACCOUNT_AUDIT_TYPE_REAPED: account.count_reaped += 1 account.is_reaped = True elif account_audit.type_id == ACCOUNT_AUDIT_TYPE_NEW: account.is_reaped = False account.updated_at_block = self.block.id except NoResultFound: account = Account( id=account_audit.account_id, address=ss58_encode(account_audit.account_id, SUBSTRATE_ADDRESS_TYPE), created_at_block=self.block.id, updated_at_block=self.block.id, balance=0 ) # If reaped but does not exist, create new account for now if account_audit.type_id != ACCOUNT_AUDIT_TYPE_NEW: account.is_reaped = True account.count_reaped = 1 account.save(db_session)
def serialize_formatting_hook(self, obj_dict): if self.author: obj_dict['attributes']['author_id'] = self.author obj_dict['attributes']['author'] = ss58_encode(self.author.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) return obj_dict
def serialize_formatting_hook(self, obj_dict): obj_dict['attributes']['account_id'] = self.account_id if self.account_id: obj_dict['attributes']['address'] = ss58_encode(self.account_id.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) else: obj_dict['attributes']['address'] = None return obj_dict
def serialize_formatting_hook(self, obj_dict): if self.type_id == LOG_TYPE_AUTHORITIESCHANGE: for idx, item in enumerate(obj_dict['attributes']['data']['value']): obj_dict['attributes']['data']['value'][idx] = ss58_encode(item.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) return obj_dict
def serialize_item(self, item): return { 'type': 'transfer', 'id': '{}-{}'.format(item.block_id, item.event_idx), 'attributes': { 'block_id': item.block_id, 'event_idx': item.event_idx, 'extrinsic_idx': item.extrinsic_idx, 'from_account_id': item.from_account_id, 'from_address': ss58_encode(item.from_account_id, SUBSTRATE_ADDRESS_TYPE), 'to_account_id': item.to_account_id, 'to_address': ss58_encode(item.to_account_id, SUBSTRATE_ADDRESS_TYPE), 'balance': float(item.balance), 'from_did': item.from_did, 'to_did': item.to_did, 'fee': float(item.fee), 'datetime': item.datetime.isoformat() } }
def serialize_formatting_hook(self, obj_dict): for item in obj_dict['attributes']['attributes']: if item['type'] in ['AccountId', 'AuthorityId', 'Address'] and item['value']: # SS58 format AccountId public keys item['orig_value'] = item['value'].replace('0x', '') item['value'] = ss58_encode(item['value'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) elif item['type'] in ['AccountIndex'] and item['value']: # SS58 format Account index item['orig_value'] = item['value'] item['value'] = ss58_encode_account_index(item['value'], SUBSTRATE_ADDRESS_TYPE) return obj_dict
def serialize_formatting_hook(self, obj_dict): if obj_dict['attributes'].get('address'): obj_dict['attributes']['address_id'] = obj_dict['attributes']['address'].replace('0x', '') obj_dict['attributes']['address'] = ss58_encode(obj_dict['attributes']['address'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) for item in obj_dict['attributes']['params']: # SS58 format Addresses public keys if item['type'] in ['Address', 'AccountId'] and item['value']: self.format_address(item) if item['type'] == 'Box<Proposal>': for proposal_param in item['value'].get('params', []): if proposal_param['type'] == 'Address': self.format_address(proposal_param) return obj_dict
def sequencing_hook(self, db_session, parent_block_data, parent_sequenced_block_data): for account_audit in AccountAudit.query(db_session).filter_by( block_id=self.block.id).order_by('event_idx'): try: account = Account.query(db_session).filter_by( id=account_audit.account_id).one() if account_audit.type_id == ACCOUNT_AUDIT_TYPE_REAPED: account.count_reaped += 1 account.is_reaped = True elif account_audit.type_id == ACCOUNT_AUDIT_TYPE_NEW: account.is_reaped = False account.updated_at_block = self.block.id except NoResultFound: account = Account(id=account_audit.account_id, address=ss58_encode(account_audit.account_id, SUBSTRATE_ADDRESS_TYPE), hash_blake2b=blake2_256( binascii.unhexlify( account_audit.account_id)), created_at_block=self.block.id, updated_at_block=self.block.id, balance=0) # Retrieve index in corresponding account account_index = AccountIndex.query(db_session).filter_by( account_id=account.id).first() if account_index: account.index_address = account_index.short_address account.save(db_session) # # If reaped but does not exist, create new account for now # if account_audit.type_id != ACCOUNT_AUDIT_TYPE_NEW: # account.is_reaped = True # account.count_reaped = 1 account.save(db_session)
def sequencing_hook(self, db_session, parent_block_data, parent_sequenced_block_data): for account_audit in AccountAudit.query(db_session).filter_by(block_id=self.block.id).order_by('event_idx'): try: account = Account.query(db_session).filter_by(id=account_audit.account_id).one() if account_audit.type_id == ACCOUNT_AUDIT_TYPE_REAPED: account.count_reaped += 1 account.is_reaped = True elif account_audit.type_id == ACCOUNT_AUDIT_TYPE_NEW: account.is_reaped = False account.updated_at_block = self.block.id except NoResultFound: account = Account( id=account_audit.account_id, address=ss58_encode(account_audit.account_id, SUBSTRATE_ADDRESS_TYPE), created_at_block=self.block.id, updated_at_block=self.block.id, balance=0 ) ### account balance substrate = SubstrateInterface(SUBSTRATE_RPC_URL) balance = substrate.get_storage( block_hash=None, module='Balances', function='FreeBalance', params=account_audit.account_id, return_scale_type='Balance', hasher='Blake2_256') or 0 account.balance = balance # If reaped but does not exist, create new account for now if account_audit.type_id != ACCOUNT_AUDIT_TYPE_NEW: account.is_reaped = True account.count_reaped = 1 account.save(db_session)
def on_get(self, req, resp): page = int(req.params.get('page') if req.params.get('page') else 1) pageSize = int( req.params.get('page_size') if req.params.get('page_size') else 20) # blocks = Block.query(self.session).order_by(Block.id.desc()).limit(pageSize).offset((page - 1) * pageSize).all() blocks = Block.latest_blocks(self.session, page, pageSize) resp.status = falcon.HTTP_200 result = [ { "block_num": blockData.id, "event_count": blockData.count_events, "extrinsics_count": blockData.count_extrinsics, "block_timestamp": blockData.datetime.strftime("%Y-%m-%d %H:%M:%S"), "block_hash": blockData.hash, "author": ss58_encode(blockData.author.replace('0x', '')) if blockData.author is not None else None, # "block_timestamp": time.mktime(blockData.datetime.timetuple()), "finalized": "1" if blockData.author is not None else None, } for blockData in blocks ] count = Block.query(self.session).count() resp.media = { 'status': 'success', 'data': { 'result': result, 'count': count } }
def serialize_formatting_hook(self, obj_dict): obj_dict["attributes"]["address"] = ss58_encode( self.account_id, SUBSTRATE_ADDRESS_TYPE) obj_dict["attributes"]["balance_free_int"] = int(self.balance_free) return obj_dict
def sequencing_hook(self, db_session, parent_block_data, parent_sequenced_block_data): for account_audit in AccountAudit.query(db_session).filter_by(block_id=self.block.id).order_by('event_idx'): try: account = Account.query(db_session).filter_by(id=account_audit.account_id).one() if account_audit.type_id == settings.ACCOUNT_AUDIT_TYPE_REAPED: account.count_reaped += 1 account.is_reaped = True elif account_audit.type_id == settings.ACCOUNT_AUDIT_TYPE_NEW: account.is_reaped = False account.updated_at_block = self.block.id except NoResultFound: account = Account( id=account_audit.account_id, address=ss58_encode(account_audit.account_id, settings.SUBSTRATE_ADDRESS_TYPE), hash_blake2b=blake2_256(binascii.unhexlify(account_audit.account_id)), is_treasury=(account_audit.data or {}).get('is_treasury', False), is_sudo=(account_audit.data or {}).get('is_sudo', False), was_sudo=(account_audit.data or {}).get('is_sudo', False), created_at_block=self.block.id, updated_at_block=self.block.id ) # Retrieve index in corresponding account account_index = AccountIndex.query(db_session).filter_by(account_id=account.id).first() if account_index: account.index_address = account_index.short_address # Retrieve and set initial balance try: account_info_data = self.substrate.get_runtime_state( module='System', storage_function='Account', params=['0x{}'.format(account.id)], block_hash=self.block.hash ).get('result') if account_info_data: account.balance_free = account_info_data["data"]["free"] account.balance_reserved = account_info_data["data"]["reserved"] account.balance_total = account_info_data["data"]["free"] + account_info_data["data"]["reserved"] account.nonce = account_info_data["nonce"] except ValueError: pass # # If reaped but does not exist, create new account for now # if account_audit.type_id != ACCOUNT_AUDIT_TYPE_NEW: # account.is_reaped = True # account.count_reaped = 1 account.save(db_session) # Until SUDO and batch calls are processed separately we need to do a safety check to be sure we include all # accounts that have activity (lookup in account_index) in current block # TODO implement calls for search_index in db_session.query(SearchIndex.account_id).filter( SearchIndex.block_id == self.block.id, SearchIndex.account_id.notin_(db_session.query(Account.id)) ).distinct(): account = Account( id=search_index.account_id, address=ss58_encode(search_index.account_id, settings.SUBSTRATE_ADDRESS_TYPE), hash_blake2b=blake2_256(binascii.unhexlify(search_index.account_id)), created_at_block=self.block.id, updated_at_block=self.block.id ) try: account_info_data = self.substrate.get_runtime_state( module='System', storage_function='Account', params=['0x{}'.format(account.id)], block_hash=self.block.hash ).get('result') if account_info_data: account.balance_free = account_info_data["data"]["free"] account.balance_reserved = account_info_data["data"]["reserved"] account.balance_total = account_info_data["data"]["free"] + account_info_data["data"]["reserved"] account.nonce = account_info_data["nonce"] except ValueError: pass account.save(db_session)
def on_post(self, req, resp): blockHash = None if req.media.get('block_id'): substrate = SubstrateInterface(url=SUBSTRATE_RPC_URL, address_type=SUBSTRATE_ADDRESS_TYPE, type_registry_preset=TYPE_REGISTRY) blockHash = substrate.get_block_hash(req.media.get('block_id')) elif req.media.get('block_hash'): blockHash = req.media.get('block_hash') else: resp.status = falcon.HTTP_BAD_REQUEST resp.media = { 'errors': ['Either blockHash or block_id should be supplied'] } if blockHash: resp.status = falcon.HTTP_200 block = Block.query( self.session).filter(Block.hash == blockHash).first() blockTotal = BlockTotal.query( self.session).filter(BlockTotal.id == block.id).first() author = ss58_encode( blockTotal.author.replace('0x', '') ) if blockTotal is not None and blockTotal.author is not None else None if block: blockInfo = {} blockInfo["timestamp"] = block.datetime.strftime( "%Y-%m-%d %H:%M:%S") blockInfo["block_hash"] = block.hash blockInfo["block_id"] = block.id blockInfo["parent_id"] = block.id - 1 if block.id > 0 else 0 blockInfo["child_id"] = block.id + 1 blockInfo["parent_hash"] = block.parent_hash blockInfo["state_root"] = block.state_root blockInfo["extrinsic_root"] = block.extrinsics_root blockInfo["validator"] = author blockInfo["count_extrinsic"] = block.count_extrinsics blockInfo["count_event"] = block.count_events blockInfo["count_log"] = block.count_log # blockInfo["age"] = time.mktime(block.datetime.timetuple()) blockInfo["age"] = block.datetime.strftime("%Y-%m-%d %H:%M:%S") # 获取和区块相关的交易信息 extrinsics = Extrinsic.query( self.session).filter(Extrinsic.block_id == block.id).all() extrinsicsObj = [ { "extrinsic_id": '{}-{}'.format(block.id, extrinsic.extrinsic_idx), "hash": extrinsic.extrinsic_hash if extrinsic.extrinsic_hash else None, # "age": time.mktime(block.datetime.timetuple()), "age": block.datetime.strftime("%Y-%m-%d %H:%M:%S"), "result": extrinsic.success, # "address": extrinsic.address if extrinsic.address else None, # "module": extrinsic.module_id, # "fee": None, # "nonce": extrinsic.nonce if extrinsic.nonce else None, # "call": extrinsic.call_id, "operation": '{}({})'.format(extrinsic.module_id, extrinsic.call_id), "params": extrinsic.params # "signature": extrinsic.signature if extrinsic.signature else None } for extrinsic in extrinsics ] # 获取和区块相关的日志信息 logs = Log.query( self.session).filter(Log.block_id == block.id).all() logsObj = [{ "log_id": '{}-{}'.format(block.id, log.log_idx), "block_id": block.id, "type": log.type, "data": log.data['value'] } for log in logs] # 获取和区块相关的事件信息 events = Event.query( self.session).filter(Event.block_id == block.id).all() eventObj = [{ "id": '{}-{}'.format(block.id, event.event_idx), "block_id": block.id, "block_hash": block.hash, "module_id": event.module_id, "event_id": event.event_id, "attributes": event.attributes, "operation": '{}({})'.format(event.module_id, event.event_id), "desc": self.getEventDesc(event.module_id, event.event_id), "hash": self.getEventHash(block.id, event.extrinsic_idx) } for event in events] resp.media = { 'status': 'success', 'data': { "block_info": blockInfo, "extrinsics": extrinsicsObj, "logs": logsObj, "events": eventObj } } else: resp.status = falcon.HTTP_404 resp.media = {'result': 'Block not found'}
def on_get(self, req, resp): resp.status = falcon.HTTP_200 extrinsicId = req.params.get('extrinsic_id') if extrinsicId is None: resp.status = falcon.HTTP_BAD_REQUEST resp.media = {'errors': ['Invalid extrinsic id']} split = extrinsicId.split("-") if split is None or len(split) != 2: resp.status = falcon.HTTP_BAD_REQUEST resp.media = {'errors': ['Invalid extrinsic id']} blockId = split[0] extrinsicIdx = split[1] extrinsic = Extrinsic.extrinsic_by_id(self.session, blockId, extrinsicIdx).first() print(extrinsic.extrinsic_idx) extrinsicDetailInfo = {} if extrinsic is not None: extrinsicDetailInfo["extrinsic_id"] = '{}-{}'.format( extrinsic.block_id, extrinsic.extrinsic_idx) extrinsicDetailInfo["block_id"] = extrinsic.block_id extrinsicDetailInfo["extrinsic_idx"] = extrinsic.extrinsic_idx extrinsicDetailInfo["hash"] = "0x{}".format( extrinsic.extrinsic_hash) if extrinsic.extrinsic_hash else None extrinsicDetailInfo["age"] = extrinsic.datetime.strftime( "%Y-%m-%d %H:%M:%S") extrinsicDetailInfo["result"] = extrinsic.success extrinsicDetailInfo["operation"] = '{}({})'.format( extrinsic.module_id, extrinsic.call_id) extrinsicDetailInfo["module_id"] = extrinsic.module_id extrinsicDetailInfo["call_id"] = extrinsic.call_id extrinsicDetailInfo[ "module_name"] = extrinsic.module_name.capitalize() extrinsicDetailInfo["call_name"] = extrinsic.call_name.capitalize() extrinsicDetailInfo["call_desc"] = extrinsic.call_desc extrinsicDetailInfo["nonce"] = int( extrinsic.nonce) if extrinsic.nonce else None extrinsicDetailInfo[ "signature"] = extrinsic.signature if extrinsic.signature else None extrinsicDetailInfo["params"] = extrinsic.params extrinsicDetailInfo["from"] = extrinsic.address.replace( '0x', '') if extrinsic.address else None extrinsicDetailInfo["from_addr"] = ss58_encode( extrinsic.address.replace('0x', '')) if extrinsic.address else None params = json.loads(extrinsic.params) for param in params: name = param.get('name') if name == 'dest': toAddr = ss58_encode(param.get('value').replace('0x', '')) extrinsicDetailInfo['to'] = param.get('value').replace( '0x', '') extrinsicDetailInfo['to_addr'] = toAddr elif name == 'value': coin = param.get('value') / 1000000000000 # 转换为单位 Unit extrinsicDetailInfo['coin'] = coin # 获取和区块相关的事件信息 events = Event.query(self.session).filter( Event.block_id == extrinsic.block_id).all() eventObj = [{ "id": '{}-{}'.format(extrinsic.block_id, event.event_idx), "block_id": extrinsic.block_id, "module_id": event.module_id, "event_id": event.event_id, "attributes": event.attributes, "operation": '{}({})'.format(event.module_id, event.event_id), "desc": self.getEventDesc(event.module_id, event.event_id), "hash": self.getEventHash(extrinsic.block_id, event.extrinsic_idx) } for event in events] resp.media = { 'status': 'success', 'data': { "extrinsic_detail": extrinsicDetailInfo, "events": eventObj, "event_count": len(eventObj) } }
def format_address(self, item): item['orig_value'] = item['value'].replace('0x', '') item['value'] = ss58_encode(item['value'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) return item
def serialize_formatting_hook(self, obj_dict): obj_dict['attributes']['vote_address'] = ss58_encode(self.vote_account_id.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) obj_dict['attributes']['stash_address'] = ss58_encode(self.stash_account_id.replace('0x', ''), SUBSTRATE_ADDRESS_TYPE) return obj_dict