## 2019年9月2日月曜日

### Python - Transactions - Transaction Fee - Calculating the Fee

Programming Bitcoin: Learn How to Program Bitcoin from Scratch (Jimmy Song(著)、O'Reilly Media)のChapter 5(Transactions)、Transaction Fee、Exercises 6(102)の解答を求めてみる。

コード

Python 3

```#!/usr/bin/env python3
from unittest import TestCase, main

class TransactionTest(TestCase):
def setUp(self):
pass

def tearDown(self):
pass

def test_parse(self):
import io
hex_transaction = '01000000' + \
'01' + \
'11223344556677889900' + \
'11223344556677889900' + \
'11223344556677889900' + \
'1122' + \
'11223344' + \
'11223344' + \
'01' + \
'1122334455667788' + \
'10000000'

b = io.BytesIO(bytes.fromhex(hex_transaction))
parsed = Transaction.parse(b)
self.assertEqual(1, parsed.version)
self.assertEqual(1, len(parsed.tx_ins))
self.assertEqual(1, len(parsed.tx_outs))
self.assertEqual(16, parsed.locktime)

def little_endian_to_int(b: bytes) -> int:
return int.from_bytes(b, 'little')

d = {0xfd: 2, 0xfe: 4, 0xff: 8}
if i in d:
return i

class Transaction:
def __init__(self, version, tx_ins, tx_outs, locktime, testnet=False):
self.version = version
self.tx_ins = tx_ins
self.tx_outs = tx_outs
self.locktime = locktime

@classmethod
def parse(cls, stream):
inputs = [TransactionInput.parse(stream)
outputs = [TransactionOutput.parse(stream)
return cls(version, inputs, outputs, locktime)

def fee(self, testnet=False):
return sum([tx_in.value() for tx_in in self.tx_ins]) - \
sum([tx_out.value() for tx_out in self.tx_outs])

class TransactionInput:
def __init__(
self, prev_tx, prev_index, script_sig=None, sequence=0xffffffff):
pass

def __repr__(self):
return f'{self.prev_tx.hex()}:{self.prev_index}'

@classmethod
def parse(cls, stream):
# script_sig = Script.parse(s)
return cls(tx_id, prev_index, None, sequence)

def value(self, testnet=False):
pass

class TransactionOutput:
def __init__(self, amount, script_pubkey):
pass

def __repr__(self):
return f'{self.amount}:{self.script_pubkey}'

@classmethod
def parse(cls, stream):
# script_pubkey = Script.parse(s)
return cls(amount, None)

def value(self, testnet=False):
pass

if __name__ == '__main__':
main()
```

```\$ mypy sample6.py
\$ ./sample6.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
\$
```