构建类 Chainlink 的去中心化预言机网络,支持链下数据聚合、多节点共识与链上数据投喂
┌─────────────────────────────────────────────────────────────┐ │ Oracle Node Cluster │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Node 1 │ │ Node 2 │ │ Node N │ │ │ │ (Leader) │◄─┤ (Follower) │◄─┤ (Follower) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ └────────────────┼────────────────┘ │ │ │ libp2p │ ├─────────────────────────────────────────────────────────────┤ │ Consensus Layer (OCR) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Observation │ │ Report Gen │ │ Transmission │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ Data Source Adapters │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │Binance │ │Coinbase│ │Uniswap │ │ API │ │ IPFS │ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ On-Chain Contracts (Aggregator, AccessControl, Staking) │ └─────────────────────────────────────────────────────────────┘
1// OCRProtocol 链下报告共识2type OCRProtocol struct {3 nodeID peer.ID4 peers []peer.ID5 threshold int6 currentRound uint647 observations map[uint64][]Observation8}9 10// Observation 节点观测值11type Observation struct {12 NodeID peer.ID13 Value *big.Int14 Timestamp time.Time15 Signature []byte16}17 18// RunConsensusRound 执行共识轮次19func (o *OCRProtocol) RunConsensusRound(20 ctx context.Context,21) (*Report, error) {22 round := atomic.AddUint64(&o.currentRound, 1)23 24 // 1. 收集观测值25 observation, err := o.collectObservation(ctx)26 if err != nil {27 return nil, err28 }29 30 // 2. 广播观测值给所有节点31 signedObs := o.signObservation(observation)32 o.broadcast(ctx, &ObservationMessage{33 Round: round,34 Observation: signedObs,35 })36 37 // 3. 等待收集足够的观测值38 observations, err := o.waitForObservations(ctx, round, o.threshold)39 if err != nil {40 return nil, fmt.Errorf("collect observations: %w", err)41 }42 43 // 4. 如果是 Leader,生成报告44 if o.isLeader(round) {45 report := o.generateReport(round, observations)46 47 // 5. 收集签名48 signatures, err := o.collectSignatures(ctx, report)49 if err != nil {50 return nil, err51 }52 53 report.Signatures = signatures54 return report, nil55 }56 57 // Follower: 等待 Leader 的报告并签名58 return o.waitAndSignReport(ctx, round)59}60 61// generateReport 生成共识报告62func (o *OCRProtocol) generateReport(63 round uint64,64 observations []Observation,65) *Report {66 // 提取所有值并排序67 values := make([]*big.Int, len(observations))68 for i, obs := range observations {69 values[i] = obs.Value70 }71 sort.Slice(values, func(i, j int) bool {72 return values[i].Cmp(values[j]) < 073 })74 75 // 取中位数76 median := values[len(values)/2]77 78 return &Report{79 Round: round,80 MedianValue: median,81 Observations: observations,82 Timestamp: time.Now(),83 }84}