Transactions
我怎樣才能找到使用者在合約上製定某個事件的區塊?
我正在嘗試建構一個 web3.py 程序來接收給定使用者的地址,並返回交易的 ETH 數量,因為他們為 Uniswap 交易所增加了流動性。Uniswap 是乙太坊平台上的智能合約。
Uniswap 合約有一個“AddLiquidity”方法,允許使用者添加資金,我想知道給定使用者何時執行此操作。
我查看了文件以了解如何執行此操作。我正在通過 infura 節點訪問區塊鏈,文件似乎說在 infura 上你不能使用過濾器。
在契約文件中,似乎我可以通過 events 對象執行此操作,但無法使其正常工作。認為事件日誌可能很重要,但正如我所說,我一直在努力讓其中的任何一個完成我希望的事情。
如果您需要任何進一步的資訊來幫助我,請告訴我,謝謝!
智能合約
pragma solidity 0.5.1; contract Uniswap { event Triggered(address indexed user); function addLiquidity() external { emit Triggered(msg.sender); } }
Javascript 事件過濾
var sha3HashOfTheEvent = web3.sha3("event Triggered(address)"); var filterOptions = { fromBlock: 0, toBlock: 'latest', topics:[sha3HashOfTheEvent] } filter.watch(function(error, result){ if(!error){ console.log("The event has been triggered.......") filter.stopWatching(); } });
希望它會幫助你。
這些將是步驟
- 以 Uniswap ABI
web3.Contract
為基礎,建構對象- 掃描
AddLiquidity
從區塊零到最後一個主網區塊的所有事件- 根據這些建立您自己的數據庫/存款清單
這是一些類似的程式碼來
Transfer
獲取令牌的所有事件:def scan_chunk(self, start_block, end_block) -> Set[str]: """Populate TokenHolderStatus for certain blocks. :return: Set of addresses where balance changes between scans. """ mutated_addresses = set() token = self.get_token_contract(self.address) # Discriminate between ERC-20 transfer and ERC-667 # The latter is not used anywhere yet AFAIK Transfer = token.events.Transfer("from", "to", "value") Issued = token.events.Issued("to", "value") block_timestamps = {} get_block_timestamp = self.get_block_timestamp # Cache block timestamps to reduce some RPC overhead # Real solution would be smarter models around block def get_block_when(block_num): if not block_num in block_timestamps: block_timestamps[block_num] = get_block_timestamp(block_num) return block_timestamps[block_num] for event_type in [Issued, Transfer]: # events = event_type.createFilter(fromBlock=start_block, toBlock=end_block).get_all_entries() events = getLogs(event_type, fromBlock=start_block, toBlock=end_block) # AttributeDict({'args': AttributeDict({'from': '0xDE5bC059aA433D72F25846bdFfe96434b406FA85', 'to': '0x0bdcc26C4B8077374ba9DB82164B77d6885b92a6', 'value': 300000000000000000000}), 'event': 'Transfer', 'logIndex': 0, 'transactionIndex': 0, 'transactionHash': HexBytes('0x973eb270e311c23dd6173a9092c9ad4ee8f3fe24627b43c7ad75dc2dadfcbdf9'), 'address': '0x890042E3d93aC10A426c7ac9e96ED6416B0cC616', 'blockHash': HexBytes('0x779f55173414a7c0df0d9fc0ab3fec461a66ceeee0b4058e495d98830c92abf8'), 'blockNumber': 7}) for e in events: idx = e["logIndex"] # nteger of the log index position in the block. null when its pending log. if idx is None: raise RuntimeError("Somehow tried to scan a pending block") if e["event"] == "Issued": # New issuances pop up from empty air - mark this specially in the database. # Also some ERC-20 tokens use Transfer from null address to symbolise issuance. from_ = self.TokenScanStatus.NULL_ADDRESS else: from_ = e["args"]["from"] mutated_addresses.add(e["args"]["from"]) block_when = get_block_when(e["blockNumber"]) self.create_deltas(e["blockNumber"], block_when, e["transactionHash"].hex(), idx, from_, e["args"]["to"], e["args"]["value"]) self.logger.debug("Imported %s, token:%s block:%d from:%s to:%s value:%s", e["event"], self.address, e["blockNumber"], from_, e["args"]["to"], e["args"]["value"]) mutated_addresses.add(e["args"]["to"]) return mutated_addresses
您可以在此處找到完整的原始碼。
如果您事先知道使用者地址,您也很可能能夠根據此地址進行過濾,因此您無需掃描所有事件。每個 Solidity 事件可以有 4 個索引參數,允許您在乙太坊節點級別過濾這些事件,這意味著內部乙太坊節點數據庫允許您查詢它們。但是,如果有很多事件,乙太坊節點可能無法快速響應這些查詢,無論如何您都需要建構自己的事件數據庫。