Author

Topic: Bitcoin Test Suite (creating a transaction which spends MAX_MONEY) (Read 883 times)

jr. member
Activity: 31
Merit: 1
Cheers Chicago.  Good luck with the new set of keys.
sr. member
Activity: 592
Merit: 259
Hi arubi,

    Thanks again for the guidance.
    Working through your examples does clear things up for me.

    There was a problem I'm still facing when attempting to go through the examples with a new set of keys - and I hope to figure that part out for myself.

    I appreciate you breaking it down for me and explaining it like I'm 5 years old.

Best Regards,
-Chicago
jr. member
Activity: 31
Merit: 1
Using bip16 it's possible to take any script and "wrap" it with a p2sh script (has a standard address), so that there's a simple way to accept payment even to more advanced scripts with the burden of setting up the redemption terms moved to the person getting paid.
The decodescript example above shows how it can be used:

run:
Code:
bitcoin-cli -testnet decodescript 21036622CF5134172EE134EA77A181AAD2D544D3E084AF105423779C94545F96508EAC
The output is :

Code:
{
  "asm": "036622cf5134172ee134ea77a181aad2d544d3e084af105423779c94545f96508e OP_CHECKSIG",
  "reqSigs": 1,
  "type": "pubkey",
  "addresses": [
    "mi9ipdx2Ddx4ARbBJ5o5UPv82uRqSZSRPm"
  ],
  "p2sh": "2N6HiGdMTTxS8yp6puVN7Roz9HCNcnwU2PH"
}

Note the p2sh address.
The scriptpubkey that is known to have this address type is made out of a push of a hash160 of the redeemscript, and an op_equal.  You can read more on the bip16 link.

You can now run:
Code:
bitcoin-cli -testnet validateaddress 2N6HiGdMTTxS8yp6puVN7Roz9HCNcnwU2PH
And see that :
Code:
...
  "scriptPubKey": "a9148f121357dc6d9130f3a19b3edd965998b6b23e5687",
...
Which is what is used in the 21 mil. redemption.
sr. member
Activity: 592
Merit: 259
Hi arubi,

    Thanks again for your support.

    Now I understand how the redeemScript is made.
    Basically, I used wif-to-public from libbitcoin-explorer on the WIF private key you provided and then derived the EC public key from the WIF private key.

Code:
./bx-linux-x64-qrcode wif-to-public cTtH93A1spUmeMV2QdPXtET8KT2w98YxDjkQJNbZbYBgKAxsTbsr
036622cf5134172ee134ea77a181aad2d544d3e084af105423779c94545f96508e

    Next, I used script-encode from libbitcoin-explorer to Base16 encode the P2PK script and came up with the same redeemScript value you provided.

Code:
./bx-linux-x64-qrcode script-encode '[036622cf5134172ee134ea77a181aad2d544d3e084af105423779c94545f96508e] checksig'
21036622cf5134172ee134ea77a181aad2d544d3e084af105423779c94545f96508eac

    How did you create the P2SH script?
wrapped that in a "pay to script hash" (p2sh) script, which is A9148F121357DC6D9130F3A19B3EDD965998B6B23E5687

    How would I turn the redeemScript into the scriptPubKey?
    Which tools did you use to wrap the redeemScript in a P2SH script?

    I was looking at the libbitcoin-explorer usage but didn't stumble on the answer by myself.

Best Regards,
-Chicago
   

jr. member
Activity: 31
Merit: 1
Well, first I generated a random private key cTtH93A1spUmeMV2QdPXtET8KT2w98YxDjkQJNbZbYBgKAxsTbsr, then got the public key from it which is 036622CF5134172EE134EA77A181AAD2D544D3E084AF105423779C94545F96508E.
I created a "pay to pubkey" (p2pk) script using it, which is 21036622CF5134172EE134EA77A181AAD2D544D3E084AF105423779C94545F96508EAC, and wrapped that in a "pay to script hash" (p2sh) script, which is A9148F121357DC6D9130F3A19B3EDD965998B6B23E5687.
The p2pk script is then the redeemscript and money (the 21 million btc) is sent to that p2sh script, which is the scriptpubkey.

The txid for the input transaction, the one that paid 21 million btc to the p2sh script, is chosen to be 0000000000000000000000000000000000000000000000000000000000000100 .  In reality, you can't choose value that but for this test this is what is used.

To redeem that input, I need to provide the redeemscript for the p2sh scriptpubkey, and since that redeemscript is actually a p2pk script, I also need to provide the private key for signage.

To read about scripts like p2pk, p2sh and more, this might be a good reference: https://bitcoin.org/en/developer-guide#term-output .

You could use Core to generate everything from the private key to the p2sh script by using commands like getnewaddress, dumpprivkey, importaddress...
I recommend using testnet or regtest locally to play around with it Smiley

* For example, you could run:
bitcoin-cli -testnet decodescript 21036622CF5134172EE134EA77A181AAD2D544D3E084AF105423779C94545F96508EAC
And see what that script actually says, which is just "do a checksig operation with this pubkey".
sr. member
Activity: 592
Merit: 259
Hi arubi,

    Thanks for your reply.

    I am having trouble understanding how to know the script key and redeem script arguments to signrawtransaction.
    I don't understand how the scriptPubKey and redeemScript are produced.
    

        [
          {
            "txid":"0000000000000000000000000000000000000000000000000000000000000100",
            "vout":0,
            "scriptPubKey": "hex",
            "redeemScript": "hex",
            "amount": 21000000.00000000
          }
        ]
    


    How did you come up with these arguments?
        "scriptPubKey":"A9148F121357DC6D9130F3A19B3EDD965998B6B23E5687"
        "redeemScript":"21036622CF5134172EE134EA77A181AAD2D544D3E084AF105423779C94545F96508EAC"

    How would I come up with my own scriptPubKey and redeemScript values for another transaction where only the key pairs are different?

Best Regards,
-Chicago
    
jr. member
Activity: 31
Merit: 1
Code:
$ bitcoin-tx -testnet -create nversion=1 in=0000000000000000000000000000000000000000000000000000000000000100:0:4294967295 outscript=21000000:1
010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010040075af0750700015100000000

$ bitcoin-cli -testnet signrawtransaction 010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff010040075af0750700015100000000 '[{"txid":"0000000000000000000000000000000000000000000000000000000000000100","vout":0,"scriptPubKey":"A9148F121357DC6D9130F3A19B3EDD965998B6B23E5687","redeemScript":"21036622CF5134172EE134EA77A181AAD2D544D3E084AF105423779C94545F96508EAC","amount":21000000}]' '["cTtH93A1spUmeMV2QdPXtET8KT2w98YxDjkQJNbZbYBgKAxsTbsr"]'
{
  "hex": "01000000010001000000000000000000000000000000000000000000000000000000000000000000006c47304402200f52ed89db0f0909b2b5db21eff27c7fc446a138d373de42e7467065e65893ab022036bd523c296eb40d6e26165969ad3553c1620c141e95df75b8c372c860f92d2b012321036622cf5134172ee134ea77a181aad2d544d3e084af105423779c94545f96508eacffffffff010040075af0750700015100000000",
  "complete": true
}


I used a different private\public key pair because I don't know what's the private key that was used in the tests, but the scripts should be the same.
You can't use createrawtransaction because the output's script is 51, and seems like createrawtransaction accepts only addresses for outputs.
sr. member
Activity: 592
Merit: 259
Hello,

    There is a unit test, which creates a transaction spending MAX_MONEY.
    It is called from src/test/transaction_tests.cpp (transaction_tests/tx_valid) and found in src/test/data/tx_valid.json.

Code:
["Tests for CTransaction::CheckTransaction()"],
["MAX_MONEY output"],
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]],
"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010040075af0750700015100000000", true]

    Decoding the serializedTransaction using decoderawtransaction, returns the following result.

Code:
{
    "txid" : "4d163e00f1966e9a1eab8f9374c3e37f4deb4857c247270e25f7d79a999d2dc9",
    "version" : 1,
    "locktime" : 0,
    "vin" : [
        {
            "txid" : "0000000000000000000000000000000000000000000000000000000000000100",
            "vout" : 0,
            "scriptSig" : {
                "asm" : "3046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f01 21030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbac",
                "hex" : "493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbac"
            },
            "sequence" : 4294967295
        }
    ],
    "vout" : [
        {
            "value" : 21000000.00000000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "1",
                "hex" : "51",
                "type" : "nonstandard"
            }
        }
    ]
}

    I would like to understand how to create the serializedTransaction.
    How would I produce this same transaction by using the RPC client with createrawtransaction and signrawtransaction using the same parameters seen here in the test suite?

    Kindly share how I would go through the mechanics of creating the same transaction using the Core client or other tools such that the serializedTransaction value is the same.
   
Code:
01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010040075af0750700015100000000

    Thanks in advance for your advice.

Best Regards,
-Chicago
Jump to: