{"id":19519,"date":"2019-08-21T00:53:09","date_gmt":"2019-08-21T00:53:09","guid":{"rendered":"http:\/\/ci027cfe65701726c3"},"modified":"2025-01-27T21:30:56","modified_gmt":"2025-01-27T21:30:56","slug":"miniscript-how-blockstream-engineers-are-making-bitcoin-programming-easyer","status":"publish","type":"post","link":"https:\/\/bitcoinmagazine.com\/technical\/miniscript-how-blockstream-engineers-are-making-bitcoin-programming-easyer","title":{"rendered":"Miniscript: How Blockstream Engineers Are Making Bitcoin Programming Easy(er)"},"content":{"rendered":"<div id=\"bsf_rt_marker\"><\/div><figure><img decoding=\"async\" src=\"https:\/\/bitcoinmagazine.com\/wp-content\/uploads\/2024\/11\/miniscript-is-making-bitcoin-programming-easier.jpg\" title=\"\"><\/figure>\n<p>Bitcoin offered the first smart contract programming language the world had ever seen. Script, as this language is called, lets users encode different conditions under which coins can be spent. But while this was a revolutionary concept, it\u2019s not easy to use, especially for more complex spending conditions. Both writing a complex contract as well as verifying that the contract does what it is supposed to do are prone to human error. Yet, especially with money at stake, correct interpretation of the conditions is of the utmost importance.<\/p>\n<p>Over the past year, blockchain engineers Andrew Poelstra, Pieter Wuille and Sanket Kanjalkar set out to improve this. By stripping down Script to its bare essentials, their \u201cnew\u201d programming language \u2014 \u201c<a href=\"http:\/\/bitcoin.sipa.be\/miniscript\/\" target=\"_blank\" rel=\"noopener\">Miniscript<\/a>\u201d \u2014 abstracts away the complexity and should make programming on Bitcoin easier and safer for everyone involved.<\/p>\n<p>\u201cMiniscript is, in a theoretical sense, more limiting than script,\u201d Blockstream director of research and Miniscript co-designer Andrew Poelstra told <em>Bitcoin Magazine<\/em>. \u201cBut it can do everything that people <em>actually use<\/em> script for.\u201d<\/p>\n<h3>Script<\/h3>\n<p>Let\u2019s start from the beginning.<\/p>\n<p>Every Bitcoin transaction consists of two main parts: inputs and outputs, both of which consist of pieces of code. The inputs \u201cunlock\u201d coins and the outputs \u201clock them up\u201d again, specifying under which conditions they can be unlocked in a subsequent transaction input. Such requirements usually include a valid cryptographic signature, but there are more possibilities; for example, perhaps a certain amount of time must have passed before a coin can be spent or a specific secret number must be included.<\/p>\n<p>This code in transactions is created with Script, a programming language specifically designed for Bitcoin. Script was inspired by Forth, a programming language invented in the 1960s that was originally designed to operate radio telescopes. Script is adjusted, however, to make it more suited for Bitcoin.<\/p>\n<p>For example, Script doesn\u2019t have an opcode (an instruction) that makes \u201cloops\u201d: the language doesn\u2019t support performing the same computation an unbounded number times. In Bitcoin, there is no need to perform the same computation an unbounded number of times because Bitcoin nodes don\u2019t actually compute transactions \u2014 they <em>validate<\/em> transactions. (For a more technical explanation of why this is the case, see <a href=\"https:\/\/old.reddit.com\/r\/Bitcoin\/comments\/4pdx6k\/comparison_between_bitcoin_and_ethereums\/d4lerhw\/\" target=\"_blank\" rel=\"noopener\">this post<\/a> by Blockstream engineer Russell O\u2019Connor.)&nbsp;<\/p>\n<p>Script is also \u201cuntyped.\u201d This means that outcomes of computations can be interpreted and used in different ways. For example, the outcome of a valid signature can be \u201ctrue,\u201d but \u201ctrue\u201d can, in turn, be interpreted and used as a number \u201c1\u201d and subsequently used in math equations: \u201ctrue\u201d plus \u201ctrue\u201d would add up to \u201c2,\u201d which could, for example, mean that enough signatures were provided if a minimum of two valid signatures is required.<\/p>\n<p>This brings us to the most important property of Script in the context of this article: it is hard to \u201c<a href=\"https:\/\/www.freecodecamp.org\/news\/what-does-it-mean-when-code-is-easy-to-reason-about-4e6f63eb386f\/\" target=\"_blank\" rel=\"noopener\">reason about<\/a>.\u201d This essentially means that the results of computations can be interpreted in many ways. Even if a signature is invalid, for example, the Script can be written such that the transaction is still valid for some other reason.<\/p>\n<p>\u201cThere are opcodes in Bitcoin Script which do really absurd things,\u201d Poelstra explained. \u201cLike, interpret a signature as a true\/false value, branch on that; convert that boolean to a number and then index into the stack, and rearrange the stack based on that number. And the specific rules for how it does this are super nuts.\u201d<\/p>\n<p>This can make Script tricky to work with. Especially if requirements to spend (\u201cunlock\u201d) coins become more complex, the author of a transaction may unintentionally include something in the code that allows the coins to be spent under different conditions than intended. Conversely, the recipient of a transaction may fail to notice such a quirk and lose his coins to an attacker who does notice.<\/p>\n<h3>A Concrete Example of a Problem<\/h3>\n<p>Here is a concrete example of how these problems limit Script\u2019s usefulness.<\/p>\n<p>The Blockstream Green wallet has a standard \u201ccosigning\u201d setup. The wallet user controls one of two keys, and Blockstream controls the other. The funds can be spent in two ways. First, whenever the user wants to spend a coin, they sign the transaction and request that Blockstream signs it as well. Blockstream would usually do this, though this might require that the user confirms they really want to make the transaction through a secondary means, like an email confirmation. But something might go wrong on Blockstream\u2019s end \u2014 perhaps the company disappears or loses its key, or it cannot sign for some other reason. In that case, the user still has a fallback solution to spend their bitcoin: After a timelock has expired, they can create a valid transaction after some predetermined time has passed. Perhaps a month.<\/p>\n<p>This works fine, but it\u2019s also limited. The user cannot use any more of Bitcoin\u2019s smart contract potential, even though they may want to add more flexibility on their end of the setup.<\/p>\n<p>\u201cRight now Green has a fixed script that it uses for all customers, which is basically just a simple multi-signature,\u201d Poelstra said. \u201cBut really, we shouldn&#8217;t care what the Script says. What we care about is: before some timeout, is it impossible for the coins to be spent without our signature? If the user wants to use some crazy policy with us, we should be able to support it, as long as that one condition we care about is met.\u201d<\/p>\n<p>The user may, for example, want to allow their loved ones to spend the coin after a year has passed, in case they pass away. Or maybe the user is actually a company, and it wants to create a multisig setup where any two out of three board members can together spend the coins (in combination with Blockstream).<\/p>\n<p>Currently, this could technically be possible with Bitcoin Script. However, it would require that the user designs a custom setup, and Blockstream would need to partake in this custom setup.<\/p>\n<p>\u201cBut if the user gives us an arbitrary script, it&#8217;s impossible for us to tell whether that one condition we care about it [is] met, because the total set of all script behaviors is really complicated,\u201d Poelstra explained. \u201cFor example, if a script seems to take a signature, we need to think about what happens if the user gives a non-signature. Can it be tricked into letting the coins be spent?\u201d<\/p>\n<h3>Miniscript<\/h3>\n<p>Over the past year, Miniscript was designed by Poelstra, Blockstream Core tech engineer Pieter Wuille and Blockstream intern Sanket Kanjalkar. (Miniscript is not officially a Blockstream product, however.)<\/p>\n<p>In short, Miniscript is a \u201cstripped down\u201d version of Script: a selection of \u201ctools\u201d from the \u201cScript toolkit\u201d that makes it easier to use and easier to verify by humans. The tools are carefully selected to enable practically anything that can be done with Script \u2014 there are only some fringe exceptions that no one actually makes use of anyway. So while a line of Miniscript is still a valid line of Script, it essentially avoids human error by preventing unexpected, perhaps unintended, outcomes of the code.<\/p>\n<p>Taking the example of a problem above, with Miniscript, a user can easily design a setup in such a way that Blockstream can trivially check that its one condition is met. Specifically, Blockstream can see that the funds can only ever be spent if it signs or if a month has passed \u2014 no matter which other conditions are included on the user\u2019s end of the setup, be it extra timelocks or multisigs or anything else. With Miniscript, there can be no unexpected quirks that would override Blockstream&#8217;s end.<\/p>\n<p>Miniscript is so straightforward and predictable, in fact, that the setup can always be turned into a decision tree: a visualization (\u201cpictural encoding\u201d) of the setup, which is very easy to reason about.<\/p>\n<p>The visualization below, for example, shows a setup where two out of three users need to sign to move coins. As a backup option, the coins can be moved with an emergency key, but only after some time has passed.<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/bitcoinmagazine.com\/wp-content\/uploads\/2025\/01\/172_image-placeholder-title.png\" title=\"\"><\/figure>\n<p>\u201cWith Miniscript it is easy for Blockstream to participate in more complex setups \u2014 we decode the script into a tree, then we check every leaf of the tree, asking (a) does this leaf have a timeout condition on it?; or (b) does this leaf require one of our signatures?\u201d Poelstra said.<\/p>\n<p>If the answer is yes to both questions, Blockstream can participate.<\/p>\n<h3>Miniscript in Use<\/h3>\n<p>While Miniscript is a work in progress, early versions of it have been released and are ready to be used.<\/p>\n<p>To make the process of writing Miniscript even easier, Wuille also designed a \u201cpolicy language.\u201d The policy language is really like a programming language of its own. After programming the conditions under which a coin can be spent in this policy language, it can be compiled (\u201ctranslated\u201d) into Miniscript, and therefore into valid Script, to be included in a Bitcoin transaction output.<\/p>\n<p>A big added benefit of this policy language is that it automatically compiles into the best, most efficient version of Miniscript possible, depending on what the Script actually encodes.<\/p>\n<p>\u201cThe thing about Miniscript is that it&#8217;s basically Script \u2026 you have a ton of different ways to write \u2018or,\u2019 a ton of ways to write \u2018and\u2019 and some are more efficient than others,\u201d Poelstra said. \u201cThe policy language only has one \u2018or,\u2019 one \u2018and\u2019 and so forth, and Pieter [Wuille] has written this super optimized compiler which will convert that to Miniscript for you, and do it in the optimal way.\u201d<\/p>\n<p>This isn\u2019t just a theoretical concept. Even though the current version of Miniscript and the compiler are not final versions, Blockstream is using it internally for the development branch of its Liquid sidechain functionary software. (Poelstra pointed out that use of Wuille&#8217;s optimizing compiler saved Blockstream 22 bytes versus its original, \u201chand-rolled\u201d Script.)&nbsp;Wuille hosts a demo version of a policy language to the Miniscript compiler for anyone to use on <a href=\"http:\/\/bitcoin.sipa.be\/miniscript\/\" target=\"_blank\" rel=\"noopener\">http:\/\/bitcoin.sipa.be\/miniscript\/<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>By stripping down the Script programming language to its bare essentials, Miniscript should make programming on Bitcoin easier and safer.<\/p>\n","protected":false},"author":2509,"featured_media":19521,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[35],"tags":[815,287,1755,3313],"class_list":{"0":"post-19519","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-technical","8":"tag-andrew-poelstra","9":"tag-blockstream","10":"tag-miniscript","11":"tag-pieter-wuille"},"author_data":{"id":2509,"name":"Aaron van Wirdum","nicename":"aaron-van-wirdum","avatar_url":"https:\/\/bitcoinmagazine.com\/wp-content\/uploads\/2024\/12\/aaron-van-wirdum-96x96.jpg"},"featured_image_url":"https:\/\/bitcoinmagazine.com\/wp-content\/uploads\/2024\/11\/miniscript-is-making-bitcoin-programming-easier.jpg","_links":{"self":[{"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/posts\/19519","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/users\/2509"}],"replies":[{"embeddable":true,"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/comments?post=19519"}],"version-history":[{"count":0,"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/posts\/19519\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/media\/19521"}],"wp:attachment":[{"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/media?parent=19519"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/categories?post=19519"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bitcoinmagazine.com\/wp-json\/wp\/v2\/tags?post=19519"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}