Author

Topic: How to redeem a "dumb script" native P2WPKH? (Nested P2SH-P2WPKH went well) (Read 242 times)

newbie
Activity: 8
Merit: 0

Oh okay, he didn't explained how he used the tool.
Such spend has to be done manually by entering the input's details, the txid, vout, scriptsig (minus the size) which is "51027551" and amount.
Then the output and its amount considering the fee, don't forget to change the coin setting to Bitcoin (testnet).

You can even reproduce the raw transaction that he shared in the OP by filling up with the same details of his transaction.

Inputs;
TXID: 85fd05407575d31155824f6cdbaae1b544af78158cc643dd4d8f7c7351ef5bfb | N: 0 | Script: 51027551 | Amount: 1
Outputs;
Address: 2N2EJxoRy5hRE74aV4NDiC22dcH3QEqzf5G | Amount: 0.99999

Then submit it.
Check the result transaction with his Byte by Byte. Take note that the address "2NAfhvQFw2GR1A1iN8Eke47HqVuDcsW4Uzw" is wrong.

It worked like a charm, thanks a lot!
legendary
Activity: 2618
Merit: 6452
Self-proclaimed Genius
-snip-
I tried the redeem script on cointoolkit(the link he provided) and it did not work I even tried on Coinbin and still it didn't work.
I might be getting something wrong or they stopped supporting non standard scripts.
Oh okay, he didn't explained how he used the tool.
Such spend has to be done manually by entering the input's details, the txid, vout, scriptsig (minus the size) which is "51027551" and amount.
Then the output and its amount considering the fee, don't forget to change the coin setting to Bitcoin (testnet).

You can even reproduce the raw transaction that he shared in the OP by filling up with the same details of his transaction.

Inputs;
TXID: 85fd05407575d31155824f6cdbaae1b544af78158cc643dd4d8f7c7351ef5bfb | N: 0 | Script: 51027551 | Amount: 1
Outputs;
Address: 2N2EJxoRy5hRE74aV4NDiC22dcH3QEqzf5G | Amount: 0.99999

Then submit it.
Check the result transaction with his Byte by Byte. Take note that the address "2NAfhvQFw2GR1A1iN8Eke47HqVuDcsW4Uzw" is wrong.
newbie
Activity: 8
Merit: 0
Do you mean in the code he provided for P2SH version?
It's just for the generation of P2SH address which is not used to spend the transaction, he did that to conveniently create an output with that script.
The Redeem Script is already the "dumb_script=7551".

This is literally the instruction to spend it:
Comments: Used "OP_1, OP_DROP, OP_1" as the sigScript, which, including length prefixes, is 0x0451027551 - all it took.
He used "OP_1" to fulfill the RedeemScript "OP_DROP, OP_1"

I tried the redeem script on cointoolkit(the link he provided) and it did not work I even tried on Coinbin and still it didn't work.
I might be getting something wrong or they stopped supporting non standard scripts.
legendary
Activity: 2618
Merit: 6452
Self-proclaimed Genius
I don't understand the part of merging the script hash with another hash to form a redeem script.
Do you mean in the code he provided for P2SH version?
It's just for the generation of P2SH address which is not used to spend the transaction, he did that to conveniently create an output with that script.
The Redeem Script is already the "dumb_script=7551".

This is literally the instruction to spend it:
Comments: Used "OP_1, OP_DROP, OP_1" as the sigScript, which, including length prefixes, is 0x0451027551 - all it took.
He used "OP_1" to fulfill the RedeemScript "OP_DROP, OP_1"
newbie
Activity: 8
Merit: 0
I fooled around a bit with "dumb scripts" like so:

Script("OP_DROP", "OP_1") is dumb but valid, will accept any one value in, drop it, and leave just a True on top of the stack. It is simply 0x7151 in hex.

To take it back, I created a raw transaction the lazy way using Cointoolkit:

Code:
0100000001fb5bef51737c8f4ddd43c68c1578af44b5e1aadb6c4f825511d375754005fd85000000000451027551ffffffff0118ddf5050000000017a914628cde58e1bcd42efb72b1821ec9fdf49e0f1d498700000000

...and broadcast it successfully in Electrum, got the tBTC back within the same block, tx id 4d7eee43f95a1402128aee4577daf0fd287f8c6aab9893f6aad559ab688cc91f


Can you or anyone give me a walkthrough of how to redeem this   ?
Just use this one as an example, I know it's already spent.
I don't understand the part of merging the script hash with another hash to form a redeem script.
copper member
Activity: 193
Merit: 255
Click "+Merit" top-right corner
No sigScript allowed when spending... hm. How do I create a witness program for a dumb script for which there is no known public and private key? Is it even possible?
The correct address should be the one provided by vjudeu from Bitcoin Core's decodescript command.

To spend it, you'll basically have to do the same as your previous transaction, but for SegWit:
Code:
01000000								< Version 1
00 < SegWit marker
01 < SegWit flag
01 < amount of input(s)
f052c63f7cc387e85f96c99dc108f53289943f03d3814e0ff5e8f54f8e22d29e < input0 txid
00000000 < input0 index
00 < script length (0 for p2wpkh)
ffffffff < input0 nSequence
01 < amount of output(s)
60EA000000000000 < output0 amount
19 76a914b77e875983ee5851006ec5bd461208ebd11ea1bf88ac < output0 Size scriptPubkey
-------------------------------------------Witness for input 0--------------------------------------------
02 < Number of Stack Items
01 51 < Stack item 0 (Size OP_PUSHNUM_1)
02 7551 < Stack item 1 (Size OP_Drop 1 OP_PUSHNUM_1)
-------------------------------------------Witness for input 0--------------------------------------------
00000000 < nLocktime

Your previous transaction's scriptSig "0x0451027551" is used as Witness.
But in P2WPKH spend, the number of stack items must be indicated followed by those stack items with their respective sizes.

Transactions:
Spent by:   blockstream.info/testnet/tx/1b291f7cf57e827f6e8d1225657264fcee9ad4a8248e769c2788a8196a2bda6b (the example above)
Funded by: blockstream.info/testnet/tx/9ed2228e4ff5e8f50f4e81d3033f948932f508c19dc9965fe887c37c3fc652f0

Excellent, many thanks! This really works.

Amended the code for public address generation, too (now produces the same results as Bitcoin Core):

Code:
def hex_to_hash160(hexdata):
    return hashlib.new('ripemd', hashlib.sha256(bytes.fromhex(hexdata)).digest()).hexdigest()
def hex_to_sha256(hexdata):
    return hashlib.sha256(bytes.fromhex(hexdata)).hexdigest()

the_script = "7551" #feel free to play around
#the_script = bitcoinutils.script.Script(["OP_DROP", "OP_1"]).to_hex() #same result but unnecessary library use

the_script_hash160 = hex_to_hash160(the_script)
the_script_sha256  = hex_to_sha256(the_script)

print('Testnet:')
print(base58.b58encode_check(bytes.fromhex('c4'+ the_script_hash160)).decode())
print(bitcoinutils.bech32.encode('tb', 0, bytes.fromhex(the_script_sha256)))
print()
print('Mainnet:')
print(base58.b58encode_check(bytes.fromhex('05'+ the_script_hash160)).decode())
print(bitcoinutils.bech32.encode('bc', 0, bytes.fromhex(the_script_sha256)))

Code:
Testnet:
2NBgCqkaw8r7s15pamKLogvWurSTFVVf1Kf
tb1qxvvc4xl77e6whhdel7499y5qz7uywfu3u4xxp89etunc4343udys6xzc00

Mainnet:
3L7zn1euXPcWoJC36Biw4yXee6F5ksEYdb
bc1qxvvc4xl77e6whhdel7499y5qz7uywfu3u4xxp89etunc4343udysdw5h4q
legendary
Activity: 2618
Merit: 6452
Self-proclaimed Genius
No sigScript allowed when spending... hm. How do I create a witness program for a dumb script for which there is no known public and private key? Is it even possible?
The correct address should be the one provided by vjudeu from Bitcoin Core's decodescript command.

To spend it, you'll basically have to do the same as your previous transaction, but for SegWit:
Code:
01000000								< Version 1
00 < SegWit marker
01 < SegWit flag
01 < amount of input(s)
f052c63f7cc387e85f96c99dc108f53289943f03d3814e0ff5e8f54f8e22d29e < input0 txid
00000000 < input0 index
00 < script length (0 for p2wpkh)
ffffffff < input0 nSequence
01 < amount of output(s)
60EA000000000000 < output0 amount
19 76a914b77e875983ee5851006ec5bd461208ebd11ea1bf88ac < output0 Size scriptPubkey
-------------------------------------------Witness for input 0--------------------------------------------
02 < Number of Stack Items
01 51 < Stack item 0 (Size OP_PUSHNUM_1)
02 7551 < Stack item 1 (Size OP_Drop 1 OP_PUSHNUM_1)
-------------------------------------------Witness for input 0--------------------------------------------
00000000 < nLocktime

Your previous transaction's scriptSig "0x0451027551" is used as Witness.
But in P2WPKH spend, the number of stack items must be indicated followed by those stack items with their respective sizes.

Transactions:
Spent by:   blockstream.info/testnet/tx/1b291f7cf57e827f6e8d1225657264fcee9ad4a8248e769c2788a8196a2bda6b (the example above)
Funded by: blockstream.info/testnet/tx/9ed2228e4ff5e8f50f4e81d3033f948932f508c19dc9965fe887c37c3fc652f0
copper member
Activity: 906
Merit: 2258
Quote
tb1qhudhq5jad3wa26unkzmt0llg4r0wt4euhpwxg7
I wonder, how you got that address. But whatever is there, it can lead you to something unspendable. Also, I wonder, which version of the library was used, and what was the result of each step in-between. Because I got a different address with that code, and I wonder, how you came up with that specific values.

Quote
No sigScript allowed when spending... hm.
Of course. You need a valid public key. Which means, that if some Script was used, and it is not a valid public key, then it is unspendable. Or rather: unlikely to be spent. Because mathematically speaking, it could be spendable, if you could bruteforce the whole address as a vanity address. But it would mean that RIPEMD-160 is no longer safe. Which means, that it is practically unspendable, unless some public key is behind it, and that "list of bytes" was treated as a seed in some different versions of the library.

Quote
How do I create a witness program for a dumb script for which there is no known public and private key?
It is very easy. Just feed it with random bytes, that are not the hash of something, and you will have a random, unspendable address.

Quote
Is it even possible?
Of course. The address tb1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0l98cr is also "unlikely to be spent", as long as RIPEMD-160 is safe.

But most importantly, there are two more important questions:

1. Why don't you test things on regtest first? In that case, it is possible to make mistakes, and then never broadcast those blocks. Which means, you can just start Bitcoin Core, run it in regtest mode, and test any scripts on your local computer, to check, if something is spendable or not.

2. Why don't you use Bitcoin Core to calculate proper addresses? It is easy, and it will always give you the right one (unless you force it to generate something unspendable). For example:
Code:
decodescript 7551
{
  "asm": "OP_DROP 1",
  "desc": "raw(7551)#udtt52c3",
  "type": "nonstandard",
  "p2sh": "2NBgCqkaw8r7s15pamKLogvWurSTFVVf1Kf",
  "segwit": {
    "asm": "0 33198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349",
    "desc": "addr(tb1qxvvc4xl77e6whhdel7499y5qz7uywfu3u4xxp89etunc4343udys6xzc00)#xqwha8gw",
    "hex": "002033198a9bfef674ebddb9ffaa52928017b8472791e54c609cb95f278ac6b1e349",
    "address": "tb1qxvvc4xl77e6whhdel7499y5qz7uywfu3u4xxp89etunc4343udys6xzc00",
    "type": "witness_v0_scripthash",
    "p2sh-segwit": "2MyMyxQoFC6bLVWfRh3H6qVQGrUfHo6Mv4F"
  }
}

Edit: Also, I recommend reading about Taproot. Because then, it is possible to create some TapScript, and spend by key, if it turns out to be unspendable by TapScript.
copper member
Activity: 193
Merit: 255
Click "+Merit" top-right corner
I fooled around a bit with "dumb scripts" like so:

Script("OP_DROP", "OP_1") is dumb but valid, will accept any one value in, drop it, and leave just a True on top of the stack. It is simply 0x7151 in hex.

Proven on testnet with (Python 3, import hashlib, base58 and bitcoinutils):

Code:
dumb_script="7551"
dumb_hash = hashlib.new('ripemd', hashlib.sha256(bytes.fromhex(dumb_script)).digest()).hexdigest()
dumb_address = base58.b58encode_check(bytes.fromhex('c4' + dumb_hash)).decode()
print(dumb_address)
#2NAfhvQFw2GR1A1iN8Eke47HqVuDcsW4Uzw

I sent 1 tBTC to 2NAfhvQFw2GR1A1iN8Eke47HqVuDcsW4Uzw, tx id 85fd05407575d31155824f6cdbaae1b544af78158cc643dd4d8f7c7351ef5bfb

To take it back, I created a raw transaction the lazy way using Cointoolkit:

Code:
0100000001fb5bef51737c8f4ddd43c68c1578af44b5e1aadb6c4f825511d375754005fd85000000000451027551ffffffff0118ddf5050000000017a914628cde58e1bcd42efb72b1821ec9fdf49e0f1d498700000000

...and broadcast it successfully in Electrum, got the tBTC back within the same block, tx id 4d7eee43f95a1402128aee4577daf0fd287f8c6aab9893f6aad559ab688cc91f

Comments: Used "OP_1, OP_DROP, OP_1" as the sigScript, which, including length prefixes, is 0x0451027551 - all it took.

I suppose I could have pushed any single number, but I went with OP_1 - and it worked as intended.

So far, so good. But now I wanted to repeat the experiment with native Segwit P2WPKH, so I changed formats while still using the same (dumb) script:

Code:
dumb_script="7551"
dumb_hash = hashlib.new('ripemd', hashlib.sha256(bytes.fromhex(dumb_script)).digest()).hexdigest()
dumb_address = bitcoinutils.bech32.encode('tb',0,memoryview(bytes.fromhex(dumb_hash)).tolist())
print(dumb_address)
#tb1qhudhq5jad3wa26unkzmt0llg4r0wt4euhpwxg7

Sent another 1 tBTC to tb1qhudhq5jad3wa26unkzmt0llg4r0wt4euhpwxg7, tx id 2df1208d368035e6ff923f5a40053792f220b3d87628db62e51a7bcdf0a50a3a

Uh oh. Need help!

No sigScript allowed when spending... hm. How do I create a witness program for a dumb script for which there is no known public and private key? Is it even possible?

Staring into a random raw P2PWKH transaction but fail to see "it."

If possible, there is 1 tBTC in it for you. Take it, and please share how the witness part was created. In case it is impossible, please explain why.

Many thanks!
Jump to: