教程区块链区块链技术第9章 去中心化应用生态

本页目录

DeFi 可组合性、AMM 数学、稳定币机制、NFT 标准、DID/DAO、去中心化存储与预言机——扫描去中心化应用生态的核心构件。

本章目录:

  • 9.1 DeFi 协议的可组合性
  • 9.2 自动做市商(AMM)数学模型
  • 9.3 稳定币机制:抵押型、算法型与混合型
  • 9.4 NFT 标准(ERC-721 / 1155)与数字资产确权
  • 9.5 去中心化身份(DID)与可验证凭证
  • 9.6 DAO 治理模式:代币投票、委托与多签
  • 9.7 去中心化存储:IPFS、Arweave 与 Filecoin
  • 9.8 预言机:Chainlink 机制与数据上链

9.1 DeFi 协议的可组合性

去中心化金融(DeFi)的核心创新不是创造出新的金融产品,而是创造出可组合(Composable)的金融原语——每个协议都像一块"货币乐高",可以在无许可的情况下被任意组合、叠加、嵌套。这种可组合性带来了前所未有的金融创新速度,也引入了"组合即漏洞"的系统性风险。


9.1.1 "货币乐高"的底层逻辑

传统金融的"组合"需要合同谈判、KYC、法律框架,DeFi 的组合只需智能合约调用

graph LR

    A["闪电贷

    Aave/dYdX"] --> B["DEX 套利

    Uniswap"]

    B --> C["收益聚合

    Yearn"]

    C --> D["衍生品对冲

    dYdX/GMX"]

    D --> A

    style A fill:#e6f3ff

    style B fill:#ccffcc

    style C fill:#ffffcc

    style D fill:#ffcccc

一笔交易可同时横跨 4-5 个协议,每个协议的前端甚至不知道用户正在使用它们——这在传统金融中是不可想象的。


9.1.2 闪电贷:零本金的原子套利

闪电贷(Flash Loan) 是 DeFi 可组合性的极致体现:

  • 用户可在一笔交易中借出数百万美元
  • 无需抵押,但必须在同一个交易的最后一步归还本金 + 手续费;
  • 如果未归还,整个交易原子回滚
graph TD

    A["开始交易"] --> B["从 Aave 借出 1000 ETH"]

    B --> C["在 DEX A 用 1000 ETH 买 3000 USDC

    假设 DEX A 价格偏低"]

    C --> D["在 DEX B 用 3000 USDC 卖回 1005 ETH

    假设 DEX B 价格偏高"]

    D --> E{归还 >= 1000.09 ETH?}

    E -->|是| F["向 Aave 归还 1000.09 ETH

    0.09% 手续费"]

    E -->|否| G["整笔交易回滚

    借出从未发生"]

    F --> H["套利利润: 4.91 ETH"]

    style F fill:#ccffcc

    style G fill:#ffcccc

9.1.3 收益聚合器:组合的自动化

Yearn Finance 的核心价值是自动组合策略:

  1. 将用户存款(如 USDC)存入 Aave 赚取利息;
  2. 当 Compound 利率更高时,自动迁移;
  3. 当发现流动性挖矿(如 CRV 奖励)机会时,自动参与挖取;
  4. 挖得的奖励自动复投。

用户只需存入一次,Yearn 的合约自动执行数十次跨协议操作。


9.1.4 组合即漏洞:系统性风险

Cream Finance 被攻击案例(2021 年)

  • 攻击者利用闪电贷操纵 AMM 价格预言机;
  • 操纵后的虚假价格被 Cream 的借贷协议采用;
  • 攻击者以虚高抵押物借出真实资产;
  • 整个过程不涉及任何"单协议漏洞",而是协议间组合的信任传递问题。
ts

// flashloan-risk-sim.ts

// 纯内置:模拟闪电贷原子套利与价格操纵风险



interface Pool {

  tokenA: string; tokenB: string; reserveA: number; reserveB: number; k: number;

}



function getPrice(pool: Pool): number { return pool.reserveB / pool.reserveA; }



function swapAtoB(pool: Pool, amountA: number): number {

  const outB = pool.reserveB - pool.k / (pool.reserveA + amountA);

  pool.reserveA += amountA; pool.reserveB -= outB; pool.k = pool.reserveA * pool.reserveB;

  return outB;

}



function atomicArb(poolA: Pool, poolB: Pool, flashAmount: number): { profit: number; success: boolean } {

  const initialA = poolA.reserveA;

  // 模拟: 先用大量资金操纵 poolA 价格

  const boughtB = swapAtoB(poolA, flashAmount);

  const priceA = getPrice(poolA); // 价格被拉高

  const priceB = getPrice(poolB); // 价格正常

  if (priceA > priceB * 1.02) {

    // 在 poolB 卖 B 买回 A,理论上可套利

    const backA = swapAtoB(poolB, boughtB * priceB / priceA); // 反向操作

    const profit = backA - flashAmount;

    return { profit, success: profit > 0 };

  }

  return { profit: 0, success: false };

}



const pool1: Pool = { tokenA: 'WETH', tokenB: 'USDC', reserveA: 1000, reserveB: 3000000, k: 3_000_000_000 };

const pool2: Pool = { tokenA: 'WETH', tokenB: 'USDC', reserveA: 10000, reserveB: 30000000, k: 300_000_000_000 };



const result = atomicArb(pool1, pool2, 100); // 闪电贷 100 WETH 操纵小池

console.log(`套利结果: 利润 result.profit.toFixed(2)WETH,成功?{result.profit.toFixed(2)} WETH, 成功?{result.success}`);

// 输出: 大资金的链上价格操纵在小流动性池中可能成功,说明闪电贷+预言机组合风险

9.1.5 可组合性的边界

维度机会风险
------------------
协议间调用无需许可的金融创新一个协议的漏洞会级联到所有下游协议
闪电贷零本金融资、市场效率提升攻击者零成本发动大规模操纵
收益聚合器用户收益最大化策略合约漏洞导致用户资金损失
预言机链上价格发现被操纵的预言机价格引发系统性清算

关键认知一:DeFi 的可组合性不是"功能特性",而是信任传递网络。当协议 A 信任协议 B 的价格、协议 B 信任协议 C 的抵押物时,整条链路的安全等于最弱环节的安全。 Cream Finance 的被攻击不是"被黑客入侵",而是被组合逻辑本身利用。



9.2 自动做市商(AMM)数学模型

在传统金融中,做市商(Market Maker)是指持续为特定资产对提供双向报价的专业机构。在 DeFi 中,自动做市商(AMM)用确定性算法替代了人工报价,用流动性池替代了订单簿。理解 AMM 的数学本质,是理解 DeFi 价格发现机制的前提。


9.2.1 恒定乘积公式:xy=kx \cdot y = k

Uniswap V2 的核心是一条极简的数学公式:

xy=kx \cdot y = k

其中 xx 是池中 Token A 的数量,yy 是 Token B 的数量,kk 是常数(每次交易前后 kk 保持不变,手续费除外)。

交易推导

Alice 用 Δx\Delta x 的 Token A 换取 Token B。新池状态为:

(x+Δx)(yΔy)=k=xy(x + \Delta x) \cdot (y - \Delta y) = k = x \cdot y

求解 Δy\Delta y

Δy=ykx+Δx=yxyx+Δx=y(1xx+Δx)=yΔxx+Δx\Delta y = y - \frac{k}{x + \Delta x} = y - \frac{x \cdot y}{x + \Delta x} = y \left(1 - \frac{x}{x + \Delta x}\right) = \frac{y \cdot \Delta x}{x + \Delta x}

含手续费情况(Uniswap V2 收取 0.3%):

Δy=yΔx(1f)x+Δx(1f),f=0.003\Delta y = \frac{y \cdot \Delta x \cdot (1 - f)}{x + \Delta x \cdot (1 - f)}, \quad f = 0.003

9.2.2 价格与滑点

瞬时价格:当前 Token A 对 Token B 的交换比率为:

PA/B=yxP_{A/B} = \frac{y}{x}

执行价格(考虑滑点):

Pexec=ΔyΔx=yx+ΔxP_{exec} = \frac{\Delta y}{\Delta x} = \frac{y}{x + \Delta x}

Δxx\Delta x \ll x 时,PexecPA/BP_{exec} \approx P_{A/B};当 Δx\Delta x 较大时,滑点显著。

滑点=PA/BPexecPA/B=1xx+Δx=Δxx+Δx\text{滑点} = \frac{P_{A/B} - P_{exec}}{P_{A/B}} = 1 - \frac{x}{x + \Delta x} = \frac{\Delta x}{x + \Delta x}

9.2.3 恒定和与恒定乘积混合:Curve 的稳定币 AMM

对于价格锚定资产(如 USDC/USDT/DAI),恒定乘积曲线会产生巨大滑点(因为 xyx \approx y 时池子位于曲线"平坦区"的远端)。Curve 引入混合曲线:

Annxi+D=AD+Dn+1nnxiA \cdot n^n \cdot \sum x_i + D = A \cdot D + \frac{D^{n+1}}{n^n \cdot \prod x_i}

简化为双资产情况:

A(x+y)+xy=AD+D24A(x + y) + xy = A \cdot D + \frac{D^2}{4}

AA 很大时,曲线近似为恒定和 x+y=Dx + y = D(零滑点);当池子失衡时,曲线近似为恒定乘积(防止枯竭)。

graph TD

    A["x+y=const 直线"] --- B["混合曲线<br>低滑点+防枯竭"]

    B --- C["x*y=const 双曲线"]

    style B fill:#ccffcc

9.2.4 无常损失(Impermanent Loss)

流动性提供者(LP)面临的核心风险:外部价格变化导致 LP 资产价值低于单纯持有的价值

设初始投入时价格为 P0=y0/x0P_0 = y_0/x_0,之后外部价格变为 P1=y1market/x1marketP_1 = y_1^{market}/x_1^{market}

LP 提供的流动性强制池子维持 xy=kx \cdot y = k,因此份额价值为:

VLP=x1P1+y1=2kP1V_{LP} = x_1 \cdot P_1 + y_1 = 2\sqrt{k \cdot P_1}

单纯持有价值为:

Vhold=x0P1+y0V_{hold} = x_0 \cdot P_1 + y_0

无常损失比例:

IL=VholdVLPVhold=2r1+r1,r=P1P0IL = \frac{V_{hold} - V_{LP}}{V_{hold}} = \frac{2\sqrt{r}}{1 + r} - 1, \quad r = \frac{P_1}{P_0}

r=1r = 1(价格不变),IL=0IL = 0;当 r=4r = 4(价格涨 4 倍),IL20%IL \approx -20\%

ts

// amm-constant-product.ts

// 纯内置:模拟恒定乘积 AMM 的交易、滑点和无常损失



class ConstantProductAMM {

  x: number; // Token A reserve

  y: number; // Token B reserve

  k: number;

  fee = 0.003;



  constructor(x: number, y: number) { this.x = x; this.y = y; this.k = x * y; }



  swapAforB(deltaX: number): { deltaY: number; priceBefore: number; priceAfter: number; slippage: number } {

    const effectiveX = deltaX * (1 - this.fee);

    const newX = this.x + effectiveX;

    const newY = this.k / newX;

    const deltaY = this.y - newY;

    const priceBefore = this.y / this.x;

    const priceAfter = newY / newX;

    const slippage = (priceBefore - deltaY / deltaX) / priceBefore;

    this.x = newX; this.y = newY; this.k = newX * newY;

    return { deltaY, priceBefore, priceAfter, slippage };

  }



  addLiquidity(xAdd: number, yAdd: number): number {

    // 按当前比例添加

    const ratio = xAdd / this.x;

    this.x += xAdd; this.y += yAdd; this.k = this.x * this.y;

    return ratio; // LP token 比例

  }



  impermanentLoss(priceRatio: number): number {

    const r = priceRatio;

    return (2 * Math.sqrt(r) / (1 + r)) - 1; // 负值表示损失

  }

}



const amm = new ConstantProductAMM(1000, 3000); // 1 WETH = 3 USDC

console.log(`初始价格: ${amm.y / amm.x} USDC/WETH`);



const swap = amm.swapAforB(10);

console.log(`换出 swap.deltaY.toFixed(2)USDC,滑点:{swap.deltaY.toFixed(2)} USDC, 滑点:{(swap.slippage * 100).toFixed(2)}%`);



// 价格翻倍后的无常损失

console.log(`价格翻倍无常损失: ${(amm.impermanentLoss(2) * 100).toFixed(2)}%`);

console.log(`价格 4 倍无常损失: ${(amm.impermanentLoss(4) * 100).toFixed(2)}%`);

// 输出: 价格涨 4 倍时,LP 相对持有损失约 20%

9.2.5 集中流动性:Uniswap V3 的 =xP\ell = x \cdot \sqrt{P}

Uniswap V3 的核心改进:允许 LP 将流动性集中在特定价格区间,而非全价格域。这意味着同样的资本可以产生更高的费用收入,但也带来了:

  • 价格区间外无流动性:当价格超出选定区间,LP 全部变为单一资产,不再赚取费用;
  • NFT 化 LP 头寸:每个价格区间的流动性头寸是独一无二的,ERC-721 代币化;
  • 刻度系统(Tick):价格空间按 P\sqrt{P} 的 0.01% 间隔离散化,每个刻度可独立提供流动性。

关键认知二:AMM 不是"自动化做市商"的简单翻译,而是用确定性算法替代主观报价的数学承诺。恒定乘积 xy=kx \cdot y = k 的美妙之处在于:它无需预言机输入、无需订单簿撮合、无需信任任何报价者,但也因此引入了滑点和无常损失——这是为"无需许可+去中心化"付出的代价。



9.3 稳定币机制:抵押型、算法型与混合型

稳定币是加密世界的"类美元":它要在没有央行背书的情况下维持对法币(通常是 USD)的锚定。这节剖析三种实现路径——超额抵押(MakerDAO 的 DAI)、纯算法(UST/Luna 的崩溃)和混合型(FRAX)——以及它们各自的经济平衡点与崩溃条件。


9.3.1 抵押型稳定币:MakerDAO 与 DAI

基本原理:用户超额抵押加密资产(如 ETH),铸造与美元 1:1 锚定的 DAI。系统通过清算和债务拍卖维持锚定。

超额抵押率

Collateralization Ratio (CR)=抵押资产 USD 价值铸造 DAI 数量>150%\text{Collateralization Ratio (CR)} = \frac{\text{抵押资产 USD 价值}}{\text{铸造 DAI 数量}} > 150\%

清算机制

当 ETH 价格下跌,某金库的 CR 低于 150%,任何人可以触发:

  1. 清算人 偿还该金库的 DAI 债务;
  2. 以 3% 折扣获得该金库的 ETH(激励清算人参与);
  3. 若 ETH 继续下跌,系统发行 MKR(治理代币) 并拍卖,用所得回购 DAI。
graph TD

    A["用户存入 1500 USD 的 ETH"] --> B["铸造 1000 DAI"]

    B --> C{CR < 150%?}

    C -->|是| D["清算人偿还 1000 DAI"]

    D --> E["清算人获得 1030 USD 的 ETH<br>3% 折扣激励"]

    C -->|否| F["继续持仓"]

    style E fill:#ccffcc

9.3.2 算法稳定币:UST/Luna 的死亡螺旋

Terra 协议设计

  • 用户燃烧 1UST获得1 UST 获得1 等值的 LUNA(治理代币);
  • 用户燃烧 1LUNA获得1 LUNA 获得1 UST;
  • 协议通过"套利激励"维持锚定——如果 UST 低于 $1,套利者买 UST 换 LUNA 卖,销毁 UST 推高价格。

崩溃条件(死亡螺旋)

当 PLUNA供应量LUNA<UST 流通量无法完全赎回\text{当 } P_{LUNA} \cdot \text{供应量}_{LUNA} < \text{UST 流通量} \Rightarrow \text{无法完全赎回}

2022 年 5 月:UST 脱钩引发 LUNA 抛售,LUNA 价格暴跌使得铸币回收机制无法运行,两者同时归零,损失约 $40B。

graph TD

    A["UST 脱钩至 $0.95"] --> B["套利者买 UST 换 LUNA 卖"]

    B --> C["LUNA 供应量激增<br>价格暴跌"]

    C --> D["UST 信心丧失

    大规模赎回"]

    D --> E["LUNA 进一步下跌"]

    E --> F["UST 完全无法赎回

    归零"]

    style F fill:#ffcccc

9.3.3 混合型:FRAX 的部分抵押模型

FRAX 采用"部分抵押 + 算法调节":

  • 铸造 1 FRAX 时,部分用 USDC 抵押(如 85%),部分用 FXS(治理代币)按市场价格补足(15%);
  • 当 FRAX 高于 $1,降低抵押率,增加 FXS 比重,激励铸币扩大供给;
  • 当 FRAX 低于 $1,提高抵押率,回购销毁 FRAX。
ts

// stablecoin-megs-sim.ts

// 纯内置:模拟 DAI 清算阈值、UST 死亡螺旋与 FRAX 部分抵押



// === DAI 抵押率与清算模拟 ===

function daiLiquidation(threshold = 1.5) {

  const ethPriceSeq = [3000, 2500, 2000, 1500, 1000];

  const debt = 1000; // DAI

  const ethDeposited = 1; // 1 ETH

  

  for (const ethPrice of ethPriceSeq) {

    const cr = (ethDeposited * ethPrice) / debt;

    const isLiquidated = cr < threshold;

    console.log(`ETH 
{ethPrice}, CR: ${cr.toFixed(2)}x, 清算? ${isLiquidated ? 'YES' : 'no'}`); } } daiLiquidation(); // === UST 死亡螺旋简化模拟 === function deathSpiral(initialLunaPrice: number, initialLunaSupply: number, ustSupply: number) { let lunaPrice = initialLunaPrice; let lunaSupply = initialLunaSupply; const marketCaps: number[] = []; for (let round = 0; round < 5; round++) { const lunaMarketCap = lunaPrice * lunaSupply; marketCaps.push(lunaMarketCap); const backingRatio = lunaMarketCap / ustSupply; console.log(`Round ${round}: LUNA cap=
{(lunaMarketCap/1e9).toFixed(1)}B, 可支撑 UST: ${(backingRatio*100).toFixed(1)}%`); if (backingRatio < 1) { console.log('→ 死亡螺旋: 市值不足以赎回全部 UST'); break; } // 模拟赎回恐慌导致 LUNA 抛售和增发 lunaPrice *= 0.5; lunaSupply *= 1.8; // 赎回时大量增发 LUNA } } deathSpiral(80, 350_000_000, 18_000_000_000); // 初始 LUNA $80, 3.5亿枚, UST 180亿 // === FRAX 部分抵押模拟 === function fraxMint(fraxAmount: number, collateralRatio: number, usdcPrice = 1.0, fxsPrice = 5.0) { const usdcNeeded = fraxAmount * collateralRatio; const fxsNeeded = (fraxAmount * (1 - collateralRatio)) / fxsPrice; console.log(`铸造 fraxAmountFRAX:{fraxAmount} FRAX: 需{usdcNeeded.toFixed(2)} USDC + ${fxsNeeded.toFixed(2)} FXS (CR=${collateralRatio*100}%)`); } fraxMint(1000, 0.85); // FRAX 85% 抵押 // 输出对比三种稳定币的抵押机制和脆弱性

9.3.4 三类稳定币对比

特征抵押型 (DAI)算法型 (UST)混合型 (FRAX)
-----------------------------------------------
抵押物超额加密资产无(纯算法)部分抵押+算法
脱钩风险中(黑天鹅清算)极高(死亡螺旋)中(抵押率可调节)
资本效率低(150% 抵押)理论无限(无抵押)中(部分抵押)
中心化程度低(多资产抵押)中(依赖治理代币)
代表事件2020 年 3 月"黑色星期四"清算2022 年 5 月归零FRAX 持续锚定

关键认知三:稳定币的"稳定"不是魔术,而是经济激励与清算机制的游戏。DAI 的 150% 抵押是付出的"保险费",UST 的死亡螺旋是"无抵押"必然面临的尾部风险。在稳定币三重难题(去中心化、稳定性、资本效率)中,任何方案最多只能同时满足两个。



9.4 NFT 标准(ERC-721 / 1155)与数字资产确权

NFT(非同质化代币)不是"数字图片"的同义词,而是链上唯一性证明的通用标准。从游戏道具到房地产凭证,从学位证书到供应链溯源,ERC-721 和 ERC-1155 提供了一套在无需中心机构的情况下,证明"某物的唯一所有权与该所有权转移历史"的基础设施。


9.4.1 非同质化vs同质化:底层数学

同质化代币(ERC-20)的集合论本质:

a,bERC-20:a=bvalue(a)=value(b)\forall a, b \in \text{ERC-20}: a = b \Leftrightarrow \text{value}(a) = \text{value}(b)

非同质化代币(ERC-721)的本质:

a,bERC-721:abtokenId(a)tokenId(b)\forall a, b \in \text{ERC-721}: a \neq b \Leftrightarrow \text{tokenId}(a) \neq \text{tokenId}(b)

关键差异:ERC-20 的余额是一个标量(uint256 balance),ERC-721 的"余额"是一个从 tokenId 到所有者的映射(mapping(uint256 => address) ownerOf)。


9.4.2 ERC-721:唯一性映射的标准

核心状态结构

ts

// 概念性 ERC-721 状态映射

interface ERC721State {

  tokenId: number;

  owner: string;  // 当前所有者地址

  approved: string; // 单地址授权(一次性转移)

  metadataUri: string; // 指向 JSON 元数据的 URI

}

标准接口

  • balanceOf(address):查询某地址持有的 NFT 数量;
  • ownerOf(tokenId):查询特定 NFT 的当前所有者;
  • transferFrom(from, to, tokenId):转移(需经授权或是所有者);
  • safeTransferFrom:转移 + 检查接收方是否为可接收合约。
sequenceDiagram

    participant M as 铸造者

    participant C as ERC-721 合约

    participant A as Alice

    participant B as Bob

    

    M->>C: mint(tokenId=42, to=Alice, uri="ipfs://...")

    C->>C: ownerOf[42] = Alice

    A->>C: approve(Bob, 42)

    C->>C: approved[42] = Bob

    B->>C: transferFrom(Alice, Bob, 42)

    C->>C: require(msg.sender==Bob||approved[42]==Bob)

    C->>C: ownerOf[42] = Bob

    C->>C: approved[42] = 0x0

9.4.3 ERC-1155:半同质化与批量管理

ERC-1155 解决了 ERC-20 + ERC-721 并存时的冗余问题

一个游戏玩家可能同时拥有 1000 个金币(同质)和 1 把传奇剑(非同质)。在 ERC-20/721 时代,这需要两个不同的合约;在 ERC-1155 中,一个合约用 tokenId 区分类型,用 amount 区分数量。

核心映射

balanceOf[address][tokenId]=amount\text{balanceOf[address][tokenId]} = amount
  • tokenId = 1:金币,amount = 1000;
  • tokenId = 42:传奇剑,amount = 1(也可 >1 表示有一定供应限制的半同质资产)。

关键优势

  1. 批量转移:一次性转移多种资产到多个地址,Gas 效率提升 10-100 倍;
  2. 单合约多资产:降低管理复杂度;
  3. 混合型资产:同时支持同质与半同质。
graph LR

    A["ERC-20

    仅同质"] --> B["ERC-721

    仅非同质"]

    A --> C["ERC-1155

    混合"]

    B --> C

    style A fill:#ffffcc

    style B fill:#ccffcc

    style C fill:#99ddff

9.4.4 NFT 的链上确权与链下元数据

NFT 本身不存储图片或数据——它只存储一个指向链下资源的 URI。这使得:

  • 可扩展性:链上数据量恒定(仅需 32 字节的 tokenURI),图片/视频存储在 IPFS/Arweave;
  • 灵活性:元数据可以更新(如果合约设计允许);
  • 风险:若 IPFS 节点全部下线,或中心化服务器关闭,tokenURI 变为"死链接"。

可验证的元数据机制:许多项目使用链上哈希验证:

链上存储:keccak256(metadataJSON)链下提供完整 JSON\text{链上存储}: \text{keccak256(metadataJSON)} \quad \text{链下提供完整 JSON}
ts

// nft-ownership-verification.ts

// 纯内置:模拟 ERC-721 所有权链证明与元数据哈希验证



interface NftRecord {

  tokenId: number;

  owner: string;

  metadataHash: bigint; // keccak256 的链上存储

  history: { from: string; to: string; block: number }[];

}



class NftRegistry {

  tokens = new Map<number, NftRecord>();



  mint(tokenId: number, to: string, metadataHash: bigint): void {

    this.tokens.set(tokenId, { tokenId, owner: to, metadataHash, history: [{ from: '0x0', to, block: 1 }] });

  }



  transfer(tokenId: number, from: string, to: string, block: number): boolean {

    const rec = this.tokens.get(tokenId);

    if (!rec || rec.owner !== from) return false;

    rec.owner = to;

    rec.history.push({ from, to, block });

    return true;

  }



  verifyMetadata(tokenId: number, content: string): boolean {

    // 纯内置哈希: DJB2 模拟 keccak256 的链上验证行为

    let hash = 5381n;

    for (let i = 0; i < content.length; i++) {

      hash = ((hash << 5n) + hash) + BigInt(content.charCodeAt(i));

    }

    const rec = this.tokens.get(tokenId);

    return rec ? rec.metadataHash === hash : false;

  }



  provenance(tokenId: number): NftRecord | null { return this.tokens.get(tokenId) || null; }

}



const registry = new NftRegistry();

registry.mint(42, '0xAlice', 12345n);

registry.transfer(42, '0xAlice', '0xBob', 100);

registry.transfer(42, '0xBob', '0xCarol', 200);



console.log('所有权链:', registry.provenance(42)?.history.map(h => `h.from{h.from}→{h.to}@#${h.block}`).join(', '));

console.log('元数据验证:', registry.verifyMetadata(42, 'fake') ? '正确' : '不匹配');

// 输出: 完整的所有权转移历史和元数据链上验证

9.4.5 超出"数字图片":NFT 的扩展用例

用例机制代表
------------------
灵魂绑定代币(SBT)不可转让的 NFT,绑定到身份学术证书、资质证明
RWA 代币化链上 NFT 代表链下实物资产房地产、发票、碳信用
动态 NFT元数据/图像随链下事件变化游戏角色、体育赛事
版税自动分配每次转售时向创作者输送费用EIP-2981 标准
碎片化将高价值 NFT 拆分为 ERC-20允许小额共同拥有

关键认知四:NFT 的"所有权"不是拥有 JPEG 文件,而是链上社会对"tokenId X 归地址 Y 所有"这一映射的共识。URI 指向的媒体文件可能被复制一万次,但只有持有对应 tokenId 的私钥才能在市场交易它或在游戏中使用它。



9.5 去中心化身份(DID)与可验证凭证

在传统互联网,你的身份是"Facebook 让你登录其他网站"、"银行证明你有信用"、"政府证明你的年龄"。在 Web3 中,DID(去中心化标识符)提出一个激进的概念:你应该拥有和控制自己的身份数据,而不是被锁定在 Facebook、Google 或政府的中心化数据库中。


9.5.1 DID 的三层架构

DID 不是单一的区块链标准,而是一个分层的身份系统

层级功能标准/技术
-----------------------
标识层唯一的、全局可解析的标识符did:ethr:0xabc...
文档层公钥、服务端点、验证方法DID 文档(JSON-LD)
凭证层可验证的声明(VC)W3C VC 数据模型

示例 DID

did:ethr:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed\text{did:ethr:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed}

"解析"(Resolve)这个 DID:

  1. 从 "ethr" 推断是在以太坊链上查找;
  2. 查询该地址对应的 ENS/DID 注册合约;
  3. 获取 DID 文档(包含公钥、认证方法、服务端点)。
graph TD

    A["验证者: 网站/服务"] -->|解析| B["ethr DID 注册合约"]

    B -->|返回| C["DID 文档

    公钥+服务端点"]

    C -->|验证签名| D["可验证凭证 VC"]

    D --> E["持有者钱包

    私钥签名认证"]

    style E fill:#ccffcc

9.5.2 可验证凭证(VC):自主掌控的证书

传统证书:你的大学学位存储在大学数据库中,雇主查询时大学服务器必须在线。

可验证凭证:你的学位被签发者用私钥签名后交给你,你可以在任何时间、任何地方向任何人出示,无需签发者在线

数据结构

json

{

  "@context": ["https://www.w3.org/2018/credentials/v1"],

  "id": "urn:uuid:...",

  "type": ["VerifiableCredential", "UniversityDegree"],

  "issuer": "did:ethr:0xUniversity...",

  "issuanceDate": "2023-06-15",

  "credentialSubject": {

    "id": "did:ethr:0xAlice...",

    "degree": { "type": "BachelorOfScience", "name": "Computer Science" }

  },

  "proof": { "type": "EcdsaSecp256k1Signature2019", "jws": "eyJ..." }

}

验证流程

  1. 验证者获取签发者的 DID 文档,提取其公钥;
  2. 用该公钥验证 VC 上的签名;
  3. 确认 VC 未被撤销(可选,通过链上撤销列表或 Merkle 证明)。

9.5.3 自主身份(SSI)vs 传统身份

维度传统身份(SAML/OAuth)自主身份(DID/VC)
-------------------------------------------------
控制权平台(Google/SSO)用户钱包
可用性依赖 IDP(身份提供商)不依赖签发者在线
隐私平台掌握完整行为数据选择性披露(零知识证明可选)
可移植性身份锁定在平台内跨平台、跨链通用
抗审查平台可冻结账号私钥即身份,无法冻结

9.5.4 选择性披露与零知识凭证

问题:证明"我已成年"不需要透露姓名或具体出生日期。

方案:零知识范围证明(ZKP over VC):

Prover: dob, dob<thresholdwithout revealing dob\text{Prover}: \exists \text{ dob, } \text{dob} < \text{threshold} \quad \text{without revealing dob}

机构签发 VC 证明你的出生日期;你通过 ZK 电路证明"当前时间 - 出生日期 > 18 年",而不透露具体日期。

ts

// did-vc-verification-sim.ts

// 纯内置:模拟 DID 文档解析与可验证凭证签名验证流程



interface DIDDocument {

  id: string;

  verificationMethod: { id: string; type: string; publicKeyHex: string }[];

  authentication: string[];

}



class DIDResolver {

  registry = new Map<string, DIDDocument>();



  register(did: string, doc: DIDDocument): void { this.registry.set(did, doc); }



  resolve(did: string): DIDDocument | null { return this.registry.get(did) || null; }

}



interface VerifiableCredential {

  id: string; issuer: string; subject: string; claim: Record<string, string>;

  // 简化:用哈希值代替 ECDSA 签名验证

  proofHash: bigint;

}



function verifyVC(vc: VerifiableCredential, resolver: DIDResolver): boolean {

  const issuerDoc = resolver.resolve(vc.issuer);

  if (!issuerDoc || issuerDoc.verificationMethod.length === 0) return false;

  // 模拟签名验证: 用公钥拼接 claim 计算哈希

  const key = BigInt('0x' + issuerDoc.verificationMethod[0].publicKeyHex.slice(0, 12));

  let claimHash = key;

  for (const [k, v] of Object.entries(vc.claim)) {

    for (let i = 0; i < (k + v).length; i++) claimHash = (claimHash * 31n + BigInt((k + v).charCodeAt(i))) % (1n << 128n);

  }

  return claimHash === vc.proofHash;

}



const resolver = new DIDResolver();

resolver.register('did:ethr:univ', {

  id: 'did:ethr:univ', verificationMethod: [{ id: 'key1', type: 'Ecdsak1', publicKeyHex: '04a1b2c3d4e5...' }], authentication: ['key1']

});



const degree: VerifiableCredential = {

  id: 'vc:1', issuer: 'did:ethr:univ', subject: 'did:ethr:alice',

  claim: { degree: 'BSc CS', date: '2023-06-15' },

  proofHash: 70184435936962265427522331256n // 预计算的正确哈希

};



console.log('VC 验证结果:', verifyVC(degree, resolver) ? '✅ 有效' : '❌ 无效');

// 输出: DID 文档解析 → 公钥获取 → 签名验证的完整流程

9.5.5 挑战:DID 的采纳困境

  1. 恢复问题:私钥丢失 = 身份丢失,没有"忘记密码"按钮(社会恢复是多签的一种变体);
  2. 互操作性did:ethr(以太坊)、did:ion(比特币侧链)、did:web(传统 DNS),解析器碎片化;
  3. 监管冲突:KYC 要求→真实身份绑定 vs 隐私保护;
  4. 用户体验:管理私钥的门槛远高于"用 Google 登录"。

关键认知五:DID 不是试图让政府或企业"消失",而是将身份数据的控制权从机构手中归还个人。用密码学替代信任、用选择性披露替代全量暴露,是 Web3 身份哲学的核心。但真正的挑战在于:用户是否真的愿意承担管理私钥的责任?



9.6 DAO 治理模式:代币投票、委托与多签

DAO(去中心化自治组织)试图用链上治理替代公司董事会和官僚层级。但"代码即法律"的理想与"投票率低、巨鲸统治、提案操纵"的现实之间存在巨大张力。本节剖析三种主流治理模型及其数学边界。


9.6.1 代币加权投票:一人一票的理想与资本现实

基本原理:持有治理代币者按权重投票,投票结果自动执行。

投票结果=sign(iwivi),wi=tokenBalancei\text{投票结果} = \text{sign}\left(\sum_i w_i \cdot v_i\right), \quad w_i = \text{tokenBalance}_i

根本问题

  • 巨鲸统治:持有 51% 代币者拥有绝对控制权;
  • 投票率极低:大多数 DAO 的投票率 <10%,少数活跃巨鲸决定方向;
  • 资本效率攻击:借入治理代币投票后立即归还("闪电贷投票攻击")。

9.6.2 二次方投票(Quadratic Voting)

思想:投票成本与票数成二次方关系,而非线性:

Cost(n 票)=n2baseCost\text{Cost}(n \text{ 票}) = n^2 \cdot \text{baseCost}

效果:100 个用户各投 1 票 vs 1 个用户投 100 票:

  • 前者总成本:100×12=100100 \times 1^2 = 100
  • 后者总成本:1×1002=10,0001 \times 100^2 = 10{,}000

这使得"集中资本"的优势被显著削弱。Gitcoin Grants 采用此机制资助公共品。

挑战:链上身份可伪造(女巫攻击),二次方投票的公平性依赖于一对一身份验证,而这在匿名链上是未解难题。


9.6.3 委托民主与流动民主

委托民主(Liquid Democracy):选民可将投票权委托给代理人,且可随时撤回。代理人可进一步委托(形成委托链)。

Compound 的实现

  • 用户可将 COMP 代币的委托投票权赋予特定地址;
  • 被委托者自动获得该用户的投票权重;
  • 委托可随时撤销或切换,无需转移代币所有权。
代理人权重=idelegatorsbalancei\text{代理人权重} = \sum_{i \in \text{delegators}} \text{balance}_i

优点:降低参与门槛,普通用户可将投票权委托给"专业治理者"。

缺点:形成新的权力中心(治理巨头),且委托链的复杂性增加了代理人的行为不透明性。


9.6.4 安全阀:时间锁与多签

时间锁(Timelock)

  • 治理投票通过后,不立即执行,而是进入延迟期(如 2 天)后执行;
  • 紧急时刻,多签委员会可取消恶意提案("安全阀"机制)。

多签治理(Gnosis Safe 模式)

  • 核心资金由 N-of-M 多签控制(如 3/5);
  • 多签成员通常为核心开发者或知名社区成员;
  • 日常治理用代币投票,紧急操作用多签名。
graph TD

    A["社区提案"] --> B["代币投票期: 3天"]

    B --> C{通过?}

    C -->|是| D["时间锁: 2天延迟"]

    D --> E["自动执行"]

    C -->|否| F["否决"]

    D --> G["多签委员会

    紧急取消"]

    G --> F

    style D fill:#ffffcc

    style G fill:#ffcccc

9.6.5 Moloch 框架:最小可行 DAO

Moloch 是一个极简的 DAO 框架(约 400 行 Solidity),设计哲学:

  1. 投入/退出机制:成员质押代币(如 WETH)获得投票份额;可随时"愤怒退出"(Rage Quit)——销毁份额并取回相应比例的国库资产;
  2. 提案机制:任何成员可发起提案,投票通过后即可执行;
  3. 捐赠/资助:主要用途是资助公共品和维护者薪酬。

安全边界

攻击成本>单次提案可转移资金×攻击成功概率\text{攻击成本} > \text{单次提案可转移资金} \times \text{攻击成功概率}

愤怒退出机制解决了 51% 攻击的部分风险:即使巨鲸通过恶意提案,被攻击者可在执行前退出并带着资产离开。


9.6.6 治理攻击向量总结

攻击目标防御
------------------
闪电贷投票借入大量代币通过提案后立即归还快照(Snapshot)锁定投票时余额
低投票率操纵用少量资金通过低参与率提案设置法定人数(Quorum)门槛
巨鲸统治大户单方面决定方向二次方投票 / 多签安全阀
提案伏击深夜发布提案,短时间投票强制冷静期、通知期
治理攫取通过提案夺取国库控制权时间锁 + 多签

关键认知六:DAO 不是"没有领导者的乌托邦",而是将行政权力替换为算法化的投票规则。但算法规则本身也是人类设计的——投票门槛、法定人数、代币分配,这些初始参数决定了 DAO 是去中心化还是"伪去中心化"。Moloch 的"愤怒退出"机制是有趣的尝试:它用退出权替代了传统公司的法律保护。



9.7 去中心化存储:IPFS、Arweave 与 Filecoin

以太坊的存储极其昂贵:存储 1 KB 数据约需 20,000 Gas,即数百美元。NFT 的元数据和 DApp 前端显然不能上链。去中心化存储网络在链下提供"类 HTTP"的数据持久性,但用密码学证明替代了中心化服务器的可信度。


9.7.1 IPFS:内容寻址而非位置寻址

HTTP 的缺陷https://server.com/cat.jpg 通过位置寻址——如果服务器下线,链接失效。

IPFS 的内容寻址:通过内容的哈希寻址:

IPFS 地址=multihash(content)=base58(sha2-256(content))\text{IPFS 地址} = \text{multihash}(\text{content}) = \text{base58}(\text{sha2-256}(\text{content}))

CID(Content Identifier)

QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwzE...\text{QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwzE...}

只要内容不变,CID 不变;内容微小改动,CID 完全不同。这天然支持不可篡改性重复内容去重

Merkle DAG 结构

IPFS 内部用 Merkle DAG(有向无环图)组织数据:

  • 大文件分块(256 KB/块),每个块有 CID;
  • 文件对象是一个指向块 CID 列表的节点;
  • 目录是指向文件 CID 的节点。
graph TD

    A["目录 CID: QmRoot"] --> B["子目录: QmDir1"]

    A --> C["文件: QmFile1<br>指向块列表"]

    B --> D["块1: QmB1

    hash=..."]

    B --> E["块2: QmB2

    hash=..."]

    C --> F["块1: QmF1"]

    C --> G["块2: QmF2"]

    C --> H["块3: QmF3"]

    style A fill:#ccffcc

9.7.2 问题:IPFS 不保证持久性

IPFS 节点是自愿的——如果最后一个持有某 CID 的节点下线,该内容就"消失"。

解决方案

  • Pinning Service:如 Pinata、Infura——中心化服务承诺长期保存特定 CID;
  • Filecoin:去中心化的 IPFS 激励层,通过经济激励让矿工存储数据。

9.7.3 Filecoin:存储的激励层

核心机制

  • 存储提供者(矿工)质押 FIL,承诺存储客户数据;
  • 网络定期检查——要求矿工提供时空证明(Proof of Spacetime, PoSt)
  • 如果矿工无法提供证明,质押被削减;

复制证明(Proof of Replication, PoRep)

证明者需要证明:

  1. 数据已被物理存储(不是计算生成);
  2. 数据的 N 个独立副本存在
PoRep=fSNARK(数据,随机挑战)证明\text{PoRep} = f_{SNARK}(\text{数据}, \text{随机挑战}) \rightarrow \text{证明}

时空证明(PoSt)

每隔一段时间,网络向存储者发起挑战,要求证明特定时间窗口内数据持续存在。

PoStt=gSNARK(数据,challenget,previous_PoStt1)\text{PoSt}_t = g_{SNARK}(\text{数据}, \text{challenge}_t, \text{previous\_PoSt}_{t-1})

9.7.4 Arweave:永久存储的一次性付费

哲学差异

  • Filecoin:按时间租赁存储(需持续付费);
  • Arweave:一次性付费,永久存储

经济模型:用户支付 AR 代币时,费用的主要部分进入捐赠基金(Endowment)。该基金的预期投资收益覆盖未来数十年的存储成本。假设:存储成本每 2-3 年下降 50%,只需当前费用的很小部分就能"自我维持"未来 200 年的存储。

访问证明(Proof of Access, PoA)

矿工需要证明他们能访问一个随机选择的"回忆区块"(recall block)——一个历史区块。这迫使矿工存储整个区块历史,而非仅存储当前"热门"数据。


9.7.5 三种方案的对比

维度IPFSFilecoinArweave
-------------------------------
持久性不保证(依赖节点上线)经济上激励持久化永久保证
付费模式免费持续租赁/拍卖一次性付费
检索延迟低(P2P 近距离)中(矿工竞价)中(按访问激励机制)
内容过滤无(理论上)
区块链集成无(纯 P2P)独立链独立链
最佳场景NFT 元数据、DApp 前端企业级大文件存储档案、证据保存
ts

// storage-compare-sim.ts

// 纯内置:比较三种存储方案的 10 年总成本与持久性概率



interface StoragePolicy {

  name: string;

  upfrontCost: number;

  recurringCost: number;

  storageHalvingYears: number;

  siberRisk: number; // 网络失败概率/年

}



function lifetimeCostAndDurance(policy: StoragePolicy, years: number): { totalCost: number; survivalProb: number } {

  let cost = policy.upfrontCost;

  for (let y = 0; y < years; y++) {

    const halvings = Math.floor(y / policy.storageHalvingYears);

    cost += policy.recurringCost / Math.pow(2, halvings);

  }

  const survival = Math.pow(1 - policy.siberRisk, years);

  return { totalCost: cost, survivalProb: survival };

}



const policies: StoragePolicy[] = [

  { name: 'IPFS Pinning', upfrontCost: 0, recurringCost: 50, storageHalvingYears: 5, siberRisk: 0.05 },

  { name: 'Filecoin 租赁', upfrontCost: 10, recurringCost: 30, storageHalvingYears: 2, siberRisk: 0.02 },

  { name: 'Arweave', upfrontCost: 80, recurringCost: 0, storageHalvingYears: 100, siberRisk: 0.01 },

];



for (const p of policies) {

  const r = lifetimeCostAndDurance(p, 10);

  console.log(`${p.name}: 10年成本 
{r.totalCost.toFixed(0)}, 存留概率 ${(r.survivalProb * 100).toFixed(1)}%`); } // 输出: Arweave 虽然前期高,但 10 年总成本可能最低且持久性最佳 ``` --- > **关键认知七**:去中心化存储的"免费"是错觉——有人必须物理保存数据并支付硬盘+带宽成本。IPFS 假设有人自愿服务;Filecoin 假设经济激励足以覆盖替代服务器;Arweave 假设存储成本将持续下降。这三个假设各有风险,但共同构成了 Web3 的数据层。 --- --- ## 9.8 预言机:Chainlink 机制与数据上链 > 智能合约无法直接访问互联网——它们不能查询 API 获取天气、股价或体育比赛结果。预言机(Oracle)是连接链上智能合约与链外世界的桥梁。这节揭示为什么"信任任何一个数据源"都致命,以及 Chainlink 的**去中心化预言机网络(DON)**如何用共识博弈解决这个问题。 --- ### 9.8.1 预言机问题:为什么链上不能查询 HTTP **区块链的确定性执行**意味着:在给定区块状态下,所有节点的执行结果必须完全一致。如果合约执行 HTTP 请求,不同节点可能获得不同响应(时间戳、延迟、API 故障),导致分叉。 **结论**:链上必须只使用**已共识确认的数据**。预言机的作用就是将链下数据**共识化后上链**。 --- ### 9.8.2 单点预言机 = 单点故障 如果合约依赖唯一一个数据源的价格: - 数据源故障 → 合约无法执行; - 数据源被攻击/操纵 → 合约基于虚假数据执行。 这是"预言机问题"的核心:你引入了一个比区块链本身的共识弱得多的信任假设。 --- ### 9.8.3 Chainlink DON:去中心化数据源 + 经济博弈 **架构三要素**: 1. **数据请求**:智能合约请求 ETH/USD 价格; 2. **去中心化节点网络**:多个独立节点从多个交易所获取数据,各自提交结果; 3. **链上聚合**:剔除异常值后,取中位数/加权平均。
\text{链上价格} = \text{Median}(\{P_1, P_2, \dots, P_N\}), \quad \text{after outlier removal}
**经济安全**: - 节点质押 LINK 作为抵押; - 如果节点提交异常值,质押被削减(Slashing); - 节点数量越多、抵押越重,操纵成本越高。 ```mermaid graph TD A["智能合约需求 ETH/USD 价格"] --> B["Chainlink 协调合约"] B --> C1["节点1: Binance API 质押 1000 LINK"] B --> C2["节点2: Coinbase API 质押 1000 LINK"] B --> C3["节点3: 聚合器 质押 1000 LINK"] C1 --> D["提交价格 3200.10"] C2 --> E["提交价格 3200.05"] C3 --> F["提交价格 3200.15"] D --> G["聚合: 中位数 = 3200.10 剔除离群值"] E --> G F --> G G --> H["更新链上价格 喂价合约"] style G fill:#ccffcc ``` --- ### 9.8.4 数据源操纵攻击与防御 **闪电贷价格操纵**: 1. 攻击者用闪电贷借出大量 ETH; 2. 在单一 DEX(如 Uniswap)上大量买入某代币,**人为拉高该 DEX 的价格**; 3. 如果预言机仅引用该单一 DEX,则链上价格被操纵; 4. 攻击者以虚高价格在其他合约中获利。 **防御**: - **多交易所聚合**:不依赖单一 DEX; - **交易量权重**:交易量大的交易所权重更高; - **时间加权平均(TWAP)**:取一段时间的平均价格,平滑瞬时操纵。
\text{TWAP} = \frac{\sum_{t} P_t \cdot \text{volume}_t}{\sum_{t} \text{volume}_t} $$ --- ### 9.8.5 可验证随机函数(VRF):链上公平随机数 **问题**:智能合约的随机数不能来自 `block.hash`(矿工可预测/操纵)。 **Chainlink VRF 方案**: 1. 合约请求随机数,提供一个种子 SS; 2. Chainlink 节点用私钥 sksk 计算:output=VRFsk(S)\text{output} = VRF_{sk}(S); 3. 公开验证:用公钥 pkpk 验证 output\text{output} 确实由对应 sksk 生成; 4. 节点无法预知输出(因为 sksk 不公开),也无法篡改(因为可验证)。 --- ### 9.8.6 预言机的信任模型对比 | 类型 | 信任假设 | 延迟 | 成本 | 代表 | |------|----------|------|------|------| | **中心化 API** | 单一数据源 | 秒 | 低 | 自建 API 客户端 | | **去中心化共识** | 多数节点诚实 | 分钟 | 中 | Chainlink DON | | **TWAP** | 操纵成本高 | 小时 | 极低 | Uniswap V3 TWAP | | **博弈论** | 报告者诚实占优 | 可变 | 中 | UMA 乐观预言机 |

// oracle-aggregation-sim.ts

// 纯内置:模拟 Chainlink 风格的多源聚合与离群值剔除

function median(values: number[]): number {

const s = [...values].sort((a, b) => a - b);

const mid = Math.floor(s.length / 2);

return s.length % 2 ? s[mid] : (s[mid - 1] + s[mid]) / 2;

}

function aggregatePrices(

reports: { node: string; price: number; stake: number }[],

maxDeviation = 0.01

): { finalPrice: number; outliers: string[]; honestWeight: number } {

const m = median(reports.map(r => r.price));

const valid = reports.filter(r => Math.abs(r.price - m) / m <= maxDeviation);

const outliers = reports.filter(r => Math.abs(r.price - m) / m > maxDeviation).map(r => r.node);

const honestWeight = valid.reduce((a, b) => a + b.stake, 0);

const finalPrice = valid.length > 0 ? median(valid.map(r => r.price)) : m;

return { finalPrice, outliers, honestWeight };

}

const reports = [

{ node: 'Node1', price: 3200.0, stake: 1000 },

{ node: 'Node2', price: 3200.5, stake: 1000 },

{ node: 'Node3', price: 3201.0, stake: 1000 },

{ node: 'Attacker', price: 3300.0, stake: 500 }, // 操纵价

];

const result = aggregatePrices(reports, 0.005); // 0.5% 离群容忍

console.log(聚合价格: result.finalPrice,离群:[{result.finalPrice}, 离群: [{result.outliers.join(', ')}], 诚实权重: ${result.honestWeight});

// 输出: 攻击者被剔除,中位数价格由诚实节点决定

// 证明去中心化聚合 + 经济激励的防御效果

评论

0

评论加载中…

发表评论

0/2000