編碼
編碼是指將數據從一種格式轉換為另一種格式以使其更加安全和高效的過程。
在區塊鏈的背景下,編碼用於確保數據以安全且易於訪問的方式存儲和傳輸。
遞歸長度前綴 (RLP) 是一種在以太坊執行客戶端中廣泛使用的序列化格式。
它的目的是對任意嵌套的二進制數據數組進行編碼,是以太坊中用於序列化對象的主要編碼方式。
RLP 僅對結構進行編碼,而將對特定原子數據類型(例如字符串、整數和浮點數)的編碼留給高階協議。
在以太坊中,整數必須以沒有前導零的大端二進制形式表示,使得整數值零等同於空字節數組。
RLP 編碼函數接受一個項目,該項目被定義為值在 [0x00, 0x7f] 範圍內的單個字節或 0-55 字節長的字符串。
如果字符串的長度超過 55 個字節,則 RLP 編碼包含一個值為 0xb7(dec.183)的字節加上長度 二進制形式的字符串長度的字節,後跟字符串的長度,後跟字符串。
RLP 用於哈希驗證,其中通過簽署交易數據的 RLP 哈希來簽署交易,並且區塊由其標頭的 RLP 哈希標識。
RLP 還用於通過網絡對數據進行編碼,以及在某些情況下應該支持默克爾樹數據結構的高效編碼。
以太坊執行層使用 RLP 作為序列化對象的主要編碼方式,但更新的 Simple Serialize (SSZ) 取代了 RLP 作為以太坊 2.0 中新共識層的編碼。
Cosmos Stargate 版本引入了 protobuf 作為客戶端和狀態序列化的主要編碼格式。
所有用於狀態和客戶端的 EVM 模塊類型,如交易消息、創世、查詢服務等,都將作為協議緩衝區消息實現。
Cosmos SDK 還支持傳統的 Amino 編碼。
Protocol Buffers (protobuf) 是一種與語言無關的二進制序列化格式,它比 JSON 更小更快。
它用於序列化結構化數據,例如消息,並且被設計為高效和可擴展的。
編碼格式以與語言無關的語言定義,稱為 Protocol Buffers Language (proto3),編碼的消息可用於為各種編程語言生成代碼。
protobuf 的主要優點是它的效率,這導致更小的消息大小和更快的序列化和反序列化時間。
RLP解碼過程如下:根據輸入數據的第一個字節(即前綴)解碼數據類型、實際數據的長度和偏移量;根據數據的類型和偏移量,對數據進行相應的解碼。
先決條件閱讀
編碼格式
*** Protocol Buffers ***
Cosmos Stargate 版本引入了 protobuf 作為客戶端和狀態序列化的主要編碼格式。
所有用於狀態和客戶端(交易消息、創世、查詢服務等)的 EVM 模塊類型都將作為協議緩衝區消息實現。
*** Amino ***
Cosmos SDK 還支持舊版 Amino 編碼格式,以向後兼容以前的版本,特別是用於客戶端編碼和使用 Ledger 設備簽名。
Daodst 在 EVM 模塊中不支持 Amino,但所有其他啟用它的 Cosmos SDK 模塊都支持它。
*** RLP ***
遞歸長度前綴 (RLP) 是一種編碼/解碼算法,可序列化消息並允許快速重建編碼數據。
Daodst 使用 RLP 編碼/解碼以太坊消息以進行 JSON-RPC 處理,以使消息符合正確的以太坊格式。這允許以與以太坊的格式完全相同的格式對消息進行編碼和解碼。
x/evm
交易 (MsgEthereumTx
) 編碼是通過將消息轉換為 go-ethereum 的 Transaction
然後使用 RLP 編組交易數據來執行的:
// TxEncoder overwrites sdk.TxEncoder to support MsgEthereumTx
func (g txConfig) TxEncoder() sdk.TxEncoder {
return func(tx sdk.Tx) ([]byte, error) {
msg, ok := tx.(*evmtypes.MsgEthereumTx)
if ok {
return msg.AsTransaction().MarshalBinary()
}
return g.TxConfig.TxEncoder()(tx)
}
}
// TxDecoder overwrites sdk.TxDecoder to support MsgEthereumTx
func (g txConfig) TxDecoder() sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) {
tx := ðtypes.Transaction{}
err := tx.UnmarshalBinary(txBytes)
if err == nil {
msg := &evmtypes.MsgEthereumTx{}
msg.FromEthereumTx(tx)
return msg, nil
}
return g.TxConfig.TxDecoder()(txBytes)
}
}