### coinbase transaction
01000000 – version
01 – # of inputs
000…00 – previous tx hash
ffffffff – previous tx index
5e0…00 ScriptSig
ffffffff – sequence
01 – # of outputs
faf20b58…00 – output amount
1976…ac – p2pkh ScriptPubKey
00000000 – locktime
coinbase transactionのインプットは必ず1つになる。
その一つのインプットの前のトランザクションIDは32バイトの00
トランザクションインデックスはffffffff 出なければならない
### Txクラスのis_coinbaseメソッド
class Tx:
//
def is_coinbase(self):
if len(self.tx_ins) != 1:
return False
first_input = self.tx_ins[0]
if first_input.prev_tx != b'\x00' * 32:
return False
if first_input.prev_index != 0xffffffff:
return False
return True
### Coinbase TxのScriptSig
ScriptSigはマイニングした人によって設定される
2バイト以上、100バイト以下の制限がある
from io import BytesIO
from script import Script
stream = BytesIO(bytes.fromhex('4d04ffff001d0104455468652054696d6573203033\
2f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64\
206261696c6f757420666f722062616e6b73'))
s = Script.parse(stream)
print(s.cmds[2])
$ python3 test.py
b’The Times 03/Jan/2009 Chancellor on brink of second bailout for banks’
### BIP0034
Coinbase transactionのScriptSigの先頭要素を規定する
トランザクションIDの重複を防ぐため、BIP0034が作成されている
BIP0034はソフトフォークルールで、マイニングされたブロックの高さをコインベースのScriptSigの先頭要素に追加する
リトルエンディアン整数として解釈され、ブロックの高さと同じ
コインベーストランザクションから高さをパースする方法
from io import BytesIO
from script import Script
from helper import little_endian_to_int
stream = BytesIO(bytes.fromhex('5e03d71b07254d696e656420627920416e74506f6f\
6c20626a31312f4542312f4144362f43205914293101fabe6d6d678e2c8c34afc36896e7d94028\
24ed38e856676ee94bfdb0c6c4bcd8b2e5666a0400000000000000c7270000a5e00e00'))
script_sig = Script.parse(stream)
print(little_endian_to_int(script_sig.cmds[0]))
def coinbase_height(self):
if not self.is_coinbase():
return None
element = self.tx_ins[0].script_sig.cmds[0]
return little_endian_to_int(element)
ScriptSigの先頭cmdsにCoinbase ブロックヘッダーの高さが入ってるのね。
### ブロックヘッダー
ブロックヘッダーは以下で構成されている
– Version、Previous Block, Merkle Root, Timestamp, Bits, Nonce
02000020 – version
8ec3…00 – previous block
5b07…be – merkle root
1e77a759 – timestamp
e93c0118 – bits
a4ffd71d – nonce
ブロックIDはヘッダーのhash256のリトルエンディアンの16進数表記
version, prev_block, merkle_root, timestampはlittle_endian, bitsとnonceはそのまま。
@classmethod
def parse(cls, s):
version = little_endian_to_int(s.read(4))
prev_block = s.read(32)[::-1]
merkle_root = s.read(32)[::-1]
timestamp = little_endian_to_int(s.read(4))
bits = s.read(4)
nonce = s.read(4)
return cls(version, prev_block, merkle_root, timestamp, bits, nonce)
def serialize(self):
result = int_to_little_endian(self.version, 4)
result += self.prev_block[::-1]
result += self.merkle_root[::-1]
result += int_to_little_endian(self.timestamp, 4)
result += self.bits
result += self.nonce
return result
def hash(self):
s = self.serialize()
sha = hash256(s)
return sha[::-1]
### ブロックのバージョンについて
バージョン2は、コインベース・トランザクションにブロック高を指定するBIP0034にソフトウェアが対応していることを意味する
バージョン3はDERエンコーディングを強制するBIP0066に対応していることを意味する
バージョン4はOP_CHECKLOCKTIMEVERIFYを規定するBIP0065に対応していることを意味する
BIP0009は4バイトヘッダーのうち、先頭3ビットを001に固定してマイナーがBIP0009に対応していることを示す
from io import BytesIO
from block import Block
b = Block.parse(BytesIO(bytes.fromhex('020000208ec39428b17323fa0ddec8e887b\
4a7c53b8c0a0a220cfd0000000000000000005b0750fce0a889502d40508d39576821155e9c9e3\
f5c3157f961db38fd8b25be1e77a759e93c0118a4ffd71d')))
print('BIP9: {}'.format(b.version >> 29 == 0b001))
print('BIP91: {}'.format(b.version >> 4 & 1 == 1))
print('BIP9: {}'.format(b.version >> 1 & 1 == 1))
$ python3 test.py
BIP9: True
BIP91: False
BIP9: True
上記をclassに含める。if ~ return trueではなく、そのままreturnと書いてしまって良い
[class]
def bip9(self):
return self.version >> 29 == 0b001
def bip91(self):
return self.version >> 4 & 1 == 1
def bip141(self):
return self.version >> 1 & 1 == 1
[/code]
### 前のブロック
全てのブロックは前のブロックを指している必要がある
### マークルルート
全てのトランザクションを32バイトハッシュにエンコードする
### timestamp
unix形式の4bytes。Unixタイムスタンプは1970年1月1日からの秒数
### bits
BitsはそのブロックのProof of Workに必要な値をエンコードするフィールド
### Nonce(number used only once)
一度だけ使われる数値の略