import json
from web3 import Web3
mainnet_infura_url = '????'
web3 = Web3(Web3.HTTPProvider(mainnet_infura_url))
res = web3.isConnected()
print(res)
#mainnet
weth_token = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
wbtc_token = '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599'
uniswap_v3_quoter_abi = json.loads('[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH9","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH9","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"quoteExactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"name":"quoteExactInputSingle","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"quoteExactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"name":"quoteExactOutputSingle","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"path","type":"bytes"}],"name":"uniswapV3SwapCallback","outputs":[],"stateMutability":"view","type":"function"}]')
uniswap_v3_quoter_address = '0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6'
uniswap_v3_quoter_contract = web3.eth.contract(address = uniswap_v3_quoter_address, abi = uniswap_v3_quoter_abi)
uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
wbtc_token, weth_token, web3.toWei(0.01, 'ether'), 3000, 0).call()它给出了错误
---------------------------------------------------------------------------
ValidationError Traceback (most recent call last)
Input In [1], in <cell line: 25>()
21 uniswap_v3_quoter_contract = web3.eth.contract(address = uniswap_v3_quoter_address, abi = uniswap_v3_quoter_abi)
23 int(web3.toWei(0.01, 'ether'))
---> 25 uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
26 wbtc_token, weth_token, web3.toWei(0.01, 'ether'), 3000, 0).call()
File ~/miniconda3/envs/web3/lib/python3.9/site-packages/web3/contract.py:878, in ContractFunction.__call__(self, *args, **kwargs)
876 else:
877 clone.kwargs = kwargs
--> 878 clone._set_function_info()
879 return clone
File ~/miniconda3/envs/web3/lib/python3.9/site-packages/web3/contract.py:883, in ContractFunction._set_function_info(self)
881 def _set_function_info(self) -> None:
882 if not self.abi:
--> 883 self.abi = find_matching_fn_abi(
884 self.contract_abi,
885 self.web3.codec,
886 self.function_identifier,
887 self.args,
888 self.kwargs
889 )
890 if self.function_identifier in [FallbackFn, ReceiveFn]:
891 self.selector = encode_hex(b'')
File ~/miniconda3/envs/web3/lib/python3.9/site-packages/web3/_utils/contracts.py:163, in find_matching_fn_abi(abi, abi_codec, fn_identifier, args, kwargs)
143 diagnosis = (
144 "\nAmbiguous argument encoding. "
145 "Provided arguments can be encoded to multiple functions matching this call."
146 )
148 message = (
149 "\nCould not identify the intended function with name `{name}`, "
150 "positional argument(s) of type `{arg_types}` and "
(...)
160 diagnosis=diagnosis,
161 )
--> 163 raise ValidationError(message)
ValidationError:
Could not identify the intended function with name `quoteExactInputSingle`, positional argument(s) of type `(<class 'str'>, <class 'str'>, <class 'int'>, <class 'int'>, <class 'int'>)` and keyword argument(s) of type `{}`.
Found 1 function(s) with the name `quoteExactInputSingle`: ['quoteExactInputSingle(address,address,uint24,uint256,uint160)']
Function invocation failed due to no matching argument types.我真的搞不懂到底是怎么回事
发布于 2022-12-05 02:01:36
看起来您使用的web3.eth.contract方法不正确。address参数应该作为关键字参数传递,如下所示:
uniswap_v3_quoter_contract = web3.eth.contract(
address=uniswap_v3_quoter_address,
abi=uniswap_v3_quoter_abi
)此外,看起来您试图在不发送事务的情况下调用合同上的函数。为了调用契约上的函数,需要对函数对象使用call()方法,如下所示:
amount_out = uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
wbtc_token, weth_token, web3.toWei(0.01, 'ether'), 3000, 0
).call()这将调用函数并返回结果,但它不会发送事务,因此不会更改合同的状态。如果要发送事务并更改合同状态,则需要对函数对象使用sendTransaction()方法。该方法将事务对象作为参数,该参数包含有关事务的信息,如from地址、气体限制和天然气价格。例如:
tx = {
'from': '0xYOUR_ADDRESS',
'gas': 1000000,
'gasPrice': web3.toWei('1', 'gwei')
}
tx_hash = uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
wbtc_token, weth_token, web3.toWei(0.01, 'ether'), 3000, 0
).sendTransaction(tx)这将发送一个事务并更改合同的状态,但它不会返回函数调用的结果。相反,它将返回发送的事务的事务哈希。然后,您可以使用此事务哈希来跟踪事务,并在挖掘后获得结果。
希望这能有所帮助!
发布于 2023-02-09 17:27:37
由于ABI解码错误,此调用失败。通过将数据作为tuple()传递,可以避免此错误。
替换
amount_out = uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
wbtc_token, weth_token, eth_client.toWei(0.01, 'ether'), 3000, 0
).call()使用
amount_out = uniswap_v3_quoter_contract.functions.quoteExactInputSingle(
(wbtc_token, weth_token, eth_client.toWei(0.01, 'ether'), 3000, 0)
).call()否则,您将遇到此异常:
web3.exceptions.ValidationError:
Could not identify the intended function with name `quoteExactInputSingle`, positional argument(s) of type `(<class 'str'>, <class 'str'>, <class 'int'>, <class 'int'>, <class 'int'>)` and keyword argument(s) of type `{}`.
Found 1 function(s) with the name `quoteExactInputSingle`: ['quoteExactInputSingle(tuple)']
Function invocation failed due to improper number of arguments您可以通过函数签名'quoteExactInputSingle(tuple)'告诉函数接受元组。
您可以在元组中看到函数所期望的内容,查看以太扫描上的quoterv2代码。https://etherscan.io/address/0x61fFE014bA17989E743c5F6cB21bF9697530B21e#code
function quoteExactInputSingle(QuoteExactInputSingleParams memory params)
public
override
returns (
uint256 amountOut,
uint160 sqrtPriceX96After,
uint32 initializedTicksCrossed,
uint256 gasEstimate
)当您查看QuoteExactInputSingleParams结构时。
QuoteExactInputSingleParams({
tokenIn: tokenIn,
tokenOut: tokenOut,
fee: fee,
amountIn: amountIn,
sqrtPriceLimitX96: 0
}因此,它必须是一个元组,并按列出的顺序排列5个参数。
https://ethereum.stackexchange.com/questions/131236
复制相似问题