Diem JSON-RPC 的 Metadata 类型详解:get_metadata 返回值字段、语义与源码实现
2026/9/21 19:10:58 网站建设 项目流程
  • 区块链
  • 金融科技

【免费下载链接】diem

Diem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.

项目地址:https://gitcode.com/gh_mirrors/di/diem
点击查看免费下载

本指南以 Diem 仓库中 type_metadata.md 为核心,系统讲解 JSON-RPCget_metadata方法返回的Metadata类型:每个字段的名称、类型、语义、返回值在不同版本请求下的差异,以及从 views.rs 与 data.rs 源码中体现的实现细节。读完本文,你将能够正确解析元数据响应、理解链上配置项(脚本白名单、模块发布开关、双签限额)的来源,并用它校验 Full Node 的同步状态。

Metadata是 Diem JSON-RPC 接口中描述区块链/账本(ledger)全局状态快照的核心类型,由 get_metadata 方法返回。它同时服务于两个用途:客户端确认所连节点的最新高度、时间与链 ID;以及读取若干链上全局配置(如脚本发布策略、Diem 主版本、双签限额)。

字段总览

下表完整继承自 type_metadata.md,列出Metadata的所有字段:

NameTypeDescription
versionunsigned int64The latest block (ledger) version
timestampunsigned int64The latest block (ledger) timestamp, unit is microsecond
chain_idunsigned int8Chain ID of the Diem network
script_hash_allow_listList<string>List of allowed scripts hex-encoded hash bytes, server may not return this field if the allow list not found in on chain configuration.
module_publishing_allowedbooleanTrue for allowing publishing customized script, server may not return this field if the flag not found in on chain configuration.
diem_versionunsigned int64Diem chain major version number
accumulator_root_hashstringaccumulator root hash of the block (ledger) version
dual_attestation_limitunsigned int64The dual attestation limit on-chain. Defined in terms of micro-XDX.

字段按来源可分为两组:

  • 账本基础信息versiontimestampchain_idaccumulator_root_hash——由存储层直接从指定版本读取,任何版本请求都会返回;
  • 链上配置快照script_hash_allow_listmodule_publishing_alloweddiem_versiondual_attestation_limit——从 Diem root 账户的链上状态读取,只有请求“最新版本”时才返回(详见下文“版本参数的影响”)。

字段语义要点

  • version / timestamp:分别表示账本版本号与出块时间戳。时间戳单位为微秒(microsecond),示例响应中1596680521771648对应约 2020-08-06 UTC 时间,换算时需除以 1e6 再按 Unix 纪元解释。
  • chain_id:8 位无符号整数,标识当前网络(主网、测试网或私有网)。示例响应中请求返回的chain_id为 4,而响应外层头部diem_chain_id为 2,二者含义不同:头部字段由节点自身配置决定,result.chain_id则来自链上/账本数据。
  • accumulator_root_hash:指定版本处账本累加器(ledger accumulator)的根哈希,用于校验该版本状态的密码学一致性。
  • dual_attestation_limit:链上“双重认证”限额,单位为 micro-XDX(1 XDX 的百万分之一),用于限制交易金额以避免洗钱场景,超过该限额的交易需要额外的双签认证流程。
  • script_hash_allow_list:允许上链执行的脚本哈希白名单,脚本以十六进制编码的哈希字节列表形式返回。
  • module_publishing_allowed:是否允许发布自定义模块(开放模块发布)。
  • diem_version:Diem 链主版本号,用于协议级版本协商。

调用方法:get_metadata

Metadata对象只能通过 get_metadata 获取。该方法说明:

  • 描述:Get the blockchain / ledger metadata.
  • 参数version(unsigned int64,可选)。不传时默认返回服务端最新账本版本。
  • 返回:Metadata。

从 methods.rs 的源码实现可以看到版本参数的校验逻辑:

async fn get_metadata(&self, params: GetMetadataParams) -> Result<MetadataView, JsonRpcError> { let chain_id = self.service.chain_id(); let version = self.version_param(params.version, "version")?; data::get_metadata(self.service.db.borrow(), self.version(), chain_id, version) }

其中version_param(methods.rs)会在version缺省时取最新账本版本,若传入版本大于已知最新版本则返回invalid_param错误("version should be <= known latest version")。

在 json-rpc-spec.md 中,该方法的正式签名记录为:

get_metadata(version: unsigned_int64) -> Metadata

版本参数的影响(重要)

原文档 type_metadata.md 明确给出两条注释:

  1. script_hash_allow_listmodule_publishing_allowed的详细语义参见 DiemTransactionPublishingOption 模块文档(仓库内相对路径为 language/diem-framework/modules/doc/DiemTransactionPublishingOption.md);
  2. 字段script_hash_allow_listmodule_publishing_alloweddiem_version只有在通过 get_metadata 请求最新版本时才会返回。

这一点在源码中得到精确印证:data.rs 中get_metadata函数先构造只含基础四字段的MetadataView,然后仅当version == ledger_version(即请求的是最新版本)时,才读取 Diem root 账户状态并调用with_diem_root填充配置字段:

let mut metadata_view = MetadataView::new(version, accumulator_root_hash, timestamp, chain_id.id()); if version == ledger_version { if let Some(diem_root) = get_account_state(db, diem_root_address(), version)? { metadata_view.with_diem_root(&diem_root)?; } }

对应的 MetadataView 定义 中,四个配置字段全部声明为Option并带有skip_serializing_if = "Option::is_none",因此当未请求最新版本时,这些字段会直接从 JSON 响应中省略:

pub struct MetadataView { pub version: u64, pub accumulator_root_hash: HashValue, pub timestamp: u64, pub chain_id: u8, #[serde(skip_serializing_if = "Option::is_none")] pub script_hash_allow_list: Option<Vec<HashValue>>, #[serde(skip_serializing_if = "Option::is_none")] pub module_publishing_allowed: Option<bool>, #[serde(skip_serializing_if = "Option::is_none")] pub diem_version: Option<u64>, #[serde(skip_serializing_if = "Option::is_none")] pub dual_attestation_limit: Option<u64>, }

with_diem_root(views.rs)展示了各配置字段的具体来源:

pub fn with_diem_root(&mut self, diem_root: &AccountState) -> Result<()> { if let Some(vm_publishing_option) = diem_root.get_vm_publishing_option()? { self.script_hash_allow_list = Some(vm_publishing_option.script_allow_list); self.module_publishing_allowed = Some(vm_publishing_option.is_open_module); } if let Some(diem_version) = diem_root.get_diem_version()? { self.diem_version = Some(diem_version.major); } if let Some(limit) = diem_root.get_resource::<Limit>()? { self.dual_attestation_limit = Some(limit.micro_xdx_limit); } Ok(()) }

也就是说:

  • script_hash_allow_listmodule_publishing_allowed来自 Diem root 账户中的 VM 发布选项(DiemTransactionPublishingOption资源);
  • diem_version来自链上的 Diem 版本资源(取其major字段);
  • dual_attestation_limit来自链上的双签限额资源(micro_xdx_limit)。

链上配置语义:脚本白名单与模块发布

script_hash_allow_listmodule_publishing_allowed的底层数据定义在 Move 模块 DiemTransactionPublishingOption.move 中(对应生成文档 language/diem-framework/modules/doc/DiemTransactionPublishingOption.md):

script_allow_list: vector<vector<u8>>, module_publishing_allowed: bool,

从模块实现(DiemTransactionPublishingOption.move)可以看到脚本白名单的判定逻辑——当白名单为空时表示“全部放行”,否则只有哈希包含在名单中的脚本才允许执行:

Vector::is_empty(&publish_option.script_allow_list) || Vector::contains(&publish_option.script_allow_list, hash)

实操中的解读:

  • script_hash_allow_list返回空列表,意味着链上对脚本执行不设白名单限制;
  • 若返回非空列表,则只有名单内哈希对应的脚本可通过;
  • module_publishing_allowedtrue表示允许发布自定义 Move 模块,为false则禁止。

注意:原文档同时说明,如果链上配置中找不到这些资源,服务端可能不返回对应字段(在 JSON 响应中表现为字段缺失而非null)。

完整示例

以下请求与响应示例完整继承自 type_metadata.md:

// Request: fetches current block metadata curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"get_metadata","params":[],"id":1}' https://testnet.diem.com/v1
// Response { "id": 1, "jsonrpc": "2.0", "diem_chain_id": 2, "diem_ledger_timestampusec": 1596680521771648, "diem_ledger_version": 3253133, "result": { "timestamp": 1596680521771648, "version": 3253133, "chain_id": 4, "script_hash_allow_list": [ <allowed scripts hex-encoded hash string> ], "module_publishing_allowed": false, "diem_version": 1, "accumulator_root_hash": "<hash string>", "dual_attestation_limit": 1000000000 } }

要点拆解:

  • 未传version参数("params":[]),因此返回的是最新账本版本,四个链上配置字段全部出现在响应中;
  • 响应顶层diem_ledger_timestampusecdiem_ledger_version是服务端头部快照,result内字段为get_metadata的返回值,两者一致;
  • accumulator_root_hash是十六进制哈希字符串;script_hash_allow_list中的每个元素也是十六进制编码的脚本哈希字符串。

批量请求的版本差异演示

从 json-rpc-spec.md 可以看到一个利用版本参数做批量对比的官方示例(同一批请求分别查版本 1 与版本 9 的元数据):

curl -X POST -H "Content-Type: application/json" --data '[{"jsonrpc":"2.0","method":"get_metadata","params":[1],"id":1},{"jsonrpc":"2.0","method":"get_metadata","params":[9],"id":2}]' "https://client.testnet.diem.com/"

由于params中携带了具体的version,当这两个版本均不是服务端最新版本时,响应中的script_hash_allow_listmodule_publishing_alloweddiem_versiondual_attestation_limit字段会被省略,仅保留versiontimestampchain_idaccumulator_root_hash四个基础字段。

典型应用场景

结合原文档描述与 data.rs 的函数注释("Can be used to verify that target Full Node is up-to-date"),Metadata的主要用途包括:

  1. 校验 Full Node 同步状态:对比节点返回的version/timestamp与已知最新高度,判断目标节点是否已追赶上网络最新状态;
  2. 读取链 ID 与版本信息:通过chain_id确认所连网络(避免误连测试网/主网),通过diem_version感知协议版本;
  3. 获取链上发布策略:查询script_hash_allow_listmodule_publishing_allowed,判断当前链是否允许发布自定义模块、是否对脚本执行设限;
  4. 读取经济/合规参数:通过dual_attestation_limit(micro-XDX 单位)了解链上双签限额,指导大额交易的合规处理;
  5. 密码学校验:使用accumulator_root_hash与本地累计的账本累加器状态做一致性比对。

参考文档与源码索引

  • 本文主体文档:json-rpc/docs/type_metadata.md
  • 调用方法说明:json-rpc/docs/method_get_metadata.md
  • JSON-RPC 规范总览:json-rpc/json-rpc-spec.md
  • 服务端返回类型定义:json-rpc/types/src/views.rs
  • 数据层实现:json-rpc/src/data.rs
  • 方法分发与版本校验:json-rpc/src/methods.rs
  • 链上发布选项 Move 模块:language/diem-framework/modules/DiemTransactionPublishingOption.move
  • 模块生成文档:language/diem-framework/modules/doc/DiemTransactionPublishingOption.md
  • 区块链
  • 金融科技

【免费下载链接】diem

Diem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.

项目地址:https://gitcode.com/gh_mirrors/di/diem
点击查看免费下载

相关推荐

上一篇:WhyNotWin11无障碍功能:屏幕阅读器兼容性实现终极指南
下一篇:Shairport Sync中的依赖安全更新流程:自动化与验证

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询