segregated witness – Why are P2WSH addresses larger than P2SH addresses?

Because P2SH addresses are too short to provide typically desirable levels of security security level we expect from Bitcoin, against certain attacks. On top of that, they use bech32 encoding rather than base58, which means they’re slightly longer for the same amount of data, but are case insensitive instead.

For any kind of “multi party” address (that is, an address constructed by multiple distinct and distrusting participants that each have their own key, such as multisig), a particular collision attack exists that has runtime O(2bits/2), where bits is the number of bits of entropy in the address.

P2PKH, P2WPKH, and P2SH addresses have 160-bit hashes in their addresses. For P2PKH and P2WPKH this is fine, as it only supports single-party construction. However, as P2SH supports multisig and other multi-party constructions, it means an ~280 attack is possible(*). Bitcoin typically has a 2128 security target for attacks, so this is insufficient. That doesn’t mean such a collision attack is practical – it’s just far weaker than what the rest of the system provides, and as computing performance increases it may become feasible for well-funded parties.

To address this, P2WSH introduced a multi-party-capable address that contains a 256-bit hash, so it has ~2128 collision security.

In the upcoming Taproot upgrade, a new P2TR address type is introduced. It has the same length as P2WSH addresses, and also contains ~256 bits of entropy. Due to the nature of Taproot, which merges P2PKH and P2SH style spending into one, this means even single-party addresses are 256 bits in it.

For details of the attack, see https://bitcoin.stackexchange.com/a/54847/208.

(*) There are ways to avoid the collision attack problem, even with short hashes. They significantly complicate address construction and spending however. So the choice to provide a 256-bit script hash mechanism is really just to make sure multi-party address construction isn’t needlessly complicated.

How to spend from a custom P2SH script using bitcore-lib

I could not find anywhere on the web about it. I was hopeless until I noticed that I could, without modifying the library.

First choose a similar class in Bitcore-lib.

  • multisigscripthash (<== suggested) or publickeyhash for P2SH outputs
  • multisig or publickey for bare script outputs (don’t use these, these are nonstandard)

Then copy it to a new file in your project such as this one**. Do not use typescript classes even if your project is of kind Typescript.

Then change require paths. Also require inherit from NPM. As in the boilerplates above, we need to inherit from Transaction.Input

A function such as “buildP2SHPushIn” in the example should produce the redeemscript. Remember, the last element of P2SH redeem scripts is a push of the P2SH script.

And finally use addInput instead of the higher-level function from to add inputs as shown here**


**The examples are for Bitcoin Cash, but they can be used the same way in Bitcoin. Do not copy from them, however!

p2sh – Transaction Puzzles, Awareness and Questions

I was just reading about the two following scenarios:

enter image description here

enter image description here

My understanding is that we have two transactions here that don’t follow the usual scriptSig/scriptPubKey situation, and I think transactions like these are sometimes called “contracts”. In both cases, some funds were sent to a bitcoin address, so they are valid UTXO’s floating around in the UTXO set, but instead of the usual situation where someone just needs to provide 0-knowledge-proof that they have private keys associated with that address, something else needs to be done to “unlock the funds”. (find the data, or find a collision).

I have some questions:

  1. How would people (likely power users) even be aware that these funds were out there, and available to be redeemed if they solved the puzzles. Did the creators of the transactions likely announce somewhere (via forums or internet), or could someone with full node / full blockchain build a tool that watches for these types of special PKscripts?
  2. What does it mean in the second photo when it says “Note that while transactions like this are fun, they are not secure, because they do not contain any signatures and thus any transaction attempting to spend them can be replaced with a different transaction sending the funds somewhere else.”. It seems to me if someone solved the puzzle they could immediately send the funds to themselves with the standard PKscript. What does it mean the transaction could be “replaced”?
  3. What kind of wallet or software would a power user claiming these funds be using? Certainly one couldn’t just hop on a ledger s and try to claim these funds with the solution to the puzzle. It seems you would need more freedom to provide the puzzle solution.

script – Invalid p2sh transaction accepted by the network

Why did the transaction was accepted by the network despite not working as intended

The network does not check the validity of output scripts. An output script can contain pretty much any data and the transaction will still be consensus valid. But your transaction is not actually invalid. It’s just like a bare multisig now, but since the pubkeys are hashes, it isn’t.

Why did my input did not go to the desired p2sh address “2N7e6ZAGXoepdVYu2Y8ho7fTf6oxE3j9UwS”

You set the output script to dat_redeem_script_op rather than target_script. So the output script is actually your multisig script rather than the P2SH script you intended.

It is on the testnet but if it was not can I retrieve my satoshis on this tx ?

No. Even if you had done this correctly with P2SH, it would still be unspendable. This is because your “public keys” are actually public key hashes. However you do not use any opcodes to for public key hashing. OP_CHECKMULTISIG takes public keys so it will try to interpret your public key hashes as pubkeys and fail to do so.

If you had constructed the multisig script correctly with public keys, this would be spendable as a bare multisig. It would be spendable in the same way that a P2SH multisig is spendable except you do not provide the multisig script in the input’s scriptSig.

Calculating P2SH addr/redeem script hash from pubkey

My calculation of the hash160 doesn’t seem to be correct – what are my sins?

'txinwitness': ('3045022100b36d2efceb87bd89466d10ee31e5c76c775d9df71095a39c38bd8c5d64fc78d202201dddf5579d993d013eb73b58110e3d280364ec47b1d7617c2f6d842e7d243d6f01',
'02d0a9b9f420d22e3c1de27e87c6ff2ec33da21302cf07688b53d72c07e88d0422')
  • So the pubkey is '02d0a9b9f420d22e3c1de27e87c6ff2ec33da21302cf07688b53d72c07e88d0422'

My understanding is that the redeem script should be:

  1. 2102d0a9b9f420d22e3c1de27e87c6ff2ec33da21302cf07688b53d72c07e88d0422ac (classic P2SH with OP_CHECKSIG)
    or

  2. 0002d0a9b9f420d22e3c1de27e87c6ff2ec33da21302cf07688b53d72c07e88d0422 for P2WPKH-nested-in-P2SH.

The expected hash output of the redeem script is:

032d2c15611c7b4b6941e62011e58cb5e204baa5 (see scriptPubKey above)

My hash outputs:

  1. ripe160(sha256('2102d0a9b9f420d22e3c1de27e87c6ff2ec33da21302cf07688b53d72c07e88d0422ac')) = 9e75bbd28314946ea5bcea5e217982fce698b041

  2. ripe160('0002d0a9b9f420d22e3c1de27e87c6ff2ec33da21302cf07688b53d72c07e88d0422') = 1c868bec66729c87e4cb60ec6d1c8846ad86d0ee

Saw this answer (P2sh redeem script hash), my calculations work fine with those inputs, but not with the above.

Related question: what is the role of the sigScript
0014cc38458a6e5c8c09e1d8fac905fb1024c8678d88 in the input if we have the txinwitness?

Difficulties trying to redeem a OP_CHECKTIMELOCKVERIFY P2SH script

I have created the following script which should always be spendable by Alice providing a signature under pk_a and pk_x or after a certain time_lock by Bob providing a signature under pk_b.

OP_IF
<lock_time>
OP_CHECKTIMELOCKVERIFY
OP_DROP
<pk_b>
OP_CHECKSIGVERIFY
OP_ELSE
2
<pk_a>
<pk_x>
2
OP_CHECKMULTISIGVERIFY
OP_ENDIF

Naturally, this script is wrapped in a P2SH. I have sent some funds to this pubScript on the testnet and am now trying to spend it (via the Alice case) Here is the transaction:

0100000001928b2cfd5f9c153714ee7968f5f7e252d5361723939ecdf44b729e059f86f70300000000fd0b014c940048304502210097eac0c34d505409ad65759651d7785540e612e865549f620258369b54adb182022063d0ce198eb50eddc86c6e00a0f14f5a998ddc485936b5fe4448dedbe2ae5e1b01483045022100d01a983e266c64fef31f1acaceeff64452a02b3d41d828118867fd67e6ac8276022057ef2a039e14b4a02c093528b4138050b352e71db704927f9e11ad047b4e791601004c73630312181db17521031d73e6f2e1022bfa98d2c8ba5ce9b100f27202bd4f49c6208316b1b488c16601ad6752210258843c644fc10bedc8640a12baf78106b62f01d8bd45294842fb20451377fc6b2102b56faea8db4cc9332d9d80204b81ea2d23a713dc307e350152c1eb4189d156d252af68ffffffff01b8820100000000001976a914773033d94eeaf80f3fd02f177be5b760c488aeab88ac00000000

and the scriptSig

4c940048304502210097eac0c34d505409ad65759651d7785540e612e865549f620258369b54adb182022063d0ce198eb50eddc86c6e00a0f14f5a998ddc485936b5fe4448dedbe2ae5e1b01483045022100d01a983e266c64fef31f1acaceeff64452a02b3d41d828118867fd67e6ac8276022057ef2a039e14b4a02c093528b4138050b352e71db704927f9e11ad047b4e791601004c73630312181db17521031d73e6f2e1022bfa98d2c8ba5ce9b100f27202bd4f49c6208316b1b488c16601ad6752210258843c644fc10bedc8640a12baf78106b62f01d8bd45294842fb20451377fc6b2102b56faea8db4cc9332d9d80204b81ea2d23a713dc307e350152c1eb4189d156d252af68

Here I have decoded the scriptSig

4c94 LENGTH
00 ZERO_BYTES (Because of the OP_CHECKMULTISIGVERIFY, I read this is recommended)
48 LENGTH
304502210097eac0c34d505409ad65759651d7785540e612e865549f620258369b54adb182022063d0ce198eb50eddc86c6e00a0f14f5a998ddc485936b5fe4448dedbe2ae5e1b01 SIG_A
48 LENGTH
3045022100d01a983e266c64fef31f1acaceeff64452a02b3d41d828118867fd67e6ac8276022057ef2a039e14b4a02c093528b4138050b352e71db704927f9e11ad047b4e791601 SIG_X
00 ZERO_BYTES (To make the OP_IF evaluate to false)
4c73 LENGTH
63 OP_IF
0312181d LOCK_TIME
b1 OP_CHECKTIMELOCKVERIFY
75 OP_DROP
21031d73e6f2e1022bfa98d2c8ba5ce9b100f27202bd4f49c6208316b1b488c16601 PK_B
ad OP_CHECKSIGVERIFY
67 OP_ELSE
52 2
210258843c644fc10bedc8640a12baf78106b62f01d8bd45294842fb20451377fc6b PK_A
2102b56faea8db4cc9332d9d80204b81ea2d23a713dc307e350152c1eb4189d156d2 PK_X
52 2
af OP_CHECKMULTISIGVERIFY
68 OP_ENDIF

Now when I try to send this transaction to the testnet it fails with mandatory-script-verify-flag-failed (Locktime requirement not satisfied) which confuses me, because after it hashed and compared the script I would assume that there is the 0x00 on the stack and therefore the OP_IF should be false and we go into the OP_ELSE case. However, this seems not to be the case. Could it be that the 0x00 is not at the right place?

Thanks in advance for any help!

How are p2sh address spent

So, I was looking into how P2SH transactions are working and by looking at different blog post and in particular to this answer, I have the following question.

So, let’s take the same transaction:

enter image description here

What I am not getting is how the operation are done.

  • Is the scriptSig executed first?
  • What is checked to be equal to 0b49fe...df1? How is it calculated ?

bitcoin core – How a new wallet knows balances locked in P2SH transactions?

If my old wallet created and submitted a P2SH TX to the blockchain, and I migrate to a completely different wallet, how can the new wallet detect that that UTXO belongs to the user? Since the script is hashed, it can be anything and contain unpredictable information, like other PKHs in multisig transactions

transaction verification – Full list of “special cases” during Bitcoin Script execution (p2sh, p2wsh, etc.)?

When executing a Bitcoin Script, there are some “special cases” where the interpreter performs extra verification beyond just executing scriptSig and then scriptPubKey.

For example, if the scriptPubKey has the following specific format:

OP_HASH160 <20 byte hash> OP_EQUAL

then the interpreter will additionally apply the BIP 0016 “Pay to Script Hash” (P2SH) rules.

What’s the full list of “special cases” that could be encountered during Script execution, and when is each encountered?