2

I can't execute the transaction, I get the error 'Fail with error 'hasFee'' Code: client.py

import logging
import traceback

from eth_account.signers.local import LocalAccount
from web3 import Web3
from typing import Optional
from web3.middleware import geth_poa_middleware

from models import TokenAmount
from models import Network

logger = logging.getLogger(__name__)


class Client:
    def __init__(self, seed: str, network: Network, abi: dict):
        self.w3 = Web3(Web3.HTTPProvider(endpoint_uri=network.rpc))
        self.w3.middleware_onion.inject(geth_poa_middleware, layer=0)
        self.w3.eth.account.enable_unaudited_hdwallet_features()

        self.account: LocalAccount = self.w3.eth.account.from_mnemonic(seed)
        self.abi = abi

    def get_decimals(self, contract_address: str) -> int:
        contract = self.w3.eth.contract(address=Web3.to_checksum_address(contract_address), abi=self.abi)
        return int(contract.functions.decimals().call())

    def balance_of(self, contract_address: str, address: Optional[str] = None) -> TokenAmount:
        if not address:
            address = self.account.address

        contract = self.w3.eth.contract(address=Web3.to_checksum_address(contract_address), abi=self.abi)
        return TokenAmount(
            amount=contract.functions.balanceOf(Web3.to_checksum_address(address)).call(),
            decimals=self.get_decimals(contract_address),
            wei=True
        )

    def get_allowance(self, contract_address: str, spender: str) -> TokenAmount:
        contract = self.w3.eth.contract(address=Web3.to_checksum_address(contract_address), abi=self.abi)
        return TokenAmount(
            amount=contract.functions.allowance(self.account.address, spender).call(),
            decimals=self.get_decimals(contract_address=contract_address),
            wei=True
        )

    def verif_tx(self, tx_hash) -> bool:
        try:
            data = self.w3.eth.wait_for_transaction_receipt(tx_hash, timeout=200)
            if 'status' in data and data['status'] == 1:
                logger.info(f'{self.account.address} | transaction was successful: {tx_hash.hex()}')
                return True
            else:
                logger.warning(f'{self.account.address} | transaction failed {data["transactionHash"].hex()}')
                return False
        except Exception as err:
            logger.error(f'{self.account.address} | unexpected error in <verif_tx> function: {err}')
            return False

    def approve(self, contract_address: str, spender_address: str, amount: TokenAmount,
                increase_gas: Optional[float] = 1.5):
        logger.info(
            f'{self.account.address} | approve | start approve {contract_address} for spender {spender_address}')

        balance = self.balance_of(contract_address=contract_address)
        if balance.Wei <= 0:
            logger.warning(f"{self.account.address} | approve | zero balance")
            return False

        if amount.Wei > balance.Wei:
            amount = balance

        approved = self.get_allowance(contract_address=contract_address, spender=spender_address)
        if amount.Wei <= approved.Wei:
            logger.info(f"{self.account.address} | approve | already approved")
            return {"hash": None, "amount": approved}

        try:
            contract = self.w3.eth.contract(address=Web3.to_checksum_address(contract_address), abi=self.abi)

            transaction_params = {
                "chainId": self.w3.eth.chain_id,
                "gasPrice": self.w3.eth.gas_price,
                "nonce": self.w3.eth.get_transaction_count(self.account.address),
                "from": self.account.address
            }
            transaction_params["gas"] = int(self.w3.eth.estimate_gas(transaction_params) * increase_gas)
            approve_tx = contract.functions.approve(spender_address, amount.Wei).build_transaction(transaction_params)
        except Exception:
            logger.info(f'{self.account.address} | Approve failed | {traceback.format_exc()}')
            return False

        sign_approve = self.account.signTransaction(approve_tx)
        return {"hash": self.w3.eth.send_raw_transaction(sign_approve.rawTransaction), "amount": amount}

    def deposit_token(self, contract_address: str, amount: TokenAmount, increase_gas: Optional[float] = 1.5):
        contract = self.w3.eth.contract(address=Web3.to_checksum_address(contract_address), abi=self.abi)
        try:
            transaction_params = {
                "chainId": self.w3.eth.chain_id,
                "gasPrice": self.w3.to_wei(5, "gwei"),
                "nonce": self.w3.eth.get_transaction_count(self.account.address),
                "from": self.account.address,
            }
            transaction_params["gas"] = int(self.w3.eth.estimate_gas(transaction_params) * increase_gas)
            deposit = contract.functions.depositToken(amount.Wei).build_transaction(transaction_params)
        except Exception:
            logger.info(f'{self.account.address} | Deposit failed | {traceback.format_exc()}')
            return False

        sign_deposit = self.account.signTransaction(deposit)
        return self.w3.eth.send_raw_transaction(sign_deposit.rawTransaction)

main.py

import logging

from eth_utils import ValidationError
from client import Client
from models import BNB_Smart_Chain, TokenAmount

from read_config import config, abi

logger = logging.getLogger(__name__)


def main():
    logging.basicConfig(level=logging.INFO,
                        format=u'%(filename)s:%(lineno)d #%(levelname)-8s [%(asctime)s] - %(name)s - %(message)s')

    logger.info("The script is up and running!")

    contract_address = config["contract_address"]
    bridge_contract_address = config["bridge_contract_address"]
    max_amount = TokenAmount(amount=config["max_amount"], decimals=config["decimals"])
    for seed in config["seeds"]:
        try:
            client = Client(seed=seed, network=BNB_Smart_Chain, abi=abi)
        except ValidationError:
            logger.error(f"Wrong mnemonic phrase! Check config.json, seed: {seed}")
            continue

        approve = client.approve(
            contract_address=contract_address, spender_address=bridge_contract_address, amount=max_amount)
        if approve:
            if approve["hash"]:
                if not client.verif_tx(approve["hash"]):
                    continue

            transaction = client.deposit_token(contract_address=bridge_contract_address, amount=approve["amount"])
            if transaction:
                if client.verif_tx(transaction):
                    logger.info("The task has been successfully completed!")
                else:
                    logger.info("Task completed with an error!")

    logger.info("The script has finished its work!")


if __name__ == "__main__":
    main()

I am suffering for the third day with this error, on the Internet on this could not find anything.I tried a bunch of things, entered the gas limit manually, calculated with estimate_gas, added value with amount and calculated afterwards. My ideas have come to an end Contract: https://bscscan.com/address/0xbaac55fdbb253b7d1b6a60763e8ffe8d3a451c0c

Help me, please!

Printon
  • 31
  • 2

0 Answers0