如何使用合约交互从 web3.py 获取未签名的交易数据
How to get an unsigned transaction data from web3.py using contract interaction
目前我正在做一个项目,我有以下流程:
- 用户想要进行交易,他们选择
chain
和token
。
- 从数据库中检索合同(可能是代理合同)和其他数据
- 我计算
data
键值对,用于我对 Metamask 的前端调用
transaction = await ethereum.request({
method: 'eth_sendTransaction',
params: [
{
to: '{{ paymentrequest.paymentaddress }}',
from: ethereum.selectedAddress,
data: '{{ paymentrequest.transhex }}',
chainId: '{{ paymentrequest.chain.chainid }}'
}],
});
- 用户会收到一个包含上述数据的元掩码弹出窗口,要求他们进行交易。
第 3 步是我 运行 遇到问题的地方。为了通过 web3.py 从计算的 tx 中获取数据属性,我必须使用 .call()
或 .transact()
。它们都适用于以太坊链。但是,当我将这些调用应用于 Polygon 或 BSC 链上的合约时,它们会报告如下错误:
错误 1:BEP20: transfer to zero address
- 我什至不明白这是怎么可能的,因为我四重检查我没有向函数中输入零地址,但是它仍然报告了这个错误而没有“to”参数,即使在函数调用中定义收件人时也是如此。
错误 2:BEP20: transfer amount exceeds balance
- 我不想使用别人提供的带有一堆令牌的地址来解决此错误。我想远离被别人钱包里有一堆硬币限制。
这是我使用的代码:
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"]
我想到的解决方案是跳过 web3.py 在返回数据哈希之前所做的所有这些检查。但是我就是做不到这样的事情。感谢任何帮助。
web3.py 文档:https://web3py.readthedocs.io/en/latest/
一如既往,开发者应该阅读得更好:
替换:
txn = contract.functions.transfer(paymentrequest.wallet, tokenamount * pow(10, paymentrequest.token.decimals)).call({"to": tokenaddress, "from": "0xbunchoflettersandnumbers"}, )
与:
txn = contract.encodeABI(fn_name="transfer", args=[paymentrequest.wallet, tokenamount * pow(10, paymentrequest.token.decimals)])
目前我正在做一个项目,我有以下流程:
- 用户想要进行交易,他们选择
chain
和token
。 - 从数据库中检索合同(可能是代理合同)和其他数据
- 我计算
data
键值对,用于我对 Metamask 的前端调用
transaction = await ethereum.request({
method: 'eth_sendTransaction',
params: [
{
to: '{{ paymentrequest.paymentaddress }}',
from: ethereum.selectedAddress,
data: '{{ paymentrequest.transhex }}',
chainId: '{{ paymentrequest.chain.chainid }}'
}],
});
- 用户会收到一个包含上述数据的元掩码弹出窗口,要求他们进行交易。
第 3 步是我 运行 遇到问题的地方。为了通过 web3.py 从计算的 tx 中获取数据属性,我必须使用 .call()
或 .transact()
。它们都适用于以太坊链。但是,当我将这些调用应用于 Polygon 或 BSC 链上的合约时,它们会报告如下错误:
错误 1:BEP20: transfer to zero address
- 我什至不明白这是怎么可能的,因为我四重检查我没有向函数中输入零地址,但是它仍然报告了这个错误而没有“to”参数,即使在函数调用中定义收件人时也是如此。
错误 2:BEP20: transfer amount exceeds balance
- 我不想使用别人提供的带有一堆令牌的地址来解决此错误。我想远离被别人钱包里有一堆硬币限制。
这是我使用的代码:
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"]
我想到的解决方案是跳过 web3.py 在返回数据哈希之前所做的所有这些检查。但是我就是做不到这样的事情。感谢任何帮助。
web3.py 文档:https://web3py.readthedocs.io/en/latest/
一如既往,开发者应该阅读得更好:
替换:
txn = contract.functions.transfer(paymentrequest.wallet, tokenamount * pow(10, paymentrequest.token.decimals)).call({"to": tokenaddress, "from": "0xbunchoflettersandnumbers"}, )
与:
txn = contract.encodeABI(fn_name="transfer", args=[paymentrequest.wallet, tokenamount * pow(10, paymentrequest.token.decimals)])