使用 web3 跟踪代幣持有者
如果我有令牌地址,我該如何導航和查找某些內容,例如:
- 代幣持有者地址
- 代幣持有者的交易,包括他們何時進行交易
我對智能合約和可靠性以及整個乙太坊開發世界都是新手,所以我可能會問一個簡單的問題。
我想知道令牌地址是否可能具有成員變數,例如令牌持有者的映射,如果是,令牌持有者是否有他們進行的交易的日誌?
謝謝!
我自己尋找最好的方法,因為我認為我使用的方式有點複雜。但是,如果您還沒有任何解決方案,那麼方法可能對您有用。至少它有效
據我所知,有兩種方法可以區分乙太坊數據:
- 連接到遠端節點,如https://infura.io/
- 安裝您自己的節點,例如https://geth.ethereum.org/downloads/
如果您使用 IPCProvider(例如 geth):
- 將您的令牌的所有交易過濾掉
filter = web3.eth.filter({ 'fromBlock': _min_block, 'toBlock': _max_block, 'address':ERC20address }) tx_list = filtering.get(only_changes=False)'
更多關於過濾的資訊: https ://web3py.readthedocs.io/en/stable/filters.html
tx_list
是參與定義的 ERC20 的交易列表——迭代它以提取地址和時間戳(他們製作它的時間)。注意: transaction entire 不包含 timstamp,但是你可以通過 block this transaction 的 timestamp 來獲取。
raw_addresses_list = [] for tx in tx_list: from_ = tx['topics'][1] to_= tx['topics'][2] raw_addresses_list.extend([from_,to_]) timestamp = web3.eth.getBlock(tx['blockHash'])['timestamp'] unique_addresses = set(raw_addresses_list)
如果您使用 HTTPprovider(例如 infura):
它有點複雜,因為infura 不支持過濾方法
- 通過迭代所有塊來獲取您的代幣的所有交易
for block in range(_min_block,_max_block+1)): block_data = web3.eth.getBlock(block) for tx in block_data['transactions']: tx = web3.eth.getTransaction(tx) input_ = tx['input'].split(delimeter) from_ = tx['from'] to_ = input_ [0][10:] timestamp = block_data['timestamp']
(幾乎所有)ERC-20 代幣合約不維護可迭代代幣持有者的列表,但您需要自己建立一個鏈下數據庫。
mapping
在 EVM 中是不可迭代的,你只能檢查一個已知的鍵值。我創建了一個獨立工具,它收集 ERC-20 代幣持有者和交易到 SQLite 數據庫並使用 web3.py 庫。
- 取一個代幣合約地址
- 使用JSON-RPC API遍歷
Transfer
令牌的所有事件eth_getLogs
- 建立這些事件的本地數據庫
- 允許您使用 SQL 查詢任意時間點的任意賬戶餘額(block num)
您可以在此處找到如何建構令牌持有者數據庫的命令行應用程序執行範例
到處都有一些怪癖:例如,檢測某些令牌的鑄幣/創建事件並不簡單。因此,如果您僅依賴
Transfer
事件,您可能會在接收初始總供應量的帳戶上出現負餘額。