Monero serialization python library, supports blockchain, Boost and RPC formats.
MIT License
The library provides basic serialization logic for the Monero types, used in transaction processing and transaction signing.
BEGIN_SERIALIZE_OBJECT()
.BEGIN_KV_SERIALIZE_MAP
is mainly supported. JSON and binary wire format.The binary wire formats use streaming dumping / parsing for better memory efficiency.
For usage please take a look at tests.
pip install monero-serialize
import binascii
from monero_serialize import xmrserialize as x
from monero_serialize import xmrtypes as xmr
msg = xmr.TxinToKey(amount=123, key_offsets=[1, 2, 3, 2**76], k_image=bytearray(range(32)))
# Serialize
writer = x.MemoryReaderWriter()
await x.dump_message(writer, msg)
print(binascii.hexlify(writer.buffer))
# Deserialize
test_deser = await x.load_message(x.MemoryReaderWriter(writer.buffer), xmr.TxinGen)
Thanks for your support!
86KCjujm1Hp4dD2uyZdXjHQr5e5aNujG6LcunA8iQYjx4AwRorVLDpHMKKmrKQfAPFC5KCKPpjdax3NEbExBRTnSTS1QXWA
import binascii
from monero_serialize import xmrserialize as x
from monero_serialize import xmrtypes as xmr
msg = xmr.TxinGen(height=42)
# Serialize
writer = x.MemoryReaderWriter()
ar1 = x.Archive(writer, True)
await ar1.message(msg)
# Deserialize
msg2 = xmr.TxinGen()
ar2 = x.Archive(x.MemoryReaderWriter(writer.buffer), False)
await ar2.message(msg2)
import binascii
from monero_serialize import xmrserialize as x
from monero_serialize import xmrtypes as xmr
from monero_serialize import xmrboost as xmrb
data_hex = b'011673657269616c697a6174696f6e3a3a61726368697665000000000134'
data_bin = base64.b16decode(data_hex, True)
reader = x.MemoryReaderWriter(bytearray(data_bin))
ar = xmrb.Archive(reader, False)
msg = xmr.TxinGen()
await ar.root_message(msg)
self.assertEqual(msg.height, 0x34)
class Hash(x.BlobType): pass;
class ECKey(x.BlobType): pass;
class ECPoint(x.BlobType): pass;
class SecretKey(ECKey): pass;
class ECPublicKey(ECPoint): pass;
class KeyImage(ECPoint): pass;
class KeyDerivation(ECPoint): pass;
class TxoutToScript(x.MessageType): pass;
class TxoutToKey(x.MessageType): pass;
class TxoutToScriptHash(x.MessageType): pass;
class TxoutTargetV(x.VariantType): pass;
class TxinGen(x.MessageType): pass;
class TxinToKey(x.MessageType): pass;
class TxinToScript(x.MessageType): pass;
class TxinToScriptHash(x.MessageType): pass;
class TxInV(x.VariantType): pass;
class TxOut(x.MessageType): pass;
class TransactionPrefix(x.MessageType): pass;
class TransactionPrefixExtraBlob(TransactionPrefix): pass;
class TxIndex(x.MessageType): pass;
class TransactionMetaData(x.MessageType): pass;
#
# rctTypes.h
#
class Key64(x.ContainerType): pass;
class KeyV(x.ContainerType): pass;
class KeyM(x.ContainerType): pass;
class KeyVFix(x.ContainerType): pass;
class KeyMFix(x.ContainerType): pass;
class CtKey(x.MessageType): pass;
class CtkeyV(x.ContainerType): pass;
class CtkeyM(x.ContainerType): pass;
class MultisigKLRki(x.MessageType): pass;
class MultisigOut(x.MessageType): pass;
class EcdhTuple(x.MessageType): pass;
class BoroSig(x.MessageType): pass;
class MgSig(x.MessageType): pass;
class RangeSig(x.MessageType): pass;
class Bulletproof(x.MessageType): pass;
class EcdhInfo(x.ContainerType): pass;
class RctSigBase(x.MessageType): pass;
class RctSigPrunable(x.MessageType): pass;
class RctSig(RctSigBase): pass;
class Signature(x.MessageType): pass;
class SignatureArray(x.ContainerType): pass;
class Transaction(TransactionPrefix): pass;
class BlockHeader(x.MessageType): pass;
class HashVector(x.ContainerType): pass;
class Block(BlockHeader): pass;
class AccountPublicAddress(x.MessageType): pass;
class SubaddressIndex(x.MessageType): pass;
class MultisigLR(x.MessageType): pass;
class MultisigInfo(x.MessageType): pass;
class MultisigStruct(x.MessageType): pass;
class TxExtraPadding(x.MessageType): pass;
class TxExtraPubKey(x.MessageType): pass;
class TxExtraNonce(x.MessageType): pass;
class TxExtraMergeMiningTag(x.MessageType): pass;
class TxExtraAdditionalPubKeys(x.MessageType): pass;
class TxExtraMysteriousMinergate(x.MessageType): pass;
class TxExtraField(x.VariantType): pass;
class TxExtraFields(x.ContainerType): pass;
class OutputEntry(x.TupleType): pass;
class TxSourceEntry(x.MessageType): pass;
class TxDestinationEntry(x.MessageType): pass;
class TransferDetails(x.MessageType): pass;
class TxConstructionData(x.MessageType): pass;
class PendingTransaction(x.MessageType): pass;
class PendingTransactionVector(x.ContainerType): pass;
class UnsignedTxSet(x.MessageType): pass;
class SignedTxSet(x.MessageType): pass;
class MultisigTxSet(x.MessageType): pass;
The BC serialization format is scheme-oriented, i.e., you have to provide the scheme according to which serialize/deserialize the data. Scheme specifies how are fields composed, whether the size of containers is fixed (and then also the size is specified by the scheme) or not.
The format is not versioned, i.e., serialization format does not store explicit version numbers which would affect serialization scheme.
Example:
0x0f -> 0f
0x1000 -> 8020
0xffff -> ffff03
0xffffff -> ffffff07
Example:
0x0f Width 4 = 0f000000
0x1000 Width 4 = 001000
0xffffff Width 4 = ffffff00
uvarint(lenght) || data
data
uvarint(length) || input.encode("utf8")
uvarint(length) || *elements
*elements
uvarint(length) || *elements
uint(variant_code) || variant_object
011673657269616c697a6174696f6e3a3a617263686976650000
which translates to \x01\x16serialization::archive\x00\x00
. The [-2]
byte enables tracking (tracking is not supported in this lib), [-1]
is a version of root element.(uvarint(tracking) || uvarint(version))
BOOST_CLASS_TRACKING
(uvarint(tracking) || uvarint(version) || uvarint(object_id))
uvarint(length) || input.encode("utf8")
uvarint(length) || data
uvarint(length)
uvarint(element_version)
(exception for case of raw containers = statically allocated like Key64)(tr, v), collection_size, element_version, (obj_tr, obj_v), obj1, obj2, ...
uvarint(variant_code) || field
(tr, v), which, (tr, v), val
Monero serialization format, with either binary or JSON form
Defines serialization types supported by the format, each supported serialization primitive has a tag.
Root of archive starts with the 0x01011101 || 0x01020101 || 0x1
, i.e, signature A, signature B, format version
Archive can be parsed as JSON, i.e., without scheme.
N<<2 | size_flag
as little endianuvarint(length) || data
element_type | SerializeType.ARRAY_FLAG
as integer, where element_type
is the object tag.uvarint(length) || serialize_string(section_1) || serialize_storage(value_1)
serialize_storage
serializes:
ARRAY_FLAG
flag