Functions: Parser¶
List of functions used to extract data from Bitcoin block headers and transactions. See the Bitcoin Developer Reference for details on the block header and transaction format.
Note
When comparing byte values, use the hash (e.g. SHA256) to avoid errors.
Block Header¶
extractHashPrevBlock¶
Extracts the hashPrevBlock
(reference to previous block) from a Bitcoin block header.
Function Signature
extractHashPrevBlock(blockHeaderBytes)
Parameters
blockHeaderBytes
: 80 byte raw Bitcoin block header.
Returns
hashPrevBlock
: the 32 byte block hash reference to the previous block.
Function Sequence¶
- Return 32 bytes starting at index 4 of
blockHeaderBytes
extractMerkleRoot¶
Extracts the merkleRoot
from a Bitcoin block header.
Function Signature
extractMerkleRoot(blockHeaderBytes)
Parameters
blockHeaderBytes
: 80 byte raw Bitcoin block header
Returns
merkleRoot
: the 32 byte Merkle tree root of the block header
Function Sequence¶
- Return 32 bytes starting at index 36 of
blockHeaderBytes
.
extractTimestamp¶
Extracts the timestamp from the block header.
Function Signature
extractTimestamp(blockHeaderBytes)
Parameters
blockHeaderBytes
: 80 byte raw Bitcoin block header
Returns
timestamp
: timestamp representation of the 4 byte timestamp field of the block header
Function Sequence¶
- Return 32 bytes starting at index 68 of
blockHeaderBytes
.
extractNBits¶
Extracts the nBits
from a Bitcoin block header. This field is necessary to compute that target
in nBitsToTarget
.
Function Signature
extractNBits(blockHeaderBytes)
Parameters
blockHeaderBytes
: 80 byte raw Bitcoin block header
Returns
nBits
: the 4 byte nBits field of the block header
Function Sequence¶
- Return 4 bytes starting at index 72 of
blockHeaderBytes
.
parseBlockHeader¶
Parses a 80 bytes raw Bitcoin block header and, if successful, returns a RichBlockHeader
struct.
Function Signature
parseBlockHeader(blockHeaderBytes)
Parameters
blockHeaderBytes
: 80 byte raw Bitcoin block header
Returns
BlockHeader
: the parsed Bitcoin block header
Errors
ERR_INVALID_HEADER_SIZE = "Invalid block header size"
: return error if the submitted block header is not exactly 80 bytes long.
Function Sequence¶
- Check that the
blockHeaderBytes
is 80 bytes long. ReturnERR_INVALID_HEADER_SIZE
exception and abort otherwise. - Create a new
BlockHeader
(BlockHeader
) struct and initialize as follows:
BlockHeader.merkleRoot =
extractMerkleRoot (blockHeaderBytes
)BlockHeader.target =
nBitsToTarget (extractNBits (blockHeaderBytes
))BlockHeader.timestamp =
extractTimestamp (blockHeaderBytes
)BlockHeader.hashPrevBlock = :ref:`extractHashPrevBlock` (``blockHeaderBytes
)
- Return
BlockHeader
Transactions¶
extractOutputs¶
Extracts the outputs from the given (raw) transaction (rawTransaction
).
Specification¶
Function Signature
extractOutputs(rawTransaction) -> u64
Parameters
rawTransaction
: A variable byte size encoded transaction.
Returns
outputs
: A list of variable byte size encoded outputs of the given transaction.
Function Sequence¶
- Determine the start of the output list in the transaction using getOutputStartIndex.
- Determine the number of outputs (determine VarInt size using determineVarIntDataLength and extract bytes indicating the number of outputs accordingly).
- Loop over the output size, determining the output length for each output (determine VarInt size using determineVarIntDataLength and extract bytes indicating the output size accordingly). Extract the bytes for each output and append them to the
outputs
list. - Return
outputs
.
Note
Optionally, check the output type here and add flag to return list (use tuple of flag and output bytes then).
getOutputStartIndex¶
Extracts the starting index of the outputs in a transaction (i.e., skips over the variable size list of inputs).
Function Signature
getOutputStartIndex(rawTransaction -> u64)
Parameters
rawTransaction
: A variable byte size encoded transaction.
Returns
outputIndex
: integer index indicating the starting point of the list of outputs in the raw transaction.
Errors
ERR_INVALID_TX_VERSION = "Invalid transaction version"
: The version of the given transaction is not 1 or 2.
Note
Currently, the transaction version can be 1 or 2. See transaction format details in the Bitcoin Developer Reference.
Function Sequence¶
See the Bitcoin transaction format in the Bitcoin Developer Reference.
- Init position counter
pos = 0
. - Check the
version
bytes of the transaction (must be 1 or 2). Then skip over:pos = pos + 4
. - Check if the transaction is a SegWit transaction. If yes,
pos = pos + 2
. - Parse the VarInt size (:ref:
determineVarIntDataLength
) and extract the bytes indicating the number of inputs accordingly. Incrementpos
accordingly. - Iterate over the number of inputs and skip over (incrementing
pos
). Note: it is necessary to determine the length of thescriptSig
using determineVarIntDataLength. - Return
pos
indicating the start of the output list in the raw transaction.
determineVarIntDataLength¶
Determines the length of the Bitcoin CompactSize Unsigned Integers (other term for VarInt) in bytes. See CompactSize Unsigned Integers for details.
Function Signature
getOutputStartIndex(varIntFlag -> u64)
Parameters
varIntFlag
: 1 byte flag indicating size of Bitcoin’s VarInt
Returns
varInt
: integer length of the VarInt (excluding flag).
Function Sequence¶
- Check flag and return accordingly:
- If
0xff
return8
,- Else if
0xfe
return 4,- Else if
0xfd
return 2,- Otherwise return
0
extractOPRETURN¶
Extracts the OP_RETURN of a given transaction. The OP_RETURN field can be used to store 80 bytes in a given Bitcoin transaction. The transaction output that includes the OP_RETURN is provably unspendable.
Note
The OP_RETURN field is used to include replay protection data in the ONEBTC Issue, Redeem, and Replace protocols.
Function Signature
extractOPRETURN()
Parameters
rawOutput
: raw encoded output
Returns
opreturn
: value of the OP_RETURN data.
Errors
ERR_NOT_OP_RETURN = "Expecting OP_RETURN output, but got another type.
: The given output was not an OP_RETURN output.
Function Sequence¶
- Check that the output is indeed an OP_RETURN output:
pk_script[0] == 0x6a
. ReturnERR_NOT_OP_RETURN
error if this check fails. Note: thepk_script
starts at index9
of the output (nevertheless, make sure to check the length of VarInt indicating the output size using determineVarIntDataLength). - Determine the length of the OP_RETURN field (
pk_script[10]
) and return the OP_RETURN value (excluding the flag and size, i.e., starting at index11
).
extractOutputValue¶
Extracts the value of the given output.
Note
Needs conversion to Big Endian when converting to integer.
Function Signature
extractOutputValue(rawOutput)
Parameters
rawOutput
: raw encoded output
Returns
value
: value of the output.
Function Sequence¶
- Return the first 8 bytes of
output
, converted from LE to BE.
extractOutputAddress¶
Extracts the value of the given output.
Note
Please refer to the Bitcoin Developer Reference on Transactions when implementing this function.
Function Signature
extractOutputAddress(rawOutput)
Parameters
rawOutput
: raw encoded output
Returns
value
: value of the output.
Errors
ERR_INVALID_OUTPUT_SCRIPT = "Invalid or malformed output script"
: The script of the given output is invalid or malformed.
Function Sequence¶
- Check if output is a SegWit output:
output[9] == 0
.- If SegWit output (P2WPKH or P2WSH), check that
output[10]
equals the length of the output script (extract from``output[8]``). If this check fails, returnERR_INVALID_OUTPUT_SCRIPT
. - Return the number of characters specified in
output[8]
(length of the output script), starting withoutput[11]
. This will be 20 bytes for P2WPKH and 32 bytes for P2WSH.
- If SegWit output (P2WPKH or P2WSH), check that
- Otherwise, extract the
tag
indicating the output type: 3 bytes starting at index8
inoutput
.- If P2PKH output (
tag == [0x19, 0x76, 0xa9]
). Check thatoutput[11] == [0x14]
or the last two bytes are equal to[0x88, 0xac]. If this check fails, return ``ERR_INVALID_OUTPUT_SCRIPT
. Otherwise, return 20 bytes starting withoutput[12]
. - If P2WSH output (
tag == [0x17, 0xa9, 0x14]
). Check that the last byte is equal to[0x87]
. If this check fails, returnERR_INVALID_OUTPUT_SCRIPT
. Otherwise, return 32 bytes starting withoutput[12]
.
- If P2PKH output (