From bf8c5d22e19c7f460fe75fbe3a885271f70df17a Mon Sep 17 00:00:00 2001 From: Ivan Kuznetsov Date: Sun, 10 Sep 2017 14:05:23 +0700 Subject: [PATCH] Store input sig and key in different fields; rename TXInput.ScriptPubKey to PubKeyHash --- transaction.go | 39 +++++++++++++++++++-------------------- transaction_input.go | 7 +++---- transaction_output.go | 8 ++++---- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/transaction.go b/transaction.go index 132ce83..4102a22 100644 --- a/transaction.go +++ b/transaction.go @@ -70,9 +70,10 @@ func (tx *Transaction) Sign(privKey ecdsa.PrivateKey, prevTXs map[string]Transac for inID, vin := range txCopy.Vin { prevTx := prevTXs[hex.EncodeToString(vin.Txid)] - txCopy.Vin[inID].ScriptSig = prevTx.Vout[vin.Vout].ScriptPubKey + txCopy.Vin[inID].Signature = []byte{} + txCopy.Vin[inID].PubKey = prevTx.Vout[vin.Vout].PubKeyHash txCopy.ID = txCopy.Hash() - txCopy.Vin[inID].ScriptSig = []byte{} + txCopy.Vin[inID].PubKey = []byte{} r, s, err := ecdsa.Sign(rand.Reader, &privKey, txCopy.ID) if err != nil { @@ -80,7 +81,7 @@ func (tx *Transaction) Sign(privKey ecdsa.PrivateKey, prevTXs map[string]Transac } signature := append(r.Bytes(), s.Bytes()...) - tx.Vin[inID].ScriptSig = append(signature, tx.Vin[inID].ScriptSig...) + tx.Vin[inID].Signature = signature } } @@ -93,15 +94,16 @@ func (tx Transaction) String() string { for i, input := range tx.Vin { lines = append(lines, fmt.Sprintf(" Input %d:", i)) - lines = append(lines, fmt.Sprintf(" TXID: %x", input.Txid)) - lines = append(lines, fmt.Sprintf(" Out: %d", input.Vout)) - lines = append(lines, fmt.Sprintf(" Script: %x", input.ScriptSig)) + lines = append(lines, fmt.Sprintf(" TXID: %x", input.Txid)) + lines = append(lines, fmt.Sprintf(" Out: %d", input.Vout)) + lines = append(lines, fmt.Sprintf(" Signature: %x", input.Signature)) + lines = append(lines, fmt.Sprintf(" PubKey: %x", input.PubKey)) } for i, output := range tx.Vout { lines = append(lines, fmt.Sprintf(" Output %d:", i)) lines = append(lines, fmt.Sprintf(" Value: %d", output.Value)) - lines = append(lines, fmt.Sprintf(" Script: %x", output.ScriptPubKey)) + lines = append(lines, fmt.Sprintf(" Script: %x", output.PubKeyHash)) } return strings.Join(lines, "\n") @@ -117,7 +119,7 @@ func (tx *Transaction) TrimmedCopy() Transaction { } for _, vout := range tx.Vout { - outputs = append(outputs, TXOutput{vout.Value, vout.ScriptPubKey}) + outputs = append(outputs, TXOutput{vout.Value, vout.PubKeyHash}) } txCopy := Transaction{tx.ID, inputs, outputs} @@ -127,8 +129,6 @@ func (tx *Transaction) TrimmedCopy() Transaction { // Verify verifies signatures of Transaction inputs func (tx *Transaction) Verify(prevTXs map[string]Transaction) bool { - sigLen := 64 - if tx.IsCoinbase() { return true } @@ -144,23 +144,22 @@ func (tx *Transaction) Verify(prevTXs map[string]Transaction) bool { for inID, vin := range tx.Vin { prevTx := prevTXs[hex.EncodeToString(vin.Txid)] - txCopy.Vin[inID].ScriptSig = prevTx.Vout[vin.Vout].ScriptPubKey + txCopy.Vin[inID].Signature = []byte{} + txCopy.Vin[inID].PubKey = prevTx.Vout[vin.Vout].PubKeyHash txCopy.ID = txCopy.Hash() - txCopy.Vin[inID].ScriptSig = []byte{} - - signature := vin.ScriptSig[:sigLen] - pubKey := vin.ScriptSig[sigLen:] + txCopy.Vin[inID].PubKey = []byte{} r := big.Int{} s := big.Int{} - r.SetBytes(signature[:(sigLen / 2)]) - s.SetBytes(signature[(sigLen / 2):]) + sigLen := len(vin.Signature) + r.SetBytes(vin.Signature[:(sigLen / 2)]) + s.SetBytes(vin.Signature[(sigLen / 2):]) x := big.Int{} y := big.Int{} - keyLen := len(pubKey) - x.SetBytes(pubKey[:(keyLen / 2)]) - y.SetBytes(pubKey[(keyLen / 2):]) + keyLen := len(vin.PubKey) + x.SetBytes(vin.PubKey[:(keyLen / 2)]) + y.SetBytes(vin.PubKey[(keyLen / 2):]) rawPubKey := ecdsa.PublicKey{curve, &x, &y} if ecdsa.Verify(&rawPubKey, txCopy.ID, &r, &s) == false { diff --git a/transaction_input.go b/transaction_input.go index baeccd9..23beeba 100644 --- a/transaction_input.go +++ b/transaction_input.go @@ -6,14 +6,13 @@ import "bytes" type TXInput struct { Txid []byte Vout int - ScriptSig []byte + Signature []byte + PubKey []byte } // UsesKey checks whether the address initiated the transaction func (in *TXInput) UsesKey(pubKeyHash []byte) bool { - sigLen := 64 - pubKey := in.ScriptSig[sigLen:] - lockingHash := HashPubKey(pubKey) + lockingHash := HashPubKey(in.PubKey) return bytes.Compare(lockingHash, pubKeyHash) == 0 } diff --git a/transaction_output.go b/transaction_output.go index 27d89b5..4d70d74 100644 --- a/transaction_output.go +++ b/transaction_output.go @@ -4,20 +4,20 @@ import "bytes" // TXOutput represents a transaction output type TXOutput struct { - Value int - ScriptPubKey []byte + Value int + PubKeyHash []byte } // Lock signs the output func (out *TXOutput) Lock(address []byte) { pubKeyHash := Base58Decode(address) pubKeyHash = pubKeyHash[1 : len(pubKeyHash)-4] - out.ScriptPubKey = pubKeyHash + out.PubKeyHash = pubKeyHash } // IsLockedWithKey checks if the output can be used by the owner of the pubkey func (out *TXOutput) IsLockedWithKey(pubKeyHash []byte) bool { - return bytes.Compare(out.ScriptPubKey, pubKeyHash) == 0 + return bytes.Compare(out.PubKeyHash, pubKeyHash) == 0 } // NewTXOutput create a new TXOutput