Helper module for parsing and encoding hex values.
If you use Cartouche.Hex, then you can use the ~h sigil for compile-time
hex-to-binary compilation.
Summary
Functions
Checksums an Ethereum address per EIP-55.
Parses an Ethereum 20-bytes hex string.
Parses a hex string, but returns :error instead
of raising if hex is invalid.
Parses a hex string and raises if invalid.
Decodes hex, allowing it to either be "0x..." or a raw binary.
Parses hex value as a big-endian integer.
Parses hex value as a big-endian integer. Raises if invalid.
Parses hex is value is not nil, otherwise returns nil.
Parses a hex value as a big-endian integer if not nil, otherwise returns nil.
Parses an Ethereum x-bytes hex string.
Parses an Ethereum 32-bytes hex string.
Encodes a binary as a checksummed Ethereum address.
Encodes hex, in CAPITALS.
Encodes a number as a binary of a fixed byte length, left-padded with zeros.
Encodes a given value as a lowercase hex string, starting with 0x.
If input is a tuple {:ok, x} then returns a tuple {:ok, hex}
where hex = encode(x). Otherwise, returns its input unchanged.
Encodes a non-negative integer as a JSON-RPC "quantity" string.
Encodes hex, striping any leading zeros.
Alias for decode_hex.
Alias for decode_hex!.
Similar non-sigil compile-time hex parser.
If input is non-nil, returns input encoded as a hex string. Otherwise,
returns nil.
Returns the nibbles of a binary as a list.
Pads a binary to a given length.
Handles the sigil ~h for list of words.
Alias for encode_address.
Alias for encode_hex.
Types
@type t() :: binary()
Functions
Checksums an Ethereum address per EIP-55.
The result is a string-encoded (mixed-case) version of the address.
Examples
iex> Cartouche.Hex.checksum_address("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"
iex> Cartouche.Hex.checksum_address("0xFB6916095CA1DF60BB79CE92CE3EA74C37C5D359")
"0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"
iex> Cartouche.Hex.checksum_address("0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb")
"0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"
iex> Cartouche.Hex.checksum_address("0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb")
"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"
Parses an Ethereum 20-bytes hex string.
Identical to decode_hex!/1 except fails if
string is not exactly 20-bytes.
Examples
iex> Cartouche.Hex.decode_address!("0x0000000000000000000000000000000000000001") <<1::160>>
iex> Cartouche.Hex.decode_address!("0xaabb") ** (Cartouche.Hex.InvalidHex) invalid hex address: "0xaabb"
Parses a hex string, but returns :error instead
of raising if hex is invalid.
Examples
iex> Cartouche.Hex.decode_hex("0xaabb")
{:ok, <<170, 187>>}
iex> Cartouche.Hex.decode_hex("aabb")
{:ok, <<170, 187>>}
iex> Cartouche.Hex.decode_hex("0xgggg")
:invalid_hex
Parses a hex string and raises if invalid.
Examples
iex> Cartouche.Hex.decode_hex!("aabb") <<170, 187>>
iex> Cartouche.Hex.decode_hex!("0xggaabb") ** (Cartouche.Hex.InvalidHex) invalid hex: "0xggaabb"
Decodes hex, allowing it to either be "0x..." or a raw binary.
Note: a hex-printed string, in this case, must start with 0x,
otherwise it will be interpreted as its ASCII values.Examples
iex> Cartouche.Hex.decode_hex_input!("0x55")
<<0x55>>
iex> Cartouche.Hex.decode_hex_input!(<<0x55>>)
<<0x55>>
Parses hex value as a big-endian integer.
Examples
iex> Cartouche.Hex.decode_hex_number("0xaabb")
{:ok, 0xaabb}
iex> Cartouche.Hex.decode_hex_number("0xgggg")
:invalid_hex
Parses hex value as a big-endian integer. Raises if invalid.
Examples
iex> Cartouche.Hex.decode_hex_number!("0xaabb") 0xaabb
iex> Cartouche.Hex.decode_hex_number!("0xgggg") ** (Cartouche.Hex.InvalidHex) invalid hex number: "0xgggg"
Parses hex is value is not nil, otherwise returns nil.
Examples
iex> Cartouche.Hex.decode_maybe_hex!("0xaabb") <<170, 187>>
iex> Cartouche.Hex.decode_maybe_hex!(nil) nil
Parses a hex value as a big-endian integer if not nil, otherwise returns nil.
Useful for JSON-RPC fields that are absent on pre-fork blocks (e.g.
blobGasUsed / blobGasPrice on pre-Cancun receipts).
Examples
iex> Cartouche.Hex.decode_maybe_hex_number!("0xaabb") 0xaabb
iex> Cartouche.Hex.decode_maybe_hex_number!(nil) nil
Parses an Ethereum x-bytes hex string.
Identical to decode_hex!/1 except fails if
string is not exactly x-bytes.
Examples
iex> Cartouche.Hex.decode_sized!("0x001122", 3) <<0x00, 0x11, 0x22>>
iex> Cartouche.Hex.decode_sized!("0xaabb", 3) ** (Cartouche.Hex.InvalidHex) invalid 3-byte sized hex: "0xaabb"
Parses an Ethereum 32-bytes hex string.
Identical to decode_hex!/1 except fails if
string is not exactly 32-bytes.
Examples
iex> Cartouche.Hex.decode_word!("0x0000000000000000000000000000000000000000000000000000000000000001") <<1::256>>
iex> Cartouche.Hex.decode_word!("0xaabb") ** (Cartouche.Hex.InvalidHex) invalid hex word: "0xaabb"
Encodes a binary as a checksummed Ethereum address.
Examples
iex> Cartouche.Hex.encode_address(<<0xaa, 0xbb, 0xcc, 0::136>>) "0xaABbcC0000000000000000000000000000000000"
iex> Cartouche.Hex.encode_address(<<55>>)
** (Cartouche.Hex.InvalidHex) Expected 20-byte address for in Cartouche.Hex.encode_address/1
Encodes hex, in CAPITALS.
Examples
iex> Cartouche.Hex.encode_big_hex(<<0xcc, 0xdd>>) "0xCCDD"
@spec encode_bytes(integer() | nil, pos_integer()) :: binary() | nil
Encodes a number as a binary of a fixed byte length, left-padded with zeros.
Examples
iex> Cartouche.Hex.encode_bytes(257, 4)
<<0, 0, 1, 1>>
iex> Cartouche.Hex.encode_bytes(nil, 4)
nil
Encodes a given value as a lowercase hex string, starting with 0x.
Examples
iex> Cartouche.Hex.encode_hex(<<0xaa, 0xbb>>) "0xaabb"
If input is a tuple {:ok, x} then returns a tuple {:ok, hex}
where hex = encode(x). Otherwise, returns its input unchanged.
Examples
iex> Cartouche.Hex.encode_hex_result({:ok, <<0xaa, 0xbb>>})
{:ok, "0xaabb"}
iex> Cartouche.Hex.encode_hex_result({:error, 55})
{:error, 55}
@spec encode_quantity(non_neg_integer()) :: String.t()
Encodes a non-negative integer as a JSON-RPC "quantity" string.
Lowercase hex with 0x prefix and no leading zeros. 0 becomes "0x0".
This matches the JSON-RPC spec for the QUANTITY type used in
eth_getBlockByNumber, eth_getBalance, eth_call block params, etc.
Examples
iex> Cartouche.Hex.encode_quantity(0)
"0x0"
iex> Cartouche.Hex.encode_quantity(55)
"0x37"
iex> Cartouche.Hex.encode_quantity(24_975_978)
"0x17d1a6a"
Encodes hex, striping any leading zeros.
Examples
iex> Cartouche.Hex.encode_short_hex(<<0xc>>) "0xC"
iex> Cartouche.Hex.encode_short_hex(12) "0xC"
iex> Cartouche.Hex.encode_short_hex(<<0x0>>) "0x0"
Alias for decode_hex.
Examples
iex> Cartouche.Hex.from_hex("0xaabb")
{:ok, <<0xaa, 0xbb>>}
iex> Cartouche.Hex.from_hex("0xgggg")
:invalid_hex
Alias for decode_hex!.
Examples
iex> Cartouche.Hex.from_hex!("0xaabb") <<0xaa, 0xbb>>
iex> Cartouche.Hex.from_hex!("0xggaabb") ** (Cartouche.Hex.InvalidHex) invalid hex: "0xggaabb"
Similar non-sigil compile-time hex parser.
Examples
iex> use Cartouche.Hex
iex> hex!("0x22")
<<0x22>>
iex> use Cartouche.Hex
iex> hex!("0x2244")
<<0x22, 0x44>>
If input is non-nil, returns input encoded as a hex string. Otherwise,
returns nil.
Examples
iex> Cartouche.Hex.maybe_encode_hex(<<0xaa, 0xbb>>) "0xaabb"
iex> Cartouche.Hex.maybe_encode_hex(nil) nil
@spec nibbles(binary()) :: [0..15]
Returns the nibbles of a binary as a list.
Examples
iex> Cartouche.Hex.nibbles(<<0xF5, 0xE6, 0xD0>>)
[0xF, 0x5, 0xE, 0x6, 0xD, 0x0]
@spec pad(binary(), pos_integer()) :: binary()
Pads a binary to a given length.
Examples
iex> Cartouche.Hex.pad(<<1, 2>>, 2)
<<1, 2>>
iex> Cartouche.Hex.pad(<<1, 2>>, 4)
<<0, 0, 1, 2>>
iex> Cartouche.Hex.pad(<<1, 2>>, 1)
** (FunctionClauseError) no function clause matching in Cartouche.Hex.pad/2
Handles the sigil ~h for list of words.
Parses a hex string at compile-time.
Examples
iex> use Cartouche.Hex
iex> ~h[0x22]
<<0x22>>
iex> use Cartouche.Hex
iex> ~h[0x2244]
<<0x22, 0x44>>
Alias for encode_address.
Examples
iex> Cartouche.Hex.to_address(<<0xaa, 0xbb, 0xcc, 0::136>>) "0xaABbcC0000000000000000000000000000000000"
Alias for encode_hex.
Examples
iex> Cartouche.Hex.to_hex(<<0xaa, 0xbb>>) "0xaabb"