ビットコインの仕組みをpythonで実装してみる #3 「トランザクションのデモ」

スポンサーリンク
Uncategorized

はじめに

前回、トランザクションについて書いていたのですが、長くなってしまったので、区切りました。

この記事は後編です。

今回はトランザクションのデモを実施し、理解を深めます。

pythonコード

今回使用した、デモ用のpythonコードは以下です。

from trx import build_demo_state


def format_utxos(label: str, utxos: list[dict]) -> str:
    lines = [label]
    for utxo in utxos:
        lines.append(
            "- owner={owner} amount={amount} sats txid={txid} index={index} address={address}".format(
                **utxo
            )
        )
    return "\n".join(lines)


if __name__ == "__main__":
    me_utxo_amount = 120_000
    me_to_other_amount = 70_000
    other_to_me_amount = 20_000
    fee = 1_000

    state = build_demo_state(
        me_to_other_amount=me_to_other_amount,
        other_to_me_amount=other_to_me_amount,
        fee=fee,
        me_utxo_amount=me_utxo_amount,
    )

    print("Addresses")
    print(f"me={state['me_address']}")
    print(f"other={state['other_address']}")
    print("\nTimeline (me -> other)")
    tx1 = state["tx1"]
    print(
        "T0 Input: txid={txid} index={index} amount={amount} sats address={address}".format(
            **tx1["input"]
        )
    )
    print(
        "T1 Output to other: amount={amount} sats address={address}".format(
            **tx1["outputs"][0]
        )
    )
    print(
        "T2 Output change to me: amount={amount} sats address={address}".format(
            **tx1["outputs"][1]
        )
    )
    print("T3 Sign input with my private key and attach public key")
    print(f"T4 Raw TX1 hex: {tx1['raw_hex']}")

    print("\nTimeline (other -> me)")
    tx2 = state["tx2"]
    print(
        "T0 Input: txid={txid} index={index} amount={amount} sats address={address}".format(
            **tx2["input"]
        )
    )
    print(
        "T1 Output to me: amount={amount} sats address={address}".format(
            **tx2["outputs"][0]
        )
    )
    print(
        "T2 Output change to other: amount={amount} sats address={address}".format(
            **tx2["outputs"][1]
        )
    )
    print("T3 Sign input with other private key and attach public key")
    print(f"T4 Raw TX2 hex: {tx2['raw_hex']}")

    print("\nUTXO state")
    print(format_utxos("T0 Before TX1", state["utxo_timeline"]["t0"]))
    print(format_utxos("T1 After TX1", state["utxo_timeline"]["t1"]))
    print(format_utxos("T2 After TX2", state["utxo_timeline"]["t2"]))

このデモは

  • 1️⃣ me → other に送金
  • 2️⃣ other → me に送金

の2回の送金をシミュレーションしています。

流れとしては、

  • 私は最初 120,000持っている
  • 70,000を相手に送る
  • 手数料は1,000
  • 後で相手が 20,000送り返す

となります。

デモ実施

実行してみると、以下のような結果が出てきます。(結果は見やす用に少し加工しています)

$ python3 demo_trx.py
Addresses
me=162y18DcCb7tLYKdawUJ4HpenHRsJon2dM
other=1Aqd1WMMjDrcn9PjiKBdk1P5TBmBW5Rdzk

Timeline (me -> other)
T0 Input: 
    txid=0000000000000000000000000000000000000000000000000000000000000000 
    index=0 
    amount=120000 
    address=162y18DcCb7tLYKdawUJ4HpenHRsJon2dM
T1 Output to other: 
    amount=70000 
    address=1Aqd1WMMjDrcn9PjiKBdk1P5TBmBW5Rdzk
T2 Output change to me: 
    amount=49000 
    address=162y18DcCb7tLYKdawUJ4HpenHRsJon2dM
T3 Sign input with my private key and attach public key
T4 Raw TX1 hex: 01000000010000000000000000000000000000000000000000000000000000000000000000000000008b483045022100f55b8cf050795f53f88100c1bee28f66e04d3bf206a4061a3df11e2e1b91277802202eac1776d0cc1d4d99f41e3889495d3cddf5f38f3969b3e45bf9156baa20fe64014104173aafcf5602a332fd5ec6da556bad8139d2c220782a1043bdce96570cc7d32647d9b97ed04b5f0c143169b6988f5987198d4f5fce84cea11da96d53e7acdafbffffffff0270110100000000001976a9146beb2823604923a4d8cd649eb90df5519e94843188ac68bf0000000000001976a9143737cb09bf74f29e9ed91d1404834770f1e6527f88ac00000000

Timeline (other -> me)
T0 Input: 
    txid=58cf567c1b43ae92e4c413ef61c1e94cefa11217b267b48b2e5650cc558a1721 
    index=0 amount=70000 
    address=1Aqd1WMMjDrcn9PjiKBdk1P5TBmBW5Rdzk
T1 Output to me: 
    amount=20000
    address=162y18DcCb7tLYKdawUJ4HpenHRsJon2dM
T2 Output change to other: 
    amount=49000
    address=1Aqd1WMMjDrcn9PjiKBdk1P5TBmBW5Rdzk
T3 Sign input with other private key and attach public key
T4 Raw TX2 hex: 010000000121178a55cc50562e8bb467b21712a1ef4ce9c161ef13c4e492ae431b7c56cf58000000008a47304402200cd44b7d1567454b3b46b26138b9f9ec3364976c4bd14cf260235ce2a98e7dd502205b6dbf62d33df142a9fa78476dde7ea7532251c482d6568c62ec64592aa8b3e30141044221743dee9f3a57b7f7aaf4e1a98e045801c54fa58b7f967e89d7defc5d5adf701001f37d6bda7276c4501b7938ebd81b089b07eb82c51ed85227f83cc298e9ffffffff02204e0000000000001976a9143737cb09bf74f29e9ed91d1404834770f1e6527f88ac68bf0000000000001976a9146beb2823604923a4d8cd649eb90df5519e94843188ac00000000

UTXO state
T0 Before TX1
- owner=me 
  amount=120000
  txid=0000000000000000000000000000000000000000000000000000000000000000 
  index=0 
  address=162y18DcCb7tLYKdawUJ4HpenHRsJon2dM

T1 After TX1
- owner=other 
    amount=70000
    txid=58cf567c1b43ae92e4c413ef61c1e94cefa11217b267b48b2e5650cc558a1721 
    index=0 
    address=1Aqd1WMMjDrcn9PjiKBdk1P5TBmBW5Rdzk
- owner=me 
    amount=49000 
    txid=58cf567c1b43ae92e4c413ef61c1e94cefa11217b267b48b2e5650cc558a1721 
    index=1 
    address=162y18DcCb7tLYKdawUJ4HpenHRsJon2dM

T2 After TX2
- owner=me 
    amount=20000 
    txid=15a4e380b569143c1ef99660463e486053cbc17f712bf1ebd266a58629a8062f 
    index=0 
    address=162y18DcCb7tLYKdawUJ4HpenHRsJon2dM
- owner=other 
    amount=49000 
    txid=15a4e380b569143c1ef99660463e486053cbc17f712bf1ebd266a58629a8062f 
    index=1 
    address=1Aqd1WMMjDrcn9PjiKBdk1P5TBmBW5Rdzk
- owner=me 
    amount=49000
    txid=58cf567c1b43ae92e4c413ef61c1e94cefa11217b267b48b2e5650cc558a1721 
    index=1 
    address=162y18DcCb7tLYKdawUJ4HpenHRsJon2dM

いや、これじゃわからないね。

図にすると以下のようなデータの変遷をします。

いやこれでも、図は文字が小さくて、まだまだ分かりにくいですね。

一つ一つ説明します。

  • T0(最初の手持ち):
    • 初期状態
    • 私は120,000のUTXOを1つ持っている(txid=00…の出力)
  • TX1(私→相手):
    • 入力: 私の120,000のUTXOを消費
    • 出力: 相手に70,000、私にお釣り49,000
    • 差額1,000は手数料として消える
    • このタイミングで新しいUTXOが2つできる(相手70,000、私49,000)
  • T1(TX1後の状態):
    • 相手: 70,000のUTXOを持つ
    • 私: 49,000のUTXOを持つ
  • TX2(相手→私):
    • 入力: 相手の70,000のUTXOを消費
    • 出力: 私に20,000、相手にお釣り49,000
    • 差額1,000は手数料
  • T2(TX2後の状態):
    • あなた: 20,000(TX2で受け取った)+ 49,000(TX1のお釣り)を持つ
    • 相手: 49,000(TX2のお釣り)を持つ

という流れになります。

最後に

トランザクションのデモ、2回の送金だけだったけど、結構ややこしいですね!

タイトルとURLをコピーしました