当我想查看智能合约函数的返回值时,为啥需要 .call()?

Posted

技术标签:

【中文标题】当我想查看智能合约函数的返回值时,为啥需要 .call()?【英文标题】:Why is .call() necessary when I want to see returned values from a smart contract function?当我想查看智能合约函数的返回值时,为什么需要 .call()? 【发布时间】:2021-07-17 05:28:49 【问题描述】:

在我的合同中我有这个功能(solc 0.8.4):

   function makeDecision(address person) external returns (string memory name, bool approved) 
       require(msg.sender == loanOfficer, "Only the loan officer can initiate a decision.");
       require(bytes(applicants[person].name).length != 0, "That person is not in the pool of applicants.");

       if (applicants[person].credScore > 650 && applicants[person].credAge > 5) 
          applicants[person].approved = true;
       

       return (applicants[person].name, applicants[person].approved);
    

当我进入我的 truffle 控制台并以这种方式调用我的函数 loanContract.makeDecision(accounts[1]) 时,一切正常,但我得到一个 tx 收据作为响应。

当我通过 truffle 控制台loanContract.makeDecision.call(accounts[1]) 以这种方式调用我的函数时,我会从我的函数中得到预期的响应。我想要一个解释,告诉我为什么会出现这种响应差异,以便我更深入地了解正在发生的事情。我讨厌在不了解它们为什么起作用的情况下使用东西。

如果有帮助,我的合约(名为 LoanDisbursement)会在控制台中初始化,如下所示:let loanContract = await LoanDisbursement.deployed() 和我的帐户变量:let accounts = await web3.eth.getAccounts()

任何提示都会有所帮助,因为我仍在学习和深入这个生态系统。到目前为止,我还没有找到任何关于这个功能的像样的文档。谢谢。

【问题讨论】:

【参考方案1】:

Truffle contract functions 创建交易 - 并返回交易数据。

call function 不创建事务,它只是进行调用。所以它不能返回交易收据,Truffle 的作者决定返回函数值。

没有交易,你的合约状态是没有改变。这可能不是您想要的,当您需要将状态更改保存到区块链时,您应该始终创建一个事务。


当您创建交易时,Truffle 不会返回函数值。使用 Truffle,他们推荐了两种方法:

读取事务产生的事件日志

向你的函数emit MadeDecision(applicants[person].name, applicants[person].approved);添加一个事件,然后在result.logs的JS代码中访问它。

在后续调用中调用 getter。

发送setValue(5),然后调用getValue()。或者在你的情况下:

发送makeDecision(0x123),然后调用applicants[0x123](假设applicants是公开的)。

【讨论】:

以上是关于当我想查看智能合约函数的返回值时,为啥需要 .call()?的主要内容,如果未能解决你的问题,请参考以下文章

一种链下绕过非view限制直接读取智能合约某类特殊函数返回结果的技巧

使用 web3.py 解码智能合约的返回值?

没有明显原因的智能合约函数调用上的ValidationError(web3py)?

为啥我不能使用这个 transferEther 函数将 Ether 发送到智能合约?

如何将智能合约返回的地址转换为可读字符串?

回调智能合约 web3.php 中的 PHP 数组