4

In this answer the compact decoding for 1 byte and multi-byte versions have been detailed. I did a sample implementation based on that information and it does what it is supposed to, at least for the specific usecase. (My toy obviously has holes, but it is more for my understanding as opposed to be production hardened)

However, the original answer didn't quite detail the decoding of the 0b01 and 0b10 flags as the last 2 bits of a compact first byte, based on that I have a gap in my knowledge which I really want to close out.

I would appreciate a full run-through answer, basically a "this is how to decode all compact numbers (for dummies)".

1 Answer 1

6

Here is a description of SCALE compact-encoding. As you mentioned in your question, there are basically 4 variants indicated by the flags from the 2 least-significant bits.

Effectively when decoding the first byte of SCALE compact, it would be in the form 0bxxxxxxyy where yy are the flags and the most-significant 6 xxxxxx are the bits containing the value in the first byte.

Interpreting the lest-significant binary flags you can have lengths of 1, 2, 4 & 4+ bytes -

00 This is a single-byte version. To extract the value, you would do byte1 >> 2. As an example 0b00000100 would be 4 >> 2 = 1

01 This is a double-byte version. To extract the value, you would do (byte1 + (byte2 << 8)) >> 2. As an example 0b11111101 0b00000111 would be (253 + (7 << 8)) >> 2 = 511

10 This is the 4 byte version. For extracting the value, it ends up being (byte1 + (byte2 << 8) + (byte3 << 16) + (byte4 << 24)) >> 2. An example would be 0b11111110 0b11111111 0b11111111 0b11111111 which would be (254 + (255 << 8) + (255 << 16) + (255 << 24)) >> 2 = 1073741823

11 This is the n-byte version. The first byte + 4 details the number of bytes following. So Assuming a first byte of 0b00000111 it would yield 5 bytes, i.e. (7 >> 2) + 4 = 5. The next 5 bytes would therefore be the LE encoded value.

Depending on your toolset and language, be aware that some of these are very large numbers and could overflow the "normal" representation. So it is recommended to use big integer support for your environment especially when converting the very large values.

(And example of this is JS where the maximum integer is 2^53 - 1. So in this specific case you may want to use BigInt or alternatives when converting. Other languages would have other limits, bear those in mind.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.