Skip to content

OP_NUM2BIN

Convert a big number to a byte string

Syntax and Stack

B MSIZE OP_NUM2BIN => D ?

  • B: The BigNum to be converted
  • MSIZE: The size in bytes to encode the magnitude (unsigned) portion of the BigNum. The actual byte string will be MSIZE + 1 bytes. Any type (e.g. BigNum, or ScriptNum-format buffers) that can be converted to a uint64_t is allowed. Out of range sizes will fail the script.
  • D: The conversion result

Operation

B is exported in little-endian sign-magnitude encoded number format into a byte buffer.

Magnitude

If the magnitude of B is too large to be expressed in MSIZE bytes, only the least significant MSIZE bytes are copied [NUM2BIN.O1] (this is different than ScriptNums, which fail the script in this condition). If the magnitude of B can be expressed in less than MSIZE bytes, the number is zero-extended to MSIZE bytes [NUM2BIN.O2].

Sign

D[MSIZE] (i.e. the MSIZE+1th byte) MUST express the sign and only the sign. If D[MSIZE]==0, the number is positive. If D[MSIZE]==0x80, the number is negative. [NUM2BIN.O3]

This formulation is more restrictive than little-endian sign-magnitude encoded numbers, which allow the MSB of D[MSIZE-1] to denote a negative number if that bit is not required to express the magnitude of the encoded number.

This formulation remains fully compatible with ScriptNum encoding but allows script authors to unambiguously access the sign of the encoded number

Limits

MSIZE MUST be <= 512 bytes [NUM2BIN.L1]. This results in a 513 byte maximum size for D. If MSIZE is greater than 512 the script fails. This limit will change if the maximum BigNum size is increased. Script authors MUST not rely on this limit to intentionally fail validation.

Design considerations

Isolating the sign bit

The serialized output of this opcode is more restrictive than little-endian sign-magnitude encoded numbers, which allow the MSB of D[MSIZE-1] to denote a negative number if that bit is not required to express the magnitude of the encoded number.

This additional restriction was added because this formulation remains fully compatible with ScriptNum encoding but allows script authors to unambiguously access the sign of the encoded number at D[MSIZE]&0x80, and access the most significant bit of the magnitude of the encode BigNum at D[MSIZE-1]&0x80.

If standard little-endian sign-magnitude were used, the script author would need to use the expected and actual length of the encoded number and the contents of the last 2 bytes to return the MSB and the sign in an awkward an error prone (in bitcoin script anyway) piece of logic.