什么是 ERC-3643?

本文介绍了ERC-3643,这是一个以太坊代币标准,专为受监管的资产设计,它通过链上身份、资格检查和模块化合规规则,在ERC-20模型的基础上,支持需要许可的代币。ERC-3643由ERC-3643协会管理,旨在标准化现实世界资产的许可代币化,适用于证券、房地产和基金等用例。

概述

ERC-3643 是以太坊许可型代币的标准,意味着代币只能由满足预定义的合规性规则(如 KYC/AML、投资者资格和管辖区要求)的身份持有和转移。它专为受监管的资产而设计,你必须知道持有该资产以及他们是否被允许持有或交易它。

最初被称为 T-REX (Token for Regulated EXchanges,受监管交易所代币),由 Tokeny 发起,现在正式成为 ERC-3643,并由 ERC-3643 协会管理,该协会专注于将现实世界资产 (RWA) 的许可型代币化进行标准化。

在实践中,ERC-3643 是智能合约套件,共同实现:

  • 链上身份 & 声明(通过 ONCHAINID
  • 合格持有者的身份注册表
  • 模块化合规性规则
  • 代币合约,在转移时强制执行合规性,同时保持与 ERC-20 的兼容性

由于 ERC-3643 将身份和合规性规则直接集成到代币标准中,因此它是代币化 RWA(如证券、房地产、基金和其他受监管工具)的绝佳选择。

你将要做什么

  • 了解与普通 ERC-20 相比,ERC-3643 正在解决什么问题
  • 学习高级架构(核心合约、注册表和角色)
  • 了解如何在链上强制执行身份和合规性
  • 演练 ERC-3643 系统中转移如何运作
  • 概述部署、角色和常见的 RWA 用例

你将需要什么

  • 熟悉 SolidityERC-20 的基础知识
  • 理解 EVM
  • KYC/AML 和监管概念的高级知识
  • 了解 EIP-173(合约所有权)和基于角色的访问控制模式

warning

本指南中的代码示例未经审计,仅用于概念理解。未经彻底审查、测试和独立安全审计,请勿在生产中使用它们。

ERC-3643 解决的问题

在深入研究之前,让我们设置背景。标准 ERC-20 代币是无需许可的。任何人都可以发送它,任何人都可以接收它,并且任何地址都可以持有它。对于像 DAIUNI 这样的资产来说,这是一个特性。

但是,当处理现实世界的资产时,例如代币化的证券(公司股份)或 fractionalized 房地产,这就会成为一个问题。现实世界的法规要求你了解谁持有该资产,并根据以下内容限制转让:

  • 身份:持有人是否通过了 KYC?
  • 管辖权:接收者是否在受制裁国家?
  • 认证:持有人是否是被允许购买此证券的“合格投资者”?
  • 锁定期:资产是否处于无法出售的“锁定期”?

ERC-3643,最初被称为 T-REX (Token for Regulated EXchanges, 受监管交易所代币),旨在将这些规则引入链上。它是一个智能合约套件,使与 ERC-20 兼容的代币具有“合规性感知”。

标准要求

从高层次来看,ERC-3643 的实现应提供:

  • 兼容性和接口
    • 保持 ERC-20 的兼容性
    • 公开用于转移的标准预检查 (canTransfer)
    • 支持受监管流程所需的批量操作和管理功能
  • 身份和合规性
    • 集成链上身份系统(例如,ONCHAINID
    • 转移、铸造和销毁时使用合规性层
  • 控制和操作
    • 支持暂停和冻结(全局、地址级别和部分冻结)
    • 使用 EIP-173 所有权加上 Agent 角色来执行敏感操作(强制转移、恢复、铸造/销毁)

ERC-3643 架构

ERC-3643 是有意的模块化。它没有将所有内容都放在一个单体代币合约中,而是将职责分配给多个合约。

概括地说,核心组件是:

组件 摘要
ONCHAINID 一个单独的身份合约(基于 ERC-734/735),它持有用户可验证的 claim,由受信任的发行者发布。
受信任的发行者注册表 受信任的地址列表(例如,KYC 提供商),可以添加有关用户身份的 claim
Claim Topics 注册表 所需 claim 类型的目录(例如,KYC 验证、合格投资者)。
身份注册表 将钱包映射到 ONCHAINID 和国家/地区,公开 isVerified 等验证。
合规性合约 编码提供和转移规则,在转移之前/之后查询。
许可型代币 (T-REX) 与 ERC-20 兼容的代币。它持有对身份注册表和合规性合约的引用,并在任何转移之前咨询它们。

ONCHAINID

ONCHAINID 是一个通用身份合约,用于记录密钥和可验证的 claim。

claim 示例包括:

  • 地址 X 通过了提供商 Y 的 KYC
  • 此投资者在管辖区 Z 中是合格的

受信任的发行者(如 KYC 提供商或受监管机构)会发布这些 claim。该合约不会直接存储个人身份信息 (PII),而是存储引用和哈希以保护隐私。

多个钱包可以链接到相同的底层身份,并且在代码中,此身份通常被称为 IIdentity。ONCHAINID 充当与合规性相关的事实的锚点

受信任的发行者注册表

受信任的发行者注册表 跟踪哪些 claim 发行者对于给定的代币是受信任的,以及每个发行者可以签署哪些 claim 主题。

例如,你可能会信任:

  • 用于 KYC_VALIDATED 主题的特定 KYC 提供商。
  • 用于 ACCREDITED_INVESTOR 的受监管实体。

只有这些发行者的 claim 才被视为对该代币的合规性检查有效。

Claim Topics 注册表

Claim Topics 注册表 定义哪些 claim 类型对于持有代币很重要,例如:

  • KYC_VALIDATED
  • ACCREDITED_INVESTOR
  • NOT_IN_RESTRICTED_COUNTRY
  • NOT_ON_SANCTIONS_LIST

Trusted Issuers Registry 一起,它定义了需要哪些 claim 以及谁可以发布它们

身份注册表

身份注册表 是代币持有者的看门人:

  • 存储每个列入白名单的钱包的 ONCHAINID
  • 公开 isVerified(address)
  • 强制只有经过验证的身份才能保留注册

它通常依赖于 IdentityRegistryStorage,因此多个代币可以共享一个白名单,同时保留特定于代币的注册表。在 KYC 之后,投资者链接或部署 ONCHAINID,从受信任的发行者收到所需的 claim,并且他们的钱包已注册国家/地区代码(ISO-3166 数字)。

合规性合约

合规性 合约编码提供规则和转移限制。例子:

  • 每个国家/地区的投资者人数上限。
  • 每个投资者的最大仓位规模。
  • 管辖区允许/拒绝列表。
  • 基于时间的规则,如锁定期和归属。

标准接口:

function canTransfer(address from, address to, uint256 amount) external view returns (bool);
function transferred(address from, address to, uint256 amount) external;
function created(address to, uint256 amount) external;
function destroyed(address from, uint256 amount) external;

代币合约使用合规性合约来:

  • 预先检查是否允许转移 (canTransfer)。
  • 在转移、铸造和销毁后通知合规性逻辑 (transferredcreateddestroyed),以便它可以保持内部状态(上限、计数器等)同步。

许可型代币 (T-REX)

该代币实现标准 ERC-20 功能,并保存对 IdentityRegistryCompliance 合约的引用。它不会盲目地发送代币,而是通过一些额外的检查来路由每个转移,以确保允许移动。它用以下内容包装转移:

  1. 暂停/冻结检查
  2. 合规性检查
  3. 转移后Hook (transferred)

典型的扩展包括:

  • 强制转移和代币恢复
  • 暂停/冻结(全局和每个地址)
  • 部分冻结(只有部分余额是可移动的)
  • 批量操作

RWA 代币转账如何运作

现在,让我们逐步了解 ERC-3643 代币转账是如何运作的。

步骤 1:用户发起转移

用户(Alice)像往常一样调用代币的 transfertransferFrom 函数,以将代币转账到新地址(Bob):

token.transfer(bob.address, amount);
token.transferFrom(from, bob.address, amount); // 如果使用 allowance

步骤 2:资格检查

Token 合约不会移动代币。它首先通过 Identity Registry 执行资格检查。该逻辑通常如下:

  1. 检查代币是否已暂停,或者两个地址是否都被冻结
  2. 通过调用 isVerified() 函数,确保接收者已注册并在 IdentityRegistry 中具有所需的 claim

在许多实现中,代币直接调用 identityRegistry.isVerified(...),然后调用 compliance.canTransfer(...)。在其他实现中,资格检查捆绑在 canTransfer 本身中。重要的一点是,在任何余额移动之前,都会强制执行资格合规性规则

步骤 3:合规性评估

在资格检查之后,Token 合约继续进行第二次检查:compliance.canTransfer(alice.address, bob.address, amount)Compliance 合约检查其模块化逻辑,以确定是否允许转移,并且未违反任何规则。

合规性合约可以评估以下规则:

  • 全局上限(例如,每个管辖区的持有人数量)
  • 每个投资者和每个国家/地区的仓位限制
  • 时间窗口、锁定期和归属
  • 为该代币配置的任何自定义模块

如果违反任何规则,canTransfer 将返回 false,并且代币应该回滚。

步骤 4:转移

如果所有检查都通过,则转移像正常的 ERC-20 转移一样执行。然后,Token 调用 compliance.transferred(from, to, amount) 以更新合规性状态,以供将来检查。

在铸造时,Token 调用 compliance.created(to, amount),在销毁时,它调用 compliance.destroyed(from, amount),以便合规性引擎也跟踪供应变化。

可审计性

由于 claim 由受信任的发行者签名并通过 ONCHAINID 存储,因此你可以维护资格的可验证审计跟踪。

你有一个可审计的跟踪

  • 谁在何时持有什么
  • 哪些 claim 和规则允许转移
  • 随着时间的推移,注册表和合规性模块的治理变更

角色和权限

ERC-3643 将 Owner(根据 EIP-173)与可以操作敏感功能的 Agent 地址分开。Agent 角色是标准化的:

interface IAgentRole {
  event AgentAdded(address indexed agent);
  event AgentRemoved(address indexed agent);
  function addAgent(address agent) external;
  function removeAgent(address agent) external;
  function isAgent(address agent) external view returns (bool);
}

Owner 管理代理和高级配置。Agent 执行诸如冻结、强制转移、铸造/销毁和批量操作之类的操作,具体取决于实现。

开发者的核心接口

ERC-3643 实现公开的关键标准化接口:

  • ERC3643 代币
  • 身份注册表
  • 身份注册表存储
  • 合规性
  • 受信任的发行者
  • Claim Topics
interface IERC3643 is IERC20 {
  // getters
  function onchainID() external view returns (address);
  function identityRegistry() external view returns (IIdentityRegistry);
  function compliance() external view returns (ICompliance);
  function paused() external view returns (bool);
  function isFrozen(address user) external view returns (bool);
  function getFrozenTokens(address user) external view returns (uint256);

  // admin
  function pause() external;
  function unpause() external;
  function setAddressFrozen(address user, bool freeze) external;
  function freezePartialTokens(address user, uint256 amount) external;
  function unfreezePartialTokens(address user, uint256 amount) external;
  function setIdentityRegistry(address identityRegistry) external;
  function setCompliance(address compliance) external;

  // lifecycle
  function forcedTransfer(address from, address to, uint256 amount) external returns (bool);
  function mint(address to, uint256 amount) external;
  function burn(address user, uint256 amount) external;
  function recoveryAddress(address lostWallet, address newWallet, address investorOnchainID) external returns (bool);

  // batch helpers
  function batchTransfer(address[] calldata toList, uint256[] calldata amounts) external;
}
interface IIdentityRegistry {
  // wiring
  function setIdentityRegistryStorage(address storageAddr) external;
  function setClaimTopicsRegistry(address topics) external;
  function setTrustedIssuersRegistry(address issuers) external;
  // actions
  function registerIdentity(address user, IIdentity id, uint16 country) external;
  function deleteIdentity(address user) external;
  function updateCountry(address user, uint16 country) external;
  function updateIdentity(address user, IIdentity id) external;
  // reads
  function isVerified(address user) external view returns (bool);
  function identity(address user) external view returns (IIdentity);
  function investorCountry(address user) external view returns (uint16);
}
interface IIdentityRegistryStorage {
  function storedIdentity(address user) external view returns (IIdentity);
  function storedInvestorCountry(address user) external view returns (uint16);
  function addIdentityToStorage(address user, IIdentity id, uint16 country) external;
  function removeIdentityFromStorage(address user) external;
  function modifyStoredInvestorCountry(address user, uint16 country) external;
  function modifyStoredIdentity(address user, IIdentity id) external;
  function bindIdentityRegistry(address identityRegistry) external;
  function unbindIdentityRegistry(address identityRegistry) external;
  function linkedIdentityRegistries() external view returns (address[] memory);
}
interface ICompliance {
  function canTransfer(address from, address to, uint256 amount) external view returns (bool);
  function transferred(address from, address to, uint256 amount) external;
  function created(address to, uint256 amount) external;
  function destroyed(address from, uint256 amount) external;
}
interface ITrustedIssuersRegistry {
  function addTrustedIssuer(IClaimIssuer issuer, uint[] calldata claimTopics) external;
  function removeTrustedIssuer(IClaimIssuer issuer) external;
  function updateIssuerClaimTopics(IClaimIssuer issuer, uint[] calldata claimTopics) external;
  function getTrustedIssuers() external view returns (IClaimIssuer[] memory);
  function isTrustedIssuer(address issuer) external view returns (bool);
  function getTrustedIssuerClaimTopics(IClaimIssuer issuer) external view returns (uint[] memory);
  function getTrustedIssuersForClaimTopic(uint256 claimTopic) external view returns (IClaimIssuer[] memory);
  function hasClaimTopic(address issuer, uint claimTopic) external view returns (bool);
}
interface IClaimTopicsRegistry {
  function addClaimTopic(uint256 claimTopic) external;
  function removeClaimTopic(uint256 claimTopic) external;
  function getClaimTopics() external view returns (uint256[] memory);
}

设计回顾

至少,ERC-3643 代币部署涉及:

  • 部署注册表:ClaimTopicsRegistryTrustedIssuersRegistryIdentityRegistryStorageIdentityRegistry
  • 配置主题和发行者:添加 claim 主题和受信任的发行者及其支持的主题。
  • 将存储绑定到身份注册表,并在身份注册表上设置注册表。
  • 部署 Compliance,并在部署后将其绑定到代币。
  • 部署代币,并引用 IdentityRegistryCompliance
  • 设置 OwnerAgent 角色,并将敏感功能限制为代理。
  • 在身份注册表中注册投资者身份 (addressONCHAINIDcountry)。
  • 使用 mint 分配供应,并确保铸造/销毁调用 created/destroyed

常见用例

  • 代币化的私募股权基金/风险投资基金/私募股权: 仅限于合格或机构投资者
  • 证券代币发行 (STO): 强制执行管辖权限制、最大持有人、锁定期等。
  • 代币化的房地产: 确保只有符合条件的投资者才能持有财产的部分所有权
  • 受监管的交易场所: 构建合规的二级市场,在其中链上验证每个买卖订单

由于它仍然与 ERC-20 兼容,因此 ERC-3643 代币可以与钱包、托管人、交易所(中心化或分散式,在允许的情况下)以及投资组合和分析工具集成,只要这些平台准备好处理资产的许可性质(例如,处理由于合规性导致的转移回滚)。

接下来是什么

从这里,你可以:

深入研究诸如交割与支付 (DvD)、交易所集成和可升级性模式之类的极端情况,这些模式超出了本概述的范围。

  • 探索参考实现

克隆 ERC-3643 / T-REX 存储库,将注册表和代币部署到本地或测试网环境,并尝试符合合规性和不合规性的转移。

  • 制作一个简单的 RWA 用例原型

例如:

  • 一个代币化的私募股权基金,其中只有来自特定辖区的合格投资者才能持有该代币
  • 一种具有锁定期和转移窗口的代币化房地产资产

使用 ERC-3643 将这些规则直接编码到代币中。

  • 构建监控和合规性工具

使用 Quicknode Streams 订阅到:

  • 来自你的 ERC-3643 代币的 Transfer 事件
  • 来自你的合规性模块的自定义事件(例如,违反规则、强制转移)

    然后将该数据馈送到仪表板、警报系统或内部合规性工具中。

当你探索这些后续步骤时,你将更加清楚地了解 ERC-3643 如何融入你自己的 RWA 或证券代币路线图。

结论

在本指南中,你学习了 ERC-3643 如何在熟悉的 ERC-20 模型之上分层链上身份、资格检查和模块化合规性规则,以支持受监管的许可资产。

如果你正在以太坊或其他 EVM 链上构建 RWA 或证券代币基础设施,ERC-3643 提供了一个开源基础 (T-REX),而不是从头开始重新发明合规性。结合 Quicknode 的可靠基础设施,你可以设计、部署和监控符合现实世界监管框架的许可代币。

订阅我们的新闻通讯,了解更多文章和指南。通过 Twitter 分享反馈或加入我们的 Discord 社区服务器。

我们 ❤️ 反馈!

如果你有任何反馈或对新主题的请求,请告诉我们。我们很乐意听到你的来信。

  • 原文链接: quicknode.com/guides/rea...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。