第3回UTXO勉強会 Bitcoinの手数料
トランザクションのデータ量計算
手数料の計算方法
手数料の推定のツール・アルゴリズム
手数料が低くて取り込まれない場合にすぐに取り込まれるようにするために
Bitcoinの手数料とは?
Bitcoinの手数料は、トランザクションのデータサイズ(バイト数)に対して支払う報酬であり、マイナーへ「次のブロックに取り込んで欲しい」というインセンティブになります。手数料レートは「satoshi/virtual byte(sats/vB)」で表現され、例えば200バイトのトランザクションに50 sats/vBを設定すると、10,000 sats(0.0001 BTC)の手数料となります
混雑具合と手数料の関係
ネットワークが混雑すると、未承認トランザクションがメモリプール(mempool)に滞留し、マイナーはより高い手数料を優先して処理します。例えば同じサイズのトランザクションでも、50 sats/vBを設定したものは5 sats/vBのものより優先的に採掘されるため、混雑時は手数料レートを高めに設定する必要があります
トランザクションサイズ計算
Segwit対応版のアドレス(P2WPKH, P2WSH, P2TR)だと手数料が安くなる
→データサイズの大きい署名部分にかかる手数料が1/4になっているため
Segwit前と後でのトランザクションフォーマットの違い
code:segwit前
- nVersion: 4 バイト
- input count: varint
- inputs(各入力):
- outpoint (36バイト)
- scriptSig length + scriptSig
- sequence (4バイト)
- output count: varint
- outputs(各出力):
- value (8バイト)
- scriptPubKey length + scriptPubKey
- nLockTime: 4 バイト
旧フォーマットでは、「署名(スクリプト)」もすべて scriptSig の中に含まれており、証明データ(サイン)はトランザクションID に含まれていた
code:segwit後
- marker: 1 バイト(常に 0x00)
- flag: 1 バイト(常に 0x01)
- witness: 各入力ごとの「witness stack」(署名・公開鍵など)の直列化
- その他のフィールド(nVersion/inputs/outputs/nLockTime)は従来と同じ形式
- nVersion
- marker(0x00) + flag(0x01)
- input count + 各入力(outpoint, 空の scriptSig あるいは P2SH-segwit の redeemScript を含む場合も) + sequence
- output count + 各出力
- witness セクション:
- 入力ごとに
- stack item count varint
- 各 witness 要素の長さ varint + 要素バイト列
- nLockTime
- 後方互換性: 従来ノードは「marker=0x00 を input count の varint として解釈しない」ため、witness 部分をスキップできる。
- wtxid と txid: witness を含む場合、トランザクション ID(txid)は従来の非-witness 部分のみで計算し、witness 承認状況のマリティに影響しない。witness を含めたハッシュは wtxid(BIP-141)と呼ばれる。
- サイズ評価: 直列化フォーマットそのものは変わるが、手数料計算には “weight(WU)” と “vsize(vB)” の仕組みを使い、witness 部分を軽減して評価する
(weight = base×3 + total, vsize = ⌈weight/4⌉)
重み付け計算
Bitcoin のトランザクションは「ベースデータ(非ウィットネス部分)」と「ウィットネスデータ(署名など)」に分かれ、それぞれに重み付けをして合算したものが weight(単位:WU) と呼ばれます
table:重み付け
フィールド バイト数 乗数 重み付け後 WU
version 4 ×4 16
marker 1 ×1 1
flag 1 ×1 1
inputs …(各入力の outpoint, scriptSig, sequence) ×4 体積に応じて
outputs …(各出力の value, scriptPubKey) ×4 体積に応じて
witness …(各入力の署名スタック) ×1 体積に応じて
locktime 4 ×4 16
例:非ウィットネス部分 116 B, ウィットネス 110 B のトランザクションでは、
W = 116 B × 4 + 110 B × 1 = 574 WU
vsize = ⌈574/4⌉ = 144 vB
署名部分が x4とならないため、その分vBが小さくなり手数料が安くなる
segwit対応前のアドレスの場合、署名部分が x4 となる
すべてsegwit対応前の tx をブロックに含めた場合、実際のByteとvBに差がでないため、ブロックサイズは1MBとなる
手数料見積もりの方法
手数料見積もりには大きく分けて2種類のアプローチがあります:
mempoolベース
未承認トランザクションの集合をリアルタイムで解析し、現在のネットワーク需要を反映したレートを提案します。次のブロック承認を目指す場合、30 ~ 50 sats/vB程度が推奨されることが多いです
履歴ベース
過去の承認データを用いて各確認ターゲット(ブロック数)ごとの安定した手数料を推定します。Bitcoin Coreのestimatesmartfeeなどがこの方式で、柔軟な時間目標に合わせたレートを提供します
低手数料時の対策
RBF(Replace-by-Fee): RBF対応トランザクションを再放送し、手数料を上乗せできます。
CPFP(Child Pays For Parent): 承認されない親トランザクションのUTXOを使い、高レートの子トランザクションを発行し、親子まとめて採掘を促します。例:親が1 sats/vB、子を25 sats/vBで送信すると両方採掘されやすくなります
アクセラレータ: ViaBTCやBTC.comなど外部サービスに支払い、キューで優先処理してもらう方法です。
手数料推奨ツール例
mempool.space REST API: fastestFee(次ブロック)、halfHourFee(30分)、hourFee(1時間)、economyFee、minimumFeeなど複数ターゲットのレートを取得可能です
code:mempool.space
# 推奨手数料の取得(Recommended Fees)
# 次のブロック~数時間以内に承認されるための推奨手数料(fastestFee, halfHourFee, hourFee, minimumFee)を取得します。
# sat/vB
{
"fastestFee": 73,
"halfHourFee": 43,
"hourFee": 25,
"minimumFee": 1
}
# メモリプールブロック手数料の取得
Bitcoin Core RPC: estimatesmartfee で履歴ベースの推奨レートを取得できます。
Esplora API / Blockstream: 履歴データに基づく手数料推奨を提供します。
code:blockstream
{
"3": 1.1280000000000001,
"5": 1.079,
"7": 1.0,
"9": 1.0,
"10": 1.0,
"14": 1.0,
"1": 2.1310000000000002,
"11": 1.0,
"16": 1.0,
"23": 1.0,
"24": 1.0,
"144": 1.0,
"17": 1.0,
"19": 1.0,
"15": 1.0,
"21": 1.0,
"4": 1.079,
"18": 1.0,
"504": 1.0,
"2": 2.1310000000000002,
"8": 1.0,
"13": 1.0,
"6": 1.0,
"12": 1.0,
"20": 1.0,
"22": 1.0,
"1008": 1.0,
"25": 1.0
}
# キー(例: "2", "3", …)は「何ブロック以内に承認したいか」の確認ターゲット(ブロック数)。
# 値(例: 32.749)はそのターゲットを満たすために推定される手数料レート(sat/vB)。
# "2": 32.749 → 2ブロック以内に承認されるには約 32.749 sats/vB
# "144": 1 → 144ブロック以内(約24時間)なら 1 sat/vB