版本:Solity6.0.0 python3.8 web3 5.13.1
我试图从更改契约结构的智能契约函数中获取返回数据。因为事务改变了区块链,所以我无法使用return来实现这一点,因此我看到可以使用so事件。现在运行我的代码,我得到了以下错误:
web3.exceptions.SolidityError: execution reverted: VM Exception while processing transaction: revert Request not approved yet.下面是一些合同。getKYCData是给我带来问题的原因。
pragma solidity ^0.6.0;
contract ReturnData
struct KYCData {
string name;
string home;
string tin;
string phone;
}
event WalletData(
string name,
string home,
string tin,
string phone
);
Request[] public requests;
uint[] public request_ids;
address public manager;
address public owner;
KYCData private data;
uint public serviceCost;
modifier restricted() {
require(msg.sender == manager || msg.sender == owner);
_;
}
constructor (address wallet_owner, address admin, string memory name, string memory home,
string memory tin, string memory phone, uint serviceFee) public {
manager = admin;
owner = wallet_owner;
data = KYCData({
name: name,
home:home,
tin: tin,
phone: phone
});
serviceCost = serviceFee;
}
function getData() public restricted view returns (string memory, string memory, string memory, string memory) {
return (data.name, data.home, data.tin, data.phone);
}
function makeRequest(string memory name, string memory description) public payable returns (uint) {
require(msg.value > serviceCost, "Did not meet fee requirement.");
Request memory newRequest = Request({
requestor: msg.sender,
name: name,
description: description,
approved: false,
active: true
});
requests.push(newRequest);
uint val = request_ids.length;
request_ids.push(val + 1);
return val;
}
function approveRequest(uint index) public restricted {
Request storage request = requests[index-1];
request.approved = true;
}
function getKYCData(uint index) public returns (string memory, string memory, string memory, string memory) {
Request storage request = requests[index-1];
require(request.approved, "Request not approved yet.");
require(request.active, "Request is not active");
require(msg.sender == request.requestor, "Must be requested from request originator.");
request.active = false;
emit WalletData(data.name, data.home, data.tin, data.phone);
}发布于 2020-12-24 22:10:21
使用事件从函数中获取返回值与在view/纯函数中使用return不一样。实际上,在声明导致事务的函数时,不应该使用关键字returns。这方面的唯一例外是,如果在智能契约中的另一个函数中调用这样的函数:
uint256 public x = 0;
function first() internal pure returns(uint256){
return 10;
}
function second() public {
x = put();
}当发出稳定的事件时,传递给它的参数存储在日志中,这是在每个事务收据中发现的一种特殊的数据结构。请记住,由于事件被认为是状态修改作用,因此发出事件需要额外的费用。
无论如何,在您的例子中,更改function getKYCData(uint index) public returns (string memory, string memory, string memory, string memory)
function getKYCData(uint index) public应该做好这项工作。
然后,您可以使用web3侦听新的事件/日志,并在事务完成并收到它时检索您想要的数据。不幸的是,我认为没有比这更有效的方法了,那就是不等待事务的完成。
web3.js用于侦听新事件的示例:
//create instance of contract
var contract = new web3.eth.Contract(ABI_of_contract, address_of_contract);
//listen for new events
contract.events.WalletData({
fromBlock: 'latest'
}, function(error, event){
console.log(event);
});此外,为了更好地理解,您可以查阅来自示例文档的web3。
除了使用事件从函数返回值之外,您还可以将它们视为一种更廉价的存储方式。请看我的答案这里或ConsenSys 这里的一篇好文章
我希望这会有帮助!
https://ethereum.stackexchange.com/questions/91192
复制相似问题