{"id":194,"date":"2023-09-25T13:00:44","date_gmt":"2023-09-25T11:00:44","guid":{"rendered":"https:\/\/blog.clovrlabs.com\/?p=194"},"modified":"2024-06-21T13:47:29","modified_gmt":"2024-06-21T11:47:29","slug":"nodeguard-signer-extension","status":"publish","type":"post","link":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/","title":{"rendered":"NodeGuard Signer Extension: How to sign a PSBT in Rust"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"194\" class=\"elementor elementor-194\">\n\t\t\t\t<div class=\"elementor-element elementor-element-41624b7d e-flex e-con-boxed e-con e-parent\" data-id=\"41624b7d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4b3b6e2d elementor-widget elementor-widget-testimonial\" data-id=\"4b3b6e2d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"testimonial.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-testimonial-wrapper\">\n\t\t\t\t\t\t\t<div class=\"elementor-testimonial-content\">Note: AI did not write this article. This is precisely what an AI would say, right? Suspicious \ud83e\udd14\u2026<\/div>\n\t\t\t\n\t\t\t\t\t\t<div class=\"elementor-testimonial-meta elementor-has-image elementor-testimonial-image-position-aside\">\n\t\t\t\t<div class=\"elementor-testimonial-meta-inner\">\n\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-testimonial-image\">\n\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"226\" height=\"226\" src=\"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/10\/rodri.webp\" class=\"attachment-full size-full wp-image-273\" alt=\"Rodrigo\" srcset=\"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/10\/rodri.webp 226w, https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/10\/rodri-150x150.webp 150w\" sizes=\"(max-width: 226px) 100vw, 226px\" \/>\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-testimonial-details\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-testimonial-name\">Rodrigo S\u00e1nchez<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"elementor-testimonial-job\">Software Developer<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1690f8a8 e-flex e-con-boxed e-con e-parent\" data-id=\"1690f8a8\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-32aacfc0 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"32aacfc0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1b81eae4 e-flex e-con-boxed e-con e-parent\" data-id=\"1b81eae4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4e5f601f elementor-widget elementor-widget-image\" data-id=\"4e5f601f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" width=\"768\" height=\"433\" src=\"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post-768x433.webp\" class=\"attachment-medium_large size-medium_large wp-image-197\" alt=\"Nodes connected\" srcset=\"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post-768x433.webp 768w, https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post-300x169.webp 300w, https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post-1024x577.webp 1024w, https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp 1400w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-79bba47 e-flex e-con-boxed e-con e-parent\" data-id=\"79bba47\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-75a4d1db elementor-widget elementor-widget-text-editor\" data-id=\"75a4d1db\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"2dcc\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">At Clovr Labs, we developed NodeGuard, a treasury management system that allows people to have money secured behind multi-signature wallets (among other features). One of the benefits of multi-signature wallets is that because of how they are constructed, a \u201ccontract\u201d prevents a single person from owning the funds. For money to change hands, multiple people must sign the operation to approve the ownership change.<\/p><p id=\"fc8a\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">To make signing more straightforward, we\u2019re developing a browser extension allowing people to import their seeds and sign an operation. This extension will be open-sourced in the future. It will be open for everyone to use, not only in the NodeGuard application but with their own applications.<\/p><p id=\"d497\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">Now, let\u2019s talk about multi-signature wallets, AKA multi-sig wallets. As stated before, multi-sig wallets are wallets in which the ownership of funds belongs to more than one person at a time. In addition, multi-sig wallets are referred to by the \u201cM-of-N\u201d description, where \u201cN\u201d denotes the number of total signers \u201cagreeing\u201d to construct the wallet. In contrast, \u201cM\u201d represents the number of signers required to do an operation or \u201ctransaction\u201d with these funds.<\/p><p id=\"30db\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">Let\u2019s set an example. Imagine I belong to a group of 3 friends, and we constructed a 2-of-3 multi-sig wallet together. That means that the 3 of us \u201cagreed\u201d to create a wallet together, and we would only need the signature of 2 friends to change ownership of funds. Since we want to send funds to a different wallet, another friend and I must sign off on a transaction. Even though my other friend \u201cagreed\u201d to be part of the wallet, they are not needed to sign.<\/p><p id=\"cf21\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">Let\u2019s do another example. I have a friend who has a business in which he has one other partner. My friend comes from a construction background, and his partner comes from an architecture background; they don\u2019t trust each other but decided to go into a business together because they complement each other well. They decided to create a Bitcoin 2-of-2 multi-sig wallet. In this scenario, they both agreed to make the wallet. The contract specifies that both signatures are needed to transact with their funds.<\/p><p id=\"0904\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">As you see, the flexibility of M-of-N wallets allows for a world of possibilities in which funds are secured via many different configurations: 3-of-6, 2-of-2, etc.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-16e48bc3 e-flex e-con-boxed e-con e-parent\" data-id=\"16e48bc3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-26cb0377 elementor-alert-warning elementor-widget elementor-widget-alert\" data-id=\"26cb0377\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"alert.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-alert\" role=\"alert\">\n\n\t\t\t\t\t\t<span class=\"elementor-alert-title\">In this article, we will learn how to sign off on a transaction by multiple people using the Rust language. But first, we need to learn a few concepts that will allow us to understand the code better.<\/span>\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7926aff e-flex e-con-boxed e-con e-parent\" data-id=\"7926aff\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-fd48688 elementor-widget elementor-widget-spacer\" data-id=\"fd48688\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-de64652 e-flex e-con-boxed e-con e-parent\" data-id=\"de64652\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ac48a91 elementor-widget elementor-widget-heading\" data-id=\"ac48a91\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 Wallet<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-48ba30e0 e-flex e-con-boxed e-con e-parent\" data-id=\"48ba30e0\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-787d40fb elementor-widget elementor-widget-text-editor\" data-id=\"787d40fb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We talked about multi-sig wallets, but how are they constructed? We mentioned in the last part that we need to sign something (we\u2019ll talk about what later) to perform a transaction. The way signatures work in Bitcoin is pretty much how a safe work in real life. To access the content of a safe, you need to prove that you know the safe combination. In comparison, to see that you have ownership of funds in Bitcoin, you need to prove that you own a \u201cprivate key\u201d, which is a 256-bit number. This private key can be encoded as 64 hexadecimal characters so humans can easily read it. In the case of a 2-of-3 multi-sig wallet, you can imagine a safe with 3 keypads, but only two out of the 3 combinations are needed to be input to open it. So in the case of a Bitcoin wallet, you (or your friends) need to prove that they know 2 of the private keys to sign off on a transaction.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-63060cf e-flex e-con-boxed e-con e-parent\" data-id=\"63060cf\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-63d94f6 elementor-widget elementor-widget-heading\" data-id=\"63d94f6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 Public Keys<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-db08f12 e-flex e-con-boxed e-con e-parent\" data-id=\"db08f12\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-655dcd7 elementor-widget elementor-widget-text-editor\" data-id=\"655dcd7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>A public key is an essential part of how wallets work. It is the face of a wallet and how wallets are constructed. The public key is derived from the private key and generates an address for receiving Bitcoin. The derivation of a public key is one way; even if someone knows your public key, they cannot retrieve the private key from it. Public keys are combined to generate an address to receive funds in a multi-sig wallet. Once funds are transferred to that address, private keys can be used to prove the ownership of that public key and \u201cunlock\u201d the funds for further expending. This is one of the main reasons you see that whenever someone loses their wallet keys, the funds are lost forever since it\u2019s impossible to reconstruct the private key from a public key. And the possibilities of guessing a private key, even with powerful computers, are astronomically small.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-bbddfb6 e-flex e-con-boxed e-con e-parent\" data-id=\"bbddfb6\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3965330 elementor-widget elementor-widget-heading\" data-id=\"3965330\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 Derivation Path<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7ae25e4 e-flex e-con-boxed e-con e-parent\" data-id=\"7ae25e4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a8815aa elementor-widget elementor-widget-text-editor\" data-id=\"a8815aa\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>A Bitcoin wallet uses a derivation path to derive multiple public keys and, in turn, create infinitely different Bitcoin addresses for the same wallet. You can think of derivation paths as other safes belonging to the same person that lives in different buildings, cities and countries. To unlock money from a safe, we first need to know the country, city, building, room and safe number. With that information, we know which safe to input the password, and the password we\u2019ll use will depend on the safe number. In Bitcoin, in contrast, the passwords from the different safes in a room can be derived from the password that unlocks the door of the room. Which also is safe if you think of a room as a big safe with a password-protected door. We\u2019ll not talk about some other complexities regarding derivation paths here. But to sign off on a transaction, we first need to know in which \u201csafe\u201d the money is and if we can prove ownership of the secret to use that money.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-84093e7 e-flex e-con-boxed e-con e-parent\" data-id=\"84093e7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3ed419d elementor-widget elementor-widget-heading\" data-id=\"3ed419d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 Fingerprint<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4a49946 e-flex e-con-boxed e-con e-parent\" data-id=\"4a49946\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ef1ced3 elementor-widget elementor-widget-text-editor\" data-id=\"ef1ced3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>A fingerprint is a more compact version of a private key. As the name suggests, it identifies a private key without using the long private key itself. In our case, we\u2019ll use it to quickly verify that our private key can be used to sign a transaction and prove that the money is ours before signing off on the transaction.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-07101d4 e-flex e-con-boxed e-con e-parent\" data-id=\"07101d4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-077468e elementor-widget elementor-widget-heading\" data-id=\"077468e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 Inputs<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-bcf211e e-flex e-con-boxed e-con e-parent\" data-id=\"bcf211e\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7887471 elementor-widget elementor-widget-text-editor\" data-id=\"7887471\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"fc04\" class=\"pw-post-body-paragraph vz wa rl lz b wc xp we wf wg xq wi wj lj xr wl wm lo xs wo wp lt xt wr ws wt ft bj\" data-selectable-paragraph=\"\">Inputs consist of information saying where the money comes from, a reference to previous transaction outputs, and information proving that the funds we want to use are authorized to be spent. Every time you do a transaction, e.g., spend money in Bitcoin, a transaction id is generated as the output of that transaction. The input contains the id of the previous transaction being made, so you can trace the money back until it was created. Because an earlier transaction can be done with more than one input, an index is necessary to identify which transaction inputs are being spent. This is somewhat difficult to follow, so let\u2019s see the anatomy of a transaction:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-11eb3474 e-flex e-con-boxed e-con e-parent\" data-id=\"11eb3474\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4c2378cd elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"4c2378cd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    Transaction: TXID: f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16\n    Input 1: a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d (vout 0)\n    Input 2: 4ce18f49ba153a51bcda9bb80d7f978e3de6e81b5fc326f00465464530c052f4 (vout 2)\n    Output 1: 1 BTC to mvhMvZi4m17c8YR44YB64LisKYA3NbqBvS\n    Output 2: 1 BTC to mgYJwtk2SWLcBbuNGnUV4dza1MERoHA9SR\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6d594ac5 e-flex e-con-boxed e-con e-parent\" data-id=\"6d594ac5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-495ead8d elementor-widget elementor-widget-text-editor\" data-id=\"495ead8d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>As you can see, a transaction id (TXID) was generated for this transaction. In this case, my transaction has two outputs to two different wallets, and we\u2019re transferring 1 BTC to each wallet. We also have inputs 1 and 2; they have the transaction id of the previous one and an index called \u201cvout\u201d that references which of the previous transaction outputs is being spent. In this example, the transaction is spending the Output number 1 (vout 0) of the previous transaction <strong>a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d<\/strong>, and the Output number 3 (vout 2) of the last transaction <strong>4ce18f49ba153a51bcda9bb80d7f978e3de6e81b5fc326f00465464530c052f<\/strong> of the previous transaction 4. And all that money spent is going into the addresses <strong>mvhMvZi4m17c8YR44YB64LisKYA3NbqBvS<\/strong> and <strong>mgYJwtk2SWLcBbuNGnUV4dza1MERoHA9SR<\/strong>.<\/p><p id=\"c03a\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">As stated before, another vital piece of information that input contains is a script that proves that the funds someone is about to spend are authorized to be spent by that person. This proof is done by providing a signature that matches this script. As you can see, signatures are not like the ones you do on a piece of paper, but they are a way to prove that you are the owner of funds, and you need to have a private key to prove that ownership. This script that the input contains is called an \u201cUnlocking Script\u201d because it provides the information you need to verify to unlock the funds. And to \u201csign off\u201d on a transaction, you need to give this signature and add them to the input data structure.<\/p><p id=\"bf49\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">We saw that inputs reference previous transaction outputs, which contain information on how the money can be spent. The name of this unspent transaction output is called UTXO. Let\u2019s talk about them.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-61ab080 e-flex e-con-boxed e-con e-parent\" data-id=\"61ab080\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c89c240 elementor-widget elementor-widget-heading\" data-id=\"c89c240\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 UTXO<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4efb0686 e-flex e-con-boxed e-con e-parent\" data-id=\"4efb0686\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2c0fe76 elementor-widget elementor-widget-text-editor\" data-id=\"2c0fe76\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"fd10\" class=\"pw-post-body-paragraph vz wa rl lz b wc xp we wf wg xq wi wj lj xr wl wm lo xs wo wp lt xt wr ws wt ft bj\" data-selectable-paragraph=\"\">An Unspent Transaction Output, UTXO for short, is the output of a previous transaction that remains to be spent. If you received the money in your Bitcoin wallet and never spent it, then you are the proud owner of UTXOs. If you spend those UTXOs, they will be used as inputs for a new transaction.<\/p><p id=\"e01f\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">And most important for what we need to do, a UTXO contains information about the conditions to spend the money. There are a lot of \u201ccontracts\u201d in Bitcoin for spending money. You can have sequence-based contracts defining that the money can be spent after several blocks have been mined. You can have time-based contracts where you can only spend the money after a specific time. You can have \u201ccustom\u201d contracts that let the owner of the money specify how to satisfy the contract to unlock the funds. These \u201ccontracts\u201d are called \u201cUnlocking Scripts\u201d. For our purposes, and because we need to ensure we are gathering the required number of signatures, we\u2019re interested in multi-signature \u201cPay to Script Hash\u201d unlocking scripts, one of the \u201ccustom\u201d contracts we mentioned earlier. In our case, the enforcer of spending conditions is a script containing the public keys of the people that can sign and the number of signatures required to fulfil the spending condition. A pay-to-script hash can look like this:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-18d2ce11 e-flex e-con-boxed e-con e-parent\" data-id=\"18d2ce11\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-5ef2e689 e-flex e-con-boxed e-con e-child\" data-id=\"5ef2e689\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-150626db elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"150626db\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    <span class=\"red\">2<\/span> PubKey1 PubKey2 PubKey3 <span class=\"red\">3<\/span> CHECKMULTISIG\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-2bdd070f e-flex e-con-boxed e-con e-parent\" data-id=\"2bdd070f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-68377a39 elementor-widget elementor-widget-text-editor\" data-id=\"68377a39\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"493a\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">Let\u2019s look at this and see what we can interpret from it. At first sight, we can see <strong>CHECKMULTISIG<\/strong> written on the script. This is the \u201ctype\u201d of the script, and it tells the code how to interpret the rest of the numbers and characters appearing in the rest of the script. Bitcoin scripts are read from right to left, so <strong>CHECKMULTISIG<\/strong> is the first thing read by the code. Thanks to <strong>CHECKMULTISIG<\/strong>, the code can interpret the numbers 2 and 3, which are the descriptors of the wallet allowed to spend the money. In this case, we\u2019re looking at a 2-of-3 multi-sig wallet. We need to prove that 2 out of the 3 public keys also appearing in this script can be derived from our private keys.<\/p><p id=\"e2c0\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">So you see, between inputs and outputs, we have all the information needed to prove who is the current owner of the funds (the locking script), that the current owner of the funds allowed the transfer of funds to a different wallet (e.g. they spent the money), how to prove that we are the new owner of the money after the transaction is being done (the unlocking script), where the money comes from and where the money is going to.<\/p><p id=\"63ee\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">One thing I skipped about the script we are using is that there are two types of those: those that have \u201cSegregated Witness\u201d and those that don\u2019t. Since we\u2019ll need to know the difference to sign off on this transaction, we\u2019ll explain these two types as our next concept.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7d1c81c e-flex e-con-boxed e-con e-parent\" data-id=\"7d1c81c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5f22d79 elementor-widget elementor-widget-heading\" data-id=\"5f22d79\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 Segregated Witness<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7b95dff e-flex e-con-boxed e-con e-parent\" data-id=\"7b95dff\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7ef0b46 elementor-widget elementor-widget-text-editor\" data-id=\"7ef0b46\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"493a\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">Segregated Witness, or SegWit, is the name assigned to an improved version of the Bitcoin protocol in 2017. Before that moment, and as we saw in the previous concept, the transaction data contained the ids of the last transaction\u2019s outputs being spent, along with the signatures that prove who the money about to be spent belongs to. As signature data can be quite large and substantially increase the size of a Bitcoin transaction, a decision to change how a transaction is constructed was made to separate the signature information into a different data structure. With this change, when the size of the transaction is calculated, the signature information is not counted as part of that size (but still very much included in the block), and since a Bitcoin block size limit is 4MB, the reduction in the size of the transaction data allows for more transactions to be included in a single block (neat trick huh?). Since the blockchain has the recorded information of all transactions being made from the beginning, and because some people might still be using the older version, there is no way to \u201cdeprecate\u201d or enforce this change for everyone. So the two versions of the blockchain (SegWit and not Segwit) coexist and can be used. However, SegWit is recommended and also incurs fewer transaction fees.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-68b6fa9 e-flex e-con-boxed e-con e-parent\" data-id=\"68b6fa9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-727fbf5 elementor-widget elementor-widget-heading\" data-id=\"727fbf5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 Sighash<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-e92c2c3 e-flex e-con-boxed e-con e-parent\" data-id=\"e92c2c3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d0c12f9 elementor-widget elementor-widget-text-editor\" data-id=\"d0c12f9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"493a\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">A Sighash is a hash of the transaction data that we\u2019ll \u201c combine\u201d with the signature to sign the inputs. This is useful for verification because the hash wouldn\u2019t match the signature if the data inside a transaction is modified. There are different types of sighashes: <strong>SIGHASH_ALL, SIGHASH_NONE, SIGHASH_SINGLE<\/strong> and <strong>SIGHASH_ANYONECANPAY.<\/strong> They all describe what information about the inputs and outputs will be included when creating the transaction hash.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-e0589f9 e-flex e-con-boxed e-con e-parent\" data-id=\"e0589f9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-78ce1c2 elementor-widget elementor-widget-heading\" data-id=\"78ce1c2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h4 class=\"elementor-heading-title elementor-size-default\">\ud83d\udd39 PSBT<\/h4>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-210f928 e-flex e-con-boxed e-con e-parent\" data-id=\"210f928\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7b4ab9b elementor-widget elementor-widget-text-editor\" data-id=\"7b4ab9b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"2380\" class=\"pw-post-body-paragraph vz wa rl lz b wc xp we wf wg xq wi wj lj xr wl wm lo xs wo wp lt xt wr ws wt ft bj\" data-selectable-paragraph=\"\">Finally, we reached the part of the article where we\u2019ll explain where all the concepts we mentioned earlier live. One of the ways an operation could be signed in a multi-sig wallet is via a Partially Signed Bitcoin Transaction (PSBT). A PSBT is a paper containing all the relevant transaction information. This includes the amount of Bitcoin to be spent, the total number of members of a wallet (N), and the required members of a wallet (M) that need to sign to do a transaction; The inputs and outputs, the witnesses and the UTXOs. PSBTs are only sometimes necessary to do multi-sig transactions and can also be used to sign single transactions. A PSBT is helpful because it provides another layer of security and privacy since it can be constructed and signed offline, minimizing the risk of exposing private keys.<\/p><p id=\"020a\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">The reason it\u2019s called \u201cPartially Signed\u201d is because it works like an actual contract. Each party has to individually sign the contract and then pass it along to the next signer. So if you encounter a PSBT in the wild, it can be in 3 states: Not signed, partially signed or fully signed. The fully signed state is reached once all required signers have added their unlocking script into the PSBT. So to \u201csign\u201d a PSBT, you need to read the inputs from the PSBT and create the Unlocking Scripts for each. Let\u2019s see how this looks in the Rust code. For this article, we\u2019ll only sign inputs with segregated witnesses.<\/p><p id=\"557a\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">The crates we\u2019ll use for this article are the \u201cbitcoin\u201d crate for manipulating our PSBT and the \u201canyhow\u201d crate for handling the errors.<\/p><p id=\"e073\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">First, we\u2019ll create the signature of our function. It will receive a psbt, a private key and a derivation path that we\u2019ll use to derive the private key for that specific location (remember the \u201csafe\u201d concept)<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1587824 e-flex e-con-boxed e-con e-parent\" data-id=\"1587824\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-505c95f e-flex e-con-boxed e-con e-child\" data-id=\"505c95f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d16f952 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"d16f952\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    fn sign_psbt(\n        mut psbt: PartiallySignedTransaction,\n        xprv: ExtendedPrivKey,\n        derivation: &DerivationPath,\n    ) -&gt; Result&lt;PartiallySignedTransaction&gt; {\n        ...\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-119ca77 e-flex e-con-boxed e-con e-parent\" data-id=\"119ca77\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b2d3189 elementor-widget elementor-widget-text-editor\" data-id=\"b2d3189\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Next, we\u2019ll iterate over all the inputs we need to sign. We\u2019ll also need an index of the input to be later able to construct the signature. Everything we\u2019ll do from now on will be inside this for a loop.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-0755f3f e-flex e-con-boxed e-con e-parent\" data-id=\"0755f3f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-13230c9 e-flex e-con-boxed e-con e-child\" data-id=\"13230c9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-78a80ad elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"78a80ad\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    for (index, input) in psbt.inputs.iter_mut().enumerate() {\n        ...\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-e4843e5 e-flex e-con-boxed e-con e-parent\" data-id=\"e4843e5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-90d5725 elementor-widget elementor-widget-text-editor\" data-id=\"90d5725\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We get the witness script, which contains the signatures from the current owners of the outputs being spent in this transaction. This will be used to verify the transaction inputs. Since we\u2019re only coding for segregated witnesses, we\u2019ll throw an error if this information is not available and let the parent of this function handle it.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-cd5cb61 e-flex e-con-boxed e-con e-parent\" data-id=\"cd5cb61\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-f70861d e-flex e-con-boxed e-con e-child\" data-id=\"f70861d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b71b791 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"b71b791\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    let witness_script = input\n        .witness_script\n        .as_ref()\n        .context(\"Missing witness script\")?;\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b61de43 e-flex e-con-boxed e-con e-parent\" data-id=\"b61de43\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-97298d7 elementor-widget elementor-widget-text-editor\" data-id=\"97298d7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"ba88\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">We get the amount from the UTXO, and as before, we\u2019ll let the parent function handle the missing witness.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6cc3a70 e-flex e-con-boxed e-con e-parent\" data-id=\"6cc3a70\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-61e8edf e-flex e-con-boxed e-con e-child\" data-id=\"61e8edf\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3aebb46 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"3aebb46\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    let amount = input\n        .witness_utxo\n        .as_ref()\n        .context(\"Witness utxo not found\")?\n        .value;\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-d345438 e-flex e-con-boxed e-con e-parent\" data-id=\"d345438\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-58ad6dd elementor-widget elementor-widget-text-editor\" data-id=\"58ad6dd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We talked briefly about the sighash before; in these couple of lines, we\u2019ll create the sighash, but we will wait to combine it with our signature. We\u2019ll include all the relevant information, and then we\u2019ll get the sighash to tell the\u00a0<strong>segwit_signature_hash<\/strong>\u00a0what information to add to the hash.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-69e8378 e-flex e-con-boxed e-con e-parent\" data-id=\"69e8378\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-164e553 e-flex e-con-boxed e-con e-child\" data-id=\"164e553\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e0c4393 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"e0c4393\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    let mut sighash_cache = SighashCache::new(&psbt.unsigned_tx);\n    let sighash = sighash_cache.segwit_signature_hash(\n        index,\n        witness_script,\n        amount,\n        get_sighash_type(input),\n    )?;\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-25f88eb e-flex e-con-boxed e-con e-parent\" data-id=\"25f88eb\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8e8447f elementor-widget elementor-widget-text-editor\" data-id=\"8e8447f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tIn the last part of the code, we invoke a function called\u00a0<strong>get_sighash_type<\/strong>; this function gets the sighash type information from the input created when the PSBT was created. If that information was not included in the input, we default to SIGHASH_ALL.\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4a67bef e-flex e-con-boxed e-con e-parent\" data-id=\"4a67bef\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-3749cd7 e-flex e-con-boxed e-con e-child\" data-id=\"3749cd7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5ab8184 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"5ab8184\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    fn get_sighash_type(input: &Input) -> EcdsaSighashType {\n        input\n            .sighash_type\n            .and_then(|t| t.ecdsa_hash_ty().ok())\n            .unwrap_or(EcdsaSighashType::All)\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-f0a8627 e-flex e-con-boxed e-con e-parent\" data-id=\"f0a8627\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-052eaa0 elementor-widget elementor-widget-text-editor\" data-id=\"052eaa0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"a4c6\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">Continuing our path, we\u2019ll see where the fingerprint we mentioned before becomes useful. We\u2019re using it to compare it against our private key\u2019s fingerprint for any matches. A matching fingerprint would mean we can later prove we have the necessary private key to sign the transaction and own the funds. After verifying that the fingerprint matches, we collect a KeyPair, a tuple of a Public and a Private Key. If there are no matching fingerprints, then we cannot sign the transaction, and that means that the funds we want to spend don\u2019t belong to us. You might be wondering why we are using an array, and that is because there is a possibility that the input has multiple required signatures that can be derived from the same private key. In case we find a matching fingerprint, and before continuing with our signature, we have to derive the private key to get the right combination to our \u201csafe\u201d Let\u2019s see that next.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-bc29a31 e-flex e-con-boxed e-con e-parent\" data-id=\"bc29a31\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-b37d2c7 e-flex e-con-boxed e-con e-child\" data-id=\"b37d2c7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-72fb74f elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"72fb74f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    let mut input_keypairs = Vec::new();\n    for (_, (fingerprint, sub_derivation)) in input.bip32_derivation.iter() {\n        if fingerprint != &xprv.fingerprint(&secp) {\n            continue;\n        }\n        let parent_xprv = derive_relative_xpriv(&xprv, &secp, derivation, sub_derivation)?;\n        input_keypairs.push(parent_xprv.to_keypair(&secp));\n    }\n    if input_keypairs.is_empty() {\n        return Err(anyhow!(\"No private keys to sign this psbt\"));\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-ed7d50d e-flex e-con-boxed e-con e-parent\" data-id=\"ed7d50d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5bf59ab elementor-widget elementor-widget-text-editor\" data-id=\"5bf59ab\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>We saw earlier that to have access to a safe, we needed to know the building, the room and the safe number. And we saw that when having the password to a room, we can derive the passwords to the safes inside it. There is a possibility that a Bitcoin wallet owner knows the master password (e.g. to the building) or just a room\u2019s password. For that reason, to know the password we need to use to open a safe, we need to combine the derivation paths of the password we own with the absolute path we want to reach. And that is what the <strong>get_partial_derivation<\/strong>\u00a0function does. You can think of derivation paths as an array with the coordinates of our safe. For example, [44, 1, 3] could be noted as the country we&#8217;re in (44), the city (1), and the building (3). If I only know the password for the city, then I know the coordinates are [44, 1]. Since the input gives us the final combination to the safe, e.g. [44, 1, 3, 2, 2], we need to derive the password from the city to the safe. Then our\u00a0<strong>get_partial_derivation<\/strong>\u00a0function will give us exactly this partial derivation path: [3, 2, 2]. Our second function, &#8216;derive_relative_xpriv&#8217;, will be responsible for deriving the private key into the one we&#8217;ll need to sign.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-d15e79f e-flex e-con-boxed e-con e-parent\" data-id=\"d15e79f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-6976a9d e-flex e-con-boxed e-con e-child\" data-id=\"6976a9d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-595f1fc elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"595f1fc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    fn get_partial_derivation(\n        derivation: &DerivationPath,\n        sub_derivation: &DerivationPath,\n    ) -&gt; Result&lt;DerivationPath&gt; {\n        if derivation.len() > sub_derivation.len() {\n            return Err(anyhow!(\n                \"Can't get a partial derivation from a derivation greater than the sub derivation\"\n            ));\n        }\n        let partial = &sub_derivation[derivation.len()..];\n        DerivationPath::try_from(partial).map_err(|e| anyhow!(\"{e}\"))\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-6d0fb7d e-flex e-con-boxed e-con e-parent\" data-id=\"6d0fb7d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-9f7e6de e-flex e-con-boxed e-con e-child\" data-id=\"9f7e6de\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b1134a8 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"b1134a8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    fn derive_relative_xpriv(\n        xprv: &ExtendedPrivKey,\n        secp: &Secp256k1&lt;All&gt;,\n        derivation: &DerivationPath,\n        sub_derivation: &DerivationPath,\n    ) -&gt; Result&lt;ExtendedPrivKey&gt; {\n        xprv.derive_priv(secp, &get_partial_derivation(derivation, sub_derivation)?)\n            .map_err(|e| anyhow!(\"{e}\"))\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-4180ad4 e-flex e-con-boxed e-con e-parent\" data-id=\"4180ad4\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c2fd39f elementor-widget elementor-widget-text-editor\" data-id=\"c2fd39f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The final part of our code is just the \u201csigning\u201d. We get the key pairs we collected in the previous steps. We create a\u00a0<strong>Message<\/strong>, a container for all the necessary information to create and sign a valid transaction. Once we construct our message, we can finally sign it and add the partial signature to the input as another tuple, a Public Key &#8211; Signature tuple. But first, we&#8217;ll need to add to the input the information about which sighash type we used to sign the data. This will be used to verify the signature later on.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-450605d e-flex e-con-boxed e-con e-parent\" data-id=\"450605d\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-79d2b04 e-flex e-con-boxed e-con e-child\" data-id=\"79d2b04\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-96fb600 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"96fb600\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    for keypair in input_keypairs {\n        let message = &Message::from_slice(&sighash)?;\n        let signature = secp.sign_ecdsa(message, &keypair.secret_key());\n        input.partial_sigs.insert(\n            PublicKey::new(keypair.public_key()),\n            set_sighash_type(signature, input),\n        );\n        secp.verify_ecdsa(message, &signature, &keypair.public_key())?;\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b5be056 e-flex e-con-boxed e-con e-parent\" data-id=\"b5be056\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-958eb1e elementor-widget elementor-widget-text-editor\" data-id=\"958eb1e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The sighash type is set by using the\u00a0<strong>get_sighash_type<\/strong>\u00a0function we used before and combining it with the signature.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-79ef558 e-flex e-con-boxed e-con e-parent\" data-id=\"79ef558\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-f348375 e-flex e-con-boxed e-con e-child\" data-id=\"f348375\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1211b93 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"1211b93\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    fn set_sighash_type(signature: Signature, input: &Input) -&gt; EcdsaSig {\n        let sighash_type = get_sighash_type(input);\n        EcdsaSig {\n            sig: signature,\n            hash_ty: sighash_type,\n        }\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-ce6e872 e-flex e-con-boxed e-con e-parent\" data-id=\"ce6e872\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5aebedf elementor-widget elementor-widget-text-editor\" data-id=\"5aebedf\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Lastly, out of our inputs for loop, we return the PSBT to the caller of the<strong>\u00a0sign_psbt<\/strong>\u00a0function so that PSBT can be signed by the next signer.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-846762e e-flex e-con-boxed e-con e-parent\" data-id=\"846762e\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-9a72114 e-flex e-con-boxed e-con e-child\" data-id=\"9a72114\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d4ae679 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"d4ae679\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n            }\n        Ok(psbt)\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-61b43fd e-flex e-con-boxed e-con e-parent\" data-id=\"61b43fd\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-391fe98 elementor-widget elementor-widget-text-editor\" data-id=\"391fe98\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p id=\"a62b\" class=\"pw-post-body-paragraph vz wa rl lz b wc wd we wf wg wh wi wj lj wk wl wm lo wn wo wp lt wq wr ws wt ft bj\" data-selectable-paragraph=\"\">You can see the full code below:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-fdbb2f7 e-flex e-con-boxed e-con e-parent\" data-id=\"fdbb2f7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-0ac27dc e-flex e-con-boxed e-con e-child\" data-id=\"0ac27dc\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b6457c8 elementor-widget__width-auto elementor-widget elementor-widget-html\" data-id=\"b6457c8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n  .code-container {\n    overflow-x: auto;\n    margin: 0; \n    padding: 10px;\n    color: white;\n  }\n\n  pre {\n    word-wrap: normal;\n    white-space: pre;\n    max-width: 100%;\n    font-size: 14px; \n  }\n  \n  .red {\n      color: red;\n  }\n\n  @media (max-width: 767px) {\n    .code-container {\n      padding: 0px; \n    }\n    pre {\n      font-size: 11px; \n    }\n  }\n<\/style>\n\n<div class=\"code-container\">\n  <pre>\n    <code>\n    use anyhow::{anyhow, Context, Result};\n    use bitcoin::psbt::Input;\n    use bitcoin::secp256k1::ecdsa::Signature;\n    use bitcoin::secp256k1::{All, Message, Secp256k1};\n    use bitcoin::util::bip32::{DerivationPath, ExtendedPrivKey};\n    use bitcoin::util::psbt::PartiallySignedTransaction;\n    use bitcoin::util::sighash::SighashCache;\n    use bitcoin::{EcdsaSig, EcdsaSighashType, PublicKey};\n    \n    fn set_sighash_type(signature: Signature, input: &Input) -&gt; EcdsaSig {\n        let sighash_type = get_sighash_type(input);\n        EcdsaSig {\n            sig: signature,\n            hash_ty: sighash_type,\n        }\n    }\n    \n    fn get_sighash_type(input: &Input) -&gt; EcdsaSighashType {\n        input\n            .sighash_type\n            .and_then(|t| t.ecdsa_hash_ty().ok())\n            .unwrap_or(EcdsaSighashType::All)\n    }\n    \n    fn get_partial_derivation(\n        derivation: &DerivationPath,\n        sub_derivation: &DerivationPath,\n    ) -&gt; Result&lt;DerivationPath&gt; {\n        if derivation.len() > sub_derivation.len() {\n            return Err(anyhow!(\n                \"Can't get a partial derivation from a derivation greater than the sub derivation\"\n            ));\n        }\n        let partial = &sub_derivation[derivation.len()..];\n        dbg!(&partial);\n        DerivationPath::try_from(partial).map_err(|e| anyhow!(\"{e}\"))\n    }\n    \n    fn derive_relative_xpriv(\n        xprv: &ExtendedPrivKey,\n        secp: &Secp256k1&lt;All&gt;,\n        derivation: &DerivationPath,\n        sub_derivation: &DerivationPath,\n    ) -&gt; Result&lt;ExtendedPrivKey&gt; {\n        xprv.derive_priv(secp, &get_partial_derivation(derivation, sub_derivation)?)\n            .map_err(|e| anyhow!(\"{e}\"))\n    }\n    \n    fn sign_psbt(\n        mut psbt: PartiallySignedTransaction,\n        xprv: ExtendedPrivKey,\n        derivation: &DerivationPath,\n    ) -&gt; Result&lt;PartiallySignedTransaction&gt; {\n        let secp = Secp256k1::new();\n        \/\/ &lt;https:\/\/github.com\/bitcoin\/bips\/blob\/master\/bip-0174.mediawiki#user-content-Signer&gt;\n        for (index, input) in psbt.inputs.iter_mut().enumerate() {\n            let witness_script = input\n                .witness_script\n                .as_ref()\n                .context(\"Missing witness script\")?;\n            let amount = input\n                .witness_utxo\n                .as_ref()\n                .context(\"Witness utxo not found\")?\n                .value;\n            let mut sighash_cache = SighashCache::new(&psbt.unsigned_tx);\n            let sighash = sighash_cache.segwit_signature_hash(\n                index,\n                witness_script,\n                amount,\n                get_sighash_type(input),\n            )?;\n            let mut input_keypairs = Vec::new();\n            for (_, (fingerprint, sub_derivation)) in input.bip32_derivation.iter() {\n                if fingerprint != &xprv.fingerprint(&secp) {\n                    continue;\n                }\n                let parent_xprv = derive_relative_xpriv(&xprv, &secp, derivation, sub_derivation)?;\n                input_keypairs.push(parent_xprv.to_keypair(&secp));\n            }\n            if input_keypairs.is_empty() {\n                return Err(anyhow!(\"No private keys to sign this psbt\"));\n            }\n            for keypair in input_keypairs {\n                let message = &Message::from_slice(&sighash)?;\n                let signature = secp.sign_ecdsa(message, &keypair.secret_key());\n                input.partial_sigs.insert(\n                    PublicKey::new(keypair.public_key()),\n                    set_sighash_type(signature, input),\n                );\n                secp.verify_ecdsa(message, &signature, &keypair.public_key())?;\n            }\n        }\n        Ok(psbt)\n    }\n    <\/code>\n  <\/pre>\n<\/div>\n\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-73e45da e-flex e-con-boxed e-con e-parent\" data-id=\"73e45da\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-89f6abd elementor-alert-warning elementor-widget elementor-widget-alert\" data-id=\"89f6abd\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"alert.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-alert\" role=\"alert\">\n\n\t\t\t\t\t\t<span class=\"elementor-alert-title\">I hope this made sense to you and that you enjoy this content.  See you in the next article!<\/span>\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-648ae166 e-flex e-con-boxed e-con e-parent\" data-id=\"648ae166\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7a4ad628 elementor-widget elementor-widget-spacer\" data-id=\"7a4ad628\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-456dc8e e-flex e-con-boxed e-con e-parent\" data-id=\"456dc8e\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-54396592 elementor-widget elementor-widget-button\" data-id=\"54396592\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-button-wrapper\">\n\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"https:\/\/blog.clovrlabs.com\/\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">\u2190 Back<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>In this article, we will learn how to sign off on a transaction by multiple people using the Rust language. <\/p>\n","protected":false},"author":1,"featured_media":197,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[237,234,239,223],"tags":[241,244],"class_list":["post-194","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-nodeguard-en","category-products-en","category-rust-en","category-technology-en","tag-nodeguard-en","tag-rust-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>NodeGuard Signer Extension: How to sign a PSBT in Rust - Clovr Labs<\/title>\n<meta name=\"description\" content=\"In this article, we will learn how to sign off on a Lightning Network transaction by multiple people using the Rust language.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"NodeGuard Signer Extension: How to sign a PSBT in Rust\" \/>\n<meta property=\"og:description\" content=\"In this article, we will learn how to sign off on a Lightning Network transaction by multiple people using the Rust language.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/\" \/>\n<meta property=\"og:site_name\" content=\"Clovr Labs\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-25T11:00:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-21T11:47:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1400\" \/>\n\t<meta property=\"og:image:height\" content=\"789\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"clovrblog\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"clovrblog\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/\"},\"author\":{\"name\":\"clovrblog\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#\\\/schema\\\/person\\\/a6b5b6390ea72a5e384639ee38c0fd88\"},\"headline\":\"NodeGuard Signer Extension: How to sign a PSBT in Rust\",\"datePublished\":\"2023-09-25T11:00:44+00:00\",\"dateModified\":\"2024-06-21T11:47:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/\"},\"wordCount\":3321,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blog.clovrlabs.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/nodeguard-post.webp\",\"keywords\":[\"NodeGuard\",\"Rust\"],\"articleSection\":[\"NodeGuard\",\"Products\",\"Rust\",\"Technology\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/\",\"url\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/\",\"name\":\"NodeGuard Signer Extension: How to sign a PSBT in Rust - Clovr Labs\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blog.clovrlabs.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/nodeguard-post.webp\",\"datePublished\":\"2023-09-25T11:00:44+00:00\",\"dateModified\":\"2024-06-21T11:47:29+00:00\",\"description\":\"In this article, we will learn how to sign off on a Lightning Network transaction by multiple people using the Rust language.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/#primaryimage\",\"url\":\"https:\\\/\\\/blog.clovrlabs.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/nodeguard-post.webp\",\"contentUrl\":\"https:\\\/\\\/blog.clovrlabs.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/nodeguard-post.webp\",\"width\":1400,\"height\":789,\"caption\":\"Nodes connected\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/en\\\/nodeguard-signer-extension\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"NodeGuard Signer Extension: How to sign a PSBT in Rust\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/\",\"name\":\"Clovr Labs Blog\",\"description\":\"Blog\",\"publisher\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#organization\",\"name\":\"Clovr Labs Blog\",\"url\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/blog.clovrlabs.com\\\/wp-content\\\/uploads\\\/2024\\\/06\\\/CL-LOGO-BLACK-VECTOR.png\",\"contentUrl\":\"https:\\\/\\\/blog.clovrlabs.com\\\/wp-content\\\/uploads\\\/2024\\\/06\\\/CL-LOGO-BLACK-VECTOR.png\",\"width\":2059,\"height\":291,\"caption\":\"Clovr Labs Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/es.linkedin.com\\\/company\\\/clovrlabsbcn\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#\\\/schema\\\/person\\\/a6b5b6390ea72a5e384639ee38c0fd88\",\"name\":\"clovrblog\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c0cd7a51aa9dd8213d8339eaed5d20be5f089e99e66002c68301e81316f13f52?s=96&d=retro&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c0cd7a51aa9dd8213d8339eaed5d20be5f089e99e66002c68301e81316f13f52?s=96&d=retro&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c0cd7a51aa9dd8213d8339eaed5d20be5f089e99e66002c68301e81316f13f52?s=96&d=retro&r=g\",\"caption\":\"clovrblog\"},\"sameAs\":[\"http:\\\/\\\/127.0.0.1\"],\"url\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/author\\\/clovrblog\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"NodeGuard Signer Extension: How to sign a PSBT in Rust - Clovr Labs","description":"In this article, we will learn how to sign off on a Lightning Network transaction by multiple people using the Rust language.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/","og_locale":"en_GB","og_type":"article","og_title":"NodeGuard Signer Extension: How to sign a PSBT in Rust","og_description":"In this article, we will learn how to sign off on a Lightning Network transaction by multiple people using the Rust language.","og_url":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/","og_site_name":"Clovr Labs","article_published_time":"2023-09-25T11:00:44+00:00","article_modified_time":"2024-06-21T11:47:29+00:00","og_image":[{"width":1400,"height":789,"url":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp","type":"image\/webp"}],"author":"clovrblog","twitter_card":"summary_large_image","twitter_misc":{"Written by":"clovrblog","Estimated reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/#article","isPartOf":{"@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/"},"author":{"name":"clovrblog","@id":"https:\/\/clovrlabs.com\/blog\/#\/schema\/person\/a6b5b6390ea72a5e384639ee38c0fd88"},"headline":"NodeGuard Signer Extension: How to sign a PSBT in Rust","datePublished":"2023-09-25T11:00:44+00:00","dateModified":"2024-06-21T11:47:29+00:00","mainEntityOfPage":{"@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/"},"wordCount":3321,"commentCount":0,"publisher":{"@id":"https:\/\/clovrlabs.com\/blog\/#organization"},"image":{"@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp","keywords":["NodeGuard","Rust"],"articleSection":["NodeGuard","Products","Rust","Technology"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/","url":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/","name":"NodeGuard Signer Extension: How to sign a PSBT in Rust - Clovr Labs","isPartOf":{"@id":"https:\/\/clovrlabs.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/#primaryimage"},"image":{"@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp","datePublished":"2023-09-25T11:00:44+00:00","dateModified":"2024-06-21T11:47:29+00:00","description":"In this article, we will learn how to sign off on a Lightning Network transaction by multiple people using the Rust language.","breadcrumb":{"@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/#primaryimage","url":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp","contentUrl":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp","width":1400,"height":789,"caption":"Nodes connected"},{"@type":"BreadcrumbList","@id":"https:\/\/clovrlabs.com\/blog\/en\/nodeguard-signer-extension\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/clovrlabs.com\/blog\/es\/"},{"@type":"ListItem","position":2,"name":"NodeGuard Signer Extension: How to sign a PSBT in Rust"}]},{"@type":"WebSite","@id":"https:\/\/clovrlabs.com\/blog\/#website","url":"https:\/\/clovrlabs.com\/blog\/","name":"Clovr Labs Blog","description":"Blog","publisher":{"@id":"https:\/\/clovrlabs.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/clovrlabs.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/clovrlabs.com\/blog\/#organization","name":"Clovr Labs Blog","url":"https:\/\/clovrlabs.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/clovrlabs.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2024\/06\/CL-LOGO-BLACK-VECTOR.png","contentUrl":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2024\/06\/CL-LOGO-BLACK-VECTOR.png","width":2059,"height":291,"caption":"Clovr Labs Blog"},"image":{"@id":"https:\/\/clovrlabs.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/es.linkedin.com\/company\/clovrlabsbcn"]},{"@type":"Person","@id":"https:\/\/clovrlabs.com\/blog\/#\/schema\/person\/a6b5b6390ea72a5e384639ee38c0fd88","name":"clovrblog","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/c0cd7a51aa9dd8213d8339eaed5d20be5f089e99e66002c68301e81316f13f52?s=96&d=retro&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c0cd7a51aa9dd8213d8339eaed5d20be5f089e99e66002c68301e81316f13f52?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c0cd7a51aa9dd8213d8339eaed5d20be5f089e99e66002c68301e81316f13f52?s=96&d=retro&r=g","caption":"clovrblog"},"sameAs":["http:\/\/127.0.0.1"],"url":"https:\/\/clovrlabs.com\/blog\/author\/clovrblog\/"}]}},"_links":{"self":[{"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/posts\/194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/comments?post=194"}],"version-history":[{"count":0,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/posts\/194\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/media\/197"}],"wp:attachment":[{"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/media?parent=194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/categories?post=194"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/tags?post=194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}