☰
DataHaven 的 Ethereum System Runtime API 深度指南:在 Substrate 运行时中查询 Ethereum 上的 Agent ID
2026/9/27 9:11:32 网站建设 项目流程
  • 区块链
  • 存储
  • Web3

【免费下载链接】datahaven

An EVM compatible Substrate chain, powered by StorageHub and secured by EigenLayer

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

本指南聚焦 DataHaven(EVM 兼容的 Substrate 链,由 StorageHub 驱动并由 EigenLayer 保障安全)中 Snowbridge 系统运行时 API 的核心实现。我们将以 operator/pallets/system/runtime-api/README.md 为骨架,深入解读ControlApi运行时 API 的声明、agent_id的底层计算逻辑、三条链(mainnet/stagenet/testnet)中的接入方式,以及它在跨链桥体系中的实际用途。读完本文,你将掌握如何查看、理解并复用以太坊侧 Agent 身份映射的完整调用链。

一、这个 API 解决什么问题:Agent ID 查询

跨链桥场景中,一条链(如 Asset Hub、Bridge Hub)需要在以太坊上拥有一个"主权账户",用于托管资产、接收消息。在 DataHaven 使用的 Snowbridge 体系中,这个账户由部署在 Ethereum 上的Agent 合约承担。而ControlApi提供的agent_id函数,就是完成"给定一个 XCM Location → 得到唯一 Agent ID(以太坊账户地址形式)"这一查询的运行时 API。

原文档的表述非常精炼:"Provides an API for looking up an agent ID on Ethereum"(提供一个在以太坊上查找 agent ID 的 API),本文将其展开为可实操、可追溯的完整技术脉络。

二、API 的声明:ControlApi 及其函数签名

API 的声明位于 operator/pallets/system/runtime-api/src/lib.rs,通过 Substrate 的sp_api::decl_runtime_apis!宏定义:

// SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com> #![cfg_attr(not(feature = "std"), no_std)] use snowbridge_core::AgentId; use xcm::VersionedLocation; sp_api::decl_runtime_apis! { pub trait ControlApi { fn agent_id(location: VersionedLocation) -> Option<AgentId>; } }

关键点拆解:

  • trait ControlApi:运行时 API 的 trait 名称,编译期由decl_runtime_apis!宏展开为节点端可调用的 RPC 方法绑定;
  • 入参VersionedLocation:XCM 的版本化 Location 类型,用于跨版本兼容地描述一条链上的位置(如全局共识、平行链 ID、账户等);
  • 返回值Option<AgentId>:查询可能失败(Location 无法转换),因此返回Option而非直接返回AgentId;
  • AgentId的实际类型:在 operator/primitives/snowbridge/core/src/location.rs 中定义为pub type AgentId = H256;,即一个 32 字节的哈希值,作为以太坊上 Agent 合约的唯一标识(契约型映射)。

该 crate 的元信息(operator/pallets/system/runtime-api/Cargo.toml)显示包名为snowbridge-system-runtime-api,版本 0.13.0,依赖codec(SCALE 编解码)、snowbridge-core、sp-api与xcm,并默认开启stdfeature。

三、agent_id 的底层实现:从 Location 到哈希

agent_id的实现分两层,均可在仓库中找到对应源码。

3.1 运行时 API 的辅助函数

位于 operator/pallets/system/src/api.rs:

use snowbridge_core::AgentId; use xcm::{prelude::*, VersionedLocation}; use crate::{agent_id_of, Config}; pub fn agent_id<Runtime>(location: VersionedLocation) -> Option<AgentId> where Runtime: Config, { let location: Location = location.try_into().ok()?; agent_id_of::<Runtime>(&location).ok() }

这里先将版本化的VersionedLocation解包为Location,失败则返回None;随后调用 pallet 内部的agent_id_of。

3.2 pallet 内部的转换函数

位于 operator/pallets/system/src/lib.rs:

pub fn agent_id_of<T: Config>(location: &Location) -> Result<H256, DispatchError> { T::AgentIdOf::convert_location(location).ok_or(Error::<T>::LocationConversionFailed.into()) }

它委托给Config中声明的关联类型AgentIdOf(见同文件第 121-122 行):

/// Converts Location to AgentId type AgentIdOf: ConvertLocation<AgentId>;

3.3 AgentIdOf 的默认实现:HashedDescription

在 operator/primitives/snowbridge/core/src/location.rs 中,AgentIdOf被实现为HashedDescription类型:

/// Creates an AgentId from a Location. An AgentId is a unique mapping to an Agent contract on /// Ethereum which acts as the sovereign account for the Location. /// Resolves Polkadot locations (as seen by Ethereum) to unique `AgentId` identifiers. pub type AgentIdOf = HashedDescription< AgentId, ( DescribeHere, DescribeFamily<DescribeAllTerminal>, DescribeGlobalPrefix<(DescribeTerminus, DescribeFamily<DescribeTokenTerminal>)>, ), >;

其原理是:将 XCMLocation按一组描述器(DescribeHere、DescribeFamily<DescribeAllTerminal>、DescribeGlobalPrefix<...>)序列化后,做哈希运算得到唯一的H256标识。从源码注释可以看出,这个 AgentId 是对"以太坊上作为该 Location 主权账户的 Agent 合约"的唯一映射,且"按以太坊视角解析 Polkadot 位置"。这正是跨链消息路由、资产管理中"链→以太坊账户"映射的标准做法。

四、运行时接入:三套网络的 impl_runtime_apis

ControlApi只是 trait 声明,真正可被节点调用需要在运行时实现。DataHaven 的三套运行时(mainnet、stagenet、testnet)均已接入:

  • operator/runtime/mainnet/src/lib.rs
  • operator/runtime/stagenet/src/lib.rs
  • operator/runtime/testnet/src/lib.rs

三者实现方式完全一致,例如 stagenet:

impl snowbridge_system_v2_runtime_api::ControlV2Api<Block> for Runtime { fn agent_id(location: VersionedLocation) -> Option<AgentId> { snowbridge_pallet_system_v2::api::agent_id::<Runtime>(location) } }

注意:运行时实现中使用的是ControlV2Api(Snowbridge v2 命名空间下的封装),内部直接转调snowbridge_pallet_system_v2::api::agent_id::<Runtime>(location),即上文第三节的辅助函数。这种"API 声明 crate → pallet 辅助函数 → 运行时 impl"的三层结构,是 Substrate 运行时 API 的标准组织方式,方便节点端通过 RPC(state_call/ 专门的 API 调用)在链下查询状态。

五、agent_id 的实际使用场景:注册 Agent 与消息路由

agent_id并非孤立存在,它在 pallet 的初始化和消息处理流程中承担关键角色。从 operator/pallets/system/src/lib.rs 可以看到:

  • Agent 注册存储:第 220 行定义了Agents存储映射:StorageMap<_, Twox64Concat, AgentId, (), OptionQuery>,以AgentId为键记录已注册的 Agent;
  • 注册流程(第 459-488 行附近):初始化时调用agent_id_of::<T>(&asset_hub_location)计算 Asset Hub 的asset_hub_agent_id并插入Agents;随后计算 Bridge Hub 的bridge_hub_agent_id = agent_id_of::<T>(&Location::here())并插入;相关事件(agent_id: asset_hub_agent_id等)随之发出;
  • 单元测试佐证:operator/pallets/system/src/tests.rs 中通过make_agent_id(origin_location)生成agent_id并断言其匹配;operator/pallets/system/src/mock.rs 中的make_agent_id正是通过<Test as snowbridge_system::Config>::AgentIdOf::convert_location(&location)复算,验证了哈希映射的确定性。

六、Agent ID 计算的确定性验证

仓库中的运行时测试直接印证了 Agent ID 计算的确定性与可复现性。以 operator/runtime/testnet/src/configs/mod.rs 中的test_rewards_agent_id_computation为例(stagenet 的 operator/runtime/stagenet/src/configs/mod.rs 亦同):

let computed_agent_id = H256(blake2_256(&encoded)); let expected_agent_id = H256(hex_literal::hex!(...)); assert_eq!(computed_agent_id, expected_agent_id);

测试先按给定编码规则计算blake2_256哈希得到computed_agent_id,再与硬编码的expected_agent_id比对。这说明 Agent ID 的生成路径在 XCM Location 编码与哈希算法上均有明确的预期值约束,是跨链合约侧(Ethereum 上的 Agent 合约地址推导)与链侧必须严格对齐的"契约点"。

七、总结与延伸阅读

ControlApi::agent_id是 DataHaven / Snowbridge 体系中"Location ↔ 以太坊 Agent 账户"映射的查询入口,其完整链路为:

VersionedLocation → Location(api.rs 解包) → agent_id_of::<T>(pallet 内转换) → T::AgentIdOf::convert_location(HashedDescription 哈希) → AgentId = H256(以太坊 Agent 合约的唯一标识)
  • API 声明:查看 operator/pallets/system/runtime-api/src/lib.rs
  • 辅助实现:查看 operator/pallets/system/src/api.rs 与 operator/pallets/system/src/lib.rs
  • 类型定义:查看 operator/primitives/snowbridge/core/src/location.rs
  • 运行时接入:查看 operator/runtime/stagenet/src/lib.rs(mainnet、testnet 相同)
  • 测试验证:查看 operator/pallets/system/src/tests.rs、operator/runtime/testnet/src/configs/mod.rs

如果你想在 DataHaven 节点上查询某个 Location 对应的 Agent ID,可以基于上述ControlApi生成对应的运行时 API 调用(例如通过 Substrate 的 state_call 机制),或在本地测试网中参照test_rewards_agent_id_computation的方式复算验证。这为理解 DataHaven 的跨链 Agent 账户体系、以及在 Ethereum 侧定位 Agent 合约提供了坚实的技术起点。

  • 区块链
  • 存储
  • Web3

【免费下载链接】datahaven

An EVM compatible Substrate chain, powered by StorageHub and secured by EigenLayer

项目地址:https://gitcode.com/gh_mirrors/da/datahaven
点击查看免费下载
上一篇:Qix技术学习资源宝库:开发者必备的终极学习指南 🚀
下一篇:LeRobot 机器人框架实操:SO-100 从录数据到跑通 ACT 策略

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

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

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

立即咨询