我们在发送交易时需要用私钥进行签名以验证此币是你币,然后在网络中广播。发送的操作做了不少遍,撸下底层的代码玩下。最核的代码有这几条:
//用privKey给txCopy.ID签名。ECDSA算法签名就是一对数字,我们把它们连起来并存放到input的Signature里。
r, s, err := ecdsa.Sign(rand.Reader, &privKey, txCopy.ID)
signature := append(r.Bytes(), s.Bytes()...)
tx.Vin[inID].Signature = signature
接下来再来细细看下:
func (tx *Transaction) Sign(privKey ecdsa.PrivateKey, prevTXs map[string]Transaction) {
if tx.IsCoinbase() {
return //coinbase不需要签名
}
//签名修剪后的交易副本,而不是整个交易
txCopy := tx.TrimmedCopy()
for inID, vin := range txCopy.Vin {
prevTx := prevTXs[hex.EncodeToString(vin.Txid)]
txCopy.Vin[inID].Signature = nil
txCopy.Vin[inID].PubKey = prevTx.Vout[vin.Vout].PubKeyHash
txCopy.ID = txCopy.Hash()
txCopy.Vin[inID].PubKey = nil
r, s, err := ecdsa.Sign(rand.Reader, &privKey, txCopy.ID)
signature := append(r.Bytes(), s.Bytes()...)
tx.Vin[inID].Signature = signature
}
}
func (tx *Transaction) TrimmedCopy() Transaction {
var inputs []TXInput
var outputs []TXOutput
for _, vin := range tx.Vin {
inputs = append(inputs, TXInput{vin.Txid, vin.Vout, nil, nil})
}
for _, vout := range tx.Vout {
outputs = append(outputs, TXOutput{vout.Value, vout.PubKeyHash})
}
txCopy := Transaction{tx.ID, inputs, outputs}
return txCopy
}
签名还是蛮复杂的,步骤也多,实现起来不容易。先看看核心的片段,然后再组合。
Together we can rebuild.🌱💪 We have resteem this.🛡♻
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit