shesek / minsc

An highly-specialized DSL scripting language for Bitcoin Script and Miniscript
https://min.sc
MIT License
190 stars 19 forks source link

Policy contains duplicate keys #12

Closed BlockMechanic closed 3 months ago

BlockMechanic commented 3 years ago

Hello

I'd like to ask, why this rule is there ? While using the online tool to craft i ran into the issue :- Below is the code :-

$federation = [ pk(A), pk(B), pk(C), pk(D), pk(E) ]; $stage1 = 5 of $federation; $stage2 = 4 of $federation && older(10); $stage3 = 3 of $federation && older(100); $stage4 = 2 of $federation && older(1000); $stage5 = 1 of $federation && older(10000); $stageArr = [$stage1, $stage2, $stage3, $stage4, $stage5]; $passw = sha256(H);

$passw && any($stageArr)

Is this in anyway invalid ?

shesek commented 2 years ago

Hi there! Apologies for the slow reply ^^

Yes, miniscript does not allow public keys to be reused across different branches. But you can use xpubs and the / child derivation operator to create unique keys for each branch by deriving them at a different index. For example:

A = xpub6B6GGqbaiEP3Cse7XaPEkRvCVyoVisRK8Whqts5Lm4E13sqBFyJPFWMynVgPW6q42e7NiVo5YWNAnY9iKXVhsMTYG1Qvs8Xq6nRETby5XB7/*;
B = xpub69zenBZXgAhuzCNdBhPJ2WueXjsHBcNoXfzgqVXvDLXo5pNbcbfUhv78WWLG2a88j7ct5Ua5m4vsaSy3V8pN25wdoULWM9BmT1CfJqdQrji/*;
C = xpub6AGShbkK3oUbqKqS2trd78MZNXhMie2wtcnhL6TZo7hvzBYaaPr2KbbDMTj5AUomoECbpkQ3HMSmZBGvMCn6CQJjn5m56b6AMAZeA5WKRCt/*;
D = xpub6A4ETnyMC4pMk52ptwDXsFMxBjbbjR6nrP5nF4iFsAenfVKmQ4kjTcaDGr8dntqEym6UgdFe2dvaJuBcBrEivJFTfNCcmgXLR6EM4MHVnBr/*;
E = xpub6BUUXrnMnq6R1Dj2RTbwz7jtfFic2bvuzoDmvFgwsWmHLfuxdXAjpAu6588cszuTtNs5CxCdLRc7jce2dbWHgLLxTVMEy6fan2dy6AevNYT/*;
$stage1 = 5 of [ pk(A/0), pk(B/0), pk(C/0), pk(D/0), pk(E/0) ];
$stage2 = 4 of [ pk(A/1), pk(B/1), pk(C/1), pk(D/1), pk(E/1) ] && older(10);
$stage3 = 3 of [ pk(A/2), pk(B/2), pk(C/2), pk(D/2), pk(E/2) ] && older(100);
// ...

As of c3468c4c0ed3bcd68ca9f12614d4b7ab481aa132 (not yet available on the live playground on min.sc) I also made it possible to use the child derivation operator on policies (without them getting coerced into descriptors). This derives all the keys contained within the policy using the same child code index, allowing you to write this more succinctly as:

$federation = [ pk(A), pk(B), pk(C), pk(D), pk(E) ];
$stage1 = (5 of $federation)/0;
$stage2 = (4 of $federation)/1 && older(10);
$stage3 = (3 of $federation)/2 && older(100);
// ...

Or alternatively when constructing the $stageArr, like so:

$federation = [ pk(A), pk(B), pk(C), pk(D), pk(E) ];
$stage1 = 5 of $federation;
$stage2 = 4 of $federation && older(10);
// ...
$stageArr = [$stage1/0, $stage2/1, $stage3/2, $stage4/3, $stage5/4];

c3468c4c0ed3bcd68ca9f12614d4b7ab481aa132 also made it possible to use the derivation operator on arrays (deriving all of the keys/policies/miniscripts/descriptors inside them). With this, you can also derive the $federation array with e.g. 5 of ($federation/0) (or 5 of $federation/0), which will give the same result as deriving the policy with (5 of $federation)/0.