Polymarket.RLP (Polymarket v0.2.0)

Copy Markdown View Source

Hand-rolled RLP (Recursive Length Prefix) encoder for Ethereum legacy (type-0) transaction serialization.

This module implements only the encoding side — there is no decoder. The set of inputs we encode is narrow: bytes, non-negative integers, and lists of already-encoded items. That's enough for legacy EIP-155 transactions and pure RLP test vectors.

Encoding rules (per the Ethereum spec)

Bytes / strings:

  • Empty: 0x80.
  • Single byte b where 0x00 <= b <= 0x7f: encoded as itself (single byte, no length prefix).
  • Other byte strings of length len:
    • 1 <= len <= 55: <<0x80 + len, ...bytes>>.
    • len > 55: <<0xb7 + size_of_len, ...len_bytes, ...bytes>> where len_bytes is the minimal big-endian encoding of len.

Lists with combined-payload size len:

  • 0 <= len <= 55: <<0xc0 + len, ...payload>>.
  • len > 55: <<0xf7 + size_of_len, ...len_bytes, ...payload>>.

Non-negative integers are encoded as their minimal-byte big-endian representation, then RLP-encoded as a byte string. Zero collapses to the empty string 0x80 — the integer 0 does NOT encode as <<0x00>>.

Output is byte-for-byte verified against ethers.encodeRlp in test/fixtures/tx.json § rlp_primitives.

Summary

Functions

Encodes a binary as an RLP string.

Encodes a non-negative integer as an RLP byte string carrying the minimal big-endian representation. Zero encodes as 0x80 (empty string), matching the canonical Ethereum/RLP convention.

Encodes a list of already-RLP-encoded items as an RLP list.

Hex-encodes raw RLP output for human display or fixture comparison. Always lowercase, always 0x-prefixed.

Functions

encode_bytes(bin)

@spec encode_bytes(binary()) :: binary()

Encodes a binary as an RLP string.

encode_integer(n)

@spec encode_integer(non_neg_integer()) :: binary()

Encodes a non-negative integer as an RLP byte string carrying the minimal big-endian representation. Zero encodes as 0x80 (empty string), matching the canonical Ethereum/RLP convention.

encode_list(items)

@spec encode_list([binary()]) :: binary()

Encodes a list of already-RLP-encoded items as an RLP list.

The caller is responsible for encoding each element first (encode_bytes/1, encode_integer/1, or a nested encode_list/1). This module deliberately keeps element-encoding decisions in the caller — there is no value tagging that would let one function decide between "string" and "integer" interpretations of arbitrary Elixir terms.

to_hex(bin)

@spec to_hex(binary()) :: String.t()

Hex-encodes raw RLP output for human display or fixture comparison. Always lowercase, always 0x-prefixed.