智能合约尽管具备很多高级语言的特性,但是本身还是存在很多限制。对于业务的精准处理,需要采用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;
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)