def restart_nonce( logger: Logger, dbsession: Session, network: str, ethereum_node_url: str, ethereum_private_key: str, ethereum_gas_limit: str, ethereum_gas_price: str, ): check_good_private_key(ethereum_private_key) web3 = create_web3(ethereum_node_url) service = EthereumStoredTXService(network, dbsession, web3, ethereum_private_key, ethereum_gas_price, ethereum_gas_limit, BroadcastAccount, PreparedTransaction) service.ensure_accounts_in_sync() account = service.get_or_create_broadcast_account() txs = service.get_last_transactions(limit=1) if txs.count() > 0: raise HistoryDeleteNeeded( "Cannot reset nonce as the database contains txs for {}. Delete database to restart." .format(service.address)) # read nonce from the network and record to the database tx_count = web3.eth.getTransactionCount(service.address) account.current_nonce = tx_count logger.info("Address %s, nonce is now set to %d", service.address, account.current_nonce) dbsession.flush()
def distribute_single(logger: Logger, dbsession: Session, network: str, ethereum_node_url: Union[str, Web3], ethereum_abi_file: Optional[str], ethereum_private_key: Optional[str], ethereum_gas_limit: Optional[int], ethereum_gas_price: Optional[int], token_address: str, ext_id: str, email: str, name: str, to_address: str, amount: Decimal) -> bool: """Send out a single transfer. :return: True if a new tx for broadcasting was created """ d = DistributionEntry(ext_id, email, name, to_address, amount) check_good_private_key(ethereum_private_key) abi = get_abi(ethereum_abi_file) web3 = create_web3(ethereum_node_url) service = EthereumStoredTXService(network, dbsession, web3, ethereum_private_key, ethereum_gas_price, ethereum_gas_limit, BroadcastAccount, PreparedTransaction) logger.info( "Starting creating distribution transactions for %s token from nonce %s", token_address, service.get_next_nonce()) total = d.amount * 10**18 available = service.get_raw_token_balance(token_address, abi) if total > available: raise NotEnoughTokens( "Not enough tokens for distribution. Account {} has {} raw token balance, needed {}" .format(service.get_or_create_broadcast_account().address, available, total)) if not service.is_distributed(d.external_id, token_address): # Going to tx queue raw_amount = int(d.amount * 10**18) note = "Distributing tokens, raw amount: {}".format(raw_amount) service.distribute_tokens(d.external_id, d.address, raw_amount, token_address, abi, note) logger.info("New broadcast has been created") return True else: logger.error("Already distributed") return False
def distribute_tokens(logger: Logger, dbsession: Session, network: str, ethereum_node_url: Union[str, Web3], ethereum_abi_file: Optional[str], ethereum_private_key: Optional[str], ethereum_gas_limit: Optional[int], ethereum_gas_price: Optional[int], token_address: str, dists: List[DistributionEntry]) -> Tuple[int, int]: """Sends tokens to their first owners in primary markets.""" check_good_private_key(ethereum_private_key) abi = get_abi(ethereum_abi_file) web3 = create_web3(ethereum_node_url) service = EthereumStoredTXService(network, dbsession, web3, ethereum_private_key, ethereum_gas_price, ethereum_gas_limit, BroadcastAccount, PreparedTransaction) logger.info( "Starting creating distribution transactions for %s token from nonce %s", token_address, service.get_next_nonce()) total = sum([dist.amount * 10**18 for dist in dists]) available = service.get_raw_token_balance(token_address, abi) if total > available: raise NotEnoughTokens( "Not enough tokens for distribution. Account {} has {} raw token balance, needed {}" .format(service.get_or_create_broadcast_account().address, available, total)) new_distributes = old_distributes = 0 for d in tqdm(dists): if not service.is_distributed(d.external_id, token_address): # Going to tx queue raw_amount = int(d.amount * 10**18) note = "Distributing tokens, raw amount: {}".format(raw_amount) service.distribute_tokens(d.external_id, d.address, raw_amount, token_address, abi, note) new_distributes += 1 else: # CSV reimports old_distributes += 1 logger.info("Prepared transactions for broadcasting for network %s", network) return new_distributes, old_distributes
def contract_status(logger: Logger, dbsession: Session, network: str, ethereum_node_url: str, ethereum_abi_file: str, ethereum_private_key: str, ethereum_gas_limit: str, ethereum_gas_price: str, token_contract: str): """Poll STO contract status.""" abi = get_abi(ethereum_abi_file) web3 = create_web3(ethereum_node_url) service = EthereumStoredTXService(network, dbsession, web3, ethereum_private_key, ethereum_gas_price, ethereum_gas_limit, BroadcastAccount, PreparedTransaction) contract = service.get_contract_proxy("SecurityToken", abi, token_contract) try: logger.info("Name: %s", contract.functions.name().call()) logger.info("Symbol: %s", contract.functions.symbol().call()) supply = contract.functions.totalSupply().call() human_supply = Decimal(supply) / Decimal( 10**contract.functions.decimals().call()) raw_balance = contract.functions.balanceOf( service.get_or_create_broadcast_account().address).call() normal_balance = Decimal(raw_balance) / Decimal( 10**contract.functions.decimals().call()) logger.info("Total supply: %s", human_supply) logger.info("Decimals: %d", contract.functions.decimals().call()) logger.info("Owner: %s", contract.functions.owner().call()) logger.info("Broadcast account token balance: %f", normal_balance) logger.info("Transfer verified: %s", contract.functions.transferVerifier().call()) except BadFunctionCallOutput as e: raise BadContractException( "Looks like this is not a token contract address. Please check on EtherScan that the address presents the token contract" ) return { "name": contract.functions.name().call(), "symbol": contract.functions.symbol().call(), "totalSupply": contract.functions.totalSupply().call(), "broadcastBalance": raw_balance, }
def next_nonce( logger: Logger, dbsession: Session, network: str, ethereum_node_url: str, ethereum_private_key: str, ethereum_gas_limit: str, ethereum_gas_price: str, ): check_good_private_key(ethereum_private_key) web3 = create_web3(ethereum_node_url) service = EthereumStoredTXService(network, dbsession, web3, ethereum_private_key, ethereum_gas_price, ethereum_gas_limit, BroadcastAccount, PreparedTransaction) account = service.get_or_create_broadcast_account() ft = pretty_date(account.created_at) logger.info("Address %s, created at %s, nonce is now set to %d", service.address, ft, account.current_nonce)