Solidity 合约调试和event事件(2023版)
目前主流的定义:事件是以太坊虚拟机(EVM)日志基础设施提供的一个便利接口。当被发送事件(调用)时,会触发参数存储到交易的日志中(一种区块链上的特殊数据结构)。这些日志与合约的地址关联,并记录到区块链中。换句话来说区块链是打包一系列交易的区块组成的链条,每一个交易“收据”会包含0到多个日志记录,日志代表着智能合约所触发的事件。event相当于solidity的日志存储成本上来说,event比sto
什么是event?
目前主流的定义:
事件是以太坊虚拟机(EVM)日志基础设施提供的一个便利接口。当被发送事件(调用)时,会触发参数存储到交易的日志中(一种区块链上的特殊数据结构)。
这些日志与合约的地址关联,并记录到区块链中。换句话来说区块链是打包一系列交易的区块组成的链条,每一个交易“收据”会包含0到多个日志记录,日志代表着智能合约所触发的事件。
- event相当于solidity的日志
- 存储成本上来说,event比storage更便宜
- event可以被客户端程序订阅
- 使用emit触发event事件
- 我们可以通过event进行合约调试
在Solidity 代码中,使用event 关键字来定义一个事件
event Deposit(address _who,uint256 _account);
event Withdraw(address _who,address _operator,uint256 _account);
定义的事件1:Deposit充值,address充值的人,account充值的数量
定义的事件2:Withdraw提现,address_who提现的人,address_operator操作者,account提现 的数量
触发事件可以在任何函数中,通过emit进行调用
function deposit(uint256 _amount)public payable{
emit Deposit(msg.sender,_amount); //触发充值事件;
}
function withdraw(uint256 _amount)public payable{
emit Withdraw(user,msg.sender,_amount); //msg.sender是调用者
}
编译发布后可在logs中查看相关触发的事件如果用户订阅了相关的事件,那么当事件发生时就会获取到相关的通知,例如我们这边提现了一个以太币:
logs | [ { "from": "0xa131AD247055FD2e2aA8b156A11bdEc81b9eAD95", "topic": "0x9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb", "event": "Withdraw", "args": { "0": "0x617F2E2fD72FD9D5503197092aC168c91465E7f2", "1": "0x17F6AD8Ef982297579C203069C1DbfFE4348c372", "2": "1000000000000000000", "_who": "0x617F2E2fD72FD9D5503197092aC168c91465E7f2", "_operator": "0x17F6AD8Ef982297579C203069C1DbfFE4348c372", "_account": "1000000000000000000" } } ] |
我们可以清晰的看到实际的体现者是0x617F2E2fD72FD9D5503197092aC168c91465E7f2;
该操作的执行者是0x17F6AD8Ef982297579C203069C1DbfFE4348c372;
提现的金额为1000000000000000000,这里的单位为Wei;
下面是完整的代码仅供测试参考
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.7;
contract event_demo{
address public admin;
address payable public user;
uint256 totalAmount;
event Deposit(address _who,uint256 _account);
event Withdraw(address _who,address _operator,uint256 _account);
constructor(address _owner){
admin = _owner;
}
function deposit(uint256 _amount)public payable{
//if(_amount!=msg.value)return;
require(_amount==msg.value,"amount must == msg.value");
user=payable(msg.sender);
totalAmount=_amount;
emit Deposit(msg.sender,_amount); //触发充值事件;
//address(this).balance+= _amount;
}
function getBalance()public view returns(uint256,uint256){
//this代表合约本身
return (address(this).balance,totalAmount);
}
function withdraw(uint256 _amount)public payable{
user.transfer(_amount);
emit Withdraw(user,msg.sender,_amount); //msg.sender是调用者
}
}
更多推荐
所有评论(0)