Script
Script 是一種有限制的可執行程式,沒有迴圈,比特幣的 Script 是在一個 stack 上執行
其中有兩類元素: elements, operations
elements是直接放到 stack 上, operations是對 stack 上的元素做操作
當操作到最後時,元素要是「非零」才會被斷為成功
TxIn
裡面的 ScriptSig, TxOut
的 ScriptPubKey 都是 Script
型態
因此我們在 Script 裡要可以解析這兩種輸入,我們用 type
這個函式來分辨是哪種形式的腳本
定義 Script
:
class Script:
def __init__(self, elements):
self.elements = elements
def __repr__(self):
result = ''
for element in self.elements:
if type(element) == int:
result += '{} '.format(OP_CODES[element])
else:
result += '{} '.format(element.hex())
return result
解析函示:
@classmethod
def parse(cls, binary):
s = BytesIO(binary)
elements = []
current = s.read(1)
while current != b'':
op_code = current[0]
if 0 < op_code <= 75:
elements.append(s.read(op_code))
else:
elements.append(op_code)
current = s.read(1)
return cls(elements)
運作如下:
首先定義「操作碼」,其值為 0 或是 76 之後,
所以當讀到 1 ~ 75, 我們就接著讀這個長度,讀出來的東西丟進 elements
裡
其他就屬於操作碼
定義 type
函式,方便我們判斷是哪一種 script
主要有 p2pkh
、 p2sh
、 p2sh multiSig
def type(self):
if len(self.elements) == 0:
return 'blank'
elif self.elements[0] == 0x76 \
and self.elements[1] == 0xa9 \
and type(self.elements[2]) == bytes \
and len(self.elements[2]) == 0x14 \
and self.elements[3] == 0x88 \
and self.elements[4] == 0xac:
# p2pkh:
# OP_DUP OP_HASH160 <20-byte hash> <OP_EQUALVERIFY> <OP_CHECKSIG>
return 'p2pkh'
elif type(self.elements[0]) == bytes \
and len(self.elements[0]) in (0x47, 0x48, 0x49) \
and type(self.elements[1]) == bytes \
and len(self.elements[1]) in (0x21, 0x41):
# p2pkh scriptSig:
# <signature> <pubkey>
return 'p2pkh sig'
elif len(self.elements) > 1 \
and type(self.elements[1]) == bytes \
and len(self.elements[1]) in (0x47, 0x48, 0x49) \
and self.elements[-1][-1] == 0xae:
# HACK: assumes p2sh is a multisig
# p2sh multisig:
# <x> <sig1> ... <sigm> <redeemscript ends with OP_CHECKMULTISIG>
return 'p2sh sig'
else:
return 'unknown'
常見的 script 有這幾種
- p2pk : 公鑰交易 (pay to public key)
- p2pkh :公鑰哈希交易 (pay to public key hash)
- p2sh : 腳本哈希交易 (pay to script hash)
- p2wpkh :見證公鑰哈希交易 (pay to witness public key hash)
- p2wsh :見證腳本哈希交易 (pay to witness script hash)