StarkWare 分析

Starkware

StarkWare是一个为了解决区块链的可扩展性和隐私的组织。 StarkWare开发了一个完整的解决方案,使用透明零知识证明(zk-STARK)技术,zk-RollupValidium模式组成Volition来生成和验证计算完整性的证明。StarkWare的密码证明可以做到零知识、简洁、透明和后量子安全的特点。 StarkWare所研发的产品主要有:StarkNetStarkExCairo

扩展解决方案

StarkEx

StarkEx是基于有效性证明的以太坊可扩展性解决方案。 它可以在zk-RollupValidium数据可用性模式下运行。
基于StarkEx之上架构使用Cairo编写的应用程序(dydxImutable X…)都会定义自己的业务运行逻辑,并在StarkEx服务上运行。 该系统具有链上组件和链下组件。 链下组件持有状态,命令执行系统中的交易,并将状态更新发送到链上组件。 链上组件持有状态承诺,持有系统资产,并负责执行状态转换的有效性。

系统元件

StarkEx系统包含以下组件:

  • 应用程序:接收用户交易的链下组件,定义业务运行逻辑和执行的顺序。最终,它将交易发送到StarkEx服务。
  • StarkEx服务:链下组件,负责批处理一组操作,根据这些操作更新系统状态。针对每一批,StarkEx服务将发送此批的操作(作为Cairo执行痕迹)到SHARP进行有效性证明,一旦证明被验证,它将新状态发布在链上。 状态由Merkle tree呈现,其叶子是保险库。每个保险库的结构和内容根据所实施的特定业务逻辑而有所不同。Merkle tree root代表要在链上提交的状态承诺。
  • SHARP(Prover):Cairo程序的共享证明服务。 它接收来自不同应用程序的证明请求,并输出证明以证明Cairo程序执行的有效性。输出的证明可以在多个证明请求之间共享。
  • STARK验证器(Verifier):这是一个链上组件,用于接收状态更新有效性证明并验证该证明是否有效。
  • StarkEx合约:该合约有两个主要功能。 第一个是在确认有效性条件得以满足后更新系统状态。第二个功能是以自主托管方式管理在StarkEx中的进出资金,这意味着在任何情况下,用户都可以提取其资金。


系统中的所有交易都通过应用程序执行,并将撮合好的交易发送到StarkEx服务。 StarkEx服务对交易进行批处理更新状态,并将批处理后将SHARP需要的参数发送到SHARP(共享证明服务)生成一份证明来表明批处理的有效性。SHARPSTARK证明发送给STARK验证器进行验证。服务随后发送一份链上状态更新交易到StarkEx合约,仅在证明被验证器验证有效时,交易才会被接受。

用户以两种方式与系统交互:

  • 通过发送链上交易到StarkEx合约。
    ‌‌当用户想要使用该系统时,他们首先将StarkKey注册到StarkEx合约中的以太坊地址。StarkKey用于验证用户的链下交易。 然后,用户将其资金存入StarkEx合约。 在应用程序接受存款后,用户可以在链下使用其资金。
  • 发送链下交易到应用程序。
    用户将由StarkKey签名的转账或限价单直接提交给应用程序。限价单经由链下程序定序匹配,并作为结算发送给StarkEx服务。转账行为照原样发送。不同类型的转账交易可以由额外的逻辑来执行。
    ‌为提取资金,用户应向应用程序提交链下提款请求。此请求被发送到StarkEx服务,一旦包含提款的状态更新被接受,用户就可以在链上获取其资金。

‌为了防止审查,如果用户的提款请求没有得到实现,他们可以使用强制操作来强制执行。

Immutable X

Immutable X使用Starkware基于StarkEx提供的方案。具体架构与上文大同小异,不再赘述。

以太坊上NFT接入

NFT接入,本质上需要让以太坊上的IMX合约拥有NFT的铸造权。

新的NFT接入

对于要新建的NFT只需要在自己的ERC721合约的基础上实现IMX给定的Mintable接口。

pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "./Mintable.sol";

contract Asset is ERC721, Mintable {
    constructor(
        address _owner,
        string memory _name,
        string memory _symbol,
        address _IMX
    ) ERC721(_name, _symbol) Mintable(_owner, _IMX) {}

    function _mintFor(
        address user,
        uint256 id,
        bytes memory
    ) internal override {
        _safeMint(user, id);
    }
}

已部署的NFT接入

对于已部署过的合约,需要写一个新的合约包装进旧的合约。
确保此合约可以铸造NFT,并且只有IMX可以调此合约的mintFor方法。

import "@imtbl/IMX-contracts/contracts/Mintable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract YourContract is IMintable, Ownable {

    function mintFor(
        address to,
        uint256 quantity,
        bytes calldata mintingBlob
    ) external override {
        // TODO: make sure only Immutable X can call this function
        // TODO: mint the token!
    }

}

创建项目 (project registration)

一个项目相当于一个超级管理员,并且和一个owner地址(拥有铸造权限)关联。用户可以在项目中发行多个合集(collections),IMX规定每个项目可以创建的collection数量有限制(一个月五个合集)。创建完项目后会生成对应的projectId

 const params: CreateProjectParams = {
  name: '项目名字',
  company_name: '公司名字',
  contact_email: '联系邮箱',
};

let project;
try {
  project = await user.createProject(params);
} catch (error) {
  throw new Error(JSON.stringify(error, null, 2));
}

合集注册 (collection registration)

合集(collection)代表一个已经在以太坊网络上部署好的ERC721合约。为了能在IMX网络上铸造资产,首先需要在IMX上注册这个合集。
合集注册也是通过IMX提供的sdkapi完成,参考代码如下:

  const params: CreateCollectionParams = {
  name: '合集的名字',
  // description: 'ENTER_COLLECTION_DESCRIPTION (OPTIONAL)',
  contract_address: collectionContractAddress,
  owner_public_key: ownerPublicKey,
  // icon_url: '',
  // metadata_api_url: '', //<metadata_api_url>/<token_id>
  // collection_image_url: '',
  project_id: parseInt(projectId, 10),
};

let collection;
try {
  collection = await user.createCollection(params);
} catch (error) {
  throw new Error(JSON.stringify(error, null, 2));
}

IMX上注册一个合集的例子可以参考这里

元数据注册 (metadata schema registration)

IMX允许项目为他们的资产指定元数据属性,这些元数据属性可以更好的帮助交易市场(marketplace)执行复杂的过滤查询,这样帮助用户更精准的发现他们想要的资产。更多资产元数据的例子可以参考这里
元数据注册也是通过IMX提供的sdk完成,参考代码如下:

const params: AddMetadataSchemaToCollectionParams = {
    metadata: [
      {
        name: 'EXAMPLE_BOOLEAN',
        type: MetadataTypes.Boolean,
        filterable: true,
      },
      // ..add rest of schema here
    ],
  };

  const collection = await user.addMetadataSchemaToCollection(
    collectionContractAddress,
    params,
  );

  log.info(
    component,
    'Added metadata schema to collection',
    collectionContractAddress,
  );
  console.log(JSON.stringify(collection, null, 2));

IMX上创建注册元数据的例子可以参考这里

功能时序图

铸造

管理员给IMX Engine发送铸币请求并附带签名,IMX Engine执行批次化后交由Prover进行生成有效性证明生成Proof提交到以太坊的验证合约进行验证。

存款

用户发送代币转账到以太坊合约中,IMX Engine监听到存款事件后更改网络状态后交由Prover进行生成有效性证明生成Proof提交到以太坊的验证合约进行验证。

取款

  • 一般情况:链下触发。用户发起提款请求。IMX Engine执行批次化后交由Prover进行生成有效性证明生成Proof提交到以太坊的验证合约进行验证。验证通过后用户在以太坊上调用取款取出资产。
  • 特殊情况(例如:IMX Engine down掉)用户可以直接调用链上的紧急退出功能经过锁定时间窗口后取出所有资产。

交易

IMX Engine内维护了一个中央订单簿。用户创建卖单将在IMX Engine中进行维护。当IMX Engine接收到对应买单会自动撮合,随后交由Prover进行生成有效性证明生成Proof提交到以太坊的验证合约进行验证。

SDK && API

Immutable X SDK 是一个由Immutable创建的Javascript包,允许与Immutable XAPI进行简单接口。主要使用的包是 Link SDKImmutable X Client
Immutable X Client用于大多数后端操作,Link SDK用于前端、面向用户的交互。

SDK
API
API调用限制

探索 StarkNet

几个概念

状态机

Y(S, T)= S'

给定一个旧的有效状态 (S)和一组新的有效交易 (T),以太坊状态转换函数 Y(S,T) 产生新的有效输出状态S'

Re-Execution

是一种通过执行相同的计算来证明一个事实。

零知识证明

零知识证明的目标是让验证者相信证明者拥有某个秘密(withness),满足某种关系,而无需向验证者或其他任何人透露秘密本身。
定义:

  • 完整性(Completeness):如果证明者是诚实的,那么她最终会说服验证者。
  • 可靠性(Soundness):证明者只能说服验证者该陈述是否属实。
  • 零知识性(Zero-knowledgeness):除了知道陈述是真实的,验证者不知道任何额外的信息。

区块链解决了什么问题?

信任问题:系统A如何相信系统B陈述了一个事实。

经典系统

  • 传统中心化账本系统:数据都存在一个大型计算机的账本系统中,用户使用时必须相信这个系统。
  • 经典区块链系统:区块链具有包容性和问责制。每个操作员都有一个账本系统,操作员除经过自己验证数据可信之外,并不相信任何人的数据。每个操作员都需要验证所有交易的有效性。


区块链系统为了验证数据,所有交易都要公开在网络中,牺牲了数据的隐私性。

解决方案

  • 增量扩容:通过扩大区块内交易数量或计算逻辑会导致操作节点需要更强的性能来处理更多的数据,越来越多的节点因为机器性能不足从而退出网络。导致节点数量减少,偏向于中心化。
  • 有效性证明系统:有效性证明将操作员拆分为二:证明者(Prover)和验证者(Verifier)。证明者执行数据逻辑生成一个证明(Proof)交由给验证者网络,使验证者可以通过验证这个证明本身就可以相信证明者数据的有效性。有效性证明是个NP问题(证明困难,验证简单)。既保证了数据的隐私,又可以让验证者轻易的相信数据可靠。

ZK-STARK Proofs

zk-STARK不需要可信设置(non-setup),是一种透明化的零知识证明系统。



验证者只需验证Proof就可以相信证明者发送的最新状态,而不需要验证交易本身。

Zkp常见系统比较

从上图可看出:STARKs的证明、验证和见证大小复杂度均高于其他系统(多项式对数复杂度随着规模扩大,系统效率越高,所以要进行批次化)。优点是不需要可信设置(Trusted setup),并且他的加密假设是基于哈希碰撞,具有良好的后量子安全的特点。

Cairo Language

Cairo是一种用于为一般计算创建STARK证明程序的图灵完备语言。CairoStarkEx提供支持,后者可扩展Mainnet上的应用程序(包括 dYdXSorareImmutable XDeversiFi)。CairoStarkNet的原生智能合约语言。

StarkNet

StarkNet是无须许可的去中心化的zk-Rollup。它作为以太坊的Layer2网络运行。在StarkNet上使用Cairo开发的dApp,可以支持无限规模的计算。
特点:

  • 可扩展性和完整性:StarkNet支持规模化,可以使用Layer1以太坊的安全性,通过在链下生成STARK证明,然后在链上进行验证。
  • 通用性:在StarkNet上,开发人员可以使用Cairo编写智能合约轻松部署任何业务逻辑。
  • 可组合性:StarkNet提供以太坊级别的可组合性,促进轻松开发和创新。

路线图

  • 阶段一 Planets: 单应用、单操作节点的Rollups
  • 阶段二 Constellations: 多应用、单操作节点的Rollups
  • 阶段三 Universe: 多应用、去中心化节点的Rollups

当前进度

架构图


StarkNet Full NodeStarkNet网络中的一个节点,仅用于查询当前StarkNet状态。
StarkNet Sequencer NodeStarkNet网络中用于定序和生成零知识证明的节点。相当于StarkNet的矿工。

递归零知识证明

定义

递归零知识证明:使用前一个状态的Proof以及当前交易作为输入,接下来Prover去尝试证明前一个状态的Proof以及当前交易是否有效,如果全部验证通过,程序会输出一个新的状态及一个Proof,过程如下图所示:


递归零知识证明验证:只要验证前一个状态的Proof就可以验证整个链的状态,比如:当验证Proof #5状态是正确的,相当于递归验证了Proof #4Proof #3

Mina(旧称Coda)项目,将整个区块链维持在22k,其中就使用了递归零知识证明。
优点:递归零知识证明有非常好的聚合(压缩)、节省空间的优点。

多层网络

某些dApp需要特殊的定制,这可能更好地在此层基础上,构建一个新的独立层提供服务。
具体过程:

  • 每层网络都有一个Cairo程序,它可以作为该层网络的共识,或具体的业务。
  • 下层网络提交ProofState Update(在zk-rollup需要包含与之相关的Merkle Tree,在Validium下只需要Merkle Tree Root)到该层Prover进行定序和批次化。
  • Prover使用State Update更新该层网络状态对应下层网络Key「保险库」的State
  • Prover调用该层Cairo程序并输入Inputs(更新前的网络状态)、Outputs(更新后的网络状态)、txs(下层网络提交的ProofsState Update),生成该层的ProofState Update,并将提交到上层网络的Verifer验证。

注意:此处是一个递归化的过程。
每层网络中都维护一个网络状态。
利用零知识隐私化的特性,每层网络只需要关心当前层的网络状态合理化而无须关心下层网络本身。

经典Layer2架构

  • L2 Contract:记录Layer2 State/Root的合约。
  • Verifier Contract:用于验证Layer2状态转移有效性的Verifier的合约。
  • 桥接Layer1Layer2的资产出入管理合约。
  • ERC20/ERC721账户模型对应网络的镜像。

应用在Layer3上

Layer2Layer1一样,Layer3也可以使用相同的结构并添加差异化的功能。

参考资料

https://medium.com/starkware/fractal-scaling-from-l2-to-l3-7fe238ecfb4f
https://medium.com/starkware/redefining-scalability-5aa11ffc5880
https://iosgvc.medium.com/scaling-summit-2021-keynote-recap-stark-validity-rollup-an-ultimate-scaling-technology-9cc62b307f69