给定一个键,我如何通过 API 从表中读取值?

问题描述 投票:0回答:2

想象一下我有一个看起来像这样的移动模块。

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?

move move-lang aptos
2个回答
2
投票

你说得对,你可以为此使用 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"

解释以上内容:

  • 通过 API 从表中获取项目的请求是 POST 请求。数据来自这个
    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 执行的操作的范围。即,在您提前知道密钥的情况下读取值。如果你想做下面的事情,你需要查询一个索引器:

  • 遍历表中的所有键。
  • 获取整个表,包括键和值。

我稍后会写一个关于如何做到这一点的答案。


-2
投票

@Daniel,如果我使用 iterable_table 而不是 table,我可以这样做吗???我已经尝试过并得到这样的错误: { “消息”:“无法反序列化从数据库中检索到的表项:剩余输入”, "error_code": "internal_error", “vm_error_code”:空 }

你能解释一下如何解决吗?

© www.soinside.com 2019 - 2024. All rights reserved.