zkSync 2.0 进展-202301

2023-04-04  本文已影响0人  雪落无留痕

zkSync 2.0目前主网上线仍是Baby Alpha 版本,代码尚未开源。将在 Fair Onboarding Alpha版本开源代码,预计在2023年第2季度。

基本概念

交易

zkSync 2.0 网络上的交易结构如下:

/// @notice Structure used to represent zkSync transaction. 
struct Transaction {
    // The type of the transaction.
    uint256 txType;   
    // The caller.
    uint256 from;
    // The callee.
    uint256 to;
    // The ergsLimit to pass with the transaction. 
    // It has the same meaning as Ethereum's gasLimit.
    uint256 ergsLimit;
    // The maximum amount of ergs the user is willing to pay for a byte of pubdata.
    uint256 ergsPerPubdataByteLimit;
    // The maximum fee per erg that the user is willing to pay. 
    // It is akin to EIP1559's maxFeePerGas.
    uint256 maxFeePerErg;
    // The maximum priority fee per erg that the user is willing to pay. 
    // It is akin to EIP1559's maxPriorityFeePerGas.
    uint256 maxPriorityFeePerErg;
    // The transaction's paymaster. If there is no paymaster, it is equal to 0.
    uint256 paymaster;
    // In the future, we might want to add some
    // new fields to the struct. The `txData` struct
    // is to be passed to account and any changes to its structure
    // would mean a breaking change to these accounts. In order to prevent this,
    // we should keep some fields as "reserved".
    // It is also recommneded that their length is fixed, since
    // it would allow easier proof integration (in case we will need
    // some special circuit for preprocessing transactions).
    uint256[6] reserved;
    // The transaction's calldata.
    bytes data;
    // The signature of the transaction.
    bytes signature;
    // The properly formatted hashes of bytecodes that must be published on L1
    // with the inclusion of this transaction. Note, that a bytecode has been published
    // before, the user won't pay fees for its republishing.
    bytes32[] factoryDeps;
    // The input to the paymaster.
    bytes paymasterInput;
    // Reserved dynamic type for the future use-case. Using it should be avoided,
    // But it is still here, just in case we want to enable some additional functionality.
    bytes reservedDynamic;
}

Operators: 负责产块,打包交易,向以太坊上提交验证的数据。

区块

L2的区块在提交到L1时,是将多个连续的块合并成一个Batch一块提交,以包含尽可能多的交易以降低交易手续费, l1BatchNumber 用于表示这个Batch 编号 。

L2区块的Hash 计算方式为:keccak256(l2_block_number), 因为L2区块Hash对L1来说无意义。

系统合约

为了保证零知识证明电路尽可能简单,zkSync 实现一些系统合约,用以实现一些专用的目的,如部署合约等。目前只提供了接口,具体实现尚未开源。

ContractDeployer

主要利用create/create2部署新的合约,并生成新的合约地址,执行完还会发出 ContractDeployed 事件。

L1Messenger

用于从zkSync 向 Ethereum 发送信息,并发出L1MessageSent 事件。

NonceHolder

主要用来存放账nonces, 包含tx noncedeployment nonce.

Bootloader

Bootloader 主要用来实现扩展,降低负载,方便实现account abstract 功能。

L1 合约

Diamond

主要用来管理Diamond 的存储:

    struct DiamondStorage {
        mapping(bytes4 => SelectorToFacet) selectorToFacet;
        mapping(address => FacetToSelectors) facetToSelectors;
        address[] facets;
        bool isFrozen;
    }

DiamondProxy

L1合约实现主要采用 EIP-2535 Diamond 代理方式,通过fallback 代理具体实现合约的调用。

DiamondInit

用于初始化Diamond 代理合约。

DiamondCutFacet

主要用来升级Diamond facets , 主要以下阶段:

GettersFacet

主要提升viewpure 方法;

GovernanceFacet

主要用来管理governor, validators 和一些系统参数;

MailboxFacet

主要用来处理L2<--->L1之间的通信过程,主要关注信息的传递,不涉及资产(ETH, ERC20, NFT)的转移。

对于 L1->L2 通信,主要是从L1发起在L2上的交易,用户从L1发起交易,添加到队列中,由validator执行,并在L1上进行标记,相关的函数有:

对于每个L1->L2执行的交易, 系统会发起 L2->L1的log.

对于L2->L1通信,主要通过调用Messenger 系统合约传递信息,而不是在L1上执行交易 。

function sendToL1(bytes memory _message) external returns (bytes32 messageHash);

在L2上, 有个zkEVM 字节码为l2ToL1Log, 当将L2区块提交到L1上时,validator 会提交l2ToL1Logs.

ExecutorFacet

用于接收L2 区块, 保证数据可用性,并检查零知识证明, 主要分为以下三个阶段:

Account abstraction

以太坊只有EOA账户能发起交易,对于智能合约钱包或Tornado cash 等隐私协议,只能通过relayers 发起交易,会导致诸多不便。

zkSync 2.0的账户能够以合约方式实现任意的逻辑,也能像EOA一起发起交易,这种功能即为·Account abstract.

抽象账户需要实现IAccount 接口, 如下:

Paymaster 接口

抽象账户支持paymasters, 主要用来支持其它账户交易的执行。paymaster 主要实现IPaymaster接口:

Transaction 保留的字段

Transaction flow

在交易的验证过程,账户会决定是否接收交易,并支付手续费;若交易验证失败,账户不会支付手续费,交易也不会打包进块中。

在执行过程中,主要是执行交易,并对未使用的ergs进行退款。若没有发生revert,则交易将会打包进块中。

采用 SystemContractCaller 库

为了提升安全,NonceHolderContractDeployer 合约只能通过 isSystem 的标签调用,需要采用SystemContractsCaller 库的方法:

跨链桥

桥由两个合约实现,一个部署在L1上,一个部署在L2上。

Deposits (to L2)

用户调用L1 桥合约的deposit 方法,向L2 发起存款操作:

对交易执行过程中失败,会有日志记录失败,用户可通过日志从L1桥发起退款:claimFailedDeposit

Withdraws (to L1)

用户需要调用L2 桥合约的withdraw 方法,执行以下过程:

智能合约开发

支持Solidity 版本 >-0.4.10, 但建议采用^0.8.0 版本。

对于Solidity 库合约,若是内联的,即只包含privateinternal 方法,则可以直接使用;

若库包含publicexternal 方法,不是内联的,则需要将合约地址传给编译器。

支持Vyper^0.3.3 版本;

目前有两种编译器:

EVM 兼容性

虽然兼容大部分合约,但有一些例外:

Web3 API

zkSync 2.0 完全兼容Ethereum JSON-RPC API, 也添加L2相关的接口。

SDK

zkSync 2.0 提供了Javascript, Python, Go, Java, Swift 多种SDK 工具方便开发者部署合约,并进行交互 。

zkSync 2.0还提供了Hardhat, Block explorer, zkSync CLI 工具。

参考

https://v2-docs.zksync.io/

https://github.com/matter-labs/v2-testnet-contracts

https://zksync.io/

https://blog.matter-labs.io/

https://blog.matter-labs.io/baby-alpha-has-arrived-5b10798bc623

https://blog.matter-labs.io/a-year-of-growth-for-zksync-bb117d1b4f0c

https://blog.matter-labs.io/open-source-is-freedom-8b1b914daa98

上一篇 下一篇

猜你喜欢

热点阅读