So, we’ve got a public key and we can hash it using RIPEMD(SHA256(pubkey)), which gives us the HASH160.
Creating a valid native segwit address from this is pretty straightforward. Everything’s working fine so far.
But what happens if we switch the version from 0 to 1 and ignore the taproot standards? We end up with a bech32m public address like this:
Is it useful for anything? Will wallets recognize it? Will nodes actually send transactions to it on the BTC network? Can we use regular private keys to spend from it, just like we do with the normal native segwit addresses?
For lack of a better name, let's call these P2WPKH(Bech32m). So, is this a real thing or what? That's what I'm getting at.
Is a P2WPKH v1/bech32m address valid and functional?
5 replies 395 views
It's good for burning your precious coins! .... or at least make it extremely difficult to be spent but spendable by anyone!!!
They should not since the address (the data part) is short and non-standard (20 byte instead of expected 32).
No because their IsStandardTx[1] check will recognize[2] such transactions as non-standard so they'll not propagate it.
[1] https://github.com/bitcoin/bitcoin/blob/dfc35c99340da3236e2841b348580f0e881762ce/src/policy/policy.cpp#L94
[2] https://github.com/bitcoin/bitcoin/blob/dfc35c99340da3236e2841b348580f0e881762ce/src/script/solver.cpp#L164
Technically anybody should be able to spend any coins sent to such output. The reason is that witness program of any size other than 32 is valid but not-defined (also non-standard hence the burned coins as I said at first) so the node ignores verification of it expecting it to be a future change/soft-fork.
It falls into this branch: https://github.com/bitcoin/bitcoin/blob/dfc35c99340da3236e2841b348580f0e881762ce/src/script/interpreter.cpp#L1946-L1952
which will return true.
No because there is nothing like it defined in the consensus rules so the protocol sees it as an arbitrary hash not pubkey hash.
I just tried it on Electrum watch-only, where
1. 2nd address created by OP got accepted without any warning or error message.
2. Electrum also let me create unsigned TX with OP's 2nd address as receiver.
Field-test results:
Using bitcointools and hashlib in Python. First, generate a normal native segwit address and its private key wif from a (very not cryptographically safe) private key:
The output is benign and as expected - our native segwit address on the last row:
Now, to verify the public address is the same, using a more "manual and hashing it yourself" approach:
It produces the identical public address - tb1qlk2s76mvtpf2rqrpm97ngk3skgjdw7jtz50lw8 - confirming our code should be OK.
Now, to generate the non-standard "P2WPKH(Bech32m/v1)", the topic of this thread, simply change witness program 0 to 1:
It yields tb1plk2s76mvtpf2rqrpm97ngk3skgjdw7jtukgcxw - for which we supposedly have the private and public keys.
What's interesting is that Bitcoin Core and Electrum accept this as a legitimate receiving address. 0.001 tBTC was sent to it, and the transaction was swiftly confirmed. Interestingly, this blockchain explorer prints out the "tb1p..." address correctly but also calls the type "Unknown."
Anyways, the big question: how about spending from it? No wallet software or semi-automatic online service (such as coinb.dev for P2SH) I am aware of can create raw transactions from segwit outputs, so I went with good old Notepad++ (and a little script to flip endianness for the tx hash)
and I decided to go with this:
Because of the comments above, I had reasons to believe the output is either eternally stuck OR spendable by all, so I only used the public key serialized as the witness program (i.e., I didn't bother to sign with the private key). I ran it through Blockcypher's decode raw transaction service to verify that the serialization checks out and makes sense, which it does.
Now, onto actually broadcasting it. Uh-oh. Problemas.
Bitcoin Core console, sendrawtransaction: "bad-txns-nonstandard-inputs (code -26)"
Electrum console, broadcast(): "TxBroadcastServerReturnedError: Witness version reserved for soft-fork upgrades"
I was, however, able to broadcast it using Blockcypher's web service: "Transaction Successfully Broadcast" (the tx here, but I think it will drop out of the mempool and disappear within hours).
At this moment, Blockcypher says, "Confidence low: 29%", and it hasn't reached the mempool of my take-back Electrum wallet, so unless someone else has a brilliant idea of how to spend it, it is stuck, barring a miracle (such as a future soft fork that allows this address format).
BUT! Isn't it strange that major wallet software allows sending to this homemade address type if outputs to such are forever unspendable?
I don't think you needed to provide any witness at all (the part I separated) to spend this output. Which is what anyone-can-spend means.
That's the non-standard error I mentioned above. Mempool rejects it but if you can bypass standard tests (like if it is already in a block) it is considered valid.
You could spend some time trying to mine a block yourself if you want to have a record of it on a public blockchain.
Otherwise you could test all of this on RegTest.
Someone correct me if I'm wrong but Taproot is always active on RegTest. So just mine a 100 blocks in a second (100 because coinbase needs to mature to be spendable), send the output of your first coinbase to your bc1p address and mine another block. Then create this final tx spending that non-standard output and mine that block too.
Read some sources on how to work on RegTest like this one for more information: https://gist.github.com/System-Glitch/cb4e87bf1ae3fec9925725bb3ebe223a
Such outputs are actually spendable by anyone until there is a consensus rule added to handle these things, then it would depend on whether you can provide the correct script to spend them.
The decision to accept the address may be because of having forward-compatibility (if some day a new version would be added, the old clients are still easy to use) although I'd say they should show a big warning that to this version of software you run and at that time the destination address you entered is non-standard and your funds could be lost.
Oh, I just realized you can test beyond v1. Said and done:
One single transaction to these nonsense addresses was accepted and confirmed without a glitch...
What have we learned here? That major wallet software gives you no warnings before sending to address types that haven't yet been defined. And that is, in my opinion, suboptimal. Wallet software should give you a "please note that you are sending funds to undefined address types, and your funds will be lost" notice.
Related topics
- discussing recent market trends 2
- Crypto firms ramp up political contributions in the US 0
- What's stopping governments from banning Bitcoin? 19
- Should we share losses after the hack? 19
- IRS Criminal Investigation Unit Increasing Focus on Crypto Tax Cases 19
- Warning about Crypto Money Services in the USA 5