1

I'm trying to verify inputs signatures 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 that should check sigA using pubKeyA

    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?

On the left decoded rawSpendingTxd to the right decoded txMessageHex before double hashing: enter image description here

Thank you!

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.