Skip to content

encode

Encoding refers to the process of converting data from one format to another to make it more secure and efficient.

In the context of blockchain, encoding is used to ensure that data is stored and transmitted in a secure and easily accessible manner.

Recursive Length Prefix (RLP) is a serialization format widely used in Ethereum execution clients.

Its purpose is to encode arbitrarily nested arrays of binary data, and is the primary encoding used to serialize objects in Ethereum.

RLP only encodes structures, leaving the encoding of specific atomic data types (such as strings, integers, and floats) to higher-level protocols.

In Ethereum, integers must be represented in big-endian binary form without leading zeros, such that an integer value of zero is equivalent to an empty byte array.

The RLP encoding function accepts an item, which is defined as a single byte with a value in the range [0x00, 0x7f] or a string 0-55 bytes long.

If the string is longer than 55 bytes, the RLP encoding contains a byte with the value 0xb7 (dec.183) plus the length The length of the string in bytes in binary, followed by the length of the string, followed by the string.

RLP is used for hash verification, where a transaction is signed by signing the RLP hash of the transaction data, and a block is identified by the RLP hash of its header.

RLP is also used to encode data over networks, and in some cases should support efficient encoding of Merkle tree data structures.

The Ethereum execution layer uses RLP as the primary encoding for serializing objects, but the newer Simple Serialize (SSZ) replaces RLP as the encoding for the new consensus layer in Ethereum 2.0.

The Cosmos Stargate release introduced protobuf as the primary encoding format for client and state serialization.

All EVM module types for state and clients, such as transaction messages, genesis, query services, etc., will be implemented as protocol buffer messages.

The Cosmos SDK also supports traditional Amino encoding.

Protocol Buffers (protobuf) is a language-independent binary serialization format that is smaller and faster than JSON.

It is used to serialize structured data, such as messages, and is designed to be efficient and scalable.

The encoding format is defined in a language-independent language called Protocol Buffers Language (proto3), and encoded messages can be used to generate code for various programming languages.

The main advantage of protobuf is its efficiency, which results in smaller message sizes and faster serialization and deserialization times.

The RLP decoding process is as follows: decode the data type, actual data length and offset according to the first byte of the input data (that is, the prefix); decode the data accordingly according to the data type and offset.

Prerequisites Reading

Encoding format

*** Protocol Buffers ***

The Cosmos Stargate release introduces protobuf as the primary encoding format for client and state serialization.

All EVM module types for state and clients (transaction messages, genesis, query services, etc.) will be implemented as protocol buffer messages.

*** Amino ***

The Cosmos SDK also supports the legacy Amino encoding format for backward compatibility with previous versions, especially for client-side encoding and signing with Ledger devices.

Daodst does not support Amino in the EVM module, but all other Cosmos SDK modules that enable it do.

*** RLP ***

Recursive Length Prefix (RLP) is an encoding/decoding algorithm that serializes messages and allows fast reconstruction of encoded data.

Daodst uses RLP to encode/decode Ethereum messages for JSON-RPC processing so that messages conform to the correct Ethereum format. This allows messages to be encoded and decoded in the exact same format as Ethereum's.

x/evm transaction (MsgEthereumTx) encoding is performed by converting the message to go-ethereum's Transaction and then using RLP to marshal the transaction data:

// 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 := &ethtypes.Transaction{}

  err := tx.UnmarshalBinary(txBytes)
  if err == nil {
    msg := &evmtypes.MsgEthereumTx{}
    msg.FromEthereumTx(tx)
    return msg, nil
  }

  return g.TxConfig.TxDecoder()(txBytes)
}
}