### 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)
一度だけ使われる数値の略