1
0
mirror of https://github.com/bitcoin/bips.git synced 2026-03-09 15:53:54 +00:00

BIP360: Pay to Merkle Root (P2MR) (#1670)

Review comments and assistance by:
  Armin Sabouri <armins88@gmail.com>
  D++ <82842780+dplusplus1024@users.noreply.github.com>
  Jameson Lopp <jameson.lopp@gmail.com>
  jbride <jbride2001@yahoo.com>
  Joey Yandle <xoloki@gmail.com>
  Jon Atack <jon@atack.com>
  Jonas Nick <jonasd.nick@gmail.com>
  Kyle Crews <kylecrews@Kyles-Mac-Studio.local>
  Mark "Murch" Erhardt <murch@murch.one>
  notmike-5 <notmike-5@users.noreply.github.com>
  Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>

Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>
Co-authored-by: Isabel Foxen Duke <110147802+Isabelfoxenduke@users.noreply.github.com>
This commit is contained in:
Hunter Beast
2026-02-11 12:54:26 -08:00
committed by Murch
parent ed7af6ae7e
commit eae7d9fc57
60 changed files with 9494 additions and 0 deletions

View File

@@ -0,0 +1,260 @@
{
"version": 1,
"test_vectors": [
{
"id": "p2tr_using_v2_witness_version_error",
"objective": "Tests that a P2TR v2 scriptPubKey fails with use of witness version 2",
"given": {
"internalPubkey": "d6889cb081036e0faefa3a35157ad71086b123b2b144b649798b494c300a961d",
"scriptTree": null
},
"intermediary": {
"merkleRoot": null,
"tweak": "b86e7be8f39bab32a6f2c0443abbc210f0edac0e2c53d501b36b64437d9c6c70",
"tweakedPubkey": "53a1f6e454df1aa2776a2814a721372d6258050de330b3c6d10ee8f4e0dda343"
},
"expected": {
"scriptPubKey": "522053a1f6e454df1aa2776a2814a721372d6258050de330b3c6d10ee8f4e0dda343",
"error": "P2TR requires witness version of 1"
}
},
{
"id": "p2mr_missing_leaf_script_tree_error",
"objective": "Tests P2MR with missing leaf script tree",
"given": {
"script_tree": ""
},
"intermediary": {
},
"expected": {
"error": "P2MR requires a script tree with at least one leaf"
}
},
{
"id": "p2mr_single_leaf_script_tree",
"objective": "Tests P2MR with single leaf script tree",
"given": {
"scriptTree": {
"id": 0,
"script": "20b617298552a72ade070667e86ca63b8f5789a9fe8731ef91202a91c9f3459007ac",
"asm": "b617298552a72ade070667e86ca63b8f5789a9fe8731ef91202a91c9f3459007 OP_CHECKSIG",
"leafVersion": 192
}
},
"intermediary": {
"leafHashes": [
"c525714a7f49c28aedbbba78c005931a81c234b2f6c99a73e4d06082adc8bf2b"
],
"merkleRoot": "c525714a7f49c28aedbbba78c005931a81c234b2f6c99a73e4d06082adc8bf2b"
},
"expected": {
"scriptPubKey": "5220c525714a7f49c28aedbbba78c005931a81c234b2f6c99a73e4d06082adc8bf2b",
"bip350Address": "bc1zc5jhzjnlf8pg4mdmhfuvqpvnr2quyd9j7mye5uly6psg9twghu4ssr0v9k",
"scriptPathControlBlocks": [
"c1"
]
}
},
{
"id": "p2mr_different_version_leaves",
"objective": "Tests P2MR with two script leaves of different versions. TO-DO: currently ignores given leaf version and over-rides. Probably better to throw error",
"given": {
"scriptTree": [
{
"id": 0,
"script": "20387671353e273264c495656e27e39ba899ea8fee3bb69fb2a680e22093447d48ac",
"asm": "387671353e273264c495656e27e39ba899ea8fee3bb69fb2a680e22093447d48 OP_CHECKSIG",
"leafVersion": 192
},
{
"id": 1,
"script": "06424950333431",
"asm": "424950333431",
"description": "just pushes the string 'BIP341' onto the stack",
"leafVersion": 250
}
]
},
"intermediary": {
"leafHashes": [
"8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7",
"f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a"
],
"merkleRoot": "6c2dc106ab816b73f9d07e3cd1ef2c8c1256f519748e0813e4edd2405d277bef"
},
"expected": {
"scriptPubKey": "52206c2dc106ab816b73f9d07e3cd1ef2c8c1256f519748e0813e4edd2405d277bef",
"bip350Address": "bc1zdskuzp4ts94h87ws0c7drmev3sf9dagewj8qsylyahfyqhf800hsam4d6e",
"scriptPathControlBlocks": [
"c1f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a",
"c18ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7"
]
}
},
{
"id": "p2mr_simple_lightning_contract",
"objective": "Tests P2MR with two script leaves that simulate a simple lightning network contract. Reference: https://github.com/bitcoin-core/btcdeb/blob/master/doc/tapscript-example-with-tap.md",
"given": {
"scriptTree": [
{
"id": 0,
"script": "029000b275209997a497d964fc1a62885b05a51166a65a90df00492c8d7cf61d6accf54803beac",
"asm": "144 OP_CHECKSEQUENCEVERIFY OP_DROP 9997a497d964fc1a62885b05a51166a65a90df00492c8d7cf61d6accf54803be OP_CHECKSIG",
"description": "Alice takes the money after waiting 1 day",
"leafVersion": 192
},
{
"id": 1,
"script": "a8206c60f404f8167a38fc70eaf8aa17ac351023bef86bcb9d1086a19afe95bd533388204edfcf9dfe6c0b5c83d1ab3f78d1b39a46ebac6798e08e19761f5ed89ec83c10ac",
"asm": "OP_SHA256 6c60f404f8167a38fc70eaf8aa17ac351023bef86bcb9d1086a19afe95bd5333 OP_EQUALVERIFY 4edfcf9dfe6c0b5c83d1ab3f78d1b39a46ebac6798e08e19761f5ed89ec83c10 OP_CHECKSIG",
"description": "Bob takes the money whenever he wishes to by revealing the preimage_hash",
"leafVersion": 192
}
]
},
"intermediary": {
"leafHashes": [
"c81451874bd9ebd4b6fd4bba1f84cdfb533c532365d22a0a702205ff658b17c9",
"632c8632b4f29c6291416e23135cf78ecb82e525788ea5ed6483e3c6ce943b42"
],
"merkleRoot": "41646f8c1fe2a96ddad7f5471bc4fee7da98794ef8c45a4f4fc6a559d60c9f6b"
},
"expected": {
"scriptPubKey": "522041646f8c1fe2a96ddad7f5471bc4fee7da98794ef8c45a4f4fc6a559d60c9f6b",
"bip350Address": "bc1zg9jxlrqlu25kmkkh74r3h387uldfs72wlrz95n60c6j4n4svna4s4lhfhe",
"scriptPathControlBlocks": [
"c1c81451874bd9ebd4b6fd4bba1f84cdfb533c532365d22a0a702205ff658b17c9",
"c1632c8632b4f29c6291416e23135cf78ecb82e525788ea5ed6483e3c6ce943b42"
]
}
},
{
"id": "p2mr_two_leaf_same_version",
"objective": "Tests P2MR with two script leaves of same version",
"given": {
"scriptTree": [
{
"id": 0,
"script": "2044b178d64c32c4a05cc4f4d1407268f764c940d20ce97abfd44db5c3592b72fdac",
"asm": "44b178d64c32c4a05cc4f4d1407268f764c940d20ce97abfd44db5c3592b72fd OP_CHECKSIG",
"leafVersion": 192
},
{
"id": 1,
"script": "07546170726f6f74",
"asm": "546170726f6f74",
"description": "pushes the string 'Taproot' onto the stack",
"leafVersion": 192
}
]
},
"intermediary": {
"leafHashes": [
"64512fecdb5afa04f98839b50e6f0cb7b1e539bf6f205f67934083cdcc3c8d89",
"2cb2b90daa543b544161530c925f285b06196940d6085ca9474d41dc3822c5cb"
],
"merkleRoot": "ab179431c28d3b68fb798957faf5497d69c883c6fb1e1cd9f81483d87bac90cc"
},
"expected": {
"scriptPubKey": "5220ab179431c28d3b68fb798957faf5497d69c883c6fb1e1cd9f81483d87bac90cc",
"bip350Address": "bc1z4vtegvwz35ak37me39tl4a2f045u3q7xlv0pek0czjpas7avjrxqz20g2y",
"scriptPathControlBlocks": [
"c12cb2b90daa543b544161530c925f285b06196940d6085ca9474d41dc3822c5cb",
"c164512fecdb5afa04f98839b50e6f0cb7b1e539bf6f205f67934083cdcc3c8d89"
]
}
},
{
"id": "p2mr_three_leaf_complex",
"objective": "Tests P2MR with a complex three-leaf script tree structure, demonstrating nested script paths and multiple verification options",
"given": {
"internalPubkey": "e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f",
"scriptTree": [
{
"id": 0,
"script": "2072ea6adcf1d371dea8fba1035a09f3d24ed5a059799bae114084130ee5898e69ac",
"asm": "72ea6adcf1d371dea8fba1035a09f3d24ed5a059799bae114084130ee5898e69 OP_CHECKSIG",
"leafVersion": 192
},
[
{
"id": 1,
"script": "202352d137f2f3ab38d1eaa976758873377fa5ebb817372c71e2c542313d4abda8ac",
"asm": "2352d137f2f3ab38d1eaa976758873377fa5ebb817372c71e2c542313d4abda8 OP_CHECKSIG",
"leafVersion": 192
},
{
"id": 2,
"script": "207337c0dd4253cb86f2c43a2351aadd82cccb12a172cd120452b9bb8324f2186aac",
"asm": "7337c0dd4253cb86f2c43a2351aadd82cccb12a172cd120452b9bb8324f2186a OP_CHECKSIG",
"leafVersion": 192
}
]
]
},
"intermediary": {
"leafHashes": [
"2645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817",
"ba982a91d4fc552163cb1c0da03676102d5b7a014304c01f0c77b2b8e888de1c",
"9e31407bffa15fefbf5090b149d53959ecdf3f62b1246780238c24501d5ceaf6"
],
"merkleRoot": "ccbd66c6f7e8fdab47b3a486f59d28262be857f30d4773f2d5ea47f7761ce0e2"
},
"expected": {
"scriptPubKey": "5220ccbd66c6f7e8fdab47b3a486f59d28262be857f30d4773f2d5ea47f7761ce0e2",
"bip350Address": "bc1zej7kd3hhar76k3an5jr0t8fgyc47s4lnp4rh8uk4afrlwasuur3qzgewqq",
"scriptPathControlBlocks": [
"c1ffe578e9ea769027e4f5a3de40732f75a88a6353a09d767ddeb66accef85e553",
"c1ba982a91d4fc552163cb1c0da03676102d5b7a014304c01f0c77b2b8e888de1c2645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817",
"c19e31407bffa15fefbf5090b149d53959ecdf3f62b1246780238c24501d5ceaf62645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817"
]
}
},
{
"id": "p2mr_three_leaf_alternative",
"objective": "Tests another variant of P2MR with three leaves arranged in a different tree structure, showing alternative script path spending options",
"given": {
"internalPubkey": "55adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d",
"scriptTree": [
{
"id": 0,
"script": "2071981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2ac",
"asm": "71981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2 OP_CHECKSIG",
"leafVersion": 192
},
[
{
"id": 1,
"script": "20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac",
"asm": "d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748 OP_CHECKSIG",
"leafVersion": 192
},
{
"id": 2,
"script": "20c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4cac",
"asm": "c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4c OP_CHECKSIG",
"leafVersion": 192
}
]
]
},
"intermediary": {
"leafHashes": [
"f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d",
"737ed1fe30bc42b8022d717b44f0d93516617af64a64753b7a06bf16b26cd711",
"d7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7"
],
"merkleRoot": "2f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def"
},
"expected": {
"scriptPubKey": "52202f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def",
"bip350Address": "bc1z9a4jc5uhkmtgegvwpx3lq5tpv68layaf3pvz64wx7paatvejnhhsv52lcv",
"scriptPathControlBlocks": [
"c13cd369a528b326bc9d2133cbd2ac21451acb31681a410434672c8e34fe757e91",
"c1737ed1fe30bc42b8022d717b44f0d93516617af64a64753b7a06bf16b26cd711f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d",
"c1d7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d"
]
}
}
]
}

View File

@@ -0,0 +1,252 @@
{
"version": 1,
"test_vectors": [
{
"id": "p2mr_missing_leaf_script_tree_error",
"objective": "Tests P2MR with missing leaf script tree",
"given": {
"script_tree": ""
},
"intermediary": {
},
"expected": {
"error": "P2MR requires a script tree with at least one leaf"
}
},
{
"id": "p2mr_single_leaf_script_tree",
"objective": "Tests P2MR with single leaf script tree",
"given": {
"scriptTree": {
"id": 0,
"script": "201f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f247f",
"asm": "1f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f24 OP_SUBSTR",
"priv_key": "3f0213a51771f25c906cd82c656175e4b2a10e85958039d6e358352a2eb62b791f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f24",
"leafVersion": 192
}
},
"intermediary": {
"leafHashes": [
"3bb0db8c6adcd87330a4a8c91be0fe1b23da3c151b6f2fb4f269429c43b8d8bc"
],
"merkleRoot": "3bb0db8c6adcd87330a4a8c91be0fe1b23da3c151b6f2fb4f269429c43b8d8bc"
},
"expected": {
"scriptPubKey": "52203bb0db8c6adcd87330a4a8c91be0fe1b23da3c151b6f2fb4f269429c43b8d8bc",
"bip350Address": "bc1z8wcdhrr2mnv8xv9y4ry3hc87rv3a50q4rdhjld8jd9pfcsacmz7qg5szm8",
"scriptPathControlBlocks": [
"c1"
]
}
},
{
"id": "p2mr_different_version_leaves",
"objective": "Tests P2MR with two script leaves of different versions. TO-DO: currently ignores given leaf version and over-rides. Probably better to throw error",
"given": {
"scriptTree": [
{
"id": 0,
"script": "201f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f247f",
"asm": "1f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f24 OP_SUBSTR",
"priv_key": "3f0213a51771f25c906cd82c656175e4b2a10e85958039d6e358352a2eb62b791f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f24",
"leafVersion": 192
},
{
"id": 1,
"script": "06424950333431",
"asm": "424950333431",
"description": "just pushes the string 'BIP341' onto the stack",
"leafVersion": 250
}
]
},
"intermediary": {
"leafHashes": [
"3bb0db8c6adcd87330a4a8c91be0fe1b23da3c151b6f2fb4f269429c43b8d8bc",
"f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a"
],
"merkleRoot": "1619ce6d22a46dea045c4adf7f5f33d6810d00d0e9c8a4c7ba35db37b915c604"
},
"expected": {
"scriptPubKey": "52201619ce6d22a46dea045c4adf7f5f33d6810d00d0e9c8a4c7ba35db37b915c604",
"bip350Address": "bc1zzcvuumfz53k75pzuft0h7hen66qs6qxsa8y2f3a6xhdn0wg4cczq0h84sj",
"scriptPathControlBlocks": [
"c13bb0db8c6adcd87330a4a8c91be0fe1b23da3c151b6f2fb4f269429c43b8d8bc",
"c1f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a"
]
}
},
{
"id": "p2mr_simple_lightning_contract",
"objective": "Tests P2MR with two script leaves that simulate a simple lightning network contract. Reference: https://github.com/bitcoin-core/btcdeb/blob/master/doc/tapscript-example-with-tap.md",
"given": {
"scriptTree": [
{
"id": 0,
"script": "029000b275201f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f247f",
"asm": "144 OP_CHECKSEQUENCEVERIFY OP_DROP 1f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f24 OP_SUBSTR",
"priv_key": "3f0213a51771f25c906cd82c656175e4b2a10e85958039d6e358352a2eb62b791f4b1febdc7dfa77c1efacc875b43317b46155e5a564decf475fc369124c5f24",
"description": "Alice takes the money after waiting 1 day",
"leafVersion": 192
},
{
"id": 1,
"script": "a8206c60f404f8167a38fc70eaf8aa17ac351023bef86bcb9d1086a19afe95bd533388204c7f98ab73cc36abeb76d6eace6a9d8b0ff69dfe0f4a17e4f94f0898ec52fadd",
"asm": "OP_SHA256 6c60f404f8167a38fc70eaf8aa17ac351023bef86bcb9d1086a19afe95bd5333 OP_EQUALVERIFY 4c7f98ab73cc36abeb76d6eace6a9d8b0ff69dfe0f4a17e4f94f0898ec52fadd OP_SUBSTR",
"priv_key": "49a4214f386240d97ea68efb4268043fd5a55208dcdac18ce5bd3332b8e488944c7f98ab73cc36abeb76d6eace6a9d8b0ff69dfe0f4a17e4f94f0898ec52fadd",
"description": "Bob takes the money whenever he wishes to by revealing the preimage_hash",
"leafVersion": 192
}
]
},
"intermediary": {
"leafHashes": [
"cfd5fc07ac39947cba799e14f933f20e7c233dea72dc2792f5547c58cdce743e",
"a9745ac96d4f3702b78751f1e08f3040fbe6347e7b4f520d22d3f907730cbb7e"
],
"merkleRoot": "2794771cd51f215ba3a19fbcdf08c771edb7de782a0c34457e0e9be5d0e4008f"
},
"expected": {
"scriptPubKey": "52202794771cd51f215ba3a19fbcdf08c771edb7de782a0c34457e0e9be5d0e4008f",
"bip350Address": "bc1zy728w8x4rus4hgapn77d7zx8w8km0hnc9gxrg3t7p6d7t58yqz8sg0nccq",
"scriptPathControlBlocks": [
"c1cfd5fc07ac39947cba799e14f933f20e7c233dea72dc2792f5547c58cdce743e",
"c1a9745ac96d4f3702b78751f1e08f3040fbe6347e7b4f520d22d3f907730cbb7e"
]
}
},
{
"id": "p2mr_two_leaf_same_version",
"objective": "Tests P2MR with two script leaves of same version",
"given": {
"scriptTree": [
{
"id": 0,
"script": "20e6b3dad32fc04095a021f5356163cfc14e15f703831e332c56f6b499801f53447f",
"asm": "e6b3dad32fc04095a021f5356163cfc14e15f703831e332c56f6b499801f5344 OP_SUBSTR",
"priv_key": "a695d8a1351774d59ed1b980462c2ab8d58b3b7a48f55b114c6a39980dc1c13ee6b3dad32fc04095a021f5356163cfc14e15f703831e332c56f6b499801f5344",
"leafVersion": 192
},
{
"id": 1,
"script": "07546170726f6f74",
"asm": "546170726f6f74",
"description": "pushes the string 'Taproot' onto the stack",
"leafVersion": 192
}
]
},
"intermediary": {
"leafHashes": [
"9de7eeded7832c28c6f80de76904dd79f98fd302747823b5bc5be440186b0c6d",
"2cb2b90daa543b544161530c925f285b06196940d6085ca9474d41dc3822c5cb"
],
"merkleRoot": "5112b3edfd2c0b717491e9d4888ed2d5dfeaa25115143540e0a08516b68c008c"
},
"expected": {
"scriptPubKey": "52205112b3edfd2c0b717491e9d4888ed2d5dfeaa25115143540e0a08516b68c008c",
"bip350Address": "bc1z2yft8m0a9s9hzay3a82g3rkj6h074gj3z52r2s8q5zz3dd5vqzxqngpk2w",
"scriptPathControlBlocks": [
"c19de7eeded7832c28c6f80de76904dd79f98fd302747823b5bc5be440186b0c6d",
"c12cb2b90daa543b544161530c925f285b06196940d6085ca9474d41dc3822c5cb"
]
}
},
{
"id": "p2mr_three_leaf_complex",
"objective": "Tests P2MR with a complex three-leaf script tree structure, demonstrating nested script paths and multiple verification options",
"given": {
"scriptTree": [
{
"id": 0,
"script": "201d58016252d5a941f84574c4821b5f87e56778b2bbc3b610dfd801fc0250f6cc7f",
"asm": "1d58016252d5a941f84574c4821b5f87e56778b2bbc3b610dfd801fc0250f6cc OP_SUBSTR",
"priv_key": "2b339b5055fad695f0595d5581fa087455854f64c5443c03d5b4ca53549f12a41d58016252d5a941f84574c4821b5f87e56778b2bbc3b610dfd801fc0250f6cc",
"leafVersion": 192
},
[
{
"id": 1,
"script": "20a3b0dcac08f86306ba04f5fe2a3243ef3a0347c0e2a4529720a18d3cfdce90ad7f",
"asm": "a3b0dcac08f86306ba04f5fe2a3243ef3a0347c0e2a4529720a18d3cfdce90ad OP_SUBSTR",
"priv_key": "ec29d60c1be9263602906499b5e3c1de9e36cc88cec31154210191a578b92e9da3b0dcac08f86306ba04f5fe2a3243ef3a0347c0e2a4529720a18d3cfdce90ad",
"leafVersion": 192
},
{
"id": 2,
"script": "20e6ccf03593dbd07eba10403e33586c130889de6e8219da0a9ccbdd46a56a5f367f",
"asm": "e6ccf03593dbd07eba10403e33586c130889de6e8219da0a9ccbdd46a56a5f36 OP_SUBSTR",
"priv_key": "da04d13f706a6e0d22ac0db7c361f1aaa706a27043efca4edfecfed3125238e1e6ccf03593dbd07eba10403e33586c130889de6e8219da0a9ccbdd46a56a5f36",
"leafVersion": 192
}
]
]
},
"intermediary": {
"leafHashes": [
"0840c39e59eda6c9deee687a480cb169130c2f053ed2eb3134511ec1cfd8a2c7",
"837ef6677aeb0df2b0de47f45024684cc6ca03bda10fa30bb5bc05a94beb8dd1",
"b2a5304f678cc5a2ed51feb377dd0a609bd22ec979cc608bfcf884d0f8e6f93a"
],
"merkleRoot": "eaf8f557fdb9673de7bb9bad7e7452da9f44a3e65133fdadf2849c55cfb3cf5b"
},
"expected": {
"scriptPubKey": "5220eaf8f557fdb9673de7bb9bad7e7452da9f44a3e65133fdadf2849c55cfb3cf5b",
"bip350Address": "bc1zatu024lah9nnmeamnwkhuazjm205fglx2yelmt0jsjw9tnaneadszq7wg7",
"scriptPathControlBlocks": [
"c1837ef6677aeb0df2b0de47f45024684cc6ca03bda10fa30bb5bc05a94beb8dd1b2a5304f678cc5a2ed51feb377dd0a609bd22ec979cc608bfcf884d0f8e6f93a",
"c10840c39e59eda6c9deee687a480cb169130c2f053ed2eb3134511ec1cfd8a2c7b2a5304f678cc5a2ed51feb377dd0a609bd22ec979cc608bfcf884d0f8e6f93a",
"c118781f42f664d67acaf0ce7c6826437e5440eb1789f232af05e9a09fdf547903"
]
}
},
{
"id": "p2mr_three_leaf_alternative",
"objective": "Tests another variant of P2MR with three leaves arranged in a different tree structure, showing alternative script path spending options",
"given": {
"scriptTree": [
{
"id": 0,
"script": "20409f78ce0978519ff5d960c4ab595174c7efca11b1f89410a4e98b70cd423e1c7f",
"asm": "409f78ce0978519ff5d960c4ab595174c7efca11b1f89410a4e98b70cd423e1c OP_SUBSTR",
"priv_key": "c6ec3801b04afa40be6f77f3f7a7b3b7cb8cfe233b0263fb70e2f087b21397c1409f78ce0978519ff5d960c4ab595174c7efca11b1f89410a4e98b70cd423e1c",
"leafVersion": 192
},
[
{
"id": 1,
"script": "209f0955dc884a5c88d1732e017d30e27e8a445889bce5aa42611b7635c5c1073a7f",
"asm": "9f0955dc884a5c88d1732e017d30e27e8a445889bce5aa42611b7635c5c1073a OP_SUBSTR",
"priv_key": "7524bca170d54231f1246f30fb00f9da2208b1363ba5a7bbaf11fc3b0309e9519f0955dc884a5c88d1732e017d30e27e8a445889bce5aa42611b7635c5c1073a",
"leafVersion": 192
},
{
"id": 2,
"script": "20c60b10d57c0cdf27e5c751e131ea4301b37abe7384948059256c7f5f1f285a7f7f",
"asm": "c60b10d57c0cdf27e5c751e131ea4301b37abe7384948059256c7f5f1f285a7f OP_SUBSTR",
"priv_key": "d9d0f17d630b6a538e6a8a036373e7b9e5023a4c08f72dd8c3ef59288b98c079c60b10d57c0cdf27e5c751e131ea4301b37abe7384948059256c7f5f1f285a7f",
"leafVersion": 192
}
]
]
},
"intermediary": {
"leafHashes": [
"52e9326c2bf04d926b7e9f6c7645dd853f3f007b870201de9b814952750c9310",
"dcef3ce86cc8cea78c9e00f3d9ef58360cb6ed3cb90ec62efe00b9703854ba5c",
"ddb521a44e33ff4974e618d8b8b7794275b7dc754d847c537404f84330454361"
],
"merkleRoot": "51e3c1151ba73d9efce801837773331bf9030977242f62dfeb6756795f482409"
},
"expected": {
"scriptPubKey": "522051e3c1151ba73d9efce801837773331bf9030977242f62dfeb6756795f482409",
"bip350Address": "bc1z283uz9gm5u7eal8gqxphwuenr0usxzthyshk9hltvat8jh6gysys28twnc",
"scriptPathControlBlocks": [
"c1dcef3ce86cc8cea78c9e00f3d9ef58360cb6ed3cb90ec62efe00b9703854ba5cddb521a44e33ff4974e618d8b8b7794275b7dc754d847c537404f84330454361",
"c152e9326c2bf04d926b7e9f6c7645dd853f3f007b870201de9b814952750c9310ddb521a44e33ff4974e618d8b8b7794275b7dc754d847c537404f84330454361",
"c1b45680a7821e4b9450096ab38adbc3c99225af8f6c7ec121a0a5f1ae02893ba3"
]
}
}
]
}

View File

@@ -0,0 +1,40 @@
#!/bin/bash
# Invokes mining simulator a configurable number of times
if [ -z "${P2MR_ADDR}" ]; then
echo "Error: Environment variable P2MR_ADDR needs to be set"
exit 1
fi
BITCOIN_SOURCE_DIR=${BITCOIN_SOURCE_DIR:-$HOME/bitcoin}
# path to bitcoin.conf for signet
BITCOIN_CONF_FILE_PATH=${BITCOIN_CONF_FILE_PATH:-$HOME/anduro-360/configs/bitcoin.conf.signet}
# Set default LOOP_COUNT to 110 if not set
LOOP_COUNT=${LOOP_COUNT:-110}
# Validate LOOP_COUNT is a positive integer
if ! [[ "$LOOP_COUNT" =~ ^[0-9]+$ ]] || [ "$LOOP_COUNT" -le 0 ]; then
echo "Error: LOOP_COUNT must be a positive integer"
exit 1
fi
# Determine name of pool by querying mempool.space backend
# curl -X GET "http://localhost:8999/api/v1/mining/pool/marapool" | jq -r .pool.regexes
export POOL_ID=${POOL_ID:-"MARA Pool"}
echo -en "\nLoop_COUNT = $LOOP_COUNT\nBITCOIN_CONF_FILE_PATH=$BITCOIN_CONF_FILE_PATH\nBITCOIN_SOURCE_DIR=$BITCOIN_SOURCE_DIR\nPOOL_ID=$POOL_ID\n\n";
for ((i=1; i<=LOOP_COUNT; i++))
do
echo "Iteration $i of $LOOP_COUNT"
$BITCOIN_SOURCE_DIR/contrib/signet/miner --cli "bitcoin-cli -conf=$BITCOIN_CONF_FILE_PATH" generate \
--address $P2MR_ADDR \
--grind-cmd "$BITCOIN_SOURCE_DIR/build/bin/bitcoin-util grind" \
--poolid "$POOL_ID" \
--min-nbits --set-block-time $(date +%s)
done

View File

@@ -0,0 +1,88 @@
# podman build -f Dockerfile.bcli -t quay.io/jbride2000/p2mr_bcli:0.1 .
# podman run -it --entrypoint /bin/bash quay.io/jbride200/p2mr_bcli:0.1
FROM rust:1-slim-bookworm AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
autoconf \
automake \
libtool \
pkg-config \
zlib1g-dev \
libevent-dev \
libboost-dev \
libzmq3-dev \
bash \
python3 \
python3-pip \
libclang-dev \
clang \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /bitcoin
# Copy Bitcoin Core source (or clone)
# COPY . /bitcoin
RUN git clone --branch p2mr-pqc --single-branch https://github.com/jbride/bitcoin.git
# Environment variables for musl
ENV CC=gcc
ENV CXX=g++
# Build Bitcoin Core
WORKDIR bitcoin
RUN apt-get update && apt-get install -y libsqlite3-dev && rm -rf /var/lib/apt/lists/*
RUN mkdir build && cd build && \
cmake .. \
-DWITH_ZMQ=ON \
-DBUILD_BENCH=ON \
-DBUILD_DAEMON=ON && \
make -j$(nproc) bitcoin-cli
# Runtime stage with Debian Slim
FROM debian:bookworm-slim
# Install minimal runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
bash \
ca-certificates \
libevent-core-2.1-7 \
libevent-pthreads-2.1-7 \
libevent-extra-2.1-7 \
libboost-filesystem1.74.0 \
libboost-thread1.74.0 \
libzmq5 \
libsqlite3-0 \
telnet \
&& rm -rf /var/lib/apt/lists/*
# Copy bitcoin-cli from builder
COPY --from=builder /bitcoin/bitcoin/build/bin/bitcoin-cli /usr/local/bin/bitcoin-cli
# Create non-root user and set permissions
RUN groupadd --system bip360 && \
useradd --system --gid bip360 --shell /bin/bash --create-home bip360 && \
chmod +x /usr/local/bin/bitcoin-cli && \
ln -s /usr/local/bin/bitcoin-cli /usr/local/bin/b-cli && \
echo 'b-cli() { /usr/local/bin/bitcoin-cli -rpcconnect=${RPC_CONNECT:-192.168.122.1} -rpcport=${RPC_PORT:-18443} -rpcuser=${RPC_USER:-signet} -rpcpassword=${RPC_PASSWORD:-signet} "$@"; }' >> /home/bip360/.bashrc
# Set default environment variables (can be overridden at runtime)
ENV RPC_CONNECT=192.168.122.1 \
RPC_PORT=38332 \
RPC_USER=signet \
RPC_PASSWORD=signet
# Switch to non-root user
USER bip360
WORKDIR /home/bip360
ENTRYPOINT ["/usr/local/bin/bitcoin-cli"]

View File

@@ -0,0 +1,115 @@
# podman build -f Dockerfile.full -t quay.io/jbride2000/p2mr_demo:0.1 .
# podman run -it --entrypoint /bin/bash quay.io/jbride2000/p2mr_demo:0.1
FROM rust:1-slim-bookworm AS builder
# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
autoconf \
automake \
libtool \
pkg-config \
zlib1g-dev \
libevent-dev \
libboost-dev \
libzmq3-dev \
bash \
python3 \
python3-pip \
libclang-dev \
clang \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /bitcoin
# Copy Bitcoin Core source (or clone)
# COPY . /bitcoin
RUN git clone --branch p2mr-pqc --single-branch https://github.com/jbride/bitcoin.git
# Environment variables for musl
ENV CC=gcc
ENV CXX=g++
# Build Bitcoin Core
WORKDIR bitcoin
RUN apt-get update && apt-get install -y libsqlite3-dev && rm -rf /var/lib/apt/lists/*
RUN mkdir build && cd build && \
cmake .. \
-DWITH_ZMQ=ON \
-DBUILD_BENCH=ON \
-DBUILD_DAEMON=ON && \
make -j$(nproc) bitcoin-cli
# Runtime stage with Debian Slim
FROM rust:1-slim-bookworm
# Install minimal runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
bash \
ca-certificates \
libevent-core-2.1-7 \
libevent-pthreads-2.1-7 \
libevent-extra-2.1-7 \
libboost-filesystem1.74.0 \
libboost-thread1.74.0 \
libzmq5 \
libsqlite3-0 \
&& rm -rf /var/lib/apt/lists/*
# Copy bitcoin-cli from builder
COPY --from=builder /bitcoin/bitcoin/build/bin/bitcoin-cli /usr/local/bin/bitcoin-cli
# Create non-root user and set permissions
RUN groupadd --system bip360 && \
useradd --system --gid bip360 --shell /bin/bash --create-home bip360 && \
chmod +x /usr/local/bin/bitcoin-cli && \
ln -s /usr/local/bin/bitcoin-cli /usr/local/bin/b-cli && \
echo 'b-cli() { /usr/local/bin/bitcoin-cli -rpcconnect=${RPC_CONNECT:-192.168.122.1} -rpcport=${RPC_PORT:-18443} -rpcuser=${RPC_USER:-signet} -rpcpassword=${RPC_PASSWORD:-signet} "$@"; }' >> /home/bip360/.bashrc
# Install additional tools needed for building Rust code (before switching to non-root user)
RUN apt-get update && apt-get install -y --no-install-recommends \
libclang-dev \
clang \
git \
curl \
cmake \
build-essential \
jq \
gawk \
telnet \
&& rm -rf /var/lib/apt/lists/*
# Set default environment variables (can be overridden at runtime)
ENV RPC_CONNECT=192.168.122.1 \
RPC_PORT=38332 \
RPC_USER=signet \
RPC_PASSWORD=signet
# Switch to non-root user
USER bip360
WORKDIR /home/bip360
RUN git clone --no-checkout --depth 1 --branch p2mr-pqc \
--single-branch https://github.com/jbride/bips.git bips && \
cd bips && \
git sparse-checkout init --cone && \
git sparse-checkout set bip-0360 && \
git checkout && \
cd bip-0360/ref-impl/rust && \
cargo build && \
rm -rf target
WORKDIR /home/bip360/bips/bip-0360/ref-impl/rust
ENV BITCOIN_NETWORK=signet \
USE_PQC=true
ENTRYPOINT ["/usr/local/bin/bitcoin-cli"]

View File

@@ -0,0 +1,10 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.1.1 Chrome/132.0.6834.210 Electron/34.3.3 Safari/537.36" version="26.1.1">
<diagram name="Page-1" id="OP7udTXFU-9K02oCjO5S">
<mxGraphModel dx="1098" dy="914" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB