How verify bitcoin spending transaction signature using public key with btcsuite?


(Lorenzo D'isidoro) #1

I’m trying to verify input signature sigA in Go using Verify Signature script of package btcec.
Decoding this p2sh spending transaction

rawSpendingTxd := 01000000013dcd7d87904c9cb7f4b79f36b5a03f96e2e729284c09856238d5353e1182b00200000000fd5d01004730440220762ce7bca626942975bfd5b130ed3470b9f538eb2ac120c2043b445709369628022051d73c80328b543f744aa64b7e9ebefa7ade3e5c716eab4a09b408d2c307ccd701483045022100abf740b58d79cab000f8b0d328c2fff7eb88933971d1b63f8b99e89ca3f2dae602203354770db3cc2623349c87dea7a50cee1f78753141a5052b2d58aeb592bcf50f014cc9524104a882d414e478039cd5b52a92ffb13dd5e6bd4515497439dffd691a0f12af9575fa349b5694ed3155b136f09e63975a1700c9f4d4df849323dac06cf3bd6458cd41046ce31db9bdd543e72fe3039a1f1c047dab87037c36a669ff90e28da1848f640de68c2fe913d363a51154a0c62d7adea1b822d05035077418267b1a1379790187410411ffd36c70776538d079fbae117dc38effafb33304af83ce4894589747aee1ef992f63280567f52f5ba870678b4ab4ff6c8ea600bd217870a8b4f1f09f3a8e8353aeffffffff0130d90000000000001976a914569076ba39fc4ff6a2291d9ea9196d8c08f9c7ab88ac00000000

there is only one transaction input, get out to inputs[0].scriptSig have two signatures:

sigA := "30440220762ce7bca626942975bfd5b130ed3470b9f538eb2ac120c2043b445709369628022051d73c80328b543f744aa64b7e9ebefa7ade3e5c716eab4a09b408d2c307ccd701"
sigC := "3045022100abf740b58d79cab000f8b0d328c2fff7eb88933971d1b63f8b99e89ca3f2dae602203354770db3cc2623349c87dea7a50cee1f78753141a5052b2d58aeb592bcf50f01"

the PublicKeys of the signatures are

pubKeyA := "04a882d414e478039cd5b52a92ffb13dd5e6bd4515497439dffd691a0f12af9575fa349b5694ed3155b136f09e63975a1700c9f4d4df849323dac06cf3bd6458cd"
pubKeyC := "0411ffd36c70776538d079fbae117dc38effafb33304af83ce4894589747aee1ef992f63280567f52f5ba870678b4ab4ff6c8ea600bd217870a8b4f1f09f3a8e83"

Go script

import (
	"bytes"
	"encoding/hex"
	"fmt"

	"./block_explorer"
	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/wire"
)

fun verifyInputsSig() {
	spendingTxBytes, err := hex.DecodeString(rawSpendingTxd)
	if err != nil {
		println(err)
	}

	var tx wire.MsgTx
	err = tx.Deserialize(bytes.NewReader(spendingTxBytes))
	if err != nil {
		println(err)
	}

	blockExplorer := blockexplorer.NewBlockExplorer("main", "blockcypher") // personal pkg
    //for each input i, build the message to be signed, in this case tx.TxIn length is 1
	for i, txInput := range tx.TxIn {
        // i script is set to the output script of the UTXO it refers to
        // Input scripts other than I are truncated to zero-length
        // Blockexplorer get info of UTXO, main net, txInput.PreviousOutPoint.Hash is 02b082113e35d5386285094c2829e7e2963fa0b5369fb7f4b79c4c90877dcd3d
		previousTxOutput, _ := blockExplorer.GetDecodedTransaction(txInput.PreviousOutPoint.Hash.String())
        // previousTxOutputIndex is 0
		previousTxOutputIndex := txInput.PreviousOutPoint.Index
		currentOutput := previousTxOutput.Outputs[previousTxOutputIndex]

		for j := range tx.TxIn {
			if i == j {
                // where the only assigned script out is currentOutput.Script = a9141a8b0026343166625c7475f01e48b5ede8c0252e87
				txInput.SignatureScript, _ = hex.DecodeString(currentOutput.Script)
			} else {
				txInput.SignatureScript, _ = hex.DecodeString("")
			}
		}

		var txMessage bytes.Buffer
		tx.Serialize(&txMessage)
		txMessageHex := hex.EncodeToString(txMessage.Bytes())

		// Verify sig
		// Decode hex-encoded serialized public key.
		pubKeyBytes, _ := hex.DecodeString(pubKeyA)
		pubKey, _ := btcec.ParsePubKey(pubKeyBytes, btcec.S256())

		// Decode hex-encoded serialized signature.
		sigBytes, _ := hex.DecodeString(sigA)
		signature, _ := btcec.ParseSignature(sigBytes, btcec.S256())

		// Verify the signature for the message using the public key.
		messageHash := chainhash.DoubleHashB([]byte(txMessageHex))
		verified := signature.Verify(messageHash, pubKey)

		println("verified: ", verified) // verified: false
}

It should be expected true? The message should not be this?

Thank you!