Skip to content

Content fixes and improvements for transactions module #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion decoding/endianness.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ Big-endian is considered more "human-readable" because the data is stored in the

## 2. Little-Endian

Little-endian stores the **least significant byte** first. This might feel counterintuitive to humans but is more efficient for modern processors.
Little-endian stores the **least significant byte** first. It might feel counterintuitive to humans but little-endian is widely used in modern processors,
particularly in the x86 architecture family, largely due to historical decisions.

Using the same number **12345678** (`0x00BC614E`), here's how it looks in **little-endian**:

Expand Down
8 changes: 4 additions & 4 deletions decoding/fee-calculation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ Without fees, miners would have no reason to include transactions in their block

### How Miners Select Transactions ?

Miners receive two types of rewards for securing the network:
Miners receive two types of payment for securing the network:

1. **Block Reward**
1. **Block Subsidy**
2. **Transaction Fees**

<div className="dark:hidden w-full rounded-lg">
Expand All @@ -96,7 +96,7 @@ A miner who mines a block will have revenue as:
$$Revenue = Tx\ Fees + Block\ Subsidy$$
</div>

To maximize their revenue, miners prioritize transactions that pay higher fees. The way they determine which transactions pay more will be covered in the next topic when we discuss fee rates.
To maximize their revenue, miners prioritize transactions that pay higher fees. The way they determine which transactions pay more will be covered in the [Fee Rate](/decoding/fee-rate) topic.

For now, understand that:

Expand Down Expand Up @@ -127,7 +127,7 @@ While miners can choose which transactions to include based on fees, there's act
This is called the **minimum relay fee**.

- It's the minimum fee required for nodes to relay and accept a transaction
- Default is typically 1 sat/vbyte (we'll explain this unit sat/vbyte in the next topic)
- Default is typically 1 sat/vbyte (we'll explain this unit sat/vbyte in the [Transaction Weight](/decoding/transaction-weight) topic)
- Transactions below this threshold will be rejected by nodes
- Helps prevent spam and DoS attacks on the network

Expand Down
8 changes: 6 additions & 2 deletions decoding/inputs-prev-txid.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ The txid uses Bitcoin's internal byte order (little-endian). Let's examine this
display_txid = "5e6e1a9b4ce3f9f39467d7129e3ecfbe6c81c08dd377aac666fedc9a758fe614"

# Internal order (how it appears in raw transaction)

internal_txid = "14e68f759adcfe66c6aa77d38dc0816cbecf3e9e12d76794f3f9e34c9b1a6e5e"`}
language="python"
/>
Expand Down Expand Up @@ -138,7 +137,12 @@ The TXID is created differently depending on the transaction type:
This difference in segwit transactions was intentionally designed to prevent transaction malleability, as signatures are no longer part of the TXID calculation.

<ExpandableAlert title="Historical Note" type="info">
There was a unique situation in Bitcoin's history where duplicate TXIDs occurred in blocks 91,722 and 91,880. As a result, BIP 30 was implemented to prevent blocks from containing duplicate TXIDs, and BIP 34 was introduced to require coinbase transactions to include block height in their data.
Duplicate TXID: `e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468`

There was a unique situation in Bitcoin's history where the same TXID (above) occurred in multiple blocks:
<a href="https://mempool.space/block/00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e" target="_blank" rel="noopener noreferrer">91,722</a> and
<a href="https://mempool.space/block/00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721" target="_blank" rel="noopener noreferrer">91,880</a>.
As a result, BIP 30 was implemented to prevent blocks from containing duplicate TXIDs, and BIP 34 was introduced to require coinbase transactions to include block height in their data.
</ExpandableAlert>

## Implementation Details
Expand Down
2 changes: 1 addition & 1 deletion decoding/inputs-scriptsig.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Let's break down the highlighted hex string from our transaction:
</td>
<td className="px-6 py-4">1 byte</td>
<td className="px-6 py-4">
Script length in hex (72 bytes in decimal)
Signature length in hex (72 bytes in decimal)
</td>
</tr>
<tr className="hover:bg-gray-100 dark:hover:bg-gray-800">
Expand Down
4 changes: 2 additions & 2 deletions decoding/inputs-scriptsigsize.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ Like the input count, the ScriptSig size uses varint encoding:
| 2³² to 2⁶⁴-1 | 0x100000000 to 0xffffffffffffffff | 9 | `0xff` followed by uint64_t |

<ExpandableAlert title="Note" type="info">
Most ScriptSig sizes are small enough to fit in a single byte, as they
typically contain just a signature and public key.
Most ScriptSig sizes are small enough to fit in a single byte, as the ScriptSig
typically contains just a signature and public key that combined are less than 253 bytes in size.
</ExpandableAlert>

## Implementation Example
Expand Down
8 changes: 4 additions & 4 deletions decoding/inputs-sequence.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ Here's how you might parse a transaction input's sequence number:
## 3- Historical Context

<ExpandableAlert title="Original Design" type="info">
Satoshi originally designed the sequence number for "high-frequency trades"
- a way to update transactions before they were mined. The idea was to
Satoshi originally designed the sequence number for "high-frequency trades" -
a way to update transactions before they were mined. The idea was to
create payment channels between parties, where each new payment would
increment the sequence number. However, this design was vulnerable to miner
manipulation and was later replaced by better payment channel designs like
Expand All @@ -155,8 +155,8 @@ BIP 68 introduced relative timelocks using sequence numbers below 0x80000000. Th
return sequence < 0xf0000000

def is_relative_timelock(sequence: int) -> bool:
"""Check if relative timelock is enabled"""
return sequence < 0x80000000`}
"""Check if relative timelock is enabled"""
return sequence < 0x80000000`}
language="python"
/>

Expand Down
4 changes: 2 additions & 2 deletions decoding/outputs-amount.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ Here's a helpful function for converting between BTC and satoshis:
return int(btc * 100_000_000)

def satoshis_to_btc(sats: int) -> float:
"""Convert satoshi amount to BTC"""
return sats / 100_000_000`}
"""Convert satoshi amount to BTC"""
return sats / 100_000_000`}
language="python"
/>

Expand Down
2 changes: 1 addition & 1 deletion decoding/transaction-creation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,4 @@ In this example:
### Final Step: Signing the Transaction

The transaction structure is now complete but not yet valid. Alice must sign it to prove she owns the inputs.
The signing process will be covered in detail in the next topic.
The signing process will be covered in detail in the [Signing Transactions](/decoding/transaction-signing) topic.
18 changes: 9 additions & 9 deletions decoding/transaction-signing-01.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,15 @@ Two essential encoding functions:
return value.to_bytes(length, 'little')

def varint(n: int) -> bytes:
"""Encode an integer as a variable length integer"""
if n < 0xfd:
return bytes([n])
elif n <= 0xffff:
return b'\\xfd' + n.to_bytes(2, 'little')
elif n <= 0xffffffff:
return b'\\xfe' + n.to_bytes(4, 'little')
else:
return b'\\xff' + n.to_bytes(8, 'little')`}
"""Encode an integer as a variable length integer"""
if n < 0xfd:
return bytes([n])
elif n <= 0xffff:
return b'\\xfd' + n.to_bytes(2, 'little')
elif n <= 0xffffffff:
return b'\\xfe' + n.to_bytes(4, 'little')
else:
return b'\\xff' + n.to_bytes(8, 'little')`}
language="python"
/>

Expand Down
2 changes: 1 addition & 1 deletion decoding/transaction-signing-03.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ For our test vector:
- `76`: OP_DUP
- `a9`: OP_HASH160
- `14`: Push 20 bytes
- `1d0f172a0ecb48aee1be1f2687d2963ae33f71a1`: Public key hash from witness program
- `1d0f172a0ecb48aee1be1f2687d2963ae33f71a1`: 20-byte public key hash from witness program
- `88`: OP_EQUALVERIFY
- `ac`: OP_CHECKSIG
</ExpandableAlert>
Expand Down