3

I have been attempting to build my own raw transaction generator in Java which I can then broadcast on the testnet network. The problem is when I attempt to broadcast the transaction it says there is an error in the redemption script, which I do not understand.

Here is an example testnet transaction:

0100000001e468833270cf713f3bbccc62b7b5b0fc0b0a4570608718530816795a6589f322000000008a473044022051646b77924f6bb7c411c5aa890110ab55db8812b8998fe24c8bdce39795ebd602200bc4de18fd5524ad8b946ee57604424e2b943ef2a14fc7199a7853dda0743cbe014104b97c679207532e0f4ee2515aedaba5f87700bbe0138f7457baa58e89a53153823ab29632e6c3c804ecaab5913656512339792479a1b898b7e5dc31f075ff8660ffffffff0176df1710000000001976a91448ddfd3891f3f422d5c3c9c25e35b382667fc6e688ac00000000

The script I am attempting to unlock:

76a91448ddfd3891f3f422d5c3c9c25e35b382667fc6e688ac

With the redemption script being:

473044022051646b77924f6bb7c411c5aa890110ab55db8812b8998fe24c8bdce39795ebd602200bc4de18fd5524ad8b946ee57604424e2b943ef2a14fc7199a7853dda0743cbe014104b97c679207532e0f4ee2515aedaba5f87700bbe0138f7457baa58e89a53153823ab29632e6c3c804ecaab5913656512339792479a1b898b7e5dc31f075ff8660

This is the Java code to sign the reverse double sha256 hash:

  public static byte[] sign(byte[] hash, BigInteger priv){

        ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
        signer.init(true, new ECPrivateKeyParameters(priv, domain));

        BigInteger[] signature = signer.generateSignature(hash);
        ByteArrayOutputStream s = new ByteArrayOutputStream();

        try {
            DERSequenceGenerator seq = new DERSequenceGenerator(s);
            seq.addObject(new ASN1Integer(signature[0]));
            seq.addObject(new ASN1Integer(signature[1]));
            seq.close();
            return s.toByteArray();
        }
        catch(IOException e){
            return null;
        }
    }

What is wrong?

  • Both the transactions and the scripts look to be fine, can you be more specific about the error you are getting? Have you tried to broadcast the transaction using other sources, such as online APIs? It may be because of the broadcasting itself instead of the transaction correctness. – sr-gi Mar 30 '17 at 10:44
  • I have attempted to broadcast the transaction using both blockcyper which gives me the error: "Error sending transaction: Error running script for input 0 referencing 22f389655a7916085318876070450a0bfcb0b5b762ccbc3b3f71cf70328368e4 at 0: Script was NOT verified successfully.." I have also attempted to use blockexplorer which gives me the error "16: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element). Code:-26". – user2965346 Mar 30 '17 at 13:09
  • Ok, now I see. It seems that the validation is failing since the signature is not correct. The script evaluation is failing in the OP_CHECKSIG, just after verifying that the ripemd160 provided in the previous tx scriptPubKey matches with the ripemd160 of the public key provided in the scriptSig. – sr-gi Mar 30 '17 at 13:47
  • I don't understand why this is the case though. When signing I place the unlock script from the transaction I am trying to spend where the signature is placed and also append a hashcode type. Finally I sha256 hash the transaction twice, reverse the hash before finally signing it. Is this right? – user2965346 Mar 30 '17 at 13:59
  • You should sha256 twice the entire transaction, sign it, and then append the hashtype. Here is quite well explained (from step 13 onwards) bitcoin.stackexchange.com/questions/3374/… – sr-gi Mar 30 '17 at 14:10
0

Quickly decoding the tx:

 VERSION      01000000
 TX_IN COUNT  hex=01, decimal=1
 TX_IN[0]
  TX_IN[0]    OutPoint hash 22F389655A7916085318876070450A0BFCB0B5B762CCBC3B3F71CF70328368E4 
  TX_IN[0]    OutPoint index hex=00000000, reversed=00000000, decimal=0
  TX_IN[0]    Script Length hex=8A, decimal=138
  TX_IN[0]    Script Sig  473044022051646B77924F6BB7C411C5AA890110AB55DB8812B8998FE24C8BDCE39795EBD602200BC4DE18FD5524AD8B946EE57604424E2B943EF2A14FC7199A7853DDA0743CBE014104B97C679207532E0F4EE2515AEDABA5F87700BBE0138F7457BAA58E89A53153823AB29632E6C3C804ECAAB5913656512339792479A1B898B7E5DC31F075FF8660
        47: OP_DATA_0x47:     push hex 47 (decimal 71) bytes as data
        30: OP_SEQUENCE_0x30: type tag indicating SEQUENCE, begin sigscript
        44: OP_LENGTH_0x44:   length of R + S
        02: OP_INT_0x02:      type tag indicating INTEGER
        20: OP_LENGTH_0x20:   this is SIG R
            51646B77924F6BB7:C411C5AA890110AB:55DB8812B8998FE2:4C8BDCE39795EBD6
        02: OP_S_INT_0x02
        20: OP_LENGTH_0x20:   this is SIG S
            0BC4DE18FD5524AD:8B946EE57604424E:2B943EF2A14FC719:9A7853DDA0743CBE
        01: OP_SIGHASHALL:    this terminates the ECDSA signature (ASN1-DER structure)
        Minimum and maximum size constraints                        - ok
        scriptsig always starts with 0x30                           - ok
        length 136 chars is less than actual sig length (140 chars) - ok
               (hex 0x44, decimal 68, 136 chars)
        length of R coordinate (64) >= 0                            - ok
        length of S coordinate (64) >= 0                            - ok
        S-Value is within scriptsig boundaries                      - ok
        Make sure the R & S length covers the entire signature      - ok
        S-value must be smaller than N/2                            - ok
        strictly check DER-encoded signature                        - ok
        41: OP_DATA_0x41:     push hex 41 (decimal 65) bytes as data
        04: OP_LENGTH_0X04
            B97C679207532E0F:4EE2515AEDABA5F8:7700BBE0138F7457:BAA58E89A5315382
            3AB29632E6C3C804:ECAAB59136565123:39792479A1B898B7:E5DC31F075FF8660
        * This terminates the Public Key, corresponding bitcoin address is:    mnAEswb3Aiz5YTsfCJc8vQETnSe19mc5Am 
 TX_IN[0] Sequence FFFFFFFF

TX_OUT COUNT, hex=01, decimal=1
 TX_OUT[0] Value hex=76DF171000000000, rev_hex=000000001017DF76, dec=269999990 
 TX_OUT[0] PK_Script Length hex=19, dec=25 
 TX_OUT[0] pk_script 76A91448DDFD3891F3F422D5C3C9C25E35B382667FC6E688AC
        76: OP_DUP
        A9: OP_HASH160
        14: OP_Data14 (= decimal 20)
            48DDFD3891F3F422:D5C3C9C25E35B382
            667FC6E6
        88: OP_EQUALVERIFY
        AC: OP_CHECKSIG   This is a P2PKH script and translates base58 encoded into this bitcoin address:    mnAEswb3Aiz5YTsfCJc8vQETnSe19mc5Am 
 LOCK_TIME 00000000

So the transaction is correct, and the signature is assembled correctly. It also follows the "strict sig check" rules. The tx is trying to spend from mnAEswb3Aiz5YTsfCJc8vQETnSe19mc5Am to mnAEswb3Aiz5YTsfCJc8vQETnSe19mc5Am. So I checked the signature against the double hash of the tx (see the famous pizza transaction run-through: How does the ECDSA verification algorithm work during transaction?):

The raw_tx.txt is:

0100000001e468833270cf713f3bbccc62b7b5b0fc0b0a4570608718530816795a6589f322000000008a473044022051646b77924f6bb7c411c5aa890110ab55db8812b8998fe24c8bdce39795ebd602200bc4de18fd5524ad8b946ee57604424e2b943ef2a14fc7199a7853dda0743cbe014104b97c679207532e0f4ee2515aedaba5f87700bbe0138f7457baa58e89a53153823ab29632e6c3c804ecaab5913656512339792479a1b898b7e5dc31f075ff8660ffffffff0176df1710000000001976a91448ddfd3891f3f422d5c3c9c25e35b382667fc6e688ac00000000

Removed sig, and entered your pubkey script into raw_tx_SIGHASH_ALL.txt:

0100000001e468833270cf713f3bbccc62b7b5b0fc0b0a4570608718530816795a6589f322000000001976a91448ddfd3891f3f422d5c3c9c25e35b382667fc6e688acffffffff0176df1710000000001976a91448ddfd3891f3f422d5c3c9c25e35b382667fc6e688ac0000000001000000

and double hash (the binary values, hence some conversion first!)

  result=$( cat raw_tx_SIGHASH_ALL.txt | sed 's/[[:xdigit:]]\{2\}/\\x&/g' )
  printf $result > raw_tx.hex
  hexdump -C raw_tx.hex 
  openssl dgst -binary -sha256 <raw_tx.hex >ssha256.hex
  openssl dgst -binary -sha256 <ssha256.hex >dsha256.hex
  hexdump -C dsha256.hex 

So the dsha256 is in readable form: 6b37475a5388fb52f227817a0ddec00e7b69495b492cd7cdc6aff2afc44810e4

I use openssl to verify the double hash hex file (dsha256.hex), with the signature and a "pem" key (need to convert pubkey from hex to pem), I always get an error:

openssl pkeyutl -verify -pubin -inkey pubkey.pem -sigfile tmp_sig.hex -in dsha256.hex

whereas running through the pizza example, it returns a "Signature Verified Successfully".

  • It's a bit confusing that you write the elements of the DER-encoded signature as "opcodes", and at the same level as the rest of the scriptSig. From Bitcoin's perspective, that whole signature is a black box array of bytes, not a sequence of opcodes (OP_SEQUENCE through OP_SIGHASH). – Pieter Wuille Aug 11 '17 at 5:50

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.