ERC-1400: 证券型代币标准(Security Token Standard)
ERC-1400 是面向**证券型代币(Security Token)**的标准库:在 ERC-20 基础上增加转账限制、错误码、分区(partition)、文档管理与强制转账(controller)能力,用于合规地发行和管理受监管的数字证券。它不是单一接口,而是整合了 ERC-1410(部分同质化)、ERC-1594(核心转账校验)、ERC-1643(文档管理)、ERC-1644(controller 操作)四部分的组合标准。
该标准由 Security Token Standard 社区维护(Polymath 等推动),已从官方 EIPs 仓库移出,接口以 SecurityTokenStandard/EIP-Spec 为准。
设计动机
普通代币(ERC-20)的转账只需余额足够;证券代币的转账可能因为下列原因失败:
- 交易对手未通过 KYC/AML;
- 代币处于锁仓期(lock-up);
- 交易对方属于受限类别(如发行人关联方);
- 代币级别规则:最大持币人数、单投资者占比上限。
ERC-1400 提供“转账前可预检 + 失败原因码 + 链下数据注入“的机制,让链上和链下都能判断一笔转账是否合规。
组成模块
| 模块 | 职责 |
|---|---|
| ERC-1410 | 分区余额(partitions),余额按 bytes32 partition 拆分 |
| ERC-1594 | 转账校验(canTransfer)、链下数据注入(transferWithData)、发行/赎回语义 |
| ERC-1643 | 文档管理(getDocument / setDocument) |
| ERC-1644 | controller 强制转账(controllerTransfer / controllerRedeem) |
核心接口(IERC1400,继承 IERC20)
interface IERC1400 is IERC20 {
// 文档管理
function getDocument(bytes32 _name) external view returns (string, bytes32);
function setDocument(bytes32 _name, string _uri, bytes32 _documentHash) external;
// 分区信息
function balanceOfByPartition(bytes32 _partition, address _tokenHolder) external view returns (uint256);
function partitionsOf(address _tokenHolder) external view returns (bytes32[]);
// 带数据转账(全同质化)
function transferWithData(address _to, uint256 _value, bytes _data) external;
function transferFromWithData(address _from, address _to, uint256 _value, bytes _data) external;
// 分区转账(部分同质化)
function transferByPartition(bytes32 _partition, address _to, uint256 _value, bytes _data) external returns (bytes32);
function operatorTransferByPartition(bytes32 _partition, address _from, address _to, uint256 _value, bytes _data, bytes _operatorData) external returns (bytes32);
// Controller(监管方 / 发行方)
function isControllable() external view returns (bool);
function controllerTransfer(address _from, address _to, uint256 _value, bytes _data, bytes _operatorData) external;
function controllerRedeem(address _tokenHolder, uint256 _value, bytes _data, bytes _operatorData) external;
// Operator 管理
function authorizeOperator(address _operator) external;
function revokeOperator(address _operator) external;
function isOperator(address _operator, address _tokenHolder) external view returns (bool);
// 发行 / 赎回
function isIssuable() external view returns (bool);
function issue(address _tokenHolder, uint256 _value, bytes _data) external;
function redeem(uint256 _value, bytes _data) external;
function redeemFrom(address _tokenHolder, uint256 _value, bytes _data) external;
// 转账预检
function canTransfer(address _to, uint256 _value, bytes _data) external view returns (byte, bytes32);
function canTransferFrom(address _from, address _to, uint256 _value, bytes _data) external view returns (byte, bytes32);
}
关键概念
分区(Partition)
余额可以按 bytes32 分区拆分,例如“一级市场发行所得“与“二级市场交易所得“分开记账。balanceOfByPartition 查询某分区余额;所有分区余额之和等于总余额。分区元数据决定该部分代币的锁仓与转让限制。
带数据转账
transferWithData / transferByPartition 接受额外的 bytes _data 参数,用于注入链下签名数据(如券商对这笔交易的审批)。数据格式由实现定义,不在标准范围内。
转账预检与错误码
canTransfer 返回 (byte statusCode, bytes32 reason),遵循 EIP-1066 的应用状态码:
| 码 | 含义 |
|---|---|
0x50 | 转账失败(通用) |
0x51 | 转账成功 |
0x52 | 余额不足 |
0x53 | 授权额度不足 |
0x54 | 合约暂停 |
0x55 | 锁仓期 |
0x56 | 发送方无效 |
0x57 | 接收方无效 |
0x58 | operator 无效 |
0x5f | 代币元数据 / 信息 |
Controller 强制操作
当 isControllable() == true 时,controller(监管机构、过户代理或发行方)可以绕过持有人授权执行 controllerTransfer / controllerRedeem,用于司法冻结、找回丢失私钥、纠正欺诈交易。强制操作必须发出 ControllerTransfer / ControllerRedemption 事件,保证透明可审计。
事件
TransferByPartition(fromPartition, operator, from, to, value, data, operatorData)
ChangedPartition(fromPartition, toPartition, value)
AuthorizedOperator(operator, tokenHolder) / RevokedOperator(operator, tokenHolder)
ControllerTransfer(controller, from, to, value, data, operatorData)
ControllerRedemption(controller, tokenHolder, value, data, operatorData)
Document(name, uri, documentHash)
Issued(operator, to, value, data) / Redeemed(operator, from, value, data)
IssuedByPartition(...) / RedeemedByPartition(...)
对照
| ERC-20 | ERC-1400 | |
|---|---|---|
| 转账校验 | 余额 + allowance | 余额 + 身份 + 合规规则 + 链下数据 |
| 失败反馈 | 无(revert) | canTransfer 错误码 |
| 余额模型 | 单一 | 分区(partial fungibility) |
| 强制操作 | 无 | controllerTransfer / controllerRedeem |
| 文档 | 无 | getDocument / setDocument |