(个人学习用,可能理解上存在谬误)
上篇中,签名的步骤如下,
solver = build_hash160_lookup([exponent])
signed_new_tx = unsigned_new_tx.sign(solver)
对于pycoin是如何完成交易签名的,很有必要从其源码中进行研究
def sign(self, hash160_lookup, hash_type=None, **kwargs):
"""
Sign a standard transaction.
hash160_lookup:
A dictionary (or another object with .get) where keys are hash160 and
values are tuples (secret exponent, public_pair, is_compressed) or None
(in which case the script will obviously not be signed).
"""
if hash_type is None:
hash_type = self.SIGHASH_ALL #1
self.check_unspents() #2
for idx, tx_in in enumerate(self.txs_in):
if self.is_signature_ok(idx) or tx_in.is_coinbase():
continue
try:
if self.unspents[idx]:
self.sign_tx_in(
hash160_lookup, idx, self.unspents[idx].script, hash_type=hash_type, **kwargs)#3
except SolvingError:
pass
return self
大致流程:
1)先检查是否交易输入都有其对应的锁定脚本(#2处)
2)逐个对未签名过的交易输入进行签名操作(#3处)
#1处,将hash_type默认设为SIGHASH_ALL,这也是目前最主流的方式,具体细节可自行搜索
继续进入sign_tx_in方法:
def sign_tx_in(self, hash160_lookup, tx_in_idx, tx_out_script, hash_type=None, **kwargs):
if hash_type is None:
hash_type = self.SIGHASH_ALL
r = self.solve(hash160_lookup, tx_in_idx, tx_out_script,
hash_type=hash_type, **kwargs) #1
if isinstance(r, bytes):
self.txs_in[tx_in_idx].script = r #2
else:
self.txs_in[tx_in_idx].script = r[0] #3
self.set_witness(tx_in_idx, r[1])
在#1处调用solve进行签名,返回解锁脚本。然后在#2处将解锁脚本设置入相应的交易输入TxIn的script字段中,完成了对该交易输入的签名。
#3处涉及到segwit相关的东西,不深入研究了
继续跟进solve
def solve(self, hash160_lookup, tx_in_idx, tx_out_script, ha