1. 引言
zkSync為以太坊的擴容和隱私引擎,當前支持或即將支持的功能有:
- 當前支持 low gas transfers of ETH and ERC20 tokens in the Ethereum network,
- 計劃在2021年,通過Zinc語言或者現有的Solidity語言,實作可編程的隱私智能合約,
- 對交易所友好,即將支持交易所協議的關鍵功能——Atomic swap:https://github.com/matter-labs/atomic-swaps
2. zkSync中的基本概念
2.1 zkSync中的operation
zkSync中有2種型別的operation操作:
- Priority operation:又可分為Deposit和FullExit兩種型別,
- Transaction:又可分為ChangePubKey、Transfer、Withdraw、ForcedExit 四種型別,
(1)Priority operation
Priority operation已直接在以太坊主網上啟動,
如,用戶創建一個存款交易,將資金由以太坊轉移到zkSync,priority operation可通過numeric ID 或 hash of the ethereum transaction that created it 來區分,
有2種型別的priority operation:
- Deposit:將資金由以太坊轉移至zkSync中的指定賬號,若zkSync中的該賬號不存在,則會創建該賬號,同時為該地址賦予一個numeric ID,
- FullExit:在不與zkSync server互動的情況下,將資金由zkSync提取到以太坊,當檢測到來自zkSync服務器節點的審查時 或 無法設定zkSync賬號的signing key時(如,某地址對應的是智能合約),該操作可用于緊急退出,
(2)Transaction
transaction 必須由zkSync operation通過API提交,
transactions通過the hash of their serialized representation 來區分,
有4種型別的transaction:
- ChangePubKey:設定或修改某賬號的signing key,若無相應的signing key,該賬號無法做出priority operation之外的任何操作,
- Transfer:將資金由一個zkSync賬號交易至另一個zkSync賬號,若zkSync上的接收賬號不存在,則會創建新賬號并為其賦予一個numeric ID,
- Withdraw:將資金由zkSync提取至以太坊,
- ForcedExit:提取資金,若該“target” L2賬號沒有相應的signing key時,(如,某地址對應的是智能合約)
2.2 zkSync中的block
zkSync中的所有操作都是按block排列的,
當zkSync operator創建好區塊之后,通過Commit transaction,會將該區塊推送到以太坊主網上的zkSync智能合約,此時,其狀態并未final,幾分鐘之后,證明該區塊正確性的ZK proof將生成,該proof通過Verify transaction 發布到以太坊,只有在該Verify tx被挖出后,該新狀態才可認定為是final的,
存在多個區塊已commit但未verify的狀態,為了讓用戶不等待區塊finalization,可將交易分組為“mini-blocks”,相應的延時會小很多,因此,區塊可以更小的間隔部分提交,也能以更短的間隔收到交易并更新相應的狀態,
這就意味著,發送交易后,用戶既不用等待block commit也不用等待block verify,在交易執行后,相應的資金即立即可用,
2.3 zkSync中的flow
zkSync中的主要流程有:
- 創建賬號
- 設定signing key
- 交易資金
- 交易費用
- 提取資金
(1)創建賬號
zkSync的賬號可通過從 以太坊存入資金 或 在zkSync中交易資金至指定的賬號,若相應賬號不存在,以上操作會創建新的賬號,
但是,新創建的賬號無法授權任意交易,必須由該賬號的owner設定相應的signing key,
(2)設定signing key
默認,每個賬號的signing key都是0值,以標識該賬號是“unowned”,主要基于以下考慮:
- 若在以太坊中交易至某地址是有效的,則其在zkSync中也是有效的,
- 并不是每一個地址都有相應的private key(如某些智能合約)
- 可交易至用戶賬號,即使其當前并不對zkSync感興趣
為了讓某賬號能發起L2交易,用戶必須通過ChangePubKey交易為其設定signing key,
該交易中必須包含2個簽名:
- zkSync signature of the transaction data,使得其無法更改交易內容,zkSync signature on all transaction fields must correspond to the public key provided in the transaction,
- Ethereum signature,用于證明account ownership,Ethereum signature應為a signature of some pre-defined message,ownership of account將由zkSync server和smart contract共同check,以保證更好的安全性,
(3)交易資金
任何在以太坊上valid的交易,在zkSync中也為valid,
用戶可交易任意數額的Ether或任意支持的ERC-20 token,
當前zkSync支持的token有:
- https://zkscan.io/tokens
相應的api見:
- https://zksync.io/api/
若交易至某個不存在的賬號,則在發送給智能合約時需再稍微多一點的資料,因為需提供新賬號的資訊,相應的交易費用也比給existing賬號的費用略高,
(4)交易費用
zkSync需要交易費用來覆寫網路維護費用,
每種交易型別的費用主要從以下3方面來計算:
- 發送到以太坊的資料量
- 當前的gas price
- 為包含該交易的區塊生成proof所需的計算資源的成本
由于在一個區塊中包含了很多交易,該成本會分攤至區塊中所包含的所有交易,所以每筆交易的費用將很低,
此外,為所有資料進行費用計算,相應的API介面為:
- https://zksync.io/api/v0.1.html#get-tx-fee
(5)提取資金
從zkSync將資金提取到以太坊賬號,當前支持3種方式:
- 通過
Withdrawtransaction:為L2交易,用于request a withdrawal from your zkSync account to any Ethereum address,與交易類似,需要由正確的zkSync private key簽名, - 通過
ForceExittransaction:為L2交易,用于request from any unowned account (one that does not have a signing key set),在該類交易中,既不能指定以太坊地址,也不能指定交易金額,僅支持將target L2地址某種特定token的所有可用金額都提取至target L1 address,與Withdrawtransaction類似,該交易的發起方將支付相應的費用、 - 通過
FullExitpriority operation:其由L1發起,智能合約可保證該request將以合理的時間間隔執行,或當網路死機或被攻陷時,合約將進入出逃模式,This method is preferred if the user will ever experience censorship from the network operator.
3. 向zkSync網路發送交易基本原則
向zkSync網路發送交易,主要考慮以下3種型別:
- send priority operation
- send transaction
- send transactions batch
3.1 send priority operation
通過呼叫相應智能合約的方法來觸發priority operation,
(1)deposit存款操作,可分為:
- 存ETH到Layer2,
- 存ERC20 token到Layer2,在存ERC20資金之前,必須批準合約相應數量的金額,即:
erc20contract.approve(zkSyncContractAddress, deposit_amount);,
// @notice Deposit ETH to Layer 2 - transfer ether from user into contract, validate it, register deposit
/// @param _franklinAddr The receiver Layer 2 address
function depositETH(address _franklinAddr) external payable nonReentrant;
/// @notice Deposit ERC20 token to Layer 2 - transfer ERC20 tokens from user into contract, validate it, register deposit
/// @param _token Token address
/// @param _amount Token amount
/// @param _franklinAddr Receiver Layer 2 address
function depositERC20(IERC20 _token, uint104 _amount, address _franklinAddr) external nonReentrant;
(2)fullExit操作:
用戶必須通過依次呼叫fullExit來注冊exit request,然后呼叫completeWithdrawals來complete this request,
/// @notice Register full exit request - pack pubdata, add priority request
/// @param _accountId Numerical id of the account in the zkSync network
/// @param _token Token address, 0 address for ether
function fullExit (uint32 _accountId, address _token) external nonReentrant;
/// @notice executes pending withdrawals
/// @param _n The number of withdrawals to complete starting from oldest
function completeWithdrawals(uint32 _n) external nonReentrant;
3.2 send transaction
在發送交易之前,用戶需做如下操作:
- 準備交易資料
- 將交易資料encode為a byte sequence
- 用zkSync私鑰對該byte sequece進行簽名
- 為transaction description生成Ethereum簽名 或 提供EIP-1271簽名
- 通過相應的 JSON RPC方法 發送交易
詳細的交易資料和encode細節可參見:
- zkSync Rollup Protocol
zkSync中采用的cryptographic primitive與以太坊中的不同,zkSync中生成私鑰和簽名交易的介面具體見:
- Cryptographic libraries
交易型別的不同,相應的Ethereum signature message也不同:(transaction分為ChangePubKey、Transfer、Withdraw、ForcedExit 四種型別)
// Amount and fee must be encoded into formatted string, e.g. by `ethers.utils.formatUnits` method
// with respect to the token decimals value.
// Token must be represented as a token symbol, e.g. `ETH` or `DAI`.
// For Transfer:
const transferEthMessage =
`Transfer ${stringAmount} ${stringToken}\n` +
`To: ${transfer.to.toLowerCase()}\n` +
`Nonce: ${transfer.nonce}\n` +
`Fee: ${stringFee} ${stringToken}\n` +
`Account Id: ${this.accountId}`;
// For Withdraw:
const withdrawEthMessage =
`Withdraw ${stringAmount} ${stringToken}\n` +
`To: ${withdraw.ethAddress.toLowerCase()}\n` +
`Nonce: ${withdraw.nonce}\n` +
`Fee: ${stringFee} ${stringToken}\n` +
`Account Id: ${this.accountId}`;
// For ChangePubKey (assuming it is a stand-alone transaction, for batch see details below):
const msgNonce = utils.hexlify(serializeNonce(nonce));
const msgAccId = utils.hexlify(serializeAccountId(accountId));
const pubKeyHashHex = pubKeyHash.replace("sync:", "").toLowerCase();
const changePubKeyEthMessage =
`Register zkSync pubkey:\n\n` + `${pubKeyHashHex}\n` + `nonce: ${msgNonce}\n` + `account id: ${msgAccId}\n\n` + `Only sign this message for a trusted client!`;
注意,某些以太坊簽名者會在簽名訊息前加\x19Ethereum Signed Message:\n${messageBytes.length} 前綴,因此若簽名者未自動加該前綴,可能需要手動加上,
3.3 send transactions batch
transactions batch 是指 a set of transactions that should succeed all together,若其中的一筆交易失敗,則該batch中的所有交易也將失敗,當前一個transactions batch最多支持50筆交易,且在transaction batch中,沒必要為每筆交易單獨設定費用,僅要求所有交易的費用之和 大于等于 單獨發送交易的費用之和,
(1)使用transaction batch模式,支持以其他的token來支付交易費用,具體實作方式為,在一個batch中創建2筆交易:
- transfer to the recipient in token
FOO的fee set設為0 - transfer to the own account in token
BAR(想用BAR來支付token)的amount set設為0,而將其fee set設為足夠的金額(足以覆寫這兩筆交易的費用)
server將check that sum of fees(0 in the first transaction and 2x expected fee in the second one) is enough to cover processing of two transfers and will execute the batch,
(2)使用transaction batch模式,無需為每筆交易單獨提供an Ethereum signature,可為每個batch提供一個簽名就足夠了,【仍然需要類似 \x19Ethereum Signed Message:\n${messageBytes.length} 的前綴】
可通過https://zksync.io/api/v0.1/#submit-txs-batch JSON RPC介面來發送batch和簽名,
為batch的簽名規則為:
// Assuming that `transactions` variable holds an array of batch transactions, and
// `serializeTx(...)` encodes transaction into bytes as per zkSync protocol.
// Obtain concatenated byte representations of each transaction.
const bytes = concat(transactions.map((tx) => serializeTx(tx)));
// Calculate `keccak256` hash of this byte sequence.
const hash = ethers.utils.keccak256(bytes).slice(2);
// Decode it into a byte sequence.
const message = Uint8Array.from(Buffer.from(hash, "hex"));
注意:當前transactions batch僅支持server-side abstraction,會在cricuit之前進行successful execution check,information about batch不會傳入circuit中,若想以不同的token來支付交易費用,則推薦在最后設定the fee payment transaction,未來,transations batch將在circuit內enforced,這樣可提升整體的安全性,
4. zkSync中的智能合約
zkSync有望推出高效、安全、圖靈完備的多語言智能合約,
zkSync的智能合約編程模型將繼承以太坊的,
Zinc和Solidity語言都是圖靈完備的,因此你可用無限回圈、遞回、向量和maps of arbitrary length等,區域變數存盤在堆疊上或堆上,而contract storage則是全域可訪問的,智能合約可通過強型別介面相互呼叫,且可訪問public storage fields,
4.1 zkSync智能合約的composability
zkSync智能合約可像以太坊智能合約那樣相互呼叫,無論包含了多少個合約,每個call transaction tree為atomic的,
任何DeFi專案都可遷移至zkSync,現有的大多數solidity代碼可無需修改直接部署,
4.2 zkSync的VM
zkSync的VM為高效、圖靈完備、SNARK友好的虛擬機,可運行zkSync智能合約,
對智能合約bytecode和虛擬機本身都進行了優化,使得交易執行速度很快,
zkSync的虛擬機是SNARK友好的,其execution trance可proven in SNARK,不需要為每個program定義一個circuit,
zkSync虛擬機的proof system是PLONK方案,
4.2 zkSync智能合約語言——Zinc
Zinc 是一個新興的框架,用于在zkSync平臺上開發智能合約和SNARK電路,
現有的ZKP框架缺乏特定于智能合約的功能,由于智能合約涉及有價值的金融資產,安全和保障至關重要,這就是為什么現代智能合約語言(如Simplicity或Libra’s move)的設計者們更傾向于代碼的安全性和形式驗證性,而不是表現力,
Zinc填補這兩個世界之間的差距,提供了一個簡單,可靠的智能合約語言,專為ZKP電路優化,易于開發人員學習,
該框架包括一個簡單的、圖靈完備的、以安全為中心的通用語言,專門用于開發智能合約和具有平坦學習曲線的零知識證明電路,語法和語意與Rust非常相似,
Zinc編譯器使用LLVM作為其中端和后端,這為代碼優化提供了一套強大的解決方案,
Zinc語言正在大力發展;因此,它的許多方面最終將得到改進或改變,但是,安全性和簡單性等基本原則永遠不會受到質疑,
4.3 zkSync智能合約語言——Solidity
Solidity 是一種通用語言,擁有龐大的代碼庫和無數的DeFi專案,一種被來自世界各地的數千名區塊鏈開發人員采用的語言,
大多數的Solidity專案可無需修改直接部署,但是,有些功能可能會被進制或忽略,以保證代碼兼容性:
- 帶記憶體訪問的ASM blocks
- 利用溢位來方便計算
- ABI合約呼叫
- 未定義行為的一般情況
此外,matter labs團隊也在研究由 Solidity 到 Zinc的transpiler,以簡化遷移程序,
4.4 zkSync智能合約的路線圖
zkSync測驗網路智能合約已于2020年10月啟動,Curve Finance為其第一個常駐dapp,
計劃于2021年上主網,屆時將同時支持Zinc和Solidity語言,
可以使用Zandbox server運行任意智能合約,
如何在Rinkeby testnet部署zkSync智能合約,可參看教程:
- https://zinc.zksync.io/07-smart-contracts/02-minimal-example.html
5. zkSync 1.x中的NFTs
NFT addresses將按如下規則來encode NFT content和metadata:
address = truncate_to_20_bytes(rescue_hash(creator_account_id || serial_id || content_hash))
這種加密方法確保了2個不變數:
- NFT addresses可看成是unique commitment to the creator、serial number of the NFT及其content hash;
- NFT addresses不受任何人控制 或 在主網上擁有smart contract code,
注意,在zkSync 1.x中,多個NFTs可被minted with the same content hash,
可在Rinkeby 測驗網上呼叫 SDK介面 來mint和transfer NFTs,
5.1 mint NFT
mint NFT,需使用new opcode MINT_NFT,相應的引數為:
- creator_account_id
- content_hash
- recipient_account_id
通過recipient_account_id引數,creator可選擇是mint to 自己還是直接mint to 其他人,
參考資料
[1] zkSync Mainnet Block Explorer
[2] zkSync project architecture
[3] Introduction to zkSync for Developers
[4] zkSync Rollup Protocol
[5] Zinc說明書
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/282675.html
標籤:區塊鏈
上一篇:csdn_export_md
