在以太坊完成上海升級(jí)后,以太坊已成功從 PoW 過(guò)渡到了 PoS 協(xié)議。以太坊路線圖中的另一個(gè)大的升級(jí)是 EIP-4844,也被稱(chēng)之為 Ptoto-Danksharding,這次升級(jí)旨在提高基于以太坊 rollup 的可擴(kuò)展性,將于 2024 年 1 月 17 日開(kāi)始在測(cè)試環(huán)境升級(jí)。這次升級(jí)也為以太坊的完整擴(kuò)容方案 Danksharding 做好了準(zhǔn)備工作。本文將介紹坎昆升級(jí)的內(nèi)容,并對(duì)其中關(guān)鍵升級(jí) EIP-4844 進(jìn)行深入分析,同時(shí)也分析了 EIP-4844 升級(jí)所帶來(lái)的影響。
本文中代碼使用 geth(執(zhí)行層)和 prysm(共識(shí)層)的實(shí)現(xiàn)。
# 01坎昆升級(jí)簡(jiǎn)介
坎昆升級(jí)最近有了新的進(jìn)展,確定會(huì)在 2024 升級(jí),測(cè)試環(huán)境將在 1 月 17 日進(jìn)行,主網(wǎng)升級(jí)預(yù)計(jì)會(huì)在 2024 年的 3-4 月。作為以太坊生態(tài)的下一個(gè)主要敘事,這次升級(jí)肯定會(huì)得到很大的關(guān)注。
坎昆(Cancun)是墨西哥的一個(gè)城市,也是 Devcon3 的舉辦地,作為以太坊升級(jí)的傳統(tǒng),這次執(zhí)行層的升級(jí)代號(hào)就是 Cancun。這次升級(jí)還會(huì)涉及到共識(shí)層的升級(jí),共識(shí)層的升級(jí)代號(hào)是 Deneb,完整的升級(jí)代號(hào)是這兩個(gè)代號(hào)的結(jié)合:Dencun = Deneb + Cancun。
這次升級(jí)包含的內(nèi)容很多,執(zhí)行層和共識(shí)層分別需要實(shí)施的 EIP 如下:
- 執(zhí)行層
- EIP-1153
- EIP-4788
- EIP-4844
- EIP-5656
- EIP-6780
- EIP-7516
- 共識(shí)層
- EIP-4788
- EIP-4844
- EIP-7044
- EIP-7045
- EIP-7514
這次升級(jí)的主角就是 EIP-4844,其他的升級(jí)要么是為它服務(wù),要么是一些小修小補(bǔ)。在本文中,我們重點(diǎn)來(lái)研究 EIP-4844 升級(jí)的細(xì)節(jié),以及升級(jí)之后帶來(lái)的影響。
EIP-4844 也被稱(chēng)之為 Proto-Danksharding,這個(gè)名字來(lái)源于 Protolambda 和 Dankrad Feist 兩位研究員。以太坊最終的數(shù)據(jù)擴(kuò)展方案是 Danksharding,EIP-4844 是 DankSharding 的前置升級(jí)。這次升級(jí)主要的目的是提升 rollup 層的可擴(kuò)展性,并且為后續(xù)的 DankSharding 升級(jí)做好準(zhǔn)備。
# 02
理解坎昆升級(jí),你需要知道
2.1 數(shù)據(jù)可用性(DA)
在區(qū)塊鏈中,不要信任,要驗(yàn)證是一個(gè)基本的原則。每個(gè)區(qū)塊鏈節(jié)點(diǎn)都可以保存完整的數(shù)據(jù),可以通過(guò)重新執(zhí)行交易來(lái)確定所有數(shù)據(jù)的真實(shí)性,通過(guò)獨(dú)立地驗(yàn)證這些數(shù)據(jù),就不用管其他的節(jié)點(diǎn)是否在*。
數(shù)據(jù)可用性是指在驗(yàn)證區(qū)塊是否正確時(shí),所需要的數(shù)據(jù)能夠公開(kāi)可獲取。對(duì)于當(dāng)前的以太坊架構(gòu)來(lái)說(shuō),這很容易做到,因?yàn)槊總€(gè)節(jié)點(diǎn)都可以保存所有的數(shù)據(jù),缺少數(shù)據(jù)的區(qū)塊會(huì)被丟棄,對(duì)于所有的節(jié)點(diǎn)來(lái)說(shuō),數(shù)據(jù)是可用的,這是區(qū)塊鏈的一個(gè)特性,數(shù)據(jù)可用性是區(qū)塊鏈的安全保障。
對(duì)于 Layer2 rollup,能證明區(qū)塊合法有效的數(shù)據(jù)都會(huì)上傳到以太坊,它們的數(shù)據(jù)可用性需要依靠以太坊來(lái)保證。
這樣就帶來(lái)了兩個(gè)問(wèn)題:
- 所有的 Layer2 都向以太坊提交數(shù)據(jù),會(huì)讓 gas fee 持續(xù)保持在高位
- 以太坊本身的存儲(chǔ)能力有限,制約了 Layer2 的發(fā)展
以太坊需要一種不犧牲數(shù)據(jù)可用性,同時(shí)又能讓 Layer2 向以太坊用更低的成本提交更多交易的方案,讓 Layer2 的潛力發(fā)揮出來(lái)。
EIP-4844 是這個(gè)方案的前半部分,通過(guò)增加一種新的 blob 交易,blob 交易中的數(shù)據(jù)存儲(chǔ)成本更低,Layer2 可以將交易打包,通過(guò) blob 交易提交到以太坊,從而增加并發(fā)、降低成本。但 EIP-4844 帶來(lái)的提升是有限的,因?yàn)?blob 數(shù)據(jù)依然會(huì)傳播到所有的節(jié)點(diǎn),會(huì)給節(jié)點(diǎn)帶來(lái)很大的存儲(chǔ)和網(wǎng)絡(luò)成本,所以這次升級(jí)中,每個(gè)區(qū)塊只能支持 6 個(gè) blob。
Dankshrding 是這個(gè)方案的后半部分,在完成 DankSharding 之后,每個(gè)區(qū)塊鏈支持的 blob 可能會(huì)到 64 個(gè),這樣 Layer2 基本就沒(méi)有什么限制了。但在這個(gè)升級(jí)之后,大多以太坊節(jié)點(diǎn)就不可能獨(dú)立的存儲(chǔ)這些數(shù)據(jù)了,大多數(shù)人承擔(dān)不了網(wǎng)絡(luò)和存儲(chǔ)成本。如果節(jié)點(diǎn)不能完整的存儲(chǔ)數(shù)據(jù),那么數(shù)據(jù) DA 要怎么來(lái)保證呢?
檢查數(shù)據(jù)可用性的方式有很多種,但 DAS(Data availability sampling)是最去中心化的一種,DankSharding 中使用的也是這種。通過(guò) DAS,完整的數(shù)據(jù)不用在節(jié)點(diǎn)之間傳播,只需要隨機(jī)檢查部分?jǐn)?shù)據(jù)的 KZG 證明就可以保證數(shù)據(jù)的可用性。
基于同樣的原因,只有區(qū)塊鏈的 Builder 需要獲取所有的數(shù)據(jù),創(chuàng)建好區(qū)塊之后,其他的 Proposer 不用下載全部的數(shù)據(jù),只需要通過(guò) DAS 來(lái)驗(yàn)證區(qū)塊是否有效,這個(gè)功能升級(jí)就是 PBS(Proposer-builder separation)。除了提高數(shù)據(jù)的處理效率,其他的 Proposer 也看不到交易的內(nèi)容,這在一定程度還增加了抗審查能力。
2.2 KZG
KZG(Kate Zaverucha Goldberg)是一種零知識(shí)證明系統(tǒng),EIP-4844 中引入了 KZG,作為 blob 驗(yàn)證和證明生成的一部分。每一個(gè) blob 都會(huì)生成一個(gè)對(duì)應(yīng)的 KZG commitment,為后續(xù)的 DankSharding 升級(jí)做準(zhǔn)備。
在 EIP-4844 升級(jí)后,blob 數(shù)據(jù)還是會(huì)在各個(gè)節(jié)點(diǎn)之間傳播。但是在完全的 DankSharding 升級(jí)之后,blob 的數(shù)據(jù)量大量增加,節(jié)點(diǎn)之間不能再全量地同步 blob 數(shù)據(jù)。節(jié)點(diǎn)之間會(huì)通過(guò) KZG 和 DAS 來(lái)檢查數(shù)據(jù)的 DA,這是 DankSharding 實(shí)現(xiàn)的基礎(chǔ)。
# 03
Blast 與 L2
EIP-4844 升級(jí)中已經(jīng)完成的工作:
- 實(shí)現(xiàn) blob 交易以及 blob 數(shù)據(jù)的 KZG 處理
- 實(shí)現(xiàn)執(zhí)行層&共識(shí)層邏輯,以及執(zhí)行層和共識(shí)層交互接口的修改
- blob 交易自動(dòng)調(diào)整 gas 的機(jī)制
在完全實(shí)施 DankSharding 之前,還需要完成的工作:
- DAS 實(shí)施
- PBS 實(shí)施
EIP-4844 完成了后續(xù) DankSharding 升級(jí)中的大部分基礎(chǔ)工作。剩下的升級(jí),只需要通過(guò)升級(jí)共識(shí)層來(lái)完成,不需要執(zhí)行層和 rollup 的參與,用戶和開(kāi)發(fā)者對(duì)后續(xù)的升級(jí)無(wú)感。
3.1 blob 交易詳解
在 blob 交易出現(xiàn)之前,Layer2 的交易數(shù)據(jù)通過(guò) calldata 來(lái)存儲(chǔ),calldata 是合約調(diào)用中傳入的函數(shù)參數(shù),是只讀的,并且會(huì)被永久存儲(chǔ)到鏈上,blob 交易中的數(shù)據(jù)存儲(chǔ)在額外的空間中,并且在一段時(shí)間后被刪除。
blob 存儲(chǔ)和 calldata 的區(qū)別:
EIP- 4844 在執(zhí)行層增加了 blob 的交易類(lèi)型:
const ( LegacyTxType = 0x00 AccessListTxType = 0x01 DynamicFeeTxType = 0x02 BlobTxType = 0x03 // 新增的 blob 交易)
blob 的交易結(jié)構(gòu)如下:
//geth core/types/tx_blob.go type BlobTx struct { //...
BlobHashes [][]byte // 相比于 EIP-1559 的交易,多了一個(gè) Sidecar 參數(shù) Sidecar *BlobTxSidecar `rlp:"-"`
//...}
// Sidecar 結(jié)構(gòu)type BlobTxSidecar struct { Blobs []kzg4844.Blob // Blobs needed by the blob pool Commitments []kzg4844.Commitment // Commitments needed by the blob pool Proofs []kzg4844.Proof // Proofs needed by the blob pool}
// 每個(gè) blob 原始數(shù)據(jù)最大 128 kbtype Blob [131072]byte
// 生成的 KZG commitment,占 48 字節(jié)type Commitment [48]byte
type Proof [48]byte
相比于 EIP-1559 交易,多了一個(gè) Sidecar 參數(shù),其中存放的就是就是 blob 數(shù)據(jù),這些 blob 不會(huì)被打包進(jìn)入執(zhí)行層的區(qū)塊。其中每個(gè) blob sidecar 包含三部分?jǐn)?shù)據(jù),包括 blob 的原始數(shù)據(jù)和經(jīng)過(guò) KZG 處理之后的數(shù)據(jù),BlobHashes 中存儲(chǔ) Sidesar 中 Commitments 的 hash 值。
blob 交易中,blob 數(shù)據(jù)存儲(chǔ)部分的價(jià)格是單獨(dú)計(jì)算的,而且會(huì)隨之前區(qū)塊 blob 的使用情況而變動(dòng),如果上一個(gè)區(qū)塊中 blob 的使用超過(guò)了 blob 最大限制的 50%,那么費(fèi)用就會(huì)上調(diào),如果低于 50%,那么費(fèi)用就會(huì)降低:
//geth core/types/transaction.go func CalcBlobFee(excessBlobGas uint64) *big.Int { return fakeExponential(minBlobGasPrice, new(big.Int).SetUint64(excessBlobGas), blobGaspriceUpdateFraction)}
// fakeExponential approximates factor * e ** (numerator / denominator) using// Taylor expansion.func fakeExponential(factor, numerator, denominator *big.Int) *big.Int { var ( output = new(big.Int) accum = new(big.Int).Mul(factor, denominator) ) for i := 1; accum.Sign() > 0; i++ { output.Add(output, accum)
accum.Mul(accum, numerator) accum.Div(accum, denominator) accum.Div(accum, big.NewInt(int64(i))) } return output.Div(output, denominator)}
計(jì)算一筆交易中 blob gas 的最大限制:
//geth core/types/transaction.gofunc (tx *BlobTx) blobGas() uint64 { return params.BlobTxBlobGasPerBlob * uint64(len(tx.BlobHashes)) }
計(jì)算最終交易的花費(fèi):
//geth core/types/transaction.gofunc (tx *Transaction) Cost() *big.Int { total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())) if tx.Type() == BlobTxType { total.Add(total, new(big.Int).Mul(tx.BlobGasFeeCap(), new(big.Int).SetUint64(tx.BlobGas()))) } total.Add(total, tx.Value()) return total}
最終一筆 blob 交易的開(kāi)銷(xiāo)由三部分組成:交易 gas fee + 發(fā)送的 value + blob fee。
在 EIP-4844 的升級(jí)中,每個(gè)區(qū)塊中攜帶的 blob 數(shù)量不超過(guò) 6 個(gè)。后續(xù)完成 DankSharding 升級(jí)之后,每個(gè)區(qū)塊上 blob 的數(shù)量可以擴(kuò)展到 64 個(gè)。
執(zhí)行層并不會(huì)存儲(chǔ)這些 blob 數(shù)據(jù),會(huì)在構(gòu)建區(qū)塊的時(shí)候,通過(guò) API 將 Blob 數(shù)據(jù)傳輸?shù)焦沧R(shí)層:
// geth beacon/engine/types.gotype ExecutionPayloadEnvelope struct { ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` BlockValue *big.Int `json:"blockValue" gencodec:"required"` BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` Override bool `json:"shouldOverrideBuilder"`}
type BlobsBundleV1 struct { Commitments []hexutil.Bytes `json:"commitments"` Proofs []hexutil.Bytes `json:"proofs"` Blobs []hexutil.Bytes `json:"blobs"`}
共識(shí)層收到這些交易之后,會(huì)將 blob 的 KZG commitment 打包到鏈上,而將 blob 原始數(shù)據(jù)分開(kāi)存儲(chǔ):
// prysm type BeaconBlockBody struct { //... blobKzgCommitments [][]byte // blob 的 Kzg 數(shù)據(jù)}
共識(shí)層會(huì)負(fù)責(zé)驗(yàn)證 Blob 數(shù)據(jù)的可用性,驗(yàn)證的邏輯都被封裝在 isDataAvailable 方法中。目前的實(shí)現(xiàn)是先驗(yàn)證本地?cái)?shù)據(jù)庫(kù)中是否可以找到完整的 blob 數(shù)據(jù),如果找不到,那就通過(guò)特定的渠道去獲取,直到獲取成功或者報(bào)錯(cuò)。后續(xù) Danksharding 升級(jí)完成后,那么通過(guò)也會(huì)通過(guò)這個(gè)方法來(lái)實(shí)現(xiàn) DAS 驗(yàn)證,減少對(duì)其他模塊的影響。
// prysm/beacon-chain/blockchainfunc (s *Service) isDataAvailable(ctx context.Context, root [32]byte, signed interfaces.ReadOnlySignedBeaconBlock) error { //...}
在 EIP-4844 的升級(jí)后,blob 數(shù)據(jù)還是會(huì)通過(guò) gossip 協(xié)議廣播到所有的節(jié)點(diǎn),在完全升級(jí)到 Danksharding 之后,會(huì)通過(guò) DAS 來(lái)驗(yàn)證數(shù)據(jù)的完整性,而不用下載完整的數(shù)據(jù)。
總結(jié)一下,新增的 blob 交易允許用戶將一些數(shù)據(jù)放到 blob 中,blob 數(shù)據(jù)不會(huì)在執(zhí)行層存儲(chǔ), EVM 也無(wú)法讀取到這些數(shù)據(jù),這些數(shù)據(jù)會(huì)被直接放到共識(shí)層存儲(chǔ),然后廣播給其他的共識(shí)層節(jié)點(diǎn)。
3.2 blob 如何影響 gas fee
理論上來(lái)說(shuō),EIP-4844 升級(jí)肯定會(huì)降低 Layer2 的 gas fee。因?yàn)?blob 的存儲(chǔ)費(fèi)用會(huì)比 calldata 更低,而且一個(gè) blob 中可以容納更多的交易,但實(shí)際的情況卻會(huì)更復(fù)雜。
EIP-4844 升級(jí)中,每個(gè)區(qū)塊的中最多可以掛 6 個(gè) blob。但 blob 的費(fèi)用是動(dòng)態(tài)調(diào)整的,如果前一個(gè)區(qū)塊中的 blob 數(shù)量超過(guò)了最大值的 50%,也就是 3 個(gè),那么當(dāng)前這個(gè)區(qū)塊的 blob fee 就會(huì)上漲 12.5%,如果低于 50%,這個(gè)區(qū)塊的 blob fee 就會(huì)下降 12.5%,所以最后每個(gè)區(qū)塊中的 blob 數(shù)量會(huì)維持在最大容量的 50% 左右。
對(duì)于 Layer2 來(lái)說(shuō),理論上 gas fee 會(huì)降低到十分之一甚至更低,但是如果鏈上交易繁忙,多個(gè) rollup 同時(shí)向以太坊提交數(shù)據(jù),那么 blob fee 也會(huì)暴漲,很難準(zhǔn)確地估計(jì)升級(jí)之后的 gas fee,這樣取決于當(dāng)時(shí)的網(wǎng)絡(luò)情況。只有等到 DankSharding 完全升級(jí),每個(gè)以太坊區(qū)塊可以支持到 64 個(gè) blob 時(shí)才能解決。
另外,一個(gè) blob 的大小是 128kb,大小不能改變,對(duì)于交易的提交方來(lái)說(shuō),即使沒(méi)有這么多數(shù)據(jù),也需要付出一個(gè)完整 blob 的成本。如果一個(gè) Layer2 上的交易量沒(méi)有這么大,有可能使用 calldata 的成本會(huì)更低。當(dāng)然也有可能多個(gè)交易量不大的 Layer2 會(huì)將數(shù)據(jù)合并后再使用 blob 交易提交。
EIP-4844 升級(jí)肯定會(huì)降低 Layer2 的 gas fee,但是也會(huì)因?yàn)榫W(wǎng)絡(luò)和 blob 交易的使用情況讓 gas fee 有比較大的波動(dòng)。
3.3 blob 數(shù)據(jù)如何存儲(chǔ)
EIP-4844 的升級(jí)某種程度上與比特幣的隔離見(jiàn)證(Segwit)升級(jí)有點(diǎn)類(lèi)似,通過(guò)額外存儲(chǔ)提升區(qū)塊鏈的容量,而不用大區(qū)塊的升級(jí)方案。這些額外多出來(lái)的數(shù)據(jù)也需要合適的存儲(chǔ)方式,否則會(huì)增加節(jié)點(diǎn)的存儲(chǔ)成本,降低以太坊網(wǎng)絡(luò)的去中心化程度。
在 EIP-4844 升級(jí)之后,每個(gè)區(qū)塊中可以有 6 個(gè) blob,如果按照 50% 利用率,每天最多可以有 21600 個(gè) blob,每天會(huì)新增 2.7G 的數(shù)據(jù),這樣會(huì)給節(jié)點(diǎn)帶來(lái)很大的存儲(chǔ)成本。所以這些數(shù)據(jù)在一定周期之后會(huì)從節(jié)點(diǎn)上刪除,轉(zhuǎn)而使用鏈下存儲(chǔ),包括 Layer2 rollup 自身、BitTorrent、區(qū)塊鏈瀏覽器、Ethereum portal network、The Graph、個(gè)人等等。
特別是在 DankSharding 完全實(shí)現(xiàn)之后,每年可能會(huì)增加 40TB 的數(shù)據(jù),單個(gè)節(jié)點(diǎn)上想要存儲(chǔ)這些數(shù)據(jù)基本是不可能的,所以會(huì)采用定期刪除,但是能按需找回的方案。
# 04
坎昆升級(jí)的影響
以太坊的坎昆升級(jí)和后續(xù)的 DankSharding 升級(jí)本質(zhì)上是在給以太坊擴(kuò)容,在完成擴(kuò)容的同時(shí),又沒(méi)有采用大區(qū)塊的方式,以太坊的區(qū)塊還是會(huì)在 1M 以內(nèi),這有利于以太坊的長(zhǎng)期發(fā)展,可以讓以太坊在長(zhǎng)時(shí)間內(nèi)保持較高的去中心化程度。
坎昆升級(jí)可以提升 Layer2 交易的吞吐量以及降低 gas fee,甚至有望將 Layer2 的 gas fe 降低到當(dāng)前十分之一的水平,各種大規(guī)模的應(yīng)用就有可能開(kāi)始爆發(fā),可以將更多的 Web2 用戶帶入 Web3,當(dāng)然這個(gè)情況更可能在 DankSharding 完全升級(jí)之后出現(xiàn)。
同時(shí) EIP-4844 的升級(jí),也是對(duì)模塊化區(qū)塊鏈的肯定,這也會(huì)繼續(xù)利好模塊化區(qū)塊鏈的發(fā)展。完成這次升級(jí)之后,以太坊的職能將會(huì)加速轉(zhuǎn)變,越來(lái)越多的 DAPP 會(huì)在 Layer2 層開(kāi)發(fā),用戶也會(huì)直接使用 Layer2,以太坊將會(huì)成為所有 Layer2 的 DA 層,成為整個(gè) EVM 生態(tài)安全的守護(hù)者。
# 05總結(jié)
EIP-4844 本身并不是一個(gè)顛覆性的升級(jí),對(duì)以太坊的用戶來(lái)說(shuō)改變并不多,以太坊還是很慢而且很貴。而各種 rollup 方案則會(huì)從從中受益,可以說(shuō)這次升級(jí)就是為 rollup 所準(zhǔn)備的。EIP-4844 的升級(jí)會(huì)讓以太坊走向模塊化區(qū)塊鏈的方向,等到 Danksharding 升級(jí)完成之后,以太坊主網(wǎng)就成了 Layer2 的 DA 層,Layer2 就成了執(zhí)行層,負(fù)責(zé)性能的提升,后續(xù)模塊化的方案應(yīng)該會(huì)不斷出現(xiàn)。