首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从事件中获取数据

从事件中获取数据
EN

Ethereum用户
提问于 2020-12-16 16:04:52
回答 1查看 2.7K关注 0票数 0

版本:Solity6.0.0 python3.8 web3 5.13.1

我试图从更改契约结构的智能契约函数中获取返回数据。因为事务改变了区块链,所以我无法使用return来实现这一点,因此我看到可以使用so事件。现在运行我的代码,我得到了以下错误:

代码语言:javascript
复制
 web3.exceptions.SolidityError: execution reverted: VM Exception while processing transaction: revert Request not approved yet.

下面是一些合同。getKYCData是给我带来问题的原因。

代码语言:javascript
复制
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);
    }
EN

回答 1

Ethereum用户

发布于 2020-12-24 22:10:21

使用事件从函数中获取返回值与在view/纯函数中使用return不一样。实际上,在声明导致事务的函数时,不应该使用关键字returns。这方面的唯一例外是,如果在智能契约中的另一个函数中调用这样的函数:

代码语言:javascript
复制
 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用于侦听新事件的示例:

代码语言:javascript
复制
//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 这里的一篇好文章

我希望这会有帮助!

票数 3
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/91192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档