先简单说明一下,我还不是很熟练使用filter,而且在使用过程还出现了许多未解决问题,以下仅是将简单的实现过程记录以便日后翻查。
以太坊中事件event和日志logs具有很大的联系,可以说事件的触发就是为了将一些信息记录到日志中。
在智能合约中定义事件:
event UserRegisterLog(address indexed addr,string publicKey);
event BookRegisterLog(address indexed owner,string bookKey,string bookInfo);
event MakeOrderLog(address indexed owner,address indexed consumer,uint indexed orderID,ConsignmentStyle style);
在智能合约中触发事件(emit):
function UserRegister(string memory _name,string memory _publicKey,string memory _wxAccount) public {
bytes memory nameBytes = bytes(_name);
require(nameBytes.length != 0);
require(Users[msg.sender].addr == address(0));
require(Users[msg.sender].ifRegister != true);
Users[msg.sender].name = _name;
Users[msg.sender].publicKey = _publicKey;
Users[msg.sender].wxAccount = _wxAccount;
Users[msg.sender].addr = msg.sender;
Users[msg.sender].ifRegister = true;
emit UserRegisterLog(msg.sender,_publicKey);
}
毕业设计主要是一个书籍交易系统,需要实现的功能就是卖方A在发布订单后需要及时知道什么时候有人下单,也就是当买方B下单购买时,卖方A的客户端有消息提醒之类的。
于是了解了以太坊的事件,觉得可用,就尝试了一下。
以太坊智能合约事件监听主要有两种方式:
"""生成区块链打包回执"""
def ProduceFuncReceipt(self,_txn_dict,_privateKey=None):
'''
利用离线签名交易机制打包区块链交易
:param _txn_dict: 交易事务哈希
:param _privateKey: 私钥
:return:
'''
signed_txn = self.web3.eth.account.signTransaction(_txn_dict, private_key=_privateKey)
# print('signed payload => {0}'.format(self.web3.toHex(signed_txn.rawTransaction)))
tx_hash = self.web3.eth.sendRawTransaction(signed_txn.rawTransaction)
receipt = self.web3.eth.waitForTransactionReceipt(self.web3.toHex(tx_hash))
return receipt
"""用户注册"""
def UserRegister(self,_useraddr,_name,_publicKey,_wxAccount,_privateKey):
'''
用户注册函数,在智能合约登记用户地址、名称、公钥、微信号
:param _useraddr:
:param _name:
:param _publicKey:
:param _wxAccount:
:param _privateKey:
:return:
'''
nonce = self.GetNounce(_useraddr)
txn_dict = self.myContract.functions.UserRegister(str(_name),str(_publicKey),str(_wxAccount))\
.buildTransaction({
'chainId':9,
'gas':3000000,
'gasPrice':self.web3.toWei('1','gwei'),
'nonce':nonce,
})
# 因为注册时还未登入,所以要连同私钥一起传递
logs = self.UserRegisterLog(self.ProduceFuncReceipt(txn_dict,_privateKey))
if len(logs) == 0:
return False
print('用户注册logs=>:{0}'.format(logs[0]['args']))
return logs[0]['args']
"""注册--事件日志读取,被UserRegister调用"""
def UserRegisterLog(self,_receipt):
rich_logs = self.myContract.events.UserRegisterLog().processReceipt(_receipt)
return rich_logs
使用后台线程利用filter实现事件监听的部分实力代码如下:
def MadeOrderListenning(self,event_filter,poll_interval):
while True:
for event in event_filter.get_new_entries():
print("监听事件:",event)
time.sleep(poll_interval)
def MadeOrderListenning_ThreadStart(self):
event_filter = self.myContract.events.MakeOrderLog.createFilter(fromBlock="latest",
argument_filters={
'consumer': '0xb94ccf8aba77ce293692dbdfe919a20357ee6335'
})
worker = Thread(target=self.MadeOrderListenning,args=(event_filter,3))
worker.start()
其中argument_filters就是以json格式传入特征参数(用indexed修饰的参数)。
遇到的问题有: