{"id":2587,"date":"2022-02-07T20:23:50","date_gmt":"2022-02-07T20:23:50","guid":{"rendered":"https:\/\/ulrichard.ch\/blog\/?p=2587"},"modified":"2022-02-07T20:23:50","modified_gmt":"2022-02-07T20:23:50","slug":"creating-proof-of-reserves-for-an-electrum-wallet","status":"publish","type":"post","link":"https:\/\/ulrichard.ch\/blog\/?p=2587","title":{"rendered":"Creating proof of reserves for an Electrum wallet"},"content":{"rendered":"\n<p>In my <a href=\"https:\/\/ulrichard.ch\/blog\/index.php\/2021\/12\/10\/proof-of-reserves\/\">last post<\/a> I promised to write about how you can produce a &#8220;proof of reserves&#8221; for your own wallet including hardware wallets. So, here we go. First you need an electrum multisig wallet that involves at least one hardware wallet. I won&#8217;t go into the details of how to construct this. Recently I created just such a wallet for testing purposes. You can download it and get a descriptor for it with the following steps:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">git clone https:\/\/github.com\/RCasatta\/electrum2descriptors.git\ncd electrum2descriptors\ncargo run -- tests\/wallets\/multisig_hw_segwit<\/pre>\n\n\n\n<p>That will output two descriptors, one for receiving- and one for change addresses:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[\"wsh(sortedmulti(2,tpubDEcw4ooTbmw62zBKdkYepoP3z4WWugdeRzPHHAbk8XVsPfBE9AAZMNghiqwtdFgtabaeppBTPmezUkRkQZidLcSJp3XTASbMakHcYauWehZ\/0\/*,tpubDEbkvhmJoZMq3SUNqEf3aEsubvqsCUPc7rroHkGERgS7qA1gQVMxUPrgzth6x43odirLohwf4aMHpvcnWi3jCB2xkizv8T4B2KqLRZVLC6K\/0\/*))\",\n\"wsh(sortedmulti(2,tpubDEcw4ooTbmw62zBKdkYepoP3z4WWugdeRzPHHAbk8XVsPfBE9AAZMNghiqwtdFgtabaeppBTPmezUkRkQZidLcSJp3XTASbMakHcYauWehZ\/1\/*,tpubDEbkvhmJoZMq3SUNqEf3aEsubvqsCUPc7rroHkGERgS7qA1gQVMxUPrgzth6x43odirLohwf4aMHpvcnWi3jCB2xkizv8T4B2KqLRZVLC6K\/1\/*))\"]<\/pre>\n\n\n\n<p>With this and the following commands, you can generate a bdk wallet, and a proof transaction:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cargo install --git https:\/\/github.com\/bitcoindevkit\/bdk-cli --features=reserves,electrum\nDESC_EXT=\"wsh(sortedmulti(2,tpubDEcw4ooTbmw62zBKdkYepoP3z4WWugdeRzPHHAbk8XVsPfBE9AAZMNghiqwtdFgtabaeppBTPmezUkRkQZidLcSJp3XTASbMakHcYauWehZ\/0\/*,tpubDEbkvhmJoZMq3SUNqEf3aEsubvqsCUPc7rroHkGERgS7qA1gQVMxUPrgzth6x43odirLohwf4aMHpvcnWi3jCB2xkizv8T4B2KqLRZVLC6K\/0\/*))\"\nDESC_CHG=\"wsh(sortedmulti(2,tpubDEcw4ooTbmw62zBKdkYepoP3z4WWugdeRzPHHAbk8XVsPfBE9AAZMNghiqwtdFgtabaeppBTPmezUkRkQZidLcSJp3XTASbMakHcYauWehZ\/1\/*,tpubDEbkvhmJoZMq3SUNqEf3aEsubvqsCUPc7rroHkGERgS7qA1gQVMxUPrgzth6x43odirLohwf4aMHpvcnWi3jCB2xkizv8T4B2KqLRZVLC6K\/1\/*))\"\nbdk-cli -n testnet wallet -w proofdemo1 --descriptor $DESC_EXT --change_descriptor $DESC_CHG --server ssl:\/\/electrum.blockstream.info:60002 sync\nbdk-cli -n testnet wallet -w proofdemo1 --descriptor $DESC_EXT --change_descriptor $DESC_CHG --server ssl:\/\/electrum.blockstream.info:60002 produce_proof --message \"Testnet coins are worthless\"\n<\/pre>\n\n\n\n<p>That will produce a partially signed bitcoin transaction, which can look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cHNidP8BANABAAAABMErBiXTxwDcvvvq771RVgP1SYJh3scx0WBImDi7rvmsAAAAAAD\/\/\/\/\/R2T53Je0wwuCC4sB4y303f5x1sXi67Sbt5GHyNJYSL8BAAAAAP\/\/\/\/+hyKIxvTPJ++2fJ9IP+0veP366E6M3+d5ndrRywC+CdQAAAAAA\/\/\/\/\/85xD7HXF5RHqDqqrmbkuSHlVkWpGr8AQkxbX0GeWMLMAQAAAAD\/\/\/\/\/ARY4AwAAAAAAGXapFJ9\/0JbTftLA4\/fwz8kkvu9P\/OtoiKwAAAAAAAEBCgAAAAAAAAAAAVEBBwAAAQEroIYBAAAAAAAiACA\/WR3mqmBSknWlsU4tF2FirFI49AnBJ\/RF3Y8MOVvj6QEFR1IhAjzWg4H+LS0DMvvpzPOBG82hnO3F2EH1ij0DfnUjXwzeIQK4J7EzNMFN5ZpMS9nZLqkSInlZWY+fv9RtNaePd\/ZN7FKuIgYCPNaDgf4tLQMy++nM84EbzaGc7cXYQfWKPQN+dSNfDN4Mw7inHwAAAAADAAAAIgYCuCexMzTBTeWaTEvZ2S6pEiJ5WVmPn7\/UbTWnj3f2TewMRyCUewAAAAADAAAAAAEBK2aKAQAAAAAAIgAgyuBYb4qmZ5NOo9az+sc19GSGVUza3boreImwW0wqdvMBBUdSIQIj9OEMidD0v63giswaS\/zatG5LqLt\/jqwauILs+Ne57CECvQAhlTCAChOhr3dosTr3S3sVmD\/ogjLDtuXgi4VihPFSriIGAiP04QyJ0PS\/reCKzBpL\/Nq0bkuou3+OrBq4guz417nsDMO4px8AAAAAAgAAACIGAr0AIZUwgAoToa93aLE690t7FZg\/6IIyw7bl4IuFYoTxDEcglHsAAAAAAgAAAAABASsQJwAAAAAAACIAIPrEeWr\/BapLkLBg2LsEzljOP3I90GNzv8xyvl5bM7xEAQVHUiECSDumk7HdO7lTOGMBO\/B5bxsj8qp\/L2f3QJzzNL+WtsMhA++dVhrt7uwufhjJcNk1+Nh1w4ipjbjCnWzfcHwJSkSCUq4iBgJIO6aTsd07uVM4YwE78HlvGyPyqn8vZ\/dAnPM0v5a2wwxHIJR7AAAAAAEAAAAiBgPvnVYa7e7sLn4YyXDZNfjYdcOIqY24wp1s33B8CUpEggzDuKcfAAAAAAEAAAAAAA==<\/pre>\n\n\n\n<p>Now load this transaction in your electrum wallet. <br>\nHere comes the interesting part: try to sign it.<br>\nUnfortunately I got the following error:<\/p>\n\n\n\n<p><code>A wallet owned pubkey was not found in the transaction input to be signed.<\/code><\/p>\n\n\n\n<p>This is an exception coming from the BitBox2 plugin. <br>\nSo, lets take a step back and just use an electrum soft wallet with local key storage. We start again with the command to extract a descriptor. In the electrum2descriptors directory, execute:<\/p>\n\n\n\n<p><code>cargo run -- tests\/wallets\/multisig_segwit<\/code><\/p>\n\n\n\n<p>That again will output two descriptors, one for receiving- and one for change addresses:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[\"wsh(sortedmulti(2,tprv8dNybiDsdyms39SAWTxyiNHABTTgiqmJpScmxGrdKEuZ7TwXcaYXT4f4ddVjWiiQs9zowHqyDmvaebN6fU2Lu6iAYnYuepiLkvzGdcZZi8D\/0\/*,tpubD9cniQzQ8XnuagyP9Xwg3sWCX77wQPWoLPW7jqzcPn37r8hq2X86uztCEyFbMY16amzwdJ1CcNRXhF3vykn1wuDv2ULzryRtaCcN5Cr8F9y\/0\/*))\",\n\"wsh(sortedmulti(2,tprv8dNybiDsdyms39SAWTxyiNHABTTgiqmJpScmxGrdKEuZ7TwXcaYXT4f4ddVjWiiQs9zowHqyDmvaebN6fU2Lu6iAYnYuepiLkvzGdcZZi8D\/1\/*,tpubD9cniQzQ8XnuagyP9Xwg3sWCX77wQPWoLPW7jqzcPn37r8hq2X86uztCEyFbMY16amzwdJ1CcNRXhF3vykn1wuDv2ULzryRtaCcN5Cr8F9y\/1\/*))\"]\n<\/pre>\n\n\n\n<p>With this and the following commands, you can generate a bdk wallet, and a proof transaction:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">DESC_EXT=\"wsh(sortedmulti(2,tprv8dNybiDsdyms39SAWTxyiNHABTTgiqmJpScmxGrdKEuZ7TwXcaYXT4f4ddVjWiiQs9zowHqyDmvaebN6fU2Lu6iAYnYuepiLkvzGdcZZi8D\/0\/*,tpubD9cniQzQ8XnuagyP9Xwg3sWCX77wQPWoLPW7jqzcPn37r8hq2X86uztCEyFbMY16amzwdJ1CcNRXhF3vykn1wuDv2ULzryRtaCcN5Cr8F9y\/0\/*))\"\nDESC_CHG=\"wsh(sortedmulti(2,tprv8dNybiDsdyms39SAWTxyiNHABTTgiqmJpScmxGrdKEuZ7TwXcaYXT4f4ddVjWiiQs9zowHqyDmvaebN6fU2Lu6iAYnYuepiLkvzGdcZZi8D\/1\/*,tpubD9cniQzQ8XnuagyP9Xwg3sWCX77wQPWoLPW7jqzcPn37r8hq2X86uztCEyFbMY16amzwdJ1CcNRXhF3vykn1wuDv2ULzryRtaCcN5Cr8F9y\/1\/*))\"\nbdk-cli -n testnet wallet -w proofdemo2 --descriptor $DESC_EXT --change_descriptor $DESC_CHG --server ssl:\/\/electrum.blockstream.info:60002 sync\nbdk-cli -n testnet wallet -w proofdemo2 --descriptor $DESC_EXT --change_descriptor $DESC_CHG --server ssl:\/\/electrum.blockstream.info:60002 produce_proof --message \"Testnet coins are worthless\"\n<\/pre>\n\n\n\n<p>That will produce a partially signed bitcoin transaction, which can look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cHNidP8BANABAAAABMErBiXTxwDcvvvq771RVgP1SYJh3scx0WBImDi7rvmsAAAAAAD\/\/\/\/\/fpjOaPHeO8iuqOAAXNYTHduKraGwzE2T6uyQKv\/xMiUAAAAAAP\/\/\/\/+PIkY8icgEgelHPdjKJ5IhDDRuUpEz0MPJDo3DQjfXhwEAAAAA\/\/\/\/\/\/7fKpENlBvDb0Sk\/pIj4asvxgJZeAl+c7QitalQiCs8AAAAAAD\/\/\/\/\/AYk6AwAAAAAAGXapFJ9\/0JbTftLA4\/fwz8kkvu9P\/OtoiKwAAAAAAAEBCgAAAAAAAAAAAVEBBwAAAQEr2YwBAAAAAAAiACA0+1ZWhppfL2hexzK\/hNEDRcsqMYpj2eygJvctc04rRiICA85usXGOxyWoB2tjhap+sMe5WMQylChyoIyPQw7YwOWYSDBFAiEAhX\/LdNf2yZEB0PNIGJVIJLGp2XYnc8iZHS+0Fb8plLwCIDXlhRegpeS6T5Pvs1zBcmOAh7bpnV2UePcs3Njn+FW+AQEFR1IhA85usXGOxyWoB2tjhap+sMe5WMQylChyoIyPQw7YwOWYIQP91mGneajoVZMtGRkFWvx2ZGUYvEEA6X8IfZK8g8r8slKuIgYDzm6xcY7HJagHa2OFqn6wx7lYxDKUKHKgjI9DDtjA5ZgMXJ6u1wAAAAABAAAAIgYD\/dZhp3mo6FWTLRkZBVr8dmRlGLxBAOl\/CH2SvIPK\/LIM9\/UCiwAAAAABAAAAAAEBKxAnAAAAAAAAIgAg0akE2gMCFP1o4HslEN0ysMFhG0q2Y74tPzXhjtUSxU4iAgL6ZTC3eAZapDHPGJ2NyXB4eo7srM6X2c3zbj09qV98AUcwRAIgFHZJzHZrXUeXxxRQtiPrM0Ays6fq1Z+rIHHsQSIjOiICID5SN2tjMSlmiO7nNz3LMKRtHoLwJcv6mGU+\/LhJGBTXAQEFR1IhAugJEDOoQ6+rqj7YlxPlMPumDknI\/5BHw6QEDGtBVWZoIQL6ZTC3eAZapDHPGJ2NyXB4eo7srM6X2c3zbj09qV98AVKuIgYC6AkQM6hDr6uqPtiXE+Uw+6YOScj\/kEfDpAQMa0FVZmgM9\/UCiwAAAAAAAAAAIgYC+mUwt3gGWqQxzxidjclweHqO7KzOl9nN8249PalffAEMXJ6u1wAAAAAAAAAAAAEBK6CGAQAAAAAAIgAg++9Wlf87jJ5jDHvPj8fVofJ+\/SOcaGpEaLAEJD068pIiAgK9OsDWjXhF2nZ0y1pgMJhdcAlmSzG3Bd1U40ONUA+\/7EcwRAIgQGAgXVcwm2X9H5s0q9W9WUNhfwIilld+ldETrlYFx\/sCIEhvT+\/pE4cM0xGKJk4G7d2E\/Zn5YfTtD3Ojf50qbONPAQEFR1IhAr06wNaNeEXadnTLWmAwmF1wCWZLMbcF3VTjQ41QD7\/sIQNzF2pZRGQFPkASin8Ll0vqni2CK5T56jLut+XRIeq0dVKuIgYCvTrA1o14Rdp2dMtaYDCYXXAJZksxtwXdVONDjVAPv+wMXJ6u1wAAAAACAAAAIgYDcxdqWURkBT5AEop\/C5dL6p4tgiuU+eoy7rfl0SHqtHUM9\/UCiwAAAAACAAAAAAA=\n<\/pre>\n\n\n\n<p>Now load this transaction in your electrum wallet.<br> Unfortunately, the &#8220;Sign&#8221; button is deactivated.<br> So, apparently, there is nothing we can do at the moment. I will opened an <a href=\"https:\/\/github.com\/spesmilo\/electrum\/issues\/7653\">issue with Electrum<\/a>, and I am curious about what they think about adding support for signing proof PSBTs.<\/p>\n\n\n\n<p>Of course we could sign the PSBT with bdk-cli, since we already transformed the Electrum wallet to descriptor format with electrum2descriptors, but that would only work with the soft wallet, while I am more interested in the use case with hardware wallets. There is at some point support for hardware wallets coming to BDK, but I don&#8217;t know when that will be.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my last post I promised to write about how you can produce a &#8220;proof of reserves&#8221; for your own wallet including hardware wallets. So, here we go. First you need an electrum multisig wallet that involves at least one hardware wallet. I won&#8217;t go into the details of how to construct this. Recently I [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[37,176],"class_list":["post-2587","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-bitcoin","tag-proofofreserve"],"_links":{"self":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2587"}],"version-history":[{"count":0,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2587\/revisions"}],"wp:attachment":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}