视图方法可以用于跨合约调用吗? (获取错误 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 节点提供商正在补贴这些调用,但将来可能会改变
一直在做跨合约调用和模拟测试。当我使用函数调用时,我通常可以正常工作,但是当我尝试使用 '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 节点提供商正在补贴这些调用,但将来可能会改变