简体   繁体   中英

How to get an unsigned transaction data from web3.py using contract interaction

Currently I'm working on a project where I have the following flow:

  1. User wants to make a transaction, they choose chain and token .
  2. The contract (possibly proxy contract) and other data is retrieved from the database
  3. I compute the data key, value pair to be used in my front-end call to Metamask
transaction = await ethereum.request({
   method: 'eth_sendTransaction',
   params: [
      {
          to: '{{ paymentrequest.paymentaddress }}',
          from: ethereum.selectedAddress,
          data: '{{ paymentrequest.transhex }}',
          chainId: '{{ paymentrequest.chain.chainid }}'
   }],
});
  1. The user gets a metamask pop-up containing the data above which asks them to make the transaction.

Step 3 is where I run into issues. In order to get the data attribute from the computed tx by web3.py I have to either use .call() or .transact() . Both of them are fine for the ethereum chain. But when I apply those calls on contracts on the Polygon or BSC chains they report errors such as:

error 1: BEP20: transfer to zero address - I don't even understand how this is even possible since I quadrouple checked that I wasn't feeding a zero address into the function, however it still reported this error without the "to" parameter even when defining a recipient in the function call.

error 2: BEP20: transfer amount exceeds balance - I don't want to use an address with a bunch of tokens in it from someone else in order to get around this error. I want to stay away from being limited by someone else having a bunch of coins in their wallet.

This is the code I use:

def bnbTXCompute(paymentrequest, tokenamount, contractaddress, tokenaddress):
    w3 = Web3(Web3.HTTPProvider(paymentrequest.chain.rpc, request_kwargs={'timeout': 60}))
    w3.middleware_onion.inject(geth_poa_middleware, layer=0)

    contract = w3.eth.contract(address=contractaddress, abi=paymentrequest.token.abi)

    txn = contract.functions.transfer(paymentrequest.wallet,
                                      tokenamount * pow(10, paymentrequest.token.decimals)).call({"to": tokenaddress, "from": "0xbunchoflettersandnumbers"}, )
                                      # I have tried to remove both the "to" and "from" parameters, but they both result in either error 1 or 2

    return txn["data"]

def polyTXCompute(paymentrequest, tokenamount, contractaddress, tokenaddress):
    w3 = Web3(Web3.HTTPProvider(paymentrequest.chain.rpc, request_kwargs={'timeout': 60}))
    w3.middleware_onion.inject(geth_poa_middleware, layer=0)

    contract = w3.eth.contract(address=contractaddress, abi=paymentrequest.token.abi)

    txn = contract.functions.transfer(paymentrequest.wallet,
                                      tokenamount * pow(10, paymentrequest.token.decimals)).transact({"to": tokenaddress, "from": "0xbunchoflettersandnumbers"})

    return txn["data"]

def ethTXCompute(paymentrequest, tokenamount, contractaddress):

    w3 = Web3(Web3.HTTPProvider(paymentrequest.chain.rpc, request_kwargs={'timeout': 60}))
    w3.middleware_onion.inject(geth_poa_middleware, layer=0)

    contract = w3.eth.contract(address=contractaddress, abi=paymentrequest.token.abi)

    txn = contract.functions.transfer(paymentrequest.wallet,
                                      tokenamount * pow(10, paymentrequest.token.decimals)).transact()

    return txn["data"]

The solution I have thought of is to just skip all of these checks web3.py is doing before returning the data hash. However I just can't manage to do such a thing. Any help is appreciated.

web3.py documentation: https://web3py.readthedocs.io/en/latest/

And as always, devs should read better:

replace:

txn = contract.functions.transfer(paymentrequest.wallet, tokenamount * pow(10, paymentrequest.token.decimals)).call({"to": tokenaddress, "from": "0xbunchoflettersandnumbers"}, )

with:

txn = contract.encodeABI(fn_name="transfer", args=[paymentrequest.wallet, tokenamount * pow(10, paymentrequest.token.decimals)])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM