RLP encoding
RLP (recursive length prefix) is a common algorithm for encoding of variable length binary data. RLP encodes data before storing on disk or transmitting via network.
Theory
Encoding
Primary RLP can only deal with “item” type, which is defined as:
Some examples are:
b'\x00\xff'
empty list
[]
list of bytes
[b'\x00', b'\x01\x03']
list of combinations
[[], b'\x00', [b'\x00']]
The encoded result is always a byte string:
Encoding algorithm
Given x
item as input, we define rlp_encode
as the following algorithm:
Let
concat
be a function that joins given bytes into single byte sequence.
If
x
is a single byte and0x00 <= x <= 0x7F
,rlp_encode(x) = x
.Otherwise, if
x
is a byte string, Letlen(x)
be length ofx
in bytes and define encoding as follows:
If
0 < len(x) < 0x38
(note that empty byte string fulfills this requirement, as well asb'0x80'
):rlp_encode(x) = concat(0x80 + len(x), x)In this case first byte is in range
[0x80; 0xB7]
.If
0x38 <= len(x) <= 0xFFFFFFFF
:rlp_encode(x) = concat(0xB7 + len(len(x)), len(x), x)In this case first byte is in range
[0xB8; 0xBF]
.For longer strings encoding is
undefined
.Otherwise, if
x
is a list, lets = concat(map(rlp_encode, x))
be concatenation of RLP encodings of all its items.
If
0 < len(s) < 0x38
(note that empty list matches):rlp_encode(x) = concat(0xC0 + len(s), s)In this case first byte is in range
[0xC0; 0xF7]
.If
0x38 <= len(s) <= 0xFFFFFFFF
:rlp_encode(x) = concat(0xF7 + len(len(s)), len(s), x)In this case first byte is in range
[0xF8; 0xFF]
.For longer lists encoding is
undefined
.
See more in Ethereum wiki.
Encoding examples
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serialization
However, in the real world, the inputs are not pure bytes nor lists.
Some are of complex key-value pairs like dict
.
Some are of "0x123"
form of number.
This module exists for some pre-defined conversion, serialization:
API documentation
RLP Encoding/Decoding layer for “real-world” objects.
Classes:
Wrapper around |
|
Convert bytes type of Python object to RLP "item". |
|
Serializer for number-like objects. |
|
Serializer for |
|
Serializer for |
|
Serializer for |
|
Serializer for |
|
A container for working with dict-like objects. |
|
Container for parsing a heterogeneous list. |
|
Container for parsing a homogeneous list. |
|
Abstract class for all serializers. |
|
Abstract class for all scalar serializers (they accept "basic" values). |
|
Abstract serializer for complex types. |
Deprecated:
Deprecated alias for |
|
Pack a Python object according to wrapper. |
|
Unpack a serialized thing back into a dict/list or a Python basic type. |
- class thor_devkit.rlp.ComplexCodec(wrapper: thor_devkit.rlp.AbstractSerializer[Any])[source]
Bases:
object
Wrapper around
BaseWrapper
that implements RLP encoding.Abstract layer to join serialization and encoding (and reverse operations) together.
Attributes:
BaseWrapper
orScalarKind
to use for serialization.Methods:
Serialize and RLP-encode given high-level data to bytes.
RLP-decode and deserialize given bytes into higher-level structure.
- wrapper: thor_devkit.rlp.AbstractSerializer[Any]
BaseWrapper
orScalarKind
to use for serialization.
- class thor_devkit.rlp.BytesKind[source]
Bases:
thor_devkit.rlp.ScalarKind
[bytes
]Convert bytes type of Python object to RLP “item”.
Methods:
Serialize the object into a RLP encodable "item".
Deserialize a RLP "item" back to bytes.
- class thor_devkit.rlp.NumericKind(max_bytes: Optional[int] = None)[source]
Bases:
rlp.sedes.big_endian_int.BigEndianInt
,thor_devkit.rlp.ScalarKind
[int
]Serializer for number-like objects.
Good examples are:
'0x0', '0x123', '0', '100', 0, 0x123, True
Bad examples are:
'0x123z', {}, '0x', -1, '0x12345678123456780'
Changed in version 2.0.0: Allowed
bool
valuesTrue
andFalse
.Initialize a NumericKind.
- Parameters
max_bytes (Optional[int], optional) – Max bytes in the encoded result (prepend 0 if there’s not enough)
Attributes:
Maximal allowed size of number, in bytes.
Methods:
Serialize the object into a RLP encodable "item".
Deserialize bytes to int.
- serialize(obj: Union[str, int]) bytes [source]
Serialize the object into a RLP encodable “item”.
- Parameters
obj (str or int) – obj is either int or string representation of int parseable by
int()
.- Returns
Serialized data
- Return type
- Raises
SerializationError – If input data is malformed
TypeError – If input is neither int nor string representation of int
- class thor_devkit.rlp.BlobKind[source]
Bases:
thor_devkit.rlp.ScalarKind
[str
]Serializer for
0x....
hex strings.Used for strings that shouldn’t be interpreted as a number, usually an identifier.
Examples: address, block_ref, data to smart contract.
Methods:
Serialize a
0x...
string to bytes.Deserialize bytes to
0x...
string.
- class thor_devkit.rlp.FixedBlobKind(byte_length: int)[source]
Bases:
thor_devkit.rlp.BlobKind
Serializer for
0x....
fixed-length hex strings.Used for strings that shouldn’t be interpreted as a number, usually an identifier. Examples: address, block_ref, data to smart contract.
Note
This kind has a fixed length of bytes. (also means the input hex is fixed length)
Attributes:
Length of blob, in bytes.
Methods:
Serialize a
0x...
string to bytes.Deserialize bytes to
0x...
string.
- class thor_devkit.rlp.OptionalFixedBlobKind(byte_length: int)[source]
Bases:
thor_devkit.rlp.FixedBlobKind
Serializer for
0x....
fixed-length hex strings that may beNone
.Used for strings that shouldn’t be interpreted as a number, usually an identifier. Examples: address, block_ref, data to smart contract.
Note
This kind has a fixed length of bytes. (also means the input hex is fixed length)
For this kind, input can be None. Then decoded is also None.
Methods:
Serialize a
0x...
string orNone
to bytes.Deserialize bytes to
0x...
string orNone
.
- class thor_devkit.rlp.CompactFixedBlobKind(byte_length: int)[source]
Bases:
thor_devkit.rlp.FixedBlobKind
Serializer for
0x....
fixed-length hex strings that may start with zeros.Used for strings that shouldn’t be interpreted as a number, usually an identifier. Examples: address, block_ref, data to smart contract.
Note
When encode, the result fixed length bytes will be removed of leading zeros. i.e.
000123 -> 123
When decode, it expects the input bytes length <= fixed_length. and it pads the leading zeros back. Output
'0x{"0" * n}xxx...'
Methods:
Serialize a
0x...
string to bytes, stripping leading zeroes.Deserialize bytes to
0x...
string.
- class thor_devkit.rlp.DictWrapper(codecs: Union[Sequence[Tuple[str, thor_devkit.rlp.AbstractSerializer[Any]]], Mapping[str, thor_devkit.rlp.AbstractSerializer[Any]]])[source]
Bases:
thor_devkit.rlp.BaseWrapper
[Mapping
[str
,Any
]]A container for working with dict-like objects.
Create wrapper from items.
- Parameters
codecs (Mapping[str, BaseWrapper or ScalarKind] or its
.values()
-like list) –Codecs to use. Possible values (codec is any BaseWrapper or ScalarKind):
Any mapping from str to codec, e.g.
{'foo': NumericKind()}
Any sequence of tuples
(name, codec)
, e.g.[('foo', NumericKind())]
Attributes:
Field names.
Codecs to use for each field.
Methods:
Serialize dictionary to sequence of serialized values.
Deserialize sequence of encoded values to dictionary with serialized values.
- codecs: Sequence[thor_devkit.rlp.AbstractSerializer[Any]]
Codecs to use for each field.
- serialize(obj: Mapping[str, Any]) Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Any]]]]]]] [source]
Serialize dictionary to sequence of serialized values.
New in version 2.0.0.
- Parameters
obj (Mapping[str, Any]) – Dictionary to serialize.
- Returns
Sequence of serialized values.
- Return type
Sequence[bytes or Sequence[…]] (recursive)
- Raises
SerializationError – If input is malformed.
- deserialize(serial: Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Any]]]]]]]) Dict[str, Any] [source]
Deserialize sequence of encoded values to dictionary with serialized values.
New in version 2.0.0.
- Parameters
obj (Sequence[bytes or Sequence[...]] (recursive)) – Sequence of values to deserialize.
- Returns
Deserialized values, mapping field names to decoded values.
- Return type
Mapping[str, Any]
- Raises
DeserializationError – If input is malformed.
- class thor_devkit.rlp.ListWrapper(codecs: Sequence[thor_devkit.rlp.AbstractSerializer[Any]])[source]
Bases:
thor_devkit.rlp.BaseWrapper
[Sequence
[Any
]]Container for parsing a heterogeneous list.
The items in the list can be of different types.
Create wrapper from items.
- Parameters
codecs (Sequence[AbstractSerializer]) – A list of codecs. eg. [codec, codec, codec…] codec is either a BaseWrapper, or a ScalarKind.
Attributes:
Codecs to use for each element of sequence.
Methods:
Serialize sequence (list) of values to sequence of serialized values.
Deserialize sequence of encoded values to sequence.
- codecs: Sequence[thor_devkit.rlp.AbstractSerializer[Any]]
Codecs to use for each element of sequence.
- serialize(obj: Sequence[Any]) Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Any]]]]]]] [source]
Serialize sequence (list) of values to sequence of serialized values.
New in version 2.0.0.
- Parameters
obj (Sequence[Any]) – Sequence of values to serialize.
- Returns
Sequence of serialized values.
- Return type
Sequence[bytes or Sequence[…]] (recursive)
- Raises
SerializationError – If input is malformed.
- deserialize(serial: Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Any]]]]]]]) Sequence[Any] [source]
Deserialize sequence of encoded values to sequence.
New in version 2.0.0.
- Parameters
obj (Sequence[bytes or Sequence[...]] (recursive)) – Sequence of values to deserialize.
- Returns
Deserialized values.
- Return type
Sequence[Any]
- Raises
DeserializationError – If input is malformed.
- class thor_devkit.rlp.HomoListWrapper(codec: thor_devkit.rlp.AbstractSerializer[Any])[source]
Bases:
thor_devkit.rlp.BaseWrapper
[Sequence
[Any
]]Container for parsing a homogeneous list.
Used when the items in the list are of the same type.
Create wrapper from items.
- Parameters
codec (AbstractSerializer) – codec is either a BaseWrapper, or a ScalarKind.
Attributes:
Codec to use for each element of array.
Methods:
Serialize sequence (list) of values to sequence of serialized values.
Deserialize sequence of encoded values to sequence.
- codec: thor_devkit.rlp.AbstractSerializer[Any]
Codec to use for each element of array.
- serialize(obj: Sequence[Any]) Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Any]]]]]]] [source]
Serialize sequence (list) of values to sequence of serialized values.
New in version 2.0.0.
- Parameters
obj (Sequence[Any]) – Sequence of values to serialize.
- Returns
Sequence of serialized values.
- Return type
Sequence[bytes or Sequence[…]] (recursive)
- Raises
SerializationError – If input is malformed.
- deserialize(serial: Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Any]]]]]]]) Sequence[Any] [source]
Deserialize sequence of encoded values to sequence.
New in version 2.0.0.
- Parameters
obj (Sequence[bytes or Sequence[...]] (recursive)) – Sequence of values to deserialize.
- Returns
Deserialized values.
- Return type
Sequence[Any]
- Raises
DeserializationError – If input is malformed.
- class thor_devkit.rlp.AbstractSerializer[source]
Bases:
Generic
[thor_devkit.rlp._T
],abc.ABC
Abstract class for all serializers.
New in version 2.0.0.
Methods:
Serialize the object into a RLP encodable "item".
Deserialize given bytes into higher-level object.
- class thor_devkit.rlp.ScalarKind[source]
Bases:
thor_devkit.rlp.AbstractSerializer
[thor_devkit.rlp._T
]Abstract class for all scalar serializers (they accept “basic” values).
Methods:
Serialize the object into a RLP encodable "item".
Deserialize given bytes into higher-level object.
- class thor_devkit.rlp.BaseWrapper[source]
Bases:
thor_devkit.rlp.AbstractSerializer
[thor_devkit.rlp._T
]Abstract serializer for complex types.
Methods:
Serialize the object into a RLP encodable "item".
Deserialize given bytes into higher-level object.
- class thor_devkit.rlp.NoneableFixedBlobKind(*args: Any, **kwargs: Any)[source]
Bases:
thor_devkit.rlp.OptionalFixedBlobKind
Deprecated alias for
OptionalFixedBlobKind
.Deprecated since version 2.0.0: Use
OptionalFixedBlobKind
instead.
- thor_devkit.rlp.pack(obj: Any, wrapper: thor_devkit.rlp.AbstractSerializer[Any]) Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Any]]]]]]]] [source]
Pack a Python object according to wrapper.
Deprecated since version 2.0.0: Use
<wrapper>.serialize
directly instead.- Parameters
obj (Any) – A dict, a list, or a string/int/any…
wrapper (AbstractSerializer[Any]) – A Wrapper.
- Returns
bytes – If obj is a basic type.
List of packed items – If obj is dict/list.
- Raises
SerializationError – If data cannot be serialized using specified codec.
TypeError – If wrapper type is unknown.
- thor_devkit.rlp.unpack(packed: Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Union[bytes, Sequence[Any]]]]]]]], wrapper: thor_devkit.rlp.AbstractSerializer[Any]) Union[Dict[str, Any], List[Any], Any] [source]
Unpack a serialized thing back into a dict/list or a Python basic type.
Deprecated since version 2.0.0: Use
<wrapper>.deserialize
directly instead.- Parameters
packed (bytes or sequence of them) – A list of RLP encoded or pure bytes (may be nested).
wrapper (AbstractSerializer[Any]) – The Wrapper.
- Returns
dict/list if the wrapper instruction is dict/list, Python basic type if input is bytes.
- Return type
Dict[str, Any] or List[Any] or Any
- Raises
DeserializationError – If data cannot be deserialized using specified codec.
TypeError – If wrapper type is unknown.