Пример #1
0
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()
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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,
    }
Пример #5
0
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)