Bitcoin Forum
April 28, 2024, 03:21:09 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: How to redeem a "dumb script" native P2WPKH? (Nested P2SH-P2WPKH went well)  (Read 105 times)
BTCW (OP)
Copper Member
Full Member
***
Offline Offline

Activity: 193
Merit: 234

Click "+Merit" top-right corner


View Profile
January 07, 2024, 04:54:18 PM
Merited by ABCbits (2), hugeblack (2), Cricktor (1), vjudeu (1)
 #1

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!

SendBTC.me <<< amazing imitative
1714317669
Hero Member
*
Offline Offline

Posts: 1714317669

View Profile Personal Message (Offline)

Ignore
1714317669
Reply with quote  #2

1714317669
Report to moderator
Each block is stacked on top of the previous one. Adding another block to the top makes all lower blocks more difficult to remove: there is more "weight" above each block. A transaction in a block 6 blocks deep (6 confirmations) will be very difficult to remove.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714317669
Hero Member
*
Offline Offline

Posts: 1714317669

View Profile Personal Message (Offline)

Ignore
1714317669
Reply with quote  #2

1714317669
Report to moderator
1714317669
Hero Member
*
Offline Offline

Posts: 1714317669

View Profile Personal Message (Offline)

Ignore
1714317669
Reply with quote  #2

1714317669
Report to moderator
vjudeu
Hero Member
*****
Offline Offline

Activity: 666
Merit: 1527



View Profile
January 07, 2024, 08:35:12 PM
Last edit: January 07, 2024, 08:46:50 PM by vjudeu
Merited by ABCbits (1), nc50lc (1)
 #2

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.

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
nc50lc
Legendary
*
Offline Offline

Activity: 2394
Merit: 5543


Self-proclaimed Genius


View Profile
January 09, 2024, 08:07:02 AM
Merited by BTCW (10), pooya87 (4), RickDeckard (4), Cricktor (1)
 #3

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

.
.HUGE.
▄██████████▄▄
▄█████████████████▄
▄█████████████████████▄
▄███████████████████████▄
▄█████████████████████████▄
███████▌██▌▐██▐██▐████▄███
████▐██▐████▌██▌██▌██▌██
█████▀███▀███▀▐██▐██▐█████

▀█████████████████████████▀

▀███████████████████████▀

▀█████████████████████▀

▀█████████████████▀

▀██████████▀▀
█▀▀▀▀











█▄▄▄▄
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
.
CASINSPORTSBOOK
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀▀█











▄▄▄▄█
BTCW (OP)
Copper Member
Full Member
***
Offline Offline

Activity: 193
Merit: 234

Click "+Merit" top-right corner


View Profile
January 09, 2024, 05:49:54 PM
 #4

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

SendBTC.me <<< amazing imitative
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!