3

I've been playing around with DLC transactions but I can't seem to create a valid CET transaction to conclude simple all or nothing bets. Further details below on my specific case, though this question also relates to methods for debugging invalid bitcoin transaction scripts in general.

In this example, when attempting to broadcast an invalid transaction, the most verbose error I am able to obtain is as follows:

Error validating transaction: Error running script for input 0 referencing f8736021c8144f6991cd05a6702197f307565b11e9b7abaaa19b0348d3d6da16 at 0: Script was NOT verified successfully..

...which isn't very helpful, since it only states that the transaction script is invalid. It does not divulge specifically what part of the script/transaction is invalid.

Having spent a lot of time debugging my own DLC logic, I am now interested - how can I approach the debugging of an invalid Bitcoin transaction itself in search for clues on what has gone wrong during transaction creation?

Specific (invalid) transaction in question here:

{
    "addresses": [
        "bc1qewcpdlhklv427mtxefvzym800mqrdvkapym2kmqleetxwa08w3gq7y6n6c",
        "bc1ql7np4a4elfkv6ae43wrfaup6c0rmvyxkqx88aw"
    ],
    "block_height": -1,
    "block_index": -1,
    "confirmations": 0,
    "double_spend": false,
    "fees": 170,
    "hash": "a740198694a1a2e8e1850970cf25e3ef795c8b5fb8da0732375644f8d5ad58c8",
    "inputs": [
        {
            "addresses": [
                "bc1qewcpdlhklv427mtxefvzym800mqrdvkapym2kmqleetxwa08w3gq7y6n6c"
            ],
            "age": 711675,
            "output_index": 0,
            "output_value": 1370,
            "prev_hash": "f8736021c8144f6991cd05a6702197f307565b11e9b7abaaa19b0348d3d6da16",
            "script_type": "pay-to-witness-script-hash",
            "sequence": 4294967295,
            "witness": [
                "",
                "304502210097aa3e394986bcc74178c16d7fee160c78e2f6b3389995d2f930162c3da1448b0220585d29c92dd4f5878ddd2da0f6cc7a50825eab20187c5e6de41a8f54c054cf9101",
                "304402206744c1ff93471ed94b4b9fe61c3e84c4f49554d15245c590245c6eba200f26c8022026d3154d08db41db10765aad4ba76dfdb8f91c0f37a5ca324c292ec5fb91b34b01",
                "5221033e7464943ac55e9f2a8fdc30325df313270fd15ef92744327241ba18a72c506d21035b00cdb5056b7c644f17dde11067e91384c7b9ed97c16d7feb28df569df1371e52ae"
            ]
        }
    ],
    "outputs": [
        {
            "addresses": [
                "bc1ql7np4a4elfkv6ae43wrfaup6c0rmvyxkqx88aw"
            ],
            "script": "0014ffa61af6b9fa6ccd77358b869ef03ac3c7b610d6",
            "script_type": "pay-to-witness-pubkey-hash",
            "value": 1200
        }
    ],
    "preference": "low",
    "received": "2021-12-20T23:08:32.284953769Z",
    "relayed_by": "44.193.204.249",
    "size": 303,
    "total": 1200,
    "ver": 2,
    "vin_sz": 1,
    "vout_sz": 1,
    "vsize": 138
}

and associated txhex:

0200000000010116dad6d348039ba1aaabb7e9115b5607f3972170a605cd91694f14c8216073f80000000000ffffffff01b004000000000000160014ffa61af6b9fa6ccd77358b869ef03ac3c7b610d6040048304502210097aa3e394986bcc74178c16d7fee160c78e2f6b3389995d2f930162c3da1448b0220585d29c92dd4f5878ddd2da0f6cc7a50825eab20187c5e6de41a8f54c054cf910147304402206744c1ff93471ed94b4b9fe61c3e84c4f49554d15245c590245c6eba200f26c8022026d3154d08db41db10765aad4ba76dfdb8f91c0f37a5ca324c292ec5fb91b34b01475221033e7464943ac55e9f2a8fdc30325df313270fd15ef92744327241ba18a72c506d21035b00cdb5056b7c644f17dde11067e91384c7b9ed97c16d7feb28df569df1371e52ae00000000

Thanks to @meshcollider's pointer, I used kallewoof's script debugging tool with the above txhex setting txin as the txhex for the associated funding transaction that created the input utxo of the CET transaction:

btcdeb --tx=0200000000010116dad6d348039ba1aaabb7e9115b5607f3972170a605cd91694f14c8216073f80000000000ffffffff01b004000000000000160014b007f44f21a153706746e09e508f43193315996b0400473044022053beeedca8004419528365422d7f41bf1c458696a7a5ca045685e1fa23114f0202200dd522014dae15d3edb28d25a7190d262ec3a4b6a4aa5aaac56de8c9cdb3b0b50147304402202de278ef40eaa143704950842cde5ac0119056ec1302413e871c3d202bb0182b022057bafc3eb34f8d8bfd884d812436a78c6aea7931589c7131b5dd80e686040ac701475221033e7464943ac55e9f2a8fdc30325df313270fd15ef92744327241ba18a72c506d21035b00cdb5056b7c644f17dde11067e91384c7b9ed97c16d7feb28df569df1371e52ae00000000 --txin=0200000000010433d8a2db6a4fc1ac1ae69b2c0c315c002195d9e6ba6a485f52601322170469400000000000ffffffff3c0f4ab770449808b9fd3fe430221bde77ed979002ff5b8f86664f12abeb7c560000000000ffffffff33d8a2db6a4fc1ac1ae69b2c0c315c002195d9e6ba6a485f52601322170469400100000000ffffffff3c0f4ab770449808b9fd3fe430221bde77ed979002ff5b8f86664f12abeb7c560100000000ffffffff035a05000000000000220020cbb016fef6fb2aaf6d66ca58226cef7ec036b2dd0936ab6c1fce566775e77450d10200000000000016001411b853839dd15f691f390611c2ebd7b7b2f51fadd10200000000000016001409973c8035089d42c2ab1328aa00dc1998a1f9bc0247304402205db089047b17d5769e34f541cba8b35cff9b8fddceac37ec4b0296b50176b3980220435932954b97688973cdc058590e77e4b9124e79ebbbceb5b78e4677dd198b82012102e01b2ba3f457708bb6317fb9d5f5a1d8a7e8c6331c0fb6d28b3c00d8930ad1fc02473044022014182c1f10edf4c44601ce4d859490544f9a3fd8abe99dd7d21f413e2a22d01e022003118089e598f7a1a989634ba61356e64a94df70b9b28ff8a953cb11cf0737b1012103a1e0a48f62065f043d71ac1565861ca49ecf0a4b9858a227a2453bfa7a3198550247304402206499708afd271848f24eef30b589834197a709123208152c93cc853fd600c12302207e3a7e0b1957f1083fb1b61a8548ffebdb71908906e73c5b842e2156594c393c012103d5d4b6f0a52331ea5f7a713104610ce946038a4aa8fcad6a5905ca0cb6c0792e02473044022063fb8c225317258bf9b6715a1117d4faeb43330cec79ed0fee97f286ddf01eff02200f810cd6080331dd82b44827f29d3ef8499af3c4c8f27ef58c66f0b1bf37d11b0121035482f5bf4ab770f9f88c6db13406a9c624aae1adff4b031f7fa1addb966f83ee00000000

VerifyECDSASignature() failed (see below). What does this tell me specifically? How can I use the output below to find the problem?

btcdeb> step
stack has 7 entries [require 1]
stack has 7 entries [require 4]
stack has 7 entries [require 7]
scriptCode = 5221033e7464943ac55e9f2a8fdc30325df313270fd15ef92744327241ba18a72c506d21035b00cdb5056b7c644f17dde11067e91384c7b9ed97c16d7feb28df569df1371e52ae
looping for multisig
loop: sigs = 2, keys = 2
- got sig 304402202de278ef40eaa143704950842cde5ac0119056ec1302413e871c3d202bb0182b022057bafc3eb34f8d8bfd884d812436a78c6aea7931589c7131b5dd80e686040ac701
- got key 035b00cdb5056b7c644f17dde11067e91384c7b9ed97c16d7feb28df569df1371e
GenericTransactionSignatureChecker::CheckECDSASignature(71 len sig, 33 len pubkey, sigversion=1)
  sig         = 304402202de278ef40eaa143704950842cde5ac0119056ec1302413e871c3d202bb0182b022057bafc3eb34f8d8bfd884d812436a78c6aea7931589c7131b5dd80e686040ac701
  pub key     = 035b00cdb5056b7c644f17dde11067e91384c7b9ed97c16d7feb28df569df1371e
  script code = 5221033e7464943ac55e9f2a8fdc30325df313270fd15ef92744327241ba18a72c506d21035b00cdb5056b7c644f17dde11067e91384c7b9ed97c16d7feb28df569df1371e52ae
  hash type   = 01 (SIGHASH_ALL)
SignatureHash(nIn=0, nHashType=01, amount=1370)
- sigversion == SIGVERSION_WITNESS_V0
  sighash     = 9b315f4e8bf72ff16827a12d832820592af81e62d3764a50ce09715a2e398bff
  pubkey.VerifyECDSASignature(sig=304402202de278ef40eaa143704950842cde5ac0119056ec1302413e871c3d202bb0182b022057bafc3eb34f8d8bfd884d812436a78c6aea7931589c7131b5dd80e686040ac7, sighash=9b315f4e8bf72ff16827a12d832820592af81e62d3764a50ce09715a2e398bff):
  result: success
- sig check succeeded
loop: sigs = 1, keys = 1
- got sig 3044022053beeedca8004419528365422d7f41bf1c458696a7a5ca045685e1fa23114f0202200dd522014dae15d3edb28d25a7190d262ec3a4b6a4aa5aaac56de8c9cdb3b0b501
- got key 033e7464943ac55e9f2a8fdc30325df313270fd15ef92744327241ba18a72c506d
GenericTransactionSignatureChecker::CheckECDSASignature(71 len sig, 33 len pubkey, sigversion=1)
  sig         = 3044022053beeedca8004419528365422d7f41bf1c458696a7a5ca045685e1fa23114f0202200dd522014dae15d3edb28d25a7190d262ec3a4b6a4aa5aaac56de8c9cdb3b0b501
  pub key     = 033e7464943ac55e9f2a8fdc30325df313270fd15ef92744327241ba18a72c506d
  script code = 5221033e7464943ac55e9f2a8fdc30325df313270fd15ef92744327241ba18a72c506d21035b00cdb5056b7c644f17dde11067e91384c7b9ed97c16d7feb28df569df1371e52ae
  hash type   = 01 (SIGHASH_ALL)
SignatureHash(nIn=0, nHashType=01, amount=1370)
- sigversion == SIGVERSION_WITNESS_V0
  sighash     = 9b315f4e8bf72ff16827a12d832820592af81e62d3764a50ce09715a2e398bff
  pubkey.VerifyECDSASignature(sig=3044022053beeedca8004419528365422d7f41bf1c458696a7a5ca045685e1fa23114f0202200dd522014dae15d3edb28d25a7190d262ec3a4b6a4aa5aaac56de8c9cdb3b0b5, sighash=9b315f4e8bf72ff16827a12d832820592af81e62d3764a50ce09715a2e398bff):
  result: FAILURE
- failed: VerifyECDSASignature() failed
- sig check failed
loop ended in failure state
        <> POP  stack
        <> POP  stack
        <> POP  stack
        <> POP  stack
error: Signature must be zero for failed CHECK(MULTI)SIG operation
3
  • 1
    This may be helpful: github.com/bitcoin-core/btcdeb
    – meshcollider
    Dec 21 '21 at 0:59
  • 1
    Very cool tool, thanks for the pointer
    – satirn
    Dec 21 '21 at 14:40
  • @meshcollider I tried the btcdeb tool with the contract ending transaction hex as tx, and the funding transaction hex as txin (please correct me if this is wrong). I included the command and associated output as an edit to my original post above, which shows a validation error as expected. How would I go about understanding why VerifyECDSASignature() failed in this instance?
    – satirn
    Dec 21 '21 at 14:55
0

As mentioned in my comment, for answer completeness, a great way of debugging Bitcoin script is using the script debugger.

VerifyECDSASignature passed on the first of the two signatures in the multisig, but failed on the second signature. Unfortunately it is difficult to know exactly why - it is likely the transaction being signed has changed slightly from when it was created.

How exactly did you generate the signatures?

1
  • I generated the CET signatures (as well as the rest of the DLC transactions) using the cfd-js and cfd-dlc-js libraries - github.com/p2pderivatives/cfd-dlc-js. I'd assume that in this case the correct signature was that of the local counterparty, who constructed the CET, while the incorrect signature is associated with the adaptor signatures that should have allowed the local counterparty to unilaterally settle the contract (by making use of the signed oracle attestation).
    – satirn
    Dec 21 '21 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.