以太坊合约获取Event事件

以太坊合约获取Event事件,第1张

智能合约Event事件

智能合约尽管具备很多高级语言的特性,但是本身还是存在很多限制。对于业务的精准处理,需要采用Event事件进行跟踪,对于不同的合约和方法,可以编写不同的Event事件,如下:

pragma solidity >=0.7.0 <0.9.0;

contract Owner {

    address private owner;
    
    // event for EVM logging
    event OwnerSet(address indexed oldOwner, address indexed newOwner);
    
    // modifier to check if caller is owner
    modifier isOwner() {
        require(msg.sender == owner, "Caller is not owner");
        _;
    }  

    constructor() {
        // 'msg.sender' is sender of current call, contract deployer for a constructor
        owner = msg.sender; 
        emit OwnerSet(address(0), owner);
    }

    function changeOwner(address newOwner) public isOwner {
        emit OwnerSet(owner, newOwner);
        owner = newOwner;
    }

    function getOwner() external view returns (address) {
        return owner;
    }
}
获取Event事件

对应的java智能合约如何获取Event事件呢?见下

@GetMapping("/setOwner")
@ResponseBody
public String getUserCopyrights(String oldePK,String newPK) {
    try {
        Credentials oldOwner = Credentials.create(oldePK);
        Credentials newOwner = Credentials.create(newPK);
        // 加载合约
        Owner contract = Owner.load(contractAddress, web3j, oldOwner, new DefaultGasProvider());
        // 调用合约方法
        TransactionReceipt transactionReceipt = contract.changeOwner(newOwner.getAddress()).send();
        // 获取Event事件
        List<Owner.OwnerSetEventResponse> ownerSetEvents = contract.getOwnerSetEvents(transactionReceipt);
        Owner.OwnerSetEventResponse ownerSetEventResponse = ownerSetEvents.get(0);
        // 简单对比链上返回的事件信息与传入的是否一致
        if (Objects.equals(ownerSetEventResponse.newOwner, newOwner.getAddress())){
            System.out.println("oldOwner:" + ownerSetEventResponse.oldOwner);
            return "change owner successful";
        }else{
            return "change owner failed";
        }
    } catch (Exception e) {
        e.printStackTrace();
        return "error happend";
    }
}
运行结果

扩展

FISCO BCOS开源社区:如何优雅地编写智能合约

  • 统一接口

合约中可以采用require的方式进行处理,不过require方式不支持动态变量,每个require处理后需要填入特定的报错内容,耦合性太重,且不便于扩展。

基于智能合约的SDK开发,对于每一个交易(方法)由于Event事件不同,需要编写大量的不可复用的代码,解析Event事件。这种写法,对于代码的理解和维护性都是非常差的。要解决这个问题,只需要编写一个基合约CommonLib,如下所示:

contract CommonLib {
    // tx code
    bytes32 constant public ADD_STUDENT = "1";
    bytes32 constant public MODIFY_STUDENT_NAME = "2";
    
    // return code
    bytes32 constant public STUDENT_EXIST = "1001";
    bytes32 constant public STUDENT_NOT_EXIST = "1002";
    bytes32 constant public TX_SUCCESS = "0000";
    
  event commonEvent(bytes id, bytes32 txCode, bytes32 rtnCode);
}

contract StudentController is CommonLib {
     function addStudent(bytes32 studentId, bytes32 studenntName) public returns(bool) {
      	// 处理过程
      	// .......
      
      	// 根据处理结果来调用不同事件
        if(add success){
          	commonEvent(studentId, ADD_STUDENT, TX_SUCCESS);
            return true;
        }else {
          	commonEvent(studentId, ADD_STUDENT, STUDENT_EXIST);
            return false;
        }
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/716450.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存