Glittr Output Structure
In this page, we will learn about the Glittr output structure. The Glittr output consists of 5 parts:
OP_RETURN opcode: the native Bitcoin opcode for the return data.
Glittr Magic prefix: used to mark the Glittr transaction; Glittr uses string bytes of "GLITTR", *this will change latter, will use more compact prefix.
Header
The Glittr message payload: where the actual data goes
The data should be less than or equal to 80 bytes
Header
The header is a 1-byte data that consists of 2 parts:
Version number: 6-bit number, 0 - 63
Flags:
Compressed flag
Reserved flag
Version Number
Version number is for transaction versioning. It's a 6-bit number
(0 - 63) used to handle different schema changes in the future so older versions can still be supported on the core. Currently, only version 0 is used.
Compressed Flag
The compressed flag indicates whether the message is compressed or not.
Glittr Message Payload
Payload is the actual data that's going to be sent to the transaction (transfer, contract creation, or contract call).
Encoding
The payload uses Borsh encoding to encode the data. The encoding is based on Borsh . We chose Borsh for simplicity and smaller size. The encoding is already implemented in the SDK, so users don't need to manually encode the data.
Data Type
To improve size efficiency, we use custom data types for the payload values like varuint/varint and azbase26, more details can be found on the glittr core repository.
Varuint/Varint
Varuint is a data type based on SQLite 4 Varuint type , supporting up to u128. For varint (signed or negative values), we use the zigzag method to convert it to unsigned integer.
AZBase26
Instead of using UTF8 for strings, we use a data type called AZBase26. As the name suggests, this data type is based on base26 encoding for characters A-Z, making it suitable for tickers or token names.
Compression
We use brotli for the payload compression, the compression is optional, it means the payload can be compressed or not compressed. If the compressed length is less than the non-compressed length, it will use compressed bytes and mark the header compressed flag as true. Sometimes if the data is too dense, the compressed version is larger than the non-compressed version, so the flag will be set to false.
Example
Compressed Payload
Payload has a lot of data, so the compression will play with it, most of the time the compressed version is smaller than the non-compressed version, the header will mark the compressed flag as true.
That example show that brotli compression is effective to reduce the size of data, the compressed version is smaller than the non-compressed version (28 bytes saved).
Non Compressed payload
Payload is to dense, so the compressed version is larger than the non-compressed version, the header will mark the compressed flag as false.
On the example above the non compressed length is smaller than compressed length, this is possible because the data is already to dense, the brotli compression added some overhead to it that's why the compressed length is larger than the non compressed length.
Exceeded 80 bytes
Output has a limit of 80 bytes, so if the payload is larger than 80 bytes, the transaction will be rejected.
That example show that if the payload is larger than 80 bytes, the transaction will be rejected, the total transaction bytes is 94 bytes which exceeded the bitcoin output size, the solution is to reduce the value like use shorter args.string
or args.fixed_string
value.
Last updated