据我所知,将值返回前端/web3 3的标准形式是订阅发送到块链的适当事件(S)(存储在通过事件链接的块链上的数据),尽管我不知道如何在回调函数中返回/检索内存中的数据,而不将所述数据发送到块链/存储中,供每个人查看?
function callbackFunction(bytes memory data) public returns (bytes memory) {
// manipulate data then return
return data;
}
类似于“订阅”执行回调函数的内容让我了解了我要寻找的内容,因为数据可以暂时存储在内存中。
我非常感谢任何反馈或洞察力!
发布于 2022-09-22 02:38:42
只要您的函数声明为view
或pure
,您就可以通过调用类似于(从web3js)的函数来直接期望得到这些值:
const contract = new web3.eth.Contract(
abi,
contractAddress,
{
from: fromAddress,
}
);
const data = await contract.methods.callbackFunction().call();
注意,我正在用callbackFunction()
调用.call()
。这意味着我们正在调用一个pure
或view
函数,或者我们只想知道调用函数的结果是什么,而不是通过网络广播事务。当我们调用一个pure
或view
函数时,我们的事务将不会被广播,也不会包含在一个块中,因此,我们立即得到响应。否则,我们不知道什么时候会挖掘我们的事务,因此我们不能等待响应。在这种情况下,我们需要发出事件并订阅它们来获取我们需要的数据。
如果要在不修改智能契约状态的智能契约中编写实用程序函数,则可以将这些函数声明为pure
或view
,并立即调用它们并期望得到值。
看看这个示例,其中我声明了您的函数,一个版本为pure
,另一个版本为view
:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
contract Contract {
function callbackFunction(bytes memory data) public pure returns (bytes memory) {
// manipulate data then return
return data;
}
function callbackFunction2(bytes memory data) public view returns (bytes memory) {
// manipulate data then return
return data;
}
function doSomething(bytes memory data) public returns (bytes memory) {
// manipulate data, update the state then return
counter++;
return data;
}
}
由于这些函数不修改智能契约的状态,所以我可以调用这些函数并立即期望得到一个值。
例如,注意doSomething()
如何修改状态。如果我们从web3js
调用该函数:
const transactionReceipt = await contract.methods.doSomething().send();
注意我是如何使用.send()
的。这意味着我正在调用一个非视图/非纯函数,它将修改状态,因此,我需要广播我的事务并支付天然气,所以它包含在一个块中。因此,函数调用将不会返回数据,而是返回一个transactionReceipt
。它不能返回数据,因为函数可能还没有包含在块中并被挖掘。所有这些都是不确定的,你的交易可以在备忘录中停留很长一段时间,或者立即被挖掘,谁知道呢。但是您会得到一个事务收据,它告诉您您的事务已被成功广播,并且正在等待被包含在一个块中。
如果我们使用doSomething()
从web3js
调用相同的函数.call()
:
const data = await contract.methods.doSomething().call();
那我们马上就能得到数据。但是不会对契约状态进行任何更改,因为您没有将事务广播到要包含在块中的网络,您只是告诉一个节点执行您的函数并返回如果您实际上广播了您的事务会发生什么,但是不需要消耗气体。这是有用的,并且通常被Metamask和其他钱包所使用,这些钱包使一个本地.call()
到一个节点,以检查如果事务实际上是广播的话会发生什么。这样我们就可以知道一项交易是否会因为任何原因而失败,因此,通过阻止我们广播一项可能失败的交易,可以节省我们的天然气。
如果契约函数没有修改状态,则将其声明为pure
或view
。您可以随时调用这些函数,并在不订阅事件的情况下立即预期值。
如果契约函数修改状态(从web3js使用.send()
调用它,则需要发出和订阅包含所需数据的事件。您可以使用web3js和.call()
调用它来立即获得结果,但是对契约状态的任何更改都不会持久,因为没有通过网络广播.call()
,因此不包括在块中。
https://ethereum.stackexchange.com/questions/136121
复制相似问题