class TokenSyncBlockEosFromDbScript(object): mysql_tool = None mysql_dev_tool = None # slog = Slog("token_sync_block_eos_from_db_script") def __init__(self): self.mysql_tool = MysqlTools() mysql_dev_conf = get_mysql_conf(env="dev") # mysql_dev_conf["host"] = "luckypark0121.cnzvcx1qv3xd.us-east-2.rds.amazonaws.com" self.mysql_dev_tool = MysqlTools(mysql_dev_conf) def work(self, last_block_num=None): with self.mysql_dev_tool.session_scope() as dev_session: if not last_block_num: last_block_num_tuple = dev_session.query(SyncEosModel.block_num).order_by(SyncEosModel.block_num.desc()).first() if last_block_num_tuple: last_block_num = last_block_num_tuple[_ZERO] else: last_block_num = _ZERO with self.mysql_tool.session_scope() as session: tmp_block_detail_list = session.query(SyncEosModel).filter(SyncEosModel.block_num > last_block_num).all() if not tmp_block_detail_list: return True dev_tmp_block_detail_list = [] for tmp_block_detail in tmp_block_detail_list: block_num = tmp_block_detail.block_num block_hash = tmp_block_detail.block_hash time_stamp = tmp_block_detail.time_stamp time_stamp_decimal = tmp_block_detail.time_stamp_decimal previous = tmp_block_detail.previous status = tmp_block_detail.status print("syncing block_num: " + str(block_num), "time_stamp: " + time_stamp) dev_tmp_block_detail = SyncEosModel( block_num=block_num, block_hash=block_hash, time_stamp=time_stamp, time_stamp_decimal=time_stamp_decimal, previous=previous, status=status, ) if len(dev_tmp_block_detail_list) <= _SIXTY: dev_tmp_block_detail_list.append(dev_tmp_block_detail) else: dev_session.add_all(dev_tmp_block_detail_list) dev_session.commit() dev_tmp_block_detail_list = [] return True
class WalletService(BaseService): symbol_to_token_coin = { _BTC: _COIN_ID_BTC, _ETH: _COIN_ID_ETH, _EOS: _COIN_ID_EOS } symbol_to_model = { _BTC: [ WalletBtcModel, SecretBtcModel, WalletBtcGatherModel, SecretBtcGatherModel ], _ETH: [ WalletEthModel, SecretEthModel, WalletEthGatherModel, SecretEthGatherModel ], _EOS: [ WalletEosModel, SecretEosModel, WalletEosGatherModel, SecretEosGatherModel ], } _gather = "gather" _normal = "normal" interval = _HUNDRED * _ONE def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) wc = get_wallet_config(remove_type=False) self.wallet = None self.chain_model = None self.chain_token_model = None self.acct_pub_key_b58_aes = None self.coin_id = None self.symbol = wc["symbol"].upper() self.key = str(wc["key"]) self.nonce = str(wc["nonce"]) self.mnemonic = wc["mnemonic"] self.passphrase = wc["passphrase"] self.category = wc.get("category", self._normal).lower() self.mysql_token = MysqlTools(get_about_conf()) self.mysql_wallet = MysqlTools() def wallet_init(self): """ :return: """ if self.symbol not in self.symbol_to_model or self.symbol not in self.symbol_to_token_coin: raise Exception("There is no corresponding symbol") if self.category == self._normal: token_model_index = _ZERO secret_model_index = _ONE elif self.category == self._gather: token_model_index = _TWO secret_model_index = _THREE else: raise Exception("The category does not exist") self.chain_token_model = self.symbol_to_model[ self.symbol][token_model_index] self.chain_model = self.symbol_to_model[ self.symbol][secret_model_index] self.wallet = Wallet(symbol=self.symbol) self.wallet.init_acct(self.mnemonic, self.passphrase) self.acct_pub_key_b58_aes = super_AES( self.wallet.get_acct_key()["acct_pub_key_b58"], self.key, self.nonce) # 查询 token_id self.coin_id = self.symbol_to_token_coin[self.symbol] with self.mysql_wallet.session_scope() as session: # 查询或插入 token_salt salt = session.query(TokenSaltModel).filter( TokenSaltModel.public_key_aes == self.acct_pub_key_b58_aes, TokenSaltModel.coin_id == self.coin_id).first() if not salt: new_salt = TokenSaltModel( coin_id=self.coin_id, public_key_aes=self.acct_pub_key_b58_aes, key_aes=self.key, nonce_aes=self.nonce) session.add(new_salt) else: if salt.key_aes != self.key or salt.nonce_aes != self.nonce: raise Exception( "Table token_salt contains this key nonce, results already generated cannot be replaced with new key or nonce" ) session.commit() def wallet_generate(self, count): """ 生成HD子钱包 :param count: 生成的子钱包个数, 按index顺序生成, 接续数据库索引 :return: """ remainder = count % self.interval times = count // self.interval + _ONE if remainder else count // self.interval for num in range(_ONE, times + _ONE): count = self.interval if num == times: if remainder: count = remainder # 获取数据库现有索引 with self.mysql_wallet.session_scope() as session: wallets = session.query(self.chain_model).filter( self.chain_model.acct_public_key_aes == self.acct_pub_key_b58_aes).with_for_update().order_by( self.chain_model.sub_index.desc(), self.chain_model._id.desc()).first() if not wallets: begin = None else: begin = int(wallets.sub_index) + _ONE print("-" * 20) print("The latest index is: " + str(begin - _ONE) if begin else str(_ZERO)) wallet_list, wallet_token_list = self.chain_model_generate( count, begin) with self.mysql_token.session_scope() as session_token: session_token.add_all(wallet_token_list) session_token.commit() session.add_all(wallet_list) session.commit() print("Now we've successfully inserted: " + str(count) + "!!!") print("-" * 20) return True def chain_model_generate(self, count, begin): """ 批量生成chain model :param count: :param begin: :return: model list """ sub_key = self.wallet.get_sub_key(count, begin) sub_key_aes = {} if self.symbol in [_BTC, _ETH]: for k, v in sub_key.items(): sub_key_aes[k] = super_AES(v, self.key, self.nonce) elif self.symbol in [_EOS]: sub_key_aes = sub_key wallet_list = [] wallet_token_list = [] for sub_index, index_info in sub_key_aes.items(): if self.symbol in [_EOS] and self.category == self._gather: index_info["sub_private_key"] = super_AES( index_info["sub_private_key"], self.key, self.nonce) index_info["sub_address"] = self.mnemonic print(' change_index: ' + index_info["change_index"] + " public_address: " + index_info["sub_address"]) w = self.chain_model( sub_index=int(sub_index), change_index=index_info["change_index"], sub_private_key_aes=index_info["sub_private_key"], sub_public_key_aes=index_info["sub_public_key"], sub_public_address=index_info["sub_address"], acct_public_key_aes=self.acct_pub_key_b58_aes, coin_id=self.coin_id) w_token = self.chain_token_model( sub_index=int(sub_index), change_index=index_info["change_index"], sub_public_address=index_info["sub_address"], acct_public_key_aes=self.acct_pub_key_b58_aes, coin_id=self.coin_id) wallet_list.append(w) wallet_token_list.append(w_token) return wallet_list, wallet_token_list @staticmethod def generate_key_nonce(key, nonce): """ transform origin args type :param key: must be origin :param nonce: :return: """ return {"key": encode_str_hex(key), "nonce": encode_str_hex(nonce)}
class CentralService(BaseService): symbol_to_model = { _BTC: [WalletBtcModel, SecretBtcModel, SecretBtcGatherModel], _ETH: [WalletEthModel, SecretEthModel, SecretEthGatherModel], } _gather = "gather" _normal = "normal" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.mysql_token = MysqlTools(get_about_conf()) self.coin_id = None def get_private_key_from_address(self, args): order_no = args["order_no"] coin_type = args["type"].upper() address = args["address"] category = args.get("category", self._normal) # 查询coin_id with self.mysql_token.session_scope() as session: # 查询 token_id token = session.query(TokenCoinModel).filter( TokenCoinModel.coin_name == coin_type).first() if not token: self.return_error(90002) self.coin_id = token.coin_id # 判断地址合法性 if isinstance(address, str): address = [address] else: if not isinstance(address, list): self.return_error(90001) # 判断币种类型合法性 if coin_type not in self.symbol_to_model: self.return_error(90002) # 判断地址类型合法性 if category == self._normal: model_index = _ONE ret = {"category": self._normal} elif category == self._gather: model_index = _TWO ret = {"category": self._gather} else: self.return_error(90004) ret = {} model_index = _ZERO # 获取对应model chain_model = self.symbol_to_model[coin_type][model_index] # 地址转成字符串 address_record = get_str_from_list(address) # 查询结果,并记录流水 with MysqlTools().session_scope() as session: record = session.query(RecordPkModel).filter( RecordPkModel.order_no == order_no).first() if record: self.return_error(10008) wallets = session.query(chain_model).filter( chain_model.sub_public_address.in_( address)).with_for_update().all() if not wallets: self.return_error(90003) for w in wallets: public_key_aes = w.acct_public_key_aes public_address = w.sub_public_address private_key_aes = w.sub_private_key_aes if public_key_aes not in ret: ret[public_key_aes] = [{ "public_address": public_address, "private_key_aes": private_key_aes, }] else: ret[public_key_aes].append({ "public_address": public_address, "private_key_aes": private_key_aes, }) record_pk = RecordPkModel(order_no=order_no, coin_id=self.coin_id, address=address_record, response=json.dumps(ret), category=category) session.add(record_pk) session.commit() return ret