DVT(Distributed Validator Technology) + BLS(Boneh-Lynn-Shacham)签名聚合系统,用于去中心化的operator惩罚(slash)决策。
核心特点:
- 最小节点数: 3个DVT验证者
- 阈值共识: 2/3或大于2/3 (例如7个节点需要5个签名)
- 签名聚合: 链下BLS聚合,链上单proof验证
- Gas效率: ~85% Gas节省 vs 链上多签
graph TB
subgraph "链下 DVT P2P 网络"
V1[Validator 1<br/>监听提案]
V2[Validator 2]
V3[Validator 3]
V4[Validator 4]
V5[Validator 5]
V6[Validator 6]
V7[Validator 7]
V1 -->|P2P广播| V2
V2 -->|累积签名| V3
V3 -->|传递| V4
V4 -->|传递| V5
V5 -->|传递| V6
V6 -->|传递| V7
V7 -->|检测阈值达到| AGG[BLS聚合器]
AGG -->|生成proof| SUBMIT[提交交易]
end
subgraph "链上智能合约"
DVT[DVTValidator.sol<br/>提案管理]
BLS[BLSAggregator.sol<br/>BLS验证]
SP[SuperPaymaster.sol<br/>执行惩罚]
SUBMIT -->|executeWithProof| DVT
DVT -->|verifyAndExecute| BLS
BLS -->|executeSlashWithBLS| SP
end
style AGG fill:#f9f,stroke:#333
style SUBMIT fill:#9f9,stroke:#333
sequenceDiagram
participant V1 as Validator 1
participant P2P as P2P网络
participant V7 as Validator 7<br/>(最后收集者)
participant Chain as 链上合约
V1->>Chain: 1. createProposal(operator, level, reason)
Chain-->>V1: proposalId
V1->>P2P: 2. 广播提案 + BLS签名1
P2P->>V7: 3. 传递签名(经V2-V6累积)
Note over V7: 4. 收集到7个BLS签名<br/>达到阈值(7 >= 7)
V7->>V7: 5. BLS聚合<br/>7个签名 → 1个proof
V7->>Chain: 6. executeWithProof(id, proof)
Chain->>Chain: 7. BLS验证proof
Chain->>Chain: 8. executeSlash(operator)
struct SlashProposal {
address operator; // 被惩罚的operator地址
uint8 slashLevel; // 惩罚级别: 0=WARNING, 1=MINOR, 2=MAJOR
string reason; // 惩罚原因
bool executed; // 是否已执行
// ✅ 不存储个体签名 - 全部链下处理
}// ABI编码格式
bytes memory proof = abi.encode(
bytes pkG1, // 聚合公钥 (G1点, 128字节)
bytes sigG2, // 聚合签名 (G2点, 256字节)
bytes msgG2, // 消息哈希的G2映射 (256字节)
uint256 signerMask // 签名者位掩码 (例如0x7F = 0111 1111)
);msgG2内容 (统一message schema):
bytes memory msgG2Bytes = abi.encode(
proposalId, // 提案ID
operator, // operator地址
slashLevel, // 惩罚级别
repUsers, // reputation影响的用户
newScores, // 新的reputation分数
epoch, // epoch编号
chainid // 链ID(防跨链重放)
);示例: 7个validator签名
位掩码: 0x7F = 0b01111111
位0 → Validator #0 ✅
位1 → Validator #1 ✅
位2 → Validator #2 ✅
位3 → Validator #3 ✅
位4 → Validator #4 ✅
位5 → Validator #5 ✅
位6 → Validator #6 ✅
位7 → (未使用)
计数: __builtin_popcount(0x7F) = 7
// 单个validator的BLS签名
interface IndividualBLSSignature {
validator: string; // validator地址
publicKey: Uint8Array; // BLS公钥 (G1点, 48字节压缩)
signature: Uint8Array; // BLS签名 (G2点, 96字节压缩)
message: Uint8Array; // 被签名的消息
}// 聚合后的BLS proof
interface AggregatedBLSProof {
aggregatedPk: Uint8Array; // 聚合公钥 (G1, 128字节未压缩)
aggregatedSig: Uint8Array; // 聚合签名 (G2, 256字节未压缩)
messageG2: Uint8Array; // 消息的G2映射 (256字节)
signerMask: bigint; // 签名者位掩码
}参考: aastar-sdk 仓库的DVT服务实现
关键模块:
aastar-sdk/
└── packages/
└── dvt/
├── src/
│ ├── p2p/
│ │ ├── network.ts # P2P网络层
│ │ └── protocol.ts # DVT协议
│ ├── bls/
│ │ ├── signer.ts # BLS签名
│ │ └── aggregator.ts # BLS聚合 ⭐
│ └── proposal/
│ ├── monitor.ts # 监听链上提案
│ └── executor.ts # 提交proof
└── examples/
└── dvt-node.ts # 完整DVT节点示例
// @aastar/dvt/src/bls/aggregator.ts
import { bls } from '@noble/curves/bls12-381';
export class BLSAggregator {
/**
* 聚合多个BLS签名
* @param signatures - 个体签名数组
* @returns 聚合后的proof
*/
aggregateSignatures(
signatures: IndividualBLSSignature[]
): AggregatedBLSProof {
// 1. 验证所有签名针对同一消息
const message = signatures[0].message;
for (const sig of signatures) {
if (!bytesEqual(sig.message, message)) {
throw new Error('All signatures must be for same message');
}
}
// 2. 聚合公钥 (G1点加法)
const pks = signatures.map(s => bls.G1.ProjectivePoint.fromHex(s.publicKey));
const aggregatedPk = pks.reduce((acc, pk) => acc.add(pk));
// 3. 聚合签名 (G2点加法)
const sigs = signatures.map(s => bls.G2.ProjectivePoint.fromHex(s.signature));
const aggregatedSig = sigs.reduce((acc, sig) => acc.add(sig));
// 4. 计算message的G2映射
const messageG2 = bls.G2.hashToCurve(message);
// 5. 生成签名者位掩码
const signerMask = this.buildSignerMask(signatures);
return {
aggregatedPk: aggregatedPk.toRawBytes(), // 128字节
aggregatedSig: aggregatedSig.toRawBytes(), // 256字节
messageG2: messageG2.toRawBytes(), // 256字节
signerMask
};
}
/**
* ABI编码proof用于链上提交
*/
encodeProof(proof: AggregatedBLSProof): Uint8Array {
return ethers.AbiCoder.defaultAbiCoder().encode(
['bytes', 'bytes', 'bytes', 'uint256'],
[
proof.aggregatedPk,
proof.aggregatedSig,
proof.messageG2,
proof.signerMask
]
);
}
}// @aastar/dvt/examples/dvt-node.ts
import { DVTNode } from '@aastar/dvt';
import { BLSAggregator } from '@aastar/dvt/bls';
async function runDVTNode() {
// 1. 初始化DVT节点
const node = new DVTNode({
privateKey: process.env.VALIDATOR_PRIVATE_KEY!,
p2pPort: 30303,
bootstrap: ['validator1.example.com:30303'],
threshold: 5, // 7个节点需要5个签名 (2/3+)
rpcUrl: 'https://sepolia.infura.io/v3/...'
});
// 2. 监听链上proposal事件
node.on('ProposalCreated', async (event) => {
const { proposalId, operator, level } = event.args;
// 3. 验证proposal有效性
if (await node.validateProposal(proposalId)) {
// 4. BLS签名
const signature = await node.signProposal(proposalId);
// 5. P2P广播签名
await node.broadcast({
type: 'PROPOSAL_SIGNATURE',
proposalId,
signature
});
}
});
// 6. 收集P2P签名
node.on('SignatureReceived', async (data) => {
const { proposalId, signatures } = data;
// 7. 检查是否达到阈值
if (signatures.length >= node.threshold) {
// 8. BLS聚合
const aggregator = new BLSAggregator();
const proof = aggregator.aggregateSignatures(signatures);
const encodedProof = aggregator.encodeProof(proof);
// 9. 提交到链上
const tx = await node.contracts.dvtValidator.executeWithProof(
proposalId,
[], // repUsers
[], // newScores
0, // epoch
encodedProof
);
console.log(`Proposal ${proposalId} executed:`, tx.hash);
}
});
await node.start();
console.log('DVT node running on port', node.p2pPort);
}
runDVTNode();| 合约 | 职责 | 核心功能 |
|---|---|---|
| DVTValidator | 提案管理 | - createProposal - 存储proposal信息 - validator权限管理 |
| BLSAggregator | BLS验证 | - BLS proof验证 - 执行slash - Registry更新 |
-
职责重叠
- DVTValidator现在只是"转发器"
- executeWithProof直接调用BLSAggregator
-
Gas节省
- 少一层合约调用
- 减少接口开销
-
代码简化
- 单一合约更易维护
- 减少部署复杂度
-
关注点分离
- DVTValidator = 业务层(提案治理)
- BLSAggregator = 技术层(密码学验证)
-
灵活性
- DVTValidator可以有其他执行路径
- BLSAggregator可以被其他合约复用
-
升级独立性
- 两个合约可独立升级
- BLS验证算法变更不影响提案逻辑
阶段性方案:
当前(V3): 保持分离
- ✅ 架构清晰
- ✅ 职责明确
- ✅ 易于理解
未来(V4): 考虑合并
- 如果DVTValidator没有其他职责扩展
- 如果BLSAggregator只服务DVT
- 那么合并为
DVTSlashGovernance.sol
合并后结构:
contract DVTSlashGovernance {
// Proposal管理
function createProposal(...) external;
// BLS验证 + 执行
function executeWithBLSProof(uint256 id, bytes proof) external {
// 1. 验证proposal存在
// 2. BLS验证proof
// 3. 执行slash
// 4. 更新Registry
}
}| 参数 | 值 | 说明 |
|---|---|---|
| 最小DVT节点 | 3 | 保证基本去中心化 |
| 推荐DVT节点 | 7 | 平衡安全性和效率 |
| 阈值 | ≥ 2/3 | 拜占庭容错 |
| BLS曲线 | BLS12-381 | EIP-2537标准 |
| 公钥大小 | 48/128字节 | 压缩/未压缩 |
| 签名大小 | 96/256字节 | 压缩/未压缩 |
- ✅ 统一message schema
- ✅ 包含proposalId防重放
- ✅ 包含chainid防跨链
- ✅ 链上验证signerMask计数
- ✅ 要求 ≥ 2/3
- ✅ BLS数学验证
⚠️ 需要身份验证⚠️ 需要加密通信⚠️ 防止女巫攻击
- 2026-01-09: 初始版本,重构为纯BLS模式
- 阈值: 修正为≥2/3
- 最小节点: 明确为3个