视图方法可以用于跨合约调用吗? (获取错误 HostError(ProhibitedInView { method_name: "promise_batch_create"})

Can view methods be used for cross contract calls? (Getting error HostError(ProhibitedInView { method_name: "promise_batch_create"})

一直在做跨合约调用和模拟测试。当我使用函数调用时,我通常可以正常工作,但是当我尝试使用 'view' 调用生成跨合约调用以获取其信息的方法。

contract1 有一个方法 (indirect_num_entries),它使用跨合约调用 contract2 中的一个方法 (num_entries),returns 计算(没有修改)

const contract1 = new nearAPI.Contract(
  account1, // the account object that is connecting
  "example-contract.testnet",
  {
    // name of contract you're connecting to
    viewMethods: ["indirect_num_entries"], // view methods do not change state but usually return a value
    changeMethods: ["indirect_add_entry"], // change methods modify state
    sender: account, // account object to initialize and sign transactions.
  }
);

以及合同 2

const contract2 = new nearAPI.Contract(
  account2, // the account object that is connecting
  "example-contract.testnet",
  {
    // name of contract you're connecting to
    viewMethods: ["num_entries"], // view methods do not change state but usually return a value
    changeMethods: ["add_entry"], // change methods modify state
    sender: account, // account object to initialize and sign transactions.
  }
);

所有这些都可以通过 Javascript SDK 正确地添加和获取条目数。

但是我 运行 在尝试创建模拟测试时遇到了问题,发现尝试在 indirect_num_entries 上使用视图导致错误:

let x : u64 =  view!(contract1.indirect_num_entries()).unwrap_json();  //error

导致了以下运行时错误:

An error occurred
Error: Querying [object Object] failed: wasm execution failed with error: FunctionCallError(HostError(ProhibitedInView { method_name: "promise_batch_create" })).

玩了一下我发现替换视图!一个电话!有效——即

let x : u64 =  call!(root, contract1.indirect_num_entries()).unwrap_json();  // works

我还发现,如果我使用 near-cli,我会看到相同的行为,即

near call contract1 indirect_num_entries "{}" --accountI contract1 (works)
near view contract1 indirect_num_entries                        (errors)

而直接对 contract2 的视图工作正常

near view contract2 num_entries  (works)
let x : u64 =  view!(contract2.num_entries()).unwrap_json();  // works

这是否符合预期,视图仅对访问(而非修改)本地合约数据的方法有效,不应用于发出跨合约调用的方法? (还是我做错了什么?)

我当然可以想象可能有需要使用调用的原因(例如,可能需要签署跨合同调用的请求)但我不记得 anything/haven没有找到任何东西这似乎描述了这一点。某处有描述或解释吗?

谢谢!

这篇文章解释了这个问题 https://docs.near.org/docs/develop/contracts/as/intro#view-and-change-functions

view 调用不提供与 change 调用

相同的上下文

原因是 view 调用未签名。没有发件人签署交易来拨打电话。这很有用,不需要签名,因为某些用例旨在用于随意浏览或频繁读取数据,例如浏览 NFT 集合或呈现仪表板

change 调用需要签名交易,因此它们包含 sender 等上下文和其他详细信息

跨合约调用需要gas,这个gas应该记在某个账户上。如果没有签署交易(在 view 电话中),那么就没有人需要为此 gas

收费

这可能会让您感到疑惑:“但是 view 调用不也很费油吗?” ... 是的,他们这样做了,今天 RPC 节点提供商正在补贴这些调用,但将来可能会改变