Data Types
Bitcoin stores and transmits data as bytes. Their meaning depends on the field and the rules used to interpret it.
Contents
Data, meaning, and representation
A data type describes what a value means and which values are allowed. An encoding defines how that value is stored as bytes. A representation is how we display those bytes or their interpreted value.
- Hexadecimal
41- Binary
01000001- Unsigned integer
65- ASCII / UTF-8 text
A
Every view describes the same byte. The byte itself does not tell us which meaning was intended.
Hexadecimal is a way to write byte values. A string of hex characters does not, by itself, identify a transaction, a hash, or an amount.
Byte sequences
A byte contains eight bits and has 256 possible patterns. A byte sequence is an ordered collection of these bytes. Its length and order are part of the data.
| Hex bytes | Byte length | Big-endian integer |
|---|---|---|
00 01 | 2 bytes | 1 |
01 | 1 byte | 1 |
The numeric values match, but the bytes differ. Leading zero bytes still matter to a field that expects a particular size.
Bitcoin uses byte sequences for hashes, public keys, signatures, and scripts. A transaction identifier is a 32-byte hash; a script is a variable-length sequence of instructions and data. Understanding those structures requires their own rules, beyond displaying the bytes.
Integers
An integer is a whole number. An unsigned integer represents zero and positive values. A signed integer can also represent negative values. The number of bits determines the range: an unsigned eight-bit integer ranges from 0 to 255; a signed eight-bit integer using two's complement ranges from −128 to 127.
For example, ff means 255 as an unsigned eight-bit integer and −1 as a signed eight-bit two's-complement integer. The bytes have not changed; the interpretation has.
For an integer spanning several bytes, byte order also matters. Big-endian places the most significant byte first; little-endian places it last. The sequence 01 00 means 256 in big-endian order and 1 in little-endian order. Many Bitcoin numeric fields use little-endian serialization.
Bitcoin transaction output amounts are stored as integers counting satoshis, where 100,000,000 satoshis equals 1 BTC. The serialized amount field is a signed 64-bit integer, but valid output amounts must be nonnegative and satisfy Bitcoin's monetary rules. A type's storage range and a field's valid values are separate questions.
Counts, lengths, and CompactSize
Some fields store a count, such as the number of transaction inputs. Others store a length, such as the number of bytes in a script. Bitcoin commonly serializes these values using CompactSize, an unsigned integer encoding that occupies one, three, five, or nine bytes depending on the value.
A count tells a reader how many items to read; a byte length tells it how many bytes to read. The encoded number and the number of bytes used to encode it are also different. For example, the integer 3 uses one CompactSize byte: 03. This byte may describe three items in a list; it is not the list itself.
Text, booleans, and flags
Text needs a character encoding to turn characters into bytes. ASCII gives meanings to 128 byte values; UTF-8 uses one or more bytes for each Unicode character. ASCII letters have the same byte values in UTF-8, but an arbitrary byte sequence may not be valid UTF-8.
Decoding a sequence successfully does not prove that it was intended as text. Likewise, an ASCII preview can reveal readable characters embedded in binary data without making the entire sequence a message.
A boolean represents true or false. Its serialization depends on the field: the Bitcoin peer-to-peer sendcmpct message uses 01 for true and 00 for false in its announcement field. A bit field uses individual bits as flags, allowing several properties to be recorded together; a peer's service flags are one example.
Recognizing a field's type
When reading Bitcoin data, start with the format of the field rather than guessing from its appearance. These examples show how different kinds of values are serialized.
Scroll horizontally to see all columns.
| Field | Kind of value | Serialized size |
|---|---|---|
| Block header nonce | Unsigned 32-bit integer | 4 bytes |
| Transaction output amount | Signed 64-bit integer counting satoshis | 8 bytes |
| Transaction input count | Unsigned integer encoded as CompactSize | 1, 3, 5, or 9 bytes |
| Previous transaction identifier | Hash byte sequence | 32 bytes |
| Output script | Instruction and data byte sequence | Variable; preceded by a byte length |
A length prefix is separate from the bytes of the field it describes.
Explore with the Data Interpreter
Open the Data Interpreter to try these examples.
The Data Interpreter lets you compare representations of the same bytes. Its numeric results are unsigned; it does not infer a field's Bitcoin meaning or decode complete transactions. Its CompactSize result encodes the interpreted integer, not the input's byte length.
- Choose Hex, enter
41, and interpret. Compare the integer65, binary01000001, and textA. - Enter
00 01in Hex format. The byte length is two, even though the big-endian integer is1. - Choose Auto and enter
16. It is read as hexadecimal, giving the unsigned decimal value22. Choose Text for the same input to obtain the UTF-8 bytes31 36instead.
Related Library topics
Continue with byte representations, byte order, and integer encoding.