想象一下我有一个看起来像这样的移动模块。
Move.toml
[package]
name = 'friends'
version = '1.0.0'
[dependencies.AptosFramework]
git = 'https://github.com/aptos-labs/aptos-core.git'
rev = 'testnet'
subdir = 'aptos-move/framework/aptos-framework'
[addresses]
friends = "81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e"
sources/nicknames.move
module friends::nicknames {
use std::error;
use std::signer;
use std::string::String;
use aptos_std::table::{Self, Table};
const ENOT_INITIALIZED: u64 = 0;
struct Nicknames has key {
// A map of friends' nicknames to wallet addresses.
nickname_to_addr: Table<String, address>
}
/// Initialize Inner to the caller's account.
public entry fun initialize(account: &signer) {
let nicknames = Nicknames {
nickname_to_addr: table::new(),
};
move_to(account, nicknames);
}
/// Initialize Inner to the caller's account.
public entry fun add(account: &signer, nickname: String, friend_addr: address) acquires Nicknames {
let signer_addr = signer::address_of(account);
assert!(exists<Nicknames>(signer_addr), error::not_found(ENOT_INITIALIZED));
let nickname_to_addr = &mut borrow_global_mut<Nicknames>(signer_addr).nickname_to_addr;
table::add(nickname_to_addr, nickname, friend_addr);
}
}
然后我发布了模块(到测试网),初始化
Nicknames
到我的帐户,然后添加了一个条目:
aptos move publish
aptos move run --function-id 81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e::nicknames::initialize
aptos move run --function-id 81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e::nicknames::add --args string:dport address:81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e
既然我的表在链上有一些数据,我将如何读取
dport
键的值。我想我可以为此使用 API?
你说得对,你可以为此使用 API!首先让我们了解一下您餐桌的一些信息。
让我们看看您从上面的 Move 模块部署到您的帐户的资源。首先让我们构建结构标签(又名资源 ID / 句柄),它看起来像这样:
<account_address>::<module>::<struct_name>
你的情况:
0x81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e::nicknames::Nicknames
因为在Aptos区块链中一个账户中的每一种资源只能有一个,我们可以用它来唯一标识您账户中的资源。然后我们可以使用它来获取表句柄。表句柄是指向该特定表的全局唯一 ID(因此,不仅在您的帐户范围内)。我们需要它来进行任何进一步的查询,所以让我们先得到它:
$ curl https://fullnode.testnet.aptoslabs.com/v1/accounts/0x81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e/resource/0x81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e::nicknames::Nicknames | jq .
{
"type": "0x81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e::nicknames::Nicknames",
"data": {
"nickname_to_addr": {
"handle": "0x64fa842ed2c9da130f0419875e6c101aeea263882fadee3257b13f1bb4d7d41d"
}
}
}
解释以上内容:
https://fullnode.testnet.aptoslabs.com/v1/accounts/0x81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e/resource/<name>
让我们获得帐户上的特定资源。0x81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e::nicknames::Nicknames
。这两个地址恰好在这里是一样的,但那只是因为我们使用的是同一个帐户,另一个例子可能是0x1::aptos_coin::AptosCoin
.0x64fa842ed2c9da130f0419875e6c101aeea263882fadee3257b13f1bb4d7d41d
.使用这个句柄,我们现在可以查询API:
$ cat query.json
{
"key_type": "0x1::string::String",
"value_type": "address",
"key": "dport"
}
$ curl -H 'Content-Type: application/json' --data-binary "@query.json" https://fullnode.testnet.aptoslabs.com/v1/tables/0x64fa842ed2c9da130f0419875e6c101aeea263882fadee3257b13f1bb4d7d41d/item
"0x81e2e2499407693c81fe65c86405ca70df529438339d9da7a6fc2520142b591e"
解释以上内容:
query.json
文件。key_type
是表中键的类型。你可以从nickname_to_addr
的原始声明中看到这是0x1::string::String
.value_type
是值的类型。它的类型是address
,一种没有部署在任何特定模块的特殊类型(因此缺少<addr>::<module>::
.key
是我们在表中查询的键。如果假设表中使用的键更复杂,就像一个结构而不是像字符串这样的单个值,您可以在请求中将该结构表示为 JSON,例如
{
"key_type": "0x1::string::String",
"value_type": "address",
"key": {
"first_name": "Ash",
"last_name": "Ketchum",
}
}
这是您现在可以使用 API 执行的操作的范围。即,在您提前知道密钥的情况下读取值。如果你想做下面的事情,你需要查询一个索引器:
我稍后会写一个关于如何做到这一点的答案。
@Daniel,如果我使用 iterable_table 而不是 table,我可以这样做吗???我已经尝试过并得到这样的错误: { “消息”:“无法反序列化从数据库中检索到的表项:剩余输入”, "error_code": "internal_error", “vm_error_code”:空 }
你能解释一下如何解决吗?