Bitcoin Forum
May 09, 2024, 11:57:41 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: [1] 2 »
1  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: February 11, 2024, 06:03:44 PM
Great this IDE, I was looking for such a program 5 years ago, but could not find it.

I played around with the IDE and it works beautifully. Especially, the 'show all frames' is super helpful.

My question: I want to us HTLC like contracts, and want to use Opcodes "OP_CHECKLOCKTIMEVERIFY" and "OP_CHECKSEQUENCEVERIFY", but I couldn't get these to work. I get the following error:

Code:
[Error: Error: RuntimeError: Error: missing op code OP_CHECKSEQUENCEVERIFY in trace builder]


Furthermore, It would be great to have some more examples such as to create 2 out of 3 lock script etc etc.

Thanks again for this great tool!

Hey there!

We just released support for OP_CHECKSIG and added a wallet/key manager to generate script signatures in v0.8.6, and v0.9.0 should be out later this week with support for OP_CHECKMULTISIG/OP_CHECKMULTISIGVERIFY/OP_CHECKSIGADD/OP_CHECKLOCKTIMEVERIFY/OP_CHECKSEQUENCEVERIFY.

For those interested in test driving OP_CHECKSIG, you can check out this step-by-step video tutorial and update BitIDE as shown below:

Update BitIDE Bitcoin Core Edition:
Code:
docker pull qedprotocol/bitide:latest
docker run -p 1337:1337 -it --rm qedprotocol/bitide:latest


Update BitIDE Liquid Edition:
Code:
docker pull qedprotocol/bitide-liquid:latest
docker run -p 1337:1337 -it --rm qedprotocol/bitide-liquid:latest

Appreciate the feedback and apologize for the incomplete VM implementation, we are closing in on 100% coverage, but still have a few more ops to implement.
2  Bitcoin / Development & Technical Discussion / [Tutorial] How to use OP_CHECKSIG + Taproot to spend 1-of-n puzzles on: February 11, 2024, 05:51:24 PM
I noticed that recently there have been some questions about properly constructing signatures for OP_CHECKSIG in P2TR, so decided to make a video for the curious.

This technique can be useful for creating puzzle/other challenges (pay to ZKP =D) that cannot be frontran by folks monitoring the mempool (one unique challenge per public key/tapscript path).




Scripts from the video

Setup
Code:
docker pull qedprotocol/bitide:latest
docker run -p 1337:1337 -it --rm qedprotocol/bitide:latest


user_1_lock.basm
Code:
/*
note that the dummy signature "?2742ce32de496f3d51ddd8b57cee513e982ef66adb51324343a9ec2516281093"
can be used to test OP_CHECKSIG in the editor, but must be removed in the tapscript runner witness input before unlocking the UTXO
*/

<"?2742ce32de496f3d51ddd8b57cee513e982ef66adb51324343a9ec2516281093">
<"some other secret value">

END_EXAMPLE_WITNESS

OP_HASH160
<0xda70d9c91368cc32d8bdaf0dd82f53c07272fd17>
OP_EQUALVERIFY

<0x2742ce32de496f3d51ddd8b57cee513e982ef66adb51324343a9ec2516281093> // public key 1
OP_CHECKSIG


user_2_lock.basm
Code:
// to make a dummy signature for any public key just push a string to the stack containing a question mark followed by the hex encoded public key (x only/last 32 bytes)
<"?bee908511ef6d1c5d99ca33ea0db1fbbf313a5c3c08471702595eae888ff012b">
<"super secret value">
END_EXAMPLE_WITNESS
OP_HASH160

<0x32cac4959b6bc4aad4bc65fc7b4eab19506359b2>
OP_EQUALVERIFY

<0xbee908511ef6d1c5d99ca33ea0db1fbbf313a5c3c08471702595eae888ff012b> // public key 2
OP_CHECKSIG


Would love any feedback on other tutorials anyone may want to see or how things could be made easier to bring in newer bitcoin devs (maybe a button to generate/download a standalone js project that automates the tx with bitcoinjs?).
3  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: January 30, 2024, 10:39:09 AM
Just released BitIDE 0.7.0 which includes bug fixes and support for Liquid BTC + a new docker image which includes a local Elements 23.2.1 regtest testnet.

To upgrade to the latest version of BitIDE, run:
Code:
docker pull qedprotocol/bitide:latest
docker run -p 1337:1337 -it --rm qedprotocol/bitide:latest

To start a Liquid/Elements regtest + install the Liquid compatible version of BitIDE, run:
Code:
docker pull qedprotocol/bitide-liquid:latest
docker run -p 1337:1337 -it --rm qedprotocol/bitide-liquid:latest

You can also change the vm mode in the web version of BitIDE by selecting "Liquid" in the new IDE Settings tab:



Currently supported Elements/Liquid only op codes:
  • OP_ADD64
  • OP_SUB64
  • OP_DIV64
  • OP_MUL64
  • OP_LESSTHAN64
  • OP_GREATERTHAN64
  • OP_LESSTHANOREQUAL64
  • OP_GREATERTHANOREQUAL64
  • OP_NEG64
  • OP_SCRIPTNUMTOLE64
  • OP_LE64TOSCRIPTNUM
  • OP_LE32TOLE64
  • OP_OR
  • OP_XOR
  • OP_AND
  • OP_CAT

More will be added soon!
4  Bitcoin / Development & Technical Discussion / Re: [PoC] SHA256/BLAKE3 hash multiple stack items without OP_CAT on: January 26, 2024, 12:46:01 AM
As expected, the total bytes for this opcode is quite long, but it seems to be doable.

The interesting part is that you seemed to have also implemented an OP_XOR, OP_OR, OP_AND, OP_MUL, OP_SHIFT and a bunch of other opcodes in the process of making this work.

So do you think there is a case where you can also show that these other disabled opcodes could be enabled back?

Yep, here are polyfills for OP_XOR/OP_AND/OP_OR for 31 bit unsigned script numbers:

OP_XOR:
Code:
OP_0
OP_TOALTSTACK
OP_DUP
<1073741824>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1073741824>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1073741824>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1073741824>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<1073741824>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<536870912>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<536870912>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<536870912>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<536870912>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<536870912>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<268435456>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<268435456>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<268435456>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<268435456>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<268435456>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<134217728>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<134217728>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<134217728>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<134217728>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<134217728>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<67108864>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<67108864>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<67108864>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<67108864>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<67108864>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<33554432>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<33554432>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<33554432>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<33554432>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<33554432>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<16777216>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16777216>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<16777216>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16777216>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<16777216>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<8388608>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8388608>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<8388608>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8388608>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<8388608>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<4194304>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4194304>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<4194304>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4194304>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<4194304>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<2097152>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2097152>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<2097152>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2097152>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<2097152>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<1048576>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1048576>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1048576>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1048576>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<1048576>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<524288>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<524288>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<524288>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<524288>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<524288>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<262144>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<262144>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<262144>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<262144>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<262144>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<131072>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<131072>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<131072>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<131072>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<131072>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<65536>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<65536>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<65536>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<65536>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<65536>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<32768>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32768>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<32768>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32768>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<32768>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<16384>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16384>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<16384>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16384>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<16384>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<8192>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8192>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<8192>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8192>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<8192>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<4096>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4096>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<4096>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4096>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<4096>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<2048>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2048>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<2048>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2048>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<2048>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<1024>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1024>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1024>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1024>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<1024>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<512>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<512>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<512>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<512>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<512>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<256>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<256>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<256>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<256>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<256>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<128>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<128>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<128>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<128>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<128>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<64>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<64>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<64>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<64>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<64>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<32>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<32>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
<32>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_16
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_16
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_16
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_16
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
OP_16
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_8
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_8
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_8
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_8
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
OP_8
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_4
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_4
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_4
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_4
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
OP_4
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_2
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_2
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_2
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_2
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_NUMNOTEQUAL
OP_IF
OP_2
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_NUMNOTEQUAL
OP_IF
OP_FROMALTSTACK
OP_1
OP_ADD
OP_ELSE
OP_FROMALTSTACK
OP_ENDIF

OP_AND:
Code:
OP_0
OP_TOALTSTACK
OP_DUP
<1073741824>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1073741824>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1073741824>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1073741824>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<1073741824>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<536870912>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<536870912>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<536870912>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<536870912>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<536870912>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<268435456>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<268435456>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<268435456>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<268435456>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<268435456>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<134217728>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<134217728>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<134217728>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<134217728>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<134217728>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<67108864>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<67108864>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<67108864>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<67108864>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<67108864>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<33554432>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<33554432>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<33554432>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<33554432>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<33554432>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<16777216>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16777216>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<16777216>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16777216>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<16777216>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<8388608>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8388608>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<8388608>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8388608>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<8388608>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<4194304>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4194304>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<4194304>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4194304>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<4194304>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<2097152>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2097152>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<2097152>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2097152>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<2097152>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<1048576>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1048576>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1048576>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1048576>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<1048576>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<524288>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<524288>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<524288>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<524288>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<524288>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<262144>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<262144>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<262144>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<262144>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<262144>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<131072>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<131072>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<131072>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<131072>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<131072>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<65536>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<65536>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<65536>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<65536>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<65536>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<32768>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32768>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<32768>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32768>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<32768>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<16384>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16384>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<16384>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16384>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<16384>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<8192>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8192>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<8192>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8192>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<8192>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<4096>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4096>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<4096>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4096>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<4096>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<2048>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2048>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<2048>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2048>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<2048>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<1024>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1024>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1024>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1024>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<1024>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<512>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<512>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<512>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<512>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<512>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<256>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<256>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<256>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<256>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<256>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<128>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<128>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<128>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<128>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<128>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<64>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<64>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<64>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<64>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<64>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<32>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<32>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
<32>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_16
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_16
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_16
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_16
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
OP_16
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_8
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_8
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_8
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_8
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
OP_8
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_4
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_4
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_4
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_4
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
OP_4
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_2
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_2
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_2
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_2
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLAND
OP_IF
OP_2
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_BOOLAND
OP_IF
OP_FROMALTSTACK
OP_1
OP_ADD
OP_ELSE
OP_FROMALTSTACK
OP_ENDIF

OP_OR:
Code:
OP_0
OP_TOALTSTACK
OP_DUP
<1073741824>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1073741824>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1073741824>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1073741824>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<1073741824>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<536870912>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<536870912>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<536870912>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<536870912>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<536870912>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<268435456>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<268435456>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<268435456>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<268435456>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<268435456>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<134217728>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<134217728>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<134217728>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<134217728>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<134217728>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<67108864>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<67108864>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<67108864>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<67108864>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<67108864>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<33554432>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<33554432>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<33554432>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<33554432>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<33554432>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<16777216>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16777216>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<16777216>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16777216>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<16777216>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<8388608>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8388608>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<8388608>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8388608>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<8388608>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<4194304>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4194304>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<4194304>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4194304>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<4194304>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<2097152>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2097152>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<2097152>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2097152>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<2097152>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<1048576>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1048576>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1048576>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1048576>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<1048576>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<524288>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<524288>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<524288>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<524288>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<524288>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<262144>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<262144>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<262144>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<262144>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<262144>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<131072>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<131072>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<131072>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<131072>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<131072>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<65536>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<65536>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<65536>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<65536>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<65536>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<32768>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32768>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<32768>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32768>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<32768>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<16384>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16384>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<16384>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<16384>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<16384>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<8192>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8192>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<8192>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<8192>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<8192>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<4096>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4096>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<4096>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<4096>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<4096>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<2048>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2048>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<2048>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<2048>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<2048>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<1024>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1024>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<1024>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<1024>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<1024>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<512>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<512>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<512>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<512>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<512>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<256>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<256>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<256>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<256>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<256>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<128>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<128>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<128>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<128>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<128>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<64>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<64>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<64>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<64>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<64>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
<32>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
<32>
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
<32>
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
<32>
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_16
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_16
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_16
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_16
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
OP_16
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_8
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_8
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_8
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_8
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
OP_8
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_4
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_4
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_4
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_4
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
OP_4
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_DUP
OP_2
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_2
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_DUP
OP_2
OP_LESSTHAN
OP_IF
OP_0
OP_ELSE
OP_2
OP_SUB
OP_1
OP_ENDIF
OP_ROT
OP_BOOLOR
OP_IF
OP_2
OP_FROMALTSTACK
OP_ADD
OP_TOALTSTACK
OP_ENDIF
OP_BOOLOR
OP_IF
OP_FROMALTSTACK
OP_1
OP_ADD
OP_ELSE
OP_FROMALTSTACK
OP_ENDIF

For OP_LSHIFT, you can left shift by 1 by multiplying by two:
Code:
OP_DUP
OP_ADD

So to left shift by 3, for example, you just do 3 left shifts by 1:
Code:
OP_DUP
OP_ADD

OP_DUP
OP_ADD

OP_DUP
OP_ADD

If your number is greater than or equal to 2^30, however, you need to first clear the topbit before doing the shift, which can be accomplished by the following:
Code:
// start clear top bit
<1073741824>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_IF
OP_SUB // subtract 2^30
OP_ELSE
OP_DROP // ignore 2^30 and leave the number unmodified
OP_ENDIF
// end clear top bit

OP_DUP
OP_ADD
5  Bitcoin / Development & Technical Discussion / [PoC] SHA256/BLAKE3 hash multiple stack items without OP_CAT on: January 23, 2024, 07:13:19 PM
In support of the BIP to enable OP_CAT, we challenged ourselves to implement hashes that could use multiple computed stack items as a preimage without OP_CAT.

In the end, we implemented both SHA256 and BLAKE3:



You can view the source + test out both hashes here:
https://bitide.qedprotocol.com/?importProject=https%3A%2F%2Fbtcscripts.qed.run%2Fexamples%2Fhash_demo.json&openFile=scripts%2Fblake3_demo_1.js

See the video above for usage. For both scripts, the inputs are represented as U32s grouped as <top bit> <lower 31 bits>.
For example, if you want to compute the blake3 hash of the data 'c85b298792a5b8d0082c2ed839c3830bcd4a6f18b827f6ce5ecf8838b1917e6a78ac10ef3e97660 c3529ca929dbbb207f6cb9279c49a4df29f67201776962c7c', you first split it the input data into U32s and get the following items on the stack:
Code:
OP_1
<120150984>
OP_1
<1354278290>
OP_1
<1479420936>
OP_0
<193184569>
OP_0
<409946829>
OP_1
<1324754872>
OP_0
<948490078>
OP_0
<1786679729>
OP_1
<1863363704>
OP_0
<208049982>
OP_1
<315238709>
OP_0
<129153949>
OP_0
<2039663606>
OP_1
<1917688516>
OP_0
<387999647>
OP_0
<2083296886>

To do this automatically, just use:
Code:
var cfg = sch.getLimbsConfig([1, 31]); // define a U32 integer stack group which has two limbs: <top bit> <lower 31 bits>  
var testInputs = sch.hexToU32Array('c85b298792a5b8d0082c2ed839c3830bcd4a6f18b827f6ce5ecf8838b1917e6a78ac10ef3e97660c3529ca929dbbb207f6cb9279c49a4df29f67201776962c7c', false);
testInputs.forEach(x => {
  b.constants(cfg.splitParts(x));
});

b.OP_HASH_U32_BLAKE3_256(testInputs.length); // 16 = number of uint32s in preimage

The result of OP_HASH_U32_BLAKE3_256 is the following stack:
Code:
OP_1
<674114300>
OP_1
<1860412368>
OP_1
<642631595>
OP_0
<1768883315>
OP_0
<1529469502>
OP_1
<1658424509>
OP_0
<1384360961>
OP_0
<918971398>

Which is the U32 representation of fc2a2ea8d0a3e3eeabc74da673046f693eda295bbd8cd9e201ac83520664c636.

And in fact blake3("c85b298792a5b8d0082c2ed839c3830bcd4a6f18b827f6ce5ecf8838b1917e6a78ac10ef3e97660 c3529ca929dbbb207f6cb9279c49a4df29f67201776962c7c") = fc2a2ea8d0a3e3eeabc74da673046f693eda295bbd8cd9e201ac83520664c636!


The scripts are chonkers but do work on the latest version of Bitcoin Core (if you want to test it on a real node, docker pull the latest version of BitIDE and replace bitide.qedprotocol.com in the link above with localhost:1337).

If you like these kind of impossible ports, show some love by supporting the long over due proposals to re-enable useful features on Bitcoin and make these scripts obsolete!
6  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: January 22, 2024, 05:10:02 PM
Quote
Password Recovery
When it comes to any puzzles, there is for example this puzzle: https://bitcointalk.org/index.php?topic=5469657.0

And then, people may think, that SHA-1 was used, to create them, and make TapScripts, unspendable by key:
Code:
1) OP_SHA1 <3045ae6fc8422f64ed579528d38120eae12196d5> OP_EQUAL
2) OP_SHA1 <bd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5> OP_EQUAL
3) OP_SHA1 <c49d360886e704936a6678e1139d26b7819f7e90> OP_EQUAL
4) OP_SHA1 <a335926aa319a27a1d00896a6773a4827acdac73> OP_EQUAL
5) OP_SHA1 <d09e8800291cb85396cc6717393284aaa0da64ba> OP_EQUAL
Imagine, how the person solving that would feel, if it would turn out, that those coins are unspendable, because of the wrong endianness.

So, instead of using unspendable key-path, it can be just "multisig behind all interested parties". It is possible to start with a single key, just like the creator of the famous puzzle, where keys #120 and #125 are sweeped, but nobody knows, if those keys are really broken, or if the author just moved those funds.

And if you have any kind of reward, then by using multisig, you can start with a single key, and then move those coins by key, to combine the same rewards into bigger coins. Which means, if Alice and Bob sent funds to some different keys, with the same attached TapScript, then they could move them to a multisig, and a TapScript. And that move may be more attractive to the puzzle solver, because having single coin is cheaper to move, than having thousands of small deposits (not to mention address reuse, which is a bad practice, and should be avoided).

Quote
Recursive Covenants + Trustless peg-in/peg-out for layer 2s
If you have more than one person, behind some coin, then it may be possible, that all of them will be online. In that case, there is no reason to use expensive TapScript path, and reveal the whole covenant on-chain. The group, which wants to be detached, can just propose a withdrawal transaction, and collect all signatures from all parties, and then it will look the same, as if everything would be owned by a single user.

To sum up: I cannot see a reason, why not to use multisig. If you are alone, then it gives you a chance to experiment with TapScript, without trapping your coins in unspendable paths. If there are at least two people (for example: Alice tells Bob that she will pay for Password Recovery), then, 2-of-2 multisig is applicable. If there are more than two people, then N-of-N multisig is applicable in a general case.

And then, for example if Bob cannot provide the password, Alice can say: "well, you tried cracking it for 10 years, and you failed, it is now useless information for me, so I sweep my funds, you don't have to work longer on that". And if Bob agrees, then it is at least possible for Alice to get her funds back. But if it is behind TapScript-only, then it may be unspendable forever. Also, there are obvious mistakes possible, for example wrong endianness, and then, key-path can be used to fix those cases, instead of losing coins forever.

So, instead of using unspendable key-path, it can be just "multisig behind all interested parties".


Totally agree!
I think the rule of thumb is: use a multisig if you know the interested parties ahead of time, otherwise use NUMS.
For the example of the puzzle/hash cracking, one may have to spend a significant portion of time/compute to crack the hash, so if they original challenge holder can just transfer away the funds at will, it may be a disincentive to commit resources to the problem.


In the case of the layer 2, I would push back, however. To be secure, the multisig should be controlled by the owners of layer 2 wrapped BTC so they can reclaim the BTC on Layer 1 back whenever they like. This is impossible if the layer 2 BTC is transferrable.

Consider the following scenario:
3 bitcoin holders each bridge 10 BTC to layer 2, locking a total of 30 BTC in a multisig (lets call the set of keys in the multisig K), minting a total 30 l2BTC on the layer 2. Since the K should proportionally represent owners of l2BTC, they should each control a key in the multisig. The 3 original users then purchase NFTs on the L2 with their l2BTC on an L2-DEX, spending all 30 BTC. Now the original set K does not represent the token holders and is instead controlled by a group which owns no l2BTC.
7  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: January 21, 2024, 10:37:29 PM
Quote
For situations where a multisig is appropriate
Could you give any example, where it is not?
1. Password Recovery
Let's say I want to crack a sha256 password hash (your own personal password and not someone else's, of course).
If know the hash is 5bf01f36fa15d5ccf2dea7a53c777426d559a9a8d1384e58bc8d3dc423cd2f12, I could offer a reward in bitcoin for anyone who can provide the preimage to the password with the following script:
Code:
OP_SHA256
<5bf01f36fa15d5ccf2dea7a53c777426d559a9a8d1384e58bc8d3dc423cd2f12>
OP_EQUAL

You can try it out if you like on testnet (the password is supersecretpassword)

2. Recursive Covenants + Trustless peg-in/peg-out for layer 2s
Imagine we have a layer 2 which posts a withdrawals tree of the chain to bitcoin, and we want to allow users to trustlessly withdraw their bitcoins from layer 2.
When block producers submit a block they spend and existing block script which has two outputs:
1. an output to a withdrawal UTXO script which can be spent by the users who withdrew funds from layer 2 back to layer 1 in the most recent block (includes a withdrawal tree merkle root)
2. a new block UTXO for the next block (recurse)

The withdrawal script can only be spent by spending a recursive covenant which includes a delta merkle proof proving the validity of the spend of one of the withdrawals and an additional recursive covenant that creates a new withdrawal script with the updated withdrawal tree root (the withdrawal made is set to the null value so you can't spend a withdrawal more than once).

The locked BTC in the layer 2 block UTXO can only be sent to a script which publishes a new block (1 output) or a withdrawal script which allows users to withdraw a portion of the BTC and sends the rest to a new script with the updated merkle root (2 outputs).

In our withdrawal script, we verify a merkle proof which links the previously submitted state root/withdrawals tree root with a spender:
Code:
<0x8fe1e5f7bc9333914565f011a63942d988c88b00547b35af859635b00cbbc64c> // old root, must be this value as enforced by the block UTXO covenant
<0x7163998f26fec2e57db7413d706d30e7b9f14e13b416217160221ff05690fb65> // new root after spending the withdrawal and removing it from the withdrawals tree

// merkle proof siblings
<0x2f0935c2963ead8b3be0ee5d4d4dcb3af23646c6bbfc330e41e90a47ee8cf7f7> // sibling at level 14
<0xeac71276dd976b550cace2fb1097ad5d296193fea0359202ca4899b398ab2436> // sibling at level 13
<0x2c7011733c31c9c58e0d5cbe40be77c714a4b77b281ffd72155276af21452e24> // sibling at level 12
<0x5cc411ccc9b0ce4704798316824afffbbeb724d7fb06701bf7c57f1fa122102f> // sibling at level 11
<0x485a020e9ce6f948b88528bc38ac34838283bd4a001db1f99b84cbe87ebe3e99> // sibling at level 10
<0x885fb789bdd39eee523ade57bedba8fa308b9014c910d6db04b779732139c5b7> // sibling at level 9
<0x8b4578b4daaa30f78eaa2f5537142c9fe277a87fc4e8c5dd872ab95524d34c48> // sibling at level 8
<0xdcd5818eaddf2de1a4fd8792664403a1b1e24779baf3bfac02f169ae63b46d95> // sibling at level 7
<0x7900bfb52e43f1c0b93a87e4b42bc652a1de0c6e72becc37a4f1d26a3eac42a6> // sibling at level 6
<0x2013541c218b99def8301bb9b283f3696605e39a267e757e61692e47623bebdb> // sibling at level 5
<0x9e5a86f32a7231309e3f4bc44473a181b3482352acc8e332d10b493a8acca77c> // sibling at level 4
<0xca67e1b7055afe377bd9fb285335a3685472b1c08f94cf133481320b0fe63653> // sibling at level 3
<0xf464a8d91ca7029a4b88483b7d778403c310c2eaabf46a905874343f975b49a0> // sibling at level 2
<0xaa6ef54b7988700bbcffcaf327be3ade37a68573e9fd6a498a00600059644a28> //sibling at leaf level

<999> // index of the withdrawal leaf we are spending with in the withdrawals tree

// recursive covenant inputs...
<0x3905000000000000> // 8 byte spend amount (1337)
<0xb4a2ef4141dfdedc3b548222b11fcf90bf81782ed6bf998b6552ab08978b2ce6> // spender
OP_2DUP
OP_CAT
OP_SHA256 // compute the withdrawal hash -> 0xeac7f4e4689862aa7baf72c1673a48a66561ab222eb6a6d8af38c32393265d90
OP_TOALTSTACK // move the withdrawal hash to the alt stack for later
// the rest of the recursive covenant code


// now only the merkle roots + siblings + index remains in the stack
OP_FROMALTSTACK // old leaf value computed earlier (withdrawal hash)
<0x0000000000000000000000000000000000000000000000000000000000000000>// new value
OP_ROT // move the index to the top of the stack



// start decompose the index into bits
// we decompose the number into bits which are stored on the alt stack
<8192>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
<4096>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
<2048>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
<1024>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
<512>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
<256>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
<128>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
<64>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
<32>
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
OP_16
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
OP_8
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
OP_4
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
OP_2
OP_2DUP
OP_GREATERTHANOREQUAL
OP_DUP
OP_TOALTSTACK
OP_DUP
OP_TOALTSTACK
OP_IF
OP_SUB
OP_ELSE
OP_DROP
OP_ENDIF
OP_DUP
OP_TOALTSTACK
OP_TOALTSTACK

// end decompose the index into bits

// now the lowest bit of the index is on the alt stack

// compute old and new merkle roots
OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


OP_ROT
OP_ROT
OP_OVER
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256 // compute old merkle path at level
OP_ROT
OP_ROT
OP_FROMALTSTACK
OP_ROLL
OP_CAT
OP_SHA256  // compute new merkle path at level


// end compute old and new merkle roots

Now we just check the old and new roots from the inputs to make sure the match the computed ones (ie. proof that the withdrawal exists in the tree, and that the merkle tree with merkle root new root has all the same leaves as old tree, except for the leaf at the specified index that has just been spent (and has been nulled out):
Code:
/*

now the stack is as follows:

<old merkle root> // guarenteed correct via the covenant
<new merkle root> // attested by the spender

<computed old merkle root> // computed from the index/siblings/withdrawal hash value
<computed new merkle root> // computed from the index/siblings/nulled out value

*/

OP_ROT
OP_EQUALVERIFY // check that the attested new merkle root is a copy of the old tree with the spent leaf nulled out

8  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: January 21, 2024, 01:41:03 PM
Quote
currently we just use a "Nothing Up My Sleeve" point which no one knows the private key of
You should not use that, unless it is strictly necessary. It is better to pick a public key, that is just N-of-N multisig of everyone involved. In this way, there is always a chance to spend by key (and make it cheaper) if everyone agrees.

In general, Taproot addresses should be "always spendable by key, and sometimes spendable by key, and by TapScript".


For situations where a multisig is appropriate Wink
9  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: January 19, 2024, 01:51:33 AM
I see this is not mobile friendly 😂 , but this is great to see people are actually developing something useful rather than trying to spam the network for more money.

Just wanted to tell you, fantastic work, amazing and thank you. Hope you could add some ECC related functions to have things in one place. 🤭

Btw, you founded QED? Any web address for it? Oh I saw it on your profile.

No plans for a mobile version (don't code on your phone haha), but more features on the way, namely:
1. Export standalone bitcoinjs-lib code in the TapScript runner (so you can see how to perform all the steps programmatically as well)
2. Support for OP_CHECKSIG/other sig related stuff + basic wallet/key manager
3. Option to pay with keypath rather than script in the TapScript runner (currently we just use a "Nothing Up My Sleeve" point which no one knows the private key of)
4. Support for Liquid
10  Bitcoin / Development & Technical Discussion / Re: I'm looking for an example of code or a tutorial that implements tapscript on: January 18, 2024, 04:31:29 PM
I'm looking to create a Bitcoin tapscript transaction, but I can't find an example or a tutorial that demonstrates how to do this. When I was building on Ethereum it was easy because there's a lot of tutorials about how to create a custom ERC-20 or ERC-721. I understand that comparing Ethereum to Bitcoin is like comparing apples to oranges. Bitcoin is designed to be a store of value while Ethereum is a platform designed to run code.

Still though... I want to practice writing tapscript transactions on Bitcoin. Can someone provide a code example or a tutorial about how to actually create a tapscript transaction?

Just to be clear, when I say a tapscript transaction, I mean constructing a UTXO that contains a script spending path. That means a taproot transaction that contains a merkle root with a taptree where spending from this UTXO means solving a logic condition in one of the tapleafs.

I'm eager to delve into Bitcoin tapscript transactions, but I'm struggling to find an example or tutorial guiding me through the process. When working with Ethereum, crafting custom ERC-20 or ERC-721 tokens was straightforward due to the abundance of tutorials available. I recognize the inherent differences between Bitcoin and Ethereum—Bitcoin as a store of value and Ethereum as a code-running platform.

Nevertheless, my curiosity persists, and I'm determined to practice tapscript transactions on Bitcoin. Could someone kindly share a code example or direct me to a tutorial illustrating the creation of a tapscript transaction? To clarify, I'm specifically interested in constructing a UTXO with a script spending path—a taproot transaction featuring a merkle root with a taptree. The goal is to enable spending from this UTXO by satisfying a logic condition within one of the tapleafs.
https://www.aoxapps.com/mobile-app-development-company


Check out https://www.youtube.com/watch?v=ixHVnvq4S7g, this goes step by step through the full flow from 0 to p2tr via script spending path (also helps you setup a local testnet + block explorer).

11  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: January 17, 2024, 04:06:33 PM
Is BitIDE open source?

Cleaning up the source and adding some tests, will be open sourced this week =)
 
Will appreciate the source.  
But is the real testnet version of this available?

Yep! BitIDE works with regtest, testnet and mainnet. To fund and unlock a script UTXO on the official Bitcoin testnet, just chose "Testnet" in the tapscript executor window and follow the steps below:


Note that Fund via RPC only works with regtest (you can't just mint testnet tBTC at will), so for step two you need to either faucet the address with a testnet faucet or send from your testnet wallet before clicking "Check for UTXOs"
12  Bitcoin / Development & Technical Discussion / Re: L2O - solving ordinal spam with ordinals on: January 16, 2024, 01:02:54 PM
Great work.

Though I'm not sure how you'll convince 3rd parties to use this.

Maybe if you go on X/Twitter you might be able to convince some Ordinals folks to use your own technology.


Haha yep, in the works! Also partnering with some larger zk projects to help promote the standard. To help the transition, will also open source a zk rollup that supports transfers/trading/swaps/pay to zkp.
13  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: January 16, 2024, 12:59:25 PM
Is BitIDE open source?

Cleaning up the source and adding some tests, will be open sourced this week =)
14  Bitcoin / Development & Technical Discussion / L2O - solving ordinal spam with ordinals on: January 14, 2024, 05:14:47 AM
Hey all, I have been thinking a lot about the issue of ordinal spam and growing demand for extending the security of bitcoin to other use cases. It seems the community is split on support for ordinals, and the only way forward is to find a solution which gets rid of the spam while letting people still play with tokens on bitcoin.

To resolve this, I propose L2Ordinals, a zero knowledge proof protocol which rolls up all the 1000s of ordinal transactions flooding the mempool into a single 300 byte proof which is verified by an indexer:


In addition to cutting down on ordinal spam, this solution still provides the same security that standard ordinal based tokens have, while also extending the security model to arbitrary computation (anything you can write in a zk circuit, ex. zkVM):
  • All token transfers are PROVED by the ZKP and VERIFIED by the indexer (just as BRC-20 tokens are verified by the indexer)
  • Sequenced by Bitcoin
  • To compute the current layer 2 network state, all you have to do is startup a bitcoin full node + indexer and playback all the blocks from genesis
  • State transitions are verified by the indexer to ensure proper sequencing (ex. enforce end state root of last proof is the start state of next proof)

There are some implementation details left out that you can checkout at:
https://l2o.io/docs/l2o-a/operations/block

If anyone else wants to help work on the indexer/has any ideas, feel free to shoot me a DM on twitter @cmpeq.
15  Other / Bitcoin Wiki / Re: Request edit privileges here on: January 09, 2024, 07:56:41 AM
Hey there!

My username is https://en.bitcoin.it/wiki/User:Carter

Looking forward to contributing!
16  Bitcoin / Development & Technical Discussion / Re: [Release] BitIDE - TapScript IDE with Macros, Scripting, Custom Opcodes & More on: January 09, 2024, 07:50:28 AM
Quote
You can make the outputs 0.
Not only that. You can also hide your scripts behind a TapScript, and then spend by key, if your TapScript will turn out to be unspendable or expensive.

Great idea, we will also added support for key paths in the next version!

In the meantime, for development purposes it shouldn't be an issue if you are using the docker image with bundled regtest + explorer and use Fund via RPC (regtest btc is free Wink), as clicking the button first runs generatetoaddress to mine 50 btc to the default wallet, and then transfers 1 BTC to the P2TR address (see screenshot below).

17  Bitcoin / Development & Technical Discussion / Re: Looking for bitcoin scripting / Transaction automation resources. on: January 07, 2024, 09:04:24 AM
Check out BitIDE, it has a full IDE, visual debugger, and integration with local testnet:
https://bitcointalk.org/index.php?topic=5478422.0


If you want to learn more about bitcoin scripting, this video has a full tutorial (0-to-1):
https://www.youtube.com/watch?v=Mp3ldiz2KQ8

For some more complex operations/testnet integrations can checkout this demonstration of how to generate a pay to tap root script-path transaction:
https://www.youtube.com/watch?v=ixHVnvq4S7g


18  Bitcoin / Development & Technical Discussion / Re: BitIDE - TapScript IDE with Local Testnet, Explorer and Custom Op Codes (P2TR) on: January 06, 2024, 10:47:32 AM
Hey all, added docker image for offline development, integration with local testnet (regtest), a block explorer and and a GUI that walks you through how to perform a pay to tapscript (script path) transaction (I saw a lot of people have been asking about this on the forum, so hope this helps).

Grab the new version and start a new local testnet with a one liner:
Code:
docker run -p 1337:1337 -it --rm qedprotocol/bitide:latest

Also shot a quick tutorial video for anyone that wants to get started with TapScript:


Edit:
If you want to use bitcoin-cli with your testnet, just change the docker command to:
Code:
docker run -p 1337:1337 -p 18443:18443 -it --rm qedprotocol/bitide:latest

19  Bitcoin / Development & Technical Discussion / Re: NFTs in the Bitcoin blockchain - Ordinal Theory on: December 20, 2023, 02:07:16 AM
But they will always claim that their network has higher transaction throughput and therefore "scales", but how do we define "scale". Higher throughput but sacrifices decentralization? That's not scaling. It actually scales the network down, reducing node count, and therefore centralizing the network.

Exactly. With one caveat, if we can verify zero knowledge proofs and merkle proofs in bitcoin script, can process millions of transactions in a single uxto without sacrificing and scale, no trade offs, just proof of math (constant size proof -> proves arbitrary number of transactions -> user proves balance via merkle proof -> unlock uxto).
20  Bitcoin / Development & Technical Discussion / Re: [Release] BitIDE - TapScript IDE with Macros, Scripting, Custom Opcodes & More on: December 19, 2023, 12:47:28 PM
It looks good, but there doesn't seem to be a desktop version. If this is using a JS framework, you know, like React or Angular or Vue or like that, you can just slap Electron on it and you'll be good to go on all platforms.

Maybe you can add a feature where a the compiled script can run on testnet if you deposit a small amount of BTC for the transaction fee. You can make the outputs 0.

Great idea! will definitely add an offline electron version in the next release. Also right now we are working on a 1-liner that spins up a clean regtest network in a docker container with funded wallets and automining so you don't have to mess around with faucets, but testnet integration also makes a lot of sense.
Pages: [1] 2 »
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!