数字签名 / go实现简易区块链 #7

in STEEM CN/中文2 years ago

我们在发送交易时需要用私钥进行签名以验证此币是你币,然后在网络中广播。发送的操作做了不少遍,撸下底层的代码玩下。最核的代码有这几条:

//用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
}

签名还是蛮复杂的,步骤也多,实现起来不容易。先看看核心的片段,然后再组合。

Sort:  

Together we can rebuild.🌱💪 We have resteem this.🛡♻

Coin Marketplace

STEEM 0.20
TRX 0.14
JST 0.029
BTC 67363.69
ETH 3247.42
USDT 1.00
SBD 2.66