Dapps

監控來自多個合約 web3.py 的事件

  • November 16, 2021

當使用者在我的系統上註冊時,會創建一個自定義的“存款”契約。N 個使用者註冊意味著 N 個存款合約。

我可以使用以下程式碼監控來自 1 個合約的事件:

contract_address = '' contract here
contract_abi = json.loads('ABI HERE')

contract = web3.eth.contract(address=contract_address, abi=contract_abi)

def handle_event(event):
   print(web3.eth.get_block('latest')['number'])

   temp = json.loads(Web3.toJSON(event))
   print(temp)

async def log_loop(event_filter, poll_interval):
   while True:
       for PairCreated in event_filter.get_new_entries():
           print("I'm here")
           handle_event(PairCreated)
       await asyncio.sleep(poll_interval)


def main():
   event_filter = contract.events.EVENT.createFilter(fromBlock='latest')
   loop = asyncio.get_event_loop()
   try:
       loop.run_until_complete(
           asyncio.gather(
               log_loop(event_filter, 2)))
   finally:
       loop.close()


if __name__ == "__main__":
   main()

但是,這只是監控一個合約,我希望它能夠監控多個合約(同一事件但從多個合約發出)

我能做些什麼來實現這一點(除了為每個新契約生成另一個偵聽器程序之外,我確信在我們執行它的任何盒子上都會很快消耗記憶體)並且根本不會擴展。

因此,我沒有監控所有合約中的所有事件,而是創建了一個新合約:

event Event:
   sender: indexed(address)
   value: uint256

admin: public(HashMap[address,address])
minter: address

@external
def __init__():
   self.minter = msg.sender


@external
def setadmin(_address: address)->bool:
   assert msg.sender != self.minter, "Not admin"
   self.admin[_address] = _address
   return True


@external
def reporter(_address: address, withdraw: uint256)->bool:
   assert msg.sender != self.admin[msg.sender], "Not admin"
   log Event(msg.sender,withdraw)
   return True

然後我在每個單獨的契約中連接這個契約,並且所有契約都有效地呼叫這個發送一個事件的契約。然後我只需要監控一份契約的事件,而不是所有契約。

在鍵入此內容時,我注意到存在一個明顯的安全問題,任何人都可以呼叫reporter() 並發出一個事件(我隨後依靠它在鏈下鑄造硬幣)。

然後我升級了合約以創建一組管理員地址(每個合約都將被隨後監控),只有他們有權呼叫 report() 並發出事件。

引用自:https://ethereum.stackexchange.com/questions/113631