Python - 如何获得以太坊交易?
Python - how to get ethereum transactions?
我开始使用 Ethereum 和 Web3py,我希望在 specific address 上发生交易时进行交易。为了做到这一点,我注册了 infura 并获得了我的项目 ID。所以这是我尝试过的:
from web3 import Web3
import asyncio
import websockets
ABI = {"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}
def handle_event(event):
# Define data from the event
print(event)
async def log_loop(event_filter, poll_interval):
while True:
for event in event_filter:
handle_event(event)
await asyncio.sleep(poll_interval)
def main():
w3 = Web3(Web3.WebsocketProvider(f'wss://mainnet.infura.io/ws/v3/<MY-PRIJECT>'))
uniswap = w3.eth.contract('0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D', abi=ABI)
block_filter = uniswap.events.getLogs.createFilter(fromBlock = 'latest').get_all_entries()
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(asyncio.gather(log_loop(block_filter, 2)))
finally:
loop.close()
if __name__ == '__main__':
main()
响应是这样的:("The event 'getLogs' was not found in this contract's abi. ", 'Are you sure you provided the correct contract abi?')
我也尝试使用 Infura 来做到这一点:
import asyncio
import websockets
async def connect():
uri = "wss://mainnet.infura.io/ws/v3/<MY-PROJECT>"
async with websockets.connect(uri) as ws:
await ws.send('{"jsonrpc":"2.0", "id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"}]}')
while True:
msg = await ws.recv()
message = json.loads(msg)
print(message)
asyncio.get_event_loop().run_until_complete(connect())
但这对我没有任何帮助。
如何在新交易完成后立即收到消息并获取该笔交易的 ETH 金额?任何建议表示赞赏
如this answer, it is simpler/faster to use a centralized tool like the Etherscan API所述,做这样的任务。
假设此解决方案适合您,那么获得您要查找的内容将非常简单:
import json
import time
import requests
# Place your own Etherscan API key here
ETHERSCAN_API_KEY =
ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"
def get_last_block():
return int(json.loads(requests.get(
f"https://api.etherscan.io/api?module=block&action=getblocknobytime×tamp={round(time.time())}&closest=before&apikey={ETHERSCAN_API_KEY}"
).text)["result"])
def get_last_txs(since=2):
return json.loads(requests.get(
f"https://api.etherscan.io/api?module=account&action=txlist&address={ADDRESS}&startblock={get_last_block() - since}&sort=asc&apikey={ETHERSCAN_API_KEY}"
).text)["result"]
txs = get_last_txs()
在 shell 中,您会得到以下行为:
>>> type(txs)
<class 'list'>
>>> len(txs)
60
>>> txs[0]
{'blockNumber': '11887758', 'timeStamp': '1613743087', 'hash': '0xacb6ba33c7fc4d8db7ad8ba4b09263ed0e6c2050842d189ba09b8a06b81ebc32', 'nonce': '25', 'blockHash': '0xebf1b16b9bccfb2dab43a304dfe2fb3d6c80d714669fd7bb651af98d497ddbea', 'transactionIndex': '56', 'from': '0xd8f19c1fd2916e10f0460976e57251d5a42e394f', 'to': '0x7a250d5630b4cf539739df2c5dacb4c659f2488d', 'value': '0', 'gas': '198839', 'gasPrice': '191000000000', 'isError': '0', 'txreceipt_status': '1', 'input': '0x18cbafe500000000000000000000000000000000000000000000000000000010245204950000000000000000000000000000000000000000000000000f58f2fc4900d7e700000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000d8f19c1fd2916e10f0460976e57251d5a42e394f00000000000000000000000000000000000000000000000000000000602fc89e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000068a0a1fef18dfcc422db8be6f0f486dea1999edc000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', 'contractAddress': '', 'cumulativeGasUsed': '3396885', 'gasUsed': '155481', 'confirmations': '3'}
>>> txs[-1]
{'blockNumber': '11887760', 'timeStamp': '1613743113', 'hash': '0x6228f262db37a2eeaba16869e45cb0e632bb1a2f301bda57fd9c7c54a2abe26b', 'nonce': '763', 'blockHash': '0x3352a2613fd38d1a4e90d8cac7f89df6f0fdfe3b9b7f20557b7d60b2e3fd643e', 'transactionIndex': '214', 'from': '0xe4fb9ca52e39b83be69e74e7fac8f807a9c16ef9', 'to': '0x7a250d5630b4cf539739df2c5dacb4c659f2488d', 'value': '0', 'gas': '174926', 'gasPrice': '148832420000', 'isError': '1', 'txreceipt_status': '0', 'input': '0x18cbafe5000000000000000000000000000000000000000000000001158e460913d0000000000000000000000000000000000000000000000000000009c18457fae1609800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e4fb9ca52e39b83be69e74e7fac8f807a9c16ef900000000000000000000000000000000000000000000000000000000602fc3080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000260e63d91fccc499606bae3fe945c4ed1cf56a56000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', 'contractAddress': '', 'cumulativeGasUsed': '11747610', 'gasUsed': '23683', 'confirmations': '1'}
然后您可以自由地对这些交易做任何您想做的事情。当然,您可以查看 Etherscan API 以获取您想要获得的任何其他信息。不过要小心,因为你被限制为 5 requests/s。这就是 since
参数可能有用的原因:您可以每 10 秒发出 1 个请求,但考虑到最后 2 或 3 个块,您肯定不会错过交易。您还必须考虑到 API returns 最多 10000 笔交易,因此如果您想要此合约的完整交易历史,则必须将它们设为 10000 x 10000。
如果这不是您要找的,请告诉我,我很乐意删除我的回答。
这看起来是个不错的解决方案。 get_last_block 和 get_last_txs 函数非常适合跟踪区块链上给定地址的交易,ERC-20 交易除外。
当尝试将相同的功能应用到诸如 Uniswap V3 USDC/ETH pool address 等相关交易是 ERC-20 交易的地址时,我在终端中收到以下信息:
type(txs)
Out[13]: list
len(txs)
Out[14]: 0
有没有人找到解决方案?
我开始使用 Ethereum 和 Web3py,我希望在 specific address 上发生交易时进行交易。为了做到这一点,我注册了 infura 并获得了我的项目 ID。所以这是我尝试过的:
from web3 import Web3
import asyncio
import websockets
ABI = {"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}
def handle_event(event):
# Define data from the event
print(event)
async def log_loop(event_filter, poll_interval):
while True:
for event in event_filter:
handle_event(event)
await asyncio.sleep(poll_interval)
def main():
w3 = Web3(Web3.WebsocketProvider(f'wss://mainnet.infura.io/ws/v3/<MY-PRIJECT>'))
uniswap = w3.eth.contract('0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D', abi=ABI)
block_filter = uniswap.events.getLogs.createFilter(fromBlock = 'latest').get_all_entries()
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(asyncio.gather(log_loop(block_filter, 2)))
finally:
loop.close()
if __name__ == '__main__':
main()
响应是这样的:("The event 'getLogs' was not found in this contract's abi. ", 'Are you sure you provided the correct contract abi?')
我也尝试使用 Infura 来做到这一点:
import asyncio
import websockets
async def connect():
uri = "wss://mainnet.infura.io/ws/v3/<MY-PROJECT>"
async with websockets.connect(uri) as ws:
await ws.send('{"jsonrpc":"2.0", "id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"}]}')
while True:
msg = await ws.recv()
message = json.loads(msg)
print(message)
asyncio.get_event_loop().run_until_complete(connect())
但这对我没有任何帮助。
如何在新交易完成后立即收到消息并获取该笔交易的 ETH 金额?任何建议表示赞赏
如this answer, it is simpler/faster to use a centralized tool like the Etherscan API所述,做这样的任务。
假设此解决方案适合您,那么获得您要查找的内容将非常简单:
import json
import time
import requests
# Place your own Etherscan API key here
ETHERSCAN_API_KEY =
ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"
def get_last_block():
return int(json.loads(requests.get(
f"https://api.etherscan.io/api?module=block&action=getblocknobytime×tamp={round(time.time())}&closest=before&apikey={ETHERSCAN_API_KEY}"
).text)["result"])
def get_last_txs(since=2):
return json.loads(requests.get(
f"https://api.etherscan.io/api?module=account&action=txlist&address={ADDRESS}&startblock={get_last_block() - since}&sort=asc&apikey={ETHERSCAN_API_KEY}"
).text)["result"]
txs = get_last_txs()
在 shell 中,您会得到以下行为:
>>> type(txs)
<class 'list'>
>>> len(txs)
60
>>> txs[0]
{'blockNumber': '11887758', 'timeStamp': '1613743087', 'hash': '0xacb6ba33c7fc4d8db7ad8ba4b09263ed0e6c2050842d189ba09b8a06b81ebc32', 'nonce': '25', 'blockHash': '0xebf1b16b9bccfb2dab43a304dfe2fb3d6c80d714669fd7bb651af98d497ddbea', 'transactionIndex': '56', 'from': '0xd8f19c1fd2916e10f0460976e57251d5a42e394f', 'to': '0x7a250d5630b4cf539739df2c5dacb4c659f2488d', 'value': '0', 'gas': '198839', 'gasPrice': '191000000000', 'isError': '0', 'txreceipt_status': '1', 'input': '0x18cbafe500000000000000000000000000000000000000000000000000000010245204950000000000000000000000000000000000000000000000000f58f2fc4900d7e700000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000d8f19c1fd2916e10f0460976e57251d5a42e394f00000000000000000000000000000000000000000000000000000000602fc89e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000068a0a1fef18dfcc422db8be6f0f486dea1999edc000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', 'contractAddress': '', 'cumulativeGasUsed': '3396885', 'gasUsed': '155481', 'confirmations': '3'}
>>> txs[-1]
{'blockNumber': '11887760', 'timeStamp': '1613743113', 'hash': '0x6228f262db37a2eeaba16869e45cb0e632bb1a2f301bda57fd9c7c54a2abe26b', 'nonce': '763', 'blockHash': '0x3352a2613fd38d1a4e90d8cac7f89df6f0fdfe3b9b7f20557b7d60b2e3fd643e', 'transactionIndex': '214', 'from': '0xe4fb9ca52e39b83be69e74e7fac8f807a9c16ef9', 'to': '0x7a250d5630b4cf539739df2c5dacb4c659f2488d', 'value': '0', 'gas': '174926', 'gasPrice': '148832420000', 'isError': '1', 'txreceipt_status': '0', 'input': '0x18cbafe5000000000000000000000000000000000000000000000001158e460913d0000000000000000000000000000000000000000000000000000009c18457fae1609800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000e4fb9ca52e39b83be69e74e7fac8f807a9c16ef900000000000000000000000000000000000000000000000000000000602fc3080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000260e63d91fccc499606bae3fe945c4ed1cf56a56000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', 'contractAddress': '', 'cumulativeGasUsed': '11747610', 'gasUsed': '23683', 'confirmations': '1'}
然后您可以自由地对这些交易做任何您想做的事情。当然,您可以查看 Etherscan API 以获取您想要获得的任何其他信息。不过要小心,因为你被限制为 5 requests/s。这就是 since
参数可能有用的原因:您可以每 10 秒发出 1 个请求,但考虑到最后 2 或 3 个块,您肯定不会错过交易。您还必须考虑到 API returns 最多 10000 笔交易,因此如果您想要此合约的完整交易历史,则必须将它们设为 10000 x 10000。
如果这不是您要找的,请告诉我,我很乐意删除我的回答。
这看起来是个不错的解决方案。 get_last_block 和 get_last_txs 函数非常适合跟踪区块链上给定地址的交易,ERC-20 交易除外。
当尝试将相同的功能应用到诸如 Uniswap V3 USDC/ETH pool address 等相关交易是 ERC-20 交易的地址时,我在终端中收到以下信息:
type(txs)
Out[13]: list
len(txs)
Out[14]: 0
有没有人找到解决方案?