Diem 框架NetworkIdentity模块深度解析Diemnet 网络身份的上链管理与轮换事件机制【免费下载链接】diemDiem’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本指南以 DiemDiem 区块链框架中0x1::NetworkIdentityMove 模块为核心讲解网络身份Network Identity如何在链上存储、如何由 Treasury Compliance 账户批量增删、以及身份变更时如何通过事件通知链下组件。读者将掌握该模块的数据结构、全部公开 API、错误码语义、基于向量模拟集合的实现技巧以及对应的形式化规范与端到端测试用例可直接据此理解或扩展 Diem 网络身份管理链路。模块定位Diemnet 网络身份的链上载体NetworkIdentity模块是 Diem 框架Diem Framework中的一员其职责一句话概括即Module managing Diemnet NetworkIdentity见模块源码注释。Diemnet 是 Diem 网络的名称网络中的节点与账户需要以身份标识identity互相区分该模块把这些身份标识以原始字节向量vectorvectoru8的形式持久化在链上账户资源中并提供增删改查接口。与多数只读或仅校验的框架模块不同本模块是一个数据仓库 事件源的组合存储侧每个参与账户可拥有一个NetworkIdentity资源内含最多 100 条身份记录事件侧身份集合一旦发生真实变更模块会向存放在TreasuryCompliance账户下的统一事件句柄发出NetworkIdentityChangeNotification事件供链下服务监听轮换rotation行为。在框架模块文档索引overview.md中可以看到该模块与DiemTimestamp、DiemConfig、ValidatorConfig等并列登记属于框架标准模块之一。它依赖以下标准库与框架模块见源码 use 声明依赖模块用途DiemFramework::DiemTimestamp获取身份变更时间now_seconds()DiemFramework::Roles校验调用者是否具备 Treasury Compliance 角色Std::Errors统一错误码构造Std::Event/EventHandle事件句柄创建与事件发射Std::Signer获取账户地址Std::Vector身份列表的增删查操作核心数据结构身份资源、事件句柄与变更通知ResourceNetworkIdentity账户身份持有者holder字段仅一个struct NetworkIdentity has key { identities: vectorvectoru8, }identities是身份的字节表示的集合。注意它被形式化规范约束为一个集合模块级spec NetworkIdentity引入了UniqueMembersvectoru8要求集合内元素两两互异见源码 L10-L16。也就是说虽然底层是向量语义上不允许重复身份存在。ResourceNetworkIdentityEventHandle全局唯一的身份变更事件句柄容器只有一个字段struct NetworkIdentityEventHandle has key { identity_change_events: EventHandleNetworkIdentityChangeNotification }该资源只能发布在TreasuryCompliance账户上通过initialize_network_identity_event_handle这是所有身份变更事件汇聚的单一出口。StructNetworkIdentityChangeNotification身份发生真实变化时发射的消息体具备drop, store能力字段类型含义accountaddress身份发生变更的账户地址identitiesvectorvectoru8变更完成后的全新身份集合time_rotated_secondsu64身份轮换发生的链上时间戳秒取自DiemTimestamp::now_seconds()定义见源码 L23-L31常量与错误码边界约束一览模块定义了 4 个错误码与 1 个容量上限见源码 L33-L44常量值触发场景ENETWORK_ID_DOESNT_EXIST0尝试get或remove_identities时目标账户尚未发布NetworkIdentity资源ENETWORK_ID_LIMIT_EXCEEDED1添加后总数超过MAX_ADDR_IDENTITIES或单次移除数量超过上限ENETWORK_ID_NO_INPUT2传入的to_add/to_remove为空向量ENETWORK_ID_EVENT_HANDLE_INVALID3事件句柄未初始化或重复初始化MAX_ADDR_IDENTITIES100单个地址可持有的最大身份数量错误码统一通过Std::Errors的already_published、not_published、invalid_argument、limit_exceeded包装后抛出便于链下根据规范错误码分类处理。初始化流程两步走缺一不可第一步初始化全局事件句柄TC 专属public fun initialize_network_identity_event_handle(tc_account: signer)实现要点源码 L46-L59Roles::assert_treasury_compliance(tc_account)强制调用者具备 Treasury Compliance 角色角色校验逻辑见 Roles.move其内部再经CoreAddresses::assert_treasury_compliance校验地址断言TreasuryCompliance下尚未存在该资源否则以ENETWORK_ID_EVENT_HANDLE_INVALID已发布中止通过Event::new_event_handle创建事件句柄并move_to到 TC 账户。辅助查询函数tc_network_identity_event_handle_exists(): bool直接检查existsNetworkIdentityEventHandle(TreasuryCompliance)源码 L61-L63后续所有增删操作都以它作为前置闸门。第二步为账户初始化空身份列表fun initialize_network_identity(account: signer)Vector::empty创建空集合并move_to(account, NetworkIdentity { identities })源码 L66-L69。该函数是私有函数对外由add_identities在首次添加时自动触发惰性初始化因此调用方通常无需显式初始化。查询与变更 APIget / add / removeget读取账户全部身份public fun get(account_addr: address): vectorvectoru8 acquires NetworkIdentity若账户尚未发布NetworkIdentity资源则抛出ENETWORK_ID_DOESNT_EXIST否则返回borrow_global引用的拷贝源码 L76-L82。add_identities批量添加可重复、自动去重、惰性初始化public fun add_identities(account: signer, to_add: vectorvectoru8) acquires NetworkIdentity, NetworkIdentityEventHandle执行流程源码 L89-L117前置校验tc_network_identity_event_handle_exists()必须为真否则以ENETWORK_ID_EVENT_HANDLE_INVALID中止to_add非空否则以ENETWORK_ID_NO_INPUT中止惰性初始化若account尚无NetworkIdentity资源先调用initialize_network_identity容量校验现有数量 新增数量 MAX_ADDR_IDENTITIES(100)否则以ENETWORK_ID_LIMIT_EXCEEDED中止。注意此处是相加后再校验因此即使to_add内含重复元素导致实际只新增少量也按名义数量计算去重合并委托add_members_internal执行集合语义的批量插入事件发射仅当has_change true确实新增了元素时向 TC 账户的事件句柄发射NetworkIdentityChangeNotificationtime_rotated_seconds取DiemTimestamp::now_seconds()。remove_identities批量移除跳过不存在的元素public fun remove_identities(account: signer, to_remove: vectorvectoru8) acquires NetworkIdentity, NetworkIdentityEventHandle执行流程源码 L149-L178同样要求事件句柄已存在、to_remove非空额外校验num_to_remove MAX_ADDR_IDENTITIES移除侧也设上限要求目标账户已存在NetworkIdentity资源与add的惰性初始化不同remove不会自动创建直接以ENETWORK_ID_DOESNT_EXIST中止委托remove_members_internal执行集合语义的批量删除——对to_remove中不存在的元素静默跳过仅当has_change true时发射变更事件。实现精髓用向量模拟集合的*_members_internal两个内部函数是整个模块最值得研读的部分源码 L204-L349它们把向量当作集合使用add_members_internalT: copy遍历to_add仅当members中不含当前元素时才push_back因此members始终保持元素唯一to_add允许含重复元素返回值Vector::length(members) num_existing精确表达是否真的发生了新增该布尔值直接决定上层是否发事件循环体内嵌大量spec invariant包括集合规模只增不减、元素唯一性始终成立、左半区与原集合完全一致、右半区元素均来自to_add已遍历前缀等供形式化验证器证明算法正确性。remove_members_internalT: drop遍历to_remove用Vector::index_of查找命中则Vector::swap_remove交换删除O(1) 摊销未命中的元素静默跳过返回值Vector::length(members) num_existing表示确实发生了删除循环不变量保证集合规模只减不增、唯一性保持、当前集合不含任何已处理过的to_remove元素、且不会误删不在to_remove中的原元素。性能提示由于add/remove_members_internal均线性扫描Vector::contains/index_of单次操作复杂度为 O(n)在MAX_ADDR_IDENTITIES 100的约束下完全可接受——这正是容量上限存在的意义之一。形式化规范Move Prover 如何证明其正确性模块随源码附带完整 Move Prover 规范NetworkIdentity.move 内 spec 块值得关注的设计UniqueMembersTschema声明向量内任意两个位置相等元素的位置索引必相同即全模块统一的集合唯一性不变量同时被NetworkIdentity资源规范和两个 internal 函数复用AddMembersInternalEnsures/RemoveMembersInternalEnsuresschema分别用全称量词表达所有to_add元素都进集合旧元素全部保留新集合元素只来自旧集合或to_add等三组双射式保证删除侧对应表达所有to_remove元素都不在集合中新集合元素均来自旧集合未被移除的旧元素必须保留pragma opaqueensures [concrete] true将 internal 函数设为不透明调用方add_identities/remove_identities只能依赖 schema 保证从而降低验证规模pragma verify falseremove_members_internal因循环不变量复杂、量词使用密集源码注释明确说明其验证耗时超过 200 秒故暂时关闭验证并留下 TODO 说明源码 L319-L324add_identities的 spec 同样标注verifyfalse并注明due to timeout。add_identities/remove_identities的 spec 还精确刻画了中止条件aborts_if、全局状态修改modifies与事件发射语义emits msg to handle if has_change并与DiemTimestamp::AbortsIfNotOperating联动——只有系统处于 operating 状态才允许发事件。端到端验证功能测试演示完整生命周期仓库自带的 Move 功能测试完整演示了该模块的使用姿势见 network_identity.move前置由 blessedTC账户为 bob 创建 ParentVASP 账户初始化NetworkIdentity::initialize_network_identity_event_handle(tc_account)创建全局事件句柄首次添加add_identities(tc_account, Vector::singleton(bid_1))——注意传入的是 TC 账户自身地址随后get断言id_1已存在测试通过// check: NetworkIdentityChangeNotification断言事件确实发射追加再次add_identities添加id_2并断言id_1、id_2同时存在验证去重合并不丢旧数据移除remove_identities(tc_account, Vector::singleton(bid_2))断言id_1仍在、id_2已消失。该测试从初始化 → 增 → 查 → 增 → 删 → 查的完整链路逐一验证了文档中每个公开函数的行为与事件语义。周边参照模块演进中的另一份NetworkIdentity文档在框架文档目录中还存在一份 AccountNetworkIdentity.md其模块名同样是0x1::NetworkIdentity但数据结构走向结构化以AddressList待监听地址列表、PublicKey32 字节 x25519 公钥规范强制len(bytes) KEY_LENGTH、NetworkIdentity { peer_id, public_key }三元组和NetworkIdentities资源组织提供initialize/get/ensure_exists/add_identity/update_identities接口且资源具备copy, drop, key能力。从源码结构看两者是同一命名空间下不同演进形态的身份管理实现一份管理裸字节身份集合 TC 全局事件另一份管理peer_id 公钥的结构化身份。读者在分析具体版本时需先确认当前链上发布的字节码对应哪一份文档框架正式发布产物文档见 releases/artifacts/current/docs/modules/NetworkIdentity.md。小结NetworkIdentity模块以极简的字节集合 全局事件句柄模型解决了 Diemnet 网络身份的上链持久化与变更通知问题。其要点可归纳为数据即集合vectorvectoru8配合UniqueMembers不变量实现唯一性语义TC 集中管控所有变更必须经过 Treasury Compliance 账户事件统一汇聚在TreasuryCompliance变更必留痕只有真实变更才发射事件事件携带账户、新集合与轮换时间构成可审计的链上记录规范驱动Move Prover 规范以 schema 复用方式证明集合操作的正确性是学习 Move 形式化验证的优质范本。结合模块源码、框架文档索引与功能测试开发者可以完整还原该模块的设计意图与运行行为并将其模式复用到其他链上集合管理 事件通知场景。【免费下载链接】diemDiem’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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
