You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When currently viewing a bitcoin transaction details on mempool.space, the script stack and corresponding witness is shown in raw OP codes and stack values (pubkeys, numbers for timelocks). It would be a great feature to visualize this in more human readable form, providing a better UX and opportunity to better learn how Bitcoin Script works. This is currently done for simple multisigs of N of M (2 of 3, 3 of 5 etc). The feature request is to provide greater context on how this can be achieved for more robust script templates. If mempool had the ability to parse miniscript script stacks, a generalizeable tool set could be built to visualize dynamic scripts.
Problem to be solved
Bitcoin Script isn't intuitive to most users of the Bitcoin Protocol, by providing visual aids to identify the rules in which a UTXO is encumbered by, would allow for an opportunity to demistify how bitcoin works for users of mempool.space, and the network.
Proposed solution
Similar to mempool googles, being able to have an option when clicking on the details to see either how the stack is visualized today, or a "script goggles" option to see how the bitcoin is secured with better abstracted diagrams.
Additional info
For reference, here is a testnet transaction I did yesterday:
So, to generate the specific UTXO: tb1qsjafrqfwrnkzay8x97zzpvju5g8ns2fqcarqwjv2nnnpxdz79xjsfnmkll you'd take the 0/0 index for each of these tpubs, as this was the first recieve address for the wallet, so swapping the tpubs for public keys gets you:
This is then compiled into bitcoin script, and shown as the P2WSH op code stack shown above. There are some transformations, for example, if an output descriptor fragment has pkh, it takes the hash of the public key, for example:
02457dd2c9741d718f3fe2e8fb2e9c844f710683cde6441be442ac5aa87ef6bb15 when ran through OP_HASH16 becomes a10a049eb8a6183dfab65de6342cf004d87a5644 - which is the actual element on the script stack.
Additionally, the after() fragments are absolute timelocks, which are seen with the OP_CLTV elements of the P2WSH:
after(1672531200) is an epoch timestamp, which is January 1st, 2023 at Midnight GMT. On the stack, this is visualized as:
OP_PUSHBYTES_4 00cdb063
OP_CLTV
00cdb063 in little endian represents 63B0CD00 in HEX, which converts to 1672531200 in decimal form. In Bitcoin Script, when a number is larger than 500,000,000, timelocks are interpreted as epoch timestamps. If lower than 500,000,000, they are interpreted as block height based timelocks, as CLTV uses the nLockTime field in a transaction. This transaction complies with CLTV, since the locktime for the transaction is: 1,672,531,200.
A low hanging fruit would be providing a calendar date/time reference for a CLTV/CSV timelock upon hovering over that block of the script stack.
As for the actual rules for how this script is being secured, one could evaluate the output descriptor:
Note: Miniscript Policy, unlike a miniscript output descriptor, can not be derived from Bitcoin Script. Going from a miniscript policy to script/output descriptors is a one way function. This is provided as a reference for a cleaner way to diagram how this bitcoin is secured.
If you take the diagram above, and swap in the mapping for Keys A-J, you can see how this is executed on the script stack in my testnet transaction:
There are other elements to consider as well for generlaized miniscript, specifically older() fragments, which use OP_CSV for relative timelocks, block height specific timelocks, hashlocks, and thresholds which combine more than just keys, for example a 3 of 4 multisig with 3 keys and ` timelocks (in practice, this is a 3 of 3 multisig, which becomes a 2 of 3 multisig after a timelock is satisfied).
There are added visualizations to be considered as well for taproot addresses and traversing to a given tapleaf, but any logic built for P2WSH/P2SH scripts could be extended to taproot.
I'd be happy to brainstorm other ways of visualizing this data as well, I think having a site like mempool provide neutral visualization of how scripts are secured will bring about better user confidence and understanding of how bitcoin is being secured!
--
The text was updated successfully, but these errors were encountered:
Since y'all are thinking about this, here is a somewhat related PR in bitcoin-core around making scripts more readable: bitcoin/bitcoin#28824
Dropping it here for context / in case its useful. Maybe some of the conventions discussed on the linked PR might also be useful here.
Either way, excited to see some interest in this kinda stuff! Better visualizers for Bitcoin script is a huge win; for usability and educational purposes.
Description
When currently viewing a bitcoin transaction details on mempool.space, the script stack and corresponding witness is shown in raw OP codes and stack values (pubkeys, numbers for timelocks). It would be a great feature to visualize this in more human readable form, providing a better UX and opportunity to better learn how Bitcoin Script works. This is currently done for simple multisigs of N of M (2 of 3, 3 of 5 etc). The feature request is to provide greater context on how this can be achieved for more robust script templates. If mempool had the ability to parse miniscript script stacks, a generalizeable tool set could be built to visualize dynamic scripts.
Problem to be solved
Bitcoin Script isn't intuitive to most users of the Bitcoin Protocol, by providing visual aids to identify the rules in which a UTXO is encumbered by, would allow for an opportunity to demistify how bitcoin works for users of mempool.space, and the network.
Proposed solution
Similar to mempool googles, being able to have an option when clicking on the details to see either how the stack is visualized today, or a "script goggles" option to see how the bitcoin is secured with better abstracted diagrams.
Additional info
For reference, here is a testnet transaction I did yesterday:
https://mempool.space/testnet/tx/7cafffe638fe32a74f3c02e89084fb89226834338f59a3e4e0a9610844bef127
The P2WSH script is as follows:
What does this mean in plain english though? I generated this script using miniscript, so the script stack can actually be abstracted to miniscript:
wsh(andor(multi(2,[30c7c72b/48'/1'/0'/2']tpubDEXQJ7zfCxN3Fm1VUoZZ5EBwb6yaT813Dt2EPcUgHkcdp5ETtY7rZbTimiVwFpBi4xcpdJ4W9mxZGkbAgfYqdRGrNtHULYTcyTLLQFR7JpD/*,[62fa764a/48'/1'/0'/2']tpubDFRjazvAAGtQjKGTTSch6FKnsXYnDNibnd5syZ3oXqSraCwbW9mhtm7CiGKQ7zZ7cpNCSXVyjYZwSb8YskRzVqoNSVX1jXJ9efRpJFPY4sf/*,[277dcebc/48'/1'/0'/2']tpubDEmEWF2iixNg9rSKtBRL6qCi9M1DpnAuwsmDYiyEi5TMnA2UfuJ2oTnpvrEvotbYtgNupL72rV4HjsM7o4EyKgqid47RM7DiYj3FgCm4HKa/*),andor(pk([562f7833/48'/1'/0'/2']tpubDFULx2EDJgEQtXLEd6zKizLP1LfMUMkY31zME6tvFReS3y3hvsZLeTDwZiZ8YxqNQWaLnHe4fdhb5EAjrrhfZD8cFRa69wTnMYutJxw3WuF/*),after(1672531200),thresh(2,pkh([860a2400/48'/1'/0'/2']tpubDEa2Qdj8t9RkyjGqixGZuvHjVYKhti2uD6YJtiUmbhYYWBvJBuT7JYWPF3fPX2inGjeTv3rVCooK1L2vLdK4Rv3psCbbGHEyDiiLaMvzvJW/*),a:pkh([6355bbe3/48'/1'/0'/2']tpubDEMVcMk6t7b3nfpLdngdudhaEnQSD4inorHmCuj1RdgJaAuRuJGe99Ssq6BPeSWZrZYGGo7qcRa1m48LGuYD9dK7B4chUTk3tANseHd5tEY/*),a:pkh([72c7e86b/48'/1'/0'/2']tpubDExTVsbh95Ps92deZWmSbazDNthPEq6osvi6r61SqRMtMxp2vSJ6JbH2TkhFkDq5R4dnbftRDeUVMfV8NTVx1daE8Z9kxADY3NoEQurVwGZ/*))),and_v(v:thresh(2,pkh([9463f6aa/48'/1'/0'/2']tpubDEtVwVxs3LCbhgrhL72LDDjvRuaJSzXiMU9B6MXy4B2aRvb9GFJ5emNgEt83EZ65yYrCqxdTocC6g2iCoLcEPQqxeVJMmQmFQqGsD6UyJ3w/*),a:pkh([f90fc832/48'/1'/0'/2']tpubDFQ3CMPN1ETYsfWMNe5nfbUMRN6Ckph2BS3wJZGiGMoNh2Nz2CG33zrYEsJ6WYG4WKpdgDNagnsDQpwVhz9B9aq1K8Vti6GRH3UAAoeqFx3/*),a:pkh([d28d56f7/48'/1'/0'/2']tpubDE63xn1YqAidzwguM5gu3LPVXaWS9xfE1Q7UwHyPYRKaiVyByoDpa63C18cM7Q5mcsTMKKGxhHDGaZTXHR3b3yXxik3hTczj5rhg6DugpZ2/*)),after(1675209600))))#f0h8g4ev
So, to generate the specific UTXO:
tb1qsjafrqfwrnkzay8x97zzpvju5g8ns2fqcarqwjv2nnnpxdz79xjsfnmkll
you'd take the 0/0 index for each of these tpubs, as this was the first recieve address for the wallet, so swapping the tpubs for public keys gets you:wsh(andor(multi(2,02d2c579a78092e946d2845b3eb30b0285d6f7f5552ca6ed0c784a77bac51e1a69,03ebfd5122214b100e9da78c22f5fb50c76d29ba832eff0051206b6aa697fd2c95,03d450e676a34fa4539e3a3cd9b2ee7e7a7c323a9ca519c7a6e62f519d60e52eea),andor(pk(03fffee31d8aa067721cc8fd9754a26ab67d42724923a8dd0f5ea71e4eb9377e64),after(1672531200),thresh(2,pkh(035b7f5811a7863db0ef70eada285ffc1098bdc612edd7413d0cf5ac38b5f42b59),a:pkh(02457dd2c9741d718f3fe2e8fb2e9c844f710683cde6441be442ac5aa87ef6bb15),a:pkh(024bb627f22745740e74482344b000d66d7d06a405a9309df4610e124fa0fcdff2))),and_v(v:thresh(2,pkh(023ab4f3af852c13d274a9a3b4eb53227a336b335f883459ee80b5e4cd59b021a1),a:pkh(034cd1d366c0d0077971fc01e331b0a294d8f4bb9097ddd1f5d99980a5988913e4),a:pkh(03efc52a221512f7b6618e5c3f11a8619ddfe7ca56ef411be1baf28b05766db322)),after(1675209600))))
This is then compiled into bitcoin script, and shown as the P2WSH op code stack shown above. There are some transformations, for example, if an output descriptor fragment has pkh, it takes the hash of the public key, for example:
02457dd2c9741d718f3fe2e8fb2e9c844f710683cde6441be442ac5aa87ef6bb15
when ran through OP_HASH16 becomesa10a049eb8a6183dfab65de6342cf004d87a5644
- which is the actual element on the script stack.Additionally, the
after()
fragments are absolute timelocks, which are seen with the OP_CLTV elements of the P2WSH:after(1672531200)
is an epoch timestamp, which is January 1st, 2023 at Midnight GMT. On the stack, this is visualized as:00cdb063
in little endian represents63B0CD00
in HEX, which converts to1672531200
in decimal form. In Bitcoin Script, when a number is larger than 500,000,000, timelocks are interpreted as epoch timestamps. If lower than 500,000,000, they are interpreted as block height based timelocks, as CLTV uses thenLockTime
field in a transaction. This transaction complies with CLTV, since the locktime for the transaction is:1,672,531,200
.A low hanging fruit would be providing a calendar date/time reference for a CLTV/CSV timelock upon hovering over that block of the script stack.
As for the actual rules for how this script is being secured, one could evaluate the output descriptor:
Ok, to actually make this plain english, this is a WSH address that can be spent several ways:
Option 1:
2 of 3 of :
AND
either:
03fffee31d8aa067721cc8fd9754a26ab67d42724923a8dd0f5ea71e4eb9377e64
ANDafter(1672531200)
(january 1st 2023 at midnight GMT)OR
2 of 3:
Option 2:
2 of 3:
AND
after(1675209600)
(February 1st, 2023 at Midnight GMT)Using the BDK Playground, this can be visualized as:
This results in the miniscript policy of:
or(99@and(thresh(2,pk(A),pk(B),pk(C)),or(thresh(2,pk(D),pk(E),pk(F)),99@and(pk(G),after(1672531200)))),and(thresh(2,pk(H),pk(I),pk(J)),after(1675209600)))
Note: Miniscript Policy, unlike a miniscript output descriptor, can not be derived from Bitcoin Script. Going from a miniscript policy to script/output descriptors is a one way function. This is provided as a reference for a cleaner way to diagram how this bitcoin is secured.
If you take the diagram above, and swap in the mapping for Keys A-J, you can see how this is executed on the script stack in my testnet transaction:
There are other elements to consider as well for generlaized miniscript, specifically
older()
fragments, which use OP_CSV for relative timelocks, block height specific timelocks, hashlocks, and thresholds which combine more than just keys, for example a 3 of 4 multisig with 3 keys and ` timelocks (in practice, this is a 3 of 3 multisig, which becomes a 2 of 3 multisig after a timelock is satisfied).There are added visualizations to be considered as well for taproot addresses and traversing to a given tapleaf, but any logic built for P2WSH/P2SH scripts could be extended to taproot.
I'd be happy to brainstorm other ways of visualizing this data as well, I think having a site like mempool provide neutral visualization of how scripts are secured will bring about better user confidence and understanding of how bitcoin is being secured!
--
The text was updated successfully, but these errors were encountered: