{"id":1647,"date":"2023-09-25T17:54:06","date_gmt":"2023-09-25T15:54:06","guid":{"rendered":"https:\/\/blog.clovrlabs.com\/?p=1647"},"modified":"2024-06-28T18:13:53","modified_gmt":"2024-06-28T16:13:53","slug":"extension-nodeguard-signer-como-firmar-un-psbt-en-rust","status":"publish","type":"post","link":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/","title":{"rendered":"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"1647\" class=\"elementor elementor-1647\">\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\">Nota: La IA no ha escrito este art\u00edculo. Esto es precisamente lo que dir\u00eda una IA, \u00bfno? Sospechoso \ud83e\udd14...<\/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>En Clovr Labs, desarrollamos NodeGuard, un sistema de gesti\u00f3n de tesorer\u00eda que permite asegurar dinero detr\u00e1s de billeteras con m\u00faltiples firmas (entre otras caracter\u00edsticas). Uno de los beneficios de las billeteras con m\u00faltiples firmas es que, debido a su construcci\u00f3n, un \u201ccontrato\u201d impide que una sola persona posea los fondos. Para que el dinero cambie de manos, m\u00faltiples personas deben firmar la operaci\u00f3n para aprobar el cambio de propiedad.<\/p><p>Para facilitar la firma, estamos desarrollando una extensi\u00f3n de navegador que permite a las personas importar sus semillas y firmar una operaci\u00f3n. Esta extensi\u00f3n ser\u00e1 de c\u00f3digo abierto en el futuro. Estar\u00e1 disponible para que todos la usen, no solo en la aplicaci\u00f3n NodeGuard, sino tambi\u00e9n en sus propias aplicaciones.<\/p><p>Ahora, hablemos de las billeteras de m\u00faltiples firmas, tambi\u00e9n conocidas como billeteras multi-sig. Como se mencion\u00f3 antes, las billeteras multi-sig son billeteras en las que la propiedad de los fondos pertenece a m\u00e1s de una persona a la vez. Adem\u00e1s, las billeteras multi-sig se describen mediante el t\u00e9rmino \u201cM-de-N\u201d, donde \u201cN\u201d denota el n\u00famero total de firmantes que \u201cacuerdan\u201d construir la billetera, mientras que \u201cM\u201d representa el n\u00famero de firmantes necesarios para realizar una operaci\u00f3n o \u201ctransacci\u00f3n\u201d con estos fondos.<\/p><p>Pongamos un ejemplo. Imagina que pertenezco a un grupo de 3 amigos y juntos construimos una billetera multi-sig de 2-de-3. Eso significa que los 3 \u201cacordamos\u201d crear una billetera juntos, y solo necesitar\u00edamos la firma de 2 amigos para cambiar la propiedad de los fondos. Como queremos enviar fondos a otra billetera, otro amigo y yo debemos firmar la transacci\u00f3n. Aunque mi otro amigo \u201cacord\u00f3\u201d ser parte de la billetera, no es necesario que firme.<\/p><p>Hagamos otro ejemplo. Tengo un amigo que tiene un negocio con otro socio. Mi amigo viene del sector de la construcci\u00f3n y su socio del sector de la arquitectura; no conf\u00edan el uno en el otro, pero decidieron emprender juntos porque se complementan bien. Decidieron crear una billetera Bitcoin multi-sig de 2-de-2. En este escenario, ambos acordaron crear la billetera. El contrato especifica que se necesitan ambas firmas para transaccionar con sus fondos.<\/p><p>Como puedes ver, la flexibilidad de las billeteras M-de-N permite un mundo de posibilidades en las que los fondos est\u00e1n asegurados mediante muchas configuraciones diferentes: 3-de-6, 2-de-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\">En este art\u00edculo, aprenderemos c\u00f3mo firmar una transacci\u00f3n por varias personas utilizando el lenguaje Rust. Pero antes, necesitamos aprender algunos conceptos que nos permitir\u00e1n entender mejor el c\u00f3digo.<\/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>Hablamos sobre las billeteras multi-sig, pero \u00bfc\u00f3mo se construyen? Mencionamos en la \u00faltima parte que necesitamos firmar algo (hablaremos de qu\u00e9 m\u00e1s adelante) para realizar una transacci\u00f3n. La forma en que funcionan las firmas en Bitcoin es muy similar a c\u00f3mo funciona una caja fuerte en la vida real. Para acceder al contenido de una caja fuerte, necesitas demostrar que conoces la combinaci\u00f3n. De manera comparativa, para demostrar que tienes la propiedad de fondos en Bitcoin, necesitas demostrar que posees una &#8220;clave privada&#8221;, que es un n\u00famero de 256 bits. Esta clave privada puede codificarse como 64 caracteres hexadecimales para que los humanos puedan leerla f\u00e1cilmente. En el caso de una billetera multi-sig de 2-de-3, puedes imaginar una caja fuerte con 3 teclados, pero solo se necesitan dos de las 3 combinaciones para abrirla. As\u00ed que, en el caso de una billetera de Bitcoin, t\u00fa (o tus amigos) necesitan demostrar que conocen 2 de las claves privadas para firmar una transacci\u00f3n.<\/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 Claves p\u00fablicas<\/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>Una clave p\u00fablica es una parte esencial de c\u00f3mo funcionan las billeteras. Es la cara de una billetera y c\u00f3mo se construyen las billeteras. La clave p\u00fablica se deriva de la clave privada y genera una direcci\u00f3n para recibir Bitcoin. La derivaci\u00f3n de una clave p\u00fablica es unidireccional; incluso si alguien conoce tu clave p\u00fablica, no puede recuperar la clave privada a partir de ella. Las claves p\u00fablicas se combinan para generar una direcci\u00f3n para recibir fondos en una billetera multi-sig. Una vez que los fondos se transfieren a esa direcci\u00f3n, se pueden usar las claves privadas para demostrar la propiedad de esa clave p\u00fablica y \u201cdesbloquear\u201d los fondos para gastarlos. Esta es una de las principales razones por las que, cuando alguien pierde las claves de su billetera, los fondos se pierden para siempre, ya que es imposible reconstruir la clave privada a partir de una clave p\u00fablica. Y las posibilidades de adivinar una clave privada, incluso con computadoras potentes, son astron\u00f3micamente peque\u00f1as.<\/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 Ruta de derivaci\u00f3n<\/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>Una billetera de Bitcoin utiliza una ruta de derivaci\u00f3n para derivar m\u00faltiples claves p\u00fablicas y, a su vez, crear infinitas direcciones de Bitcoin diferentes para la misma billetera. Puedes pensar en las rutas de derivaci\u00f3n como otras cajas fuertes pertenecientes a la misma persona que se encuentran en diferentes edificios, ciudades y pa\u00edses. Para desbloquear el dinero de una caja fuerte, primero necesitamos saber el pa\u00eds, la ciudad, el edificio, la habitaci\u00f3n y el n\u00famero de la caja fuerte. Con esa informaci\u00f3n, sabemos en qu\u00e9 caja fuerte introducir la contrase\u00f1a, y la contrase\u00f1a que usaremos depender\u00e1 del n\u00famero de la caja fuerte.<\/p><p>En Bitcoin, en cambio, las contrase\u00f1as de las diferentes cajas fuertes en una habitaci\u00f3n pueden derivarse de la contrase\u00f1a que desbloquea la puerta de la habitaci\u00f3n. Esto tambi\u00e9n es seguro si piensas en una habitaci\u00f3n como una gran caja fuerte con una puerta protegida por contrase\u00f1a. No hablaremos aqu\u00ed de algunas otras complejidades respecto a las rutas de derivaci\u00f3n. Pero, para firmar una transacci\u00f3n, primero necesitamos saber en qu\u00e9 &#8220;caja fuerte&#8221; est\u00e1 el dinero y si podemos demostrar la propiedad del secreto para usar ese dinero.<\/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 Huella dactilar<\/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<div class=\"flex-shrink-0 flex flex-col relative items-end\"><div><div class=\"pt-0.5 juice:pt-0\"><div class=\"gizmo-bot-avatar flex h-6 w-6 items-center justify-center overflow-hidden rounded-full juice:h-8 juice:w-8\"><div class=\"relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8\">Una huella digital es una versi\u00f3n m\u00e1s compacta de una clave privada. Como su nombre sugiere, identifica una clave privada sin utilizar la clave privada larga en s\u00ed. En nuestro caso, la usaremos para verificar r\u00e1pidamente que nuestra clave privada puede utilizarse para firmar una transacci\u00f3n y demostrar que el dinero es nuestro antes de firmar la transacci\u00f3n.<\/div><\/div><\/div><\/div><\/div>\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 Entradas<\/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<div class=\"flex-shrink-0 flex flex-col relative items-end\"><div><div class=\"pt-0.5 juice:pt-0\"><div class=\"gizmo-bot-avatar flex h-6 w-6 items-center justify-center overflow-hidden rounded-full juice:h-8 juice:w-8\"><div class=\"relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8\">Las entradas consisten en informaci\u00f3n que indica de d\u00f3nde proviene el dinero, una referencia a las salidas de transacciones anteriores y la informaci\u00f3n que demuestra que los fondos que queremos usar est\u00e1n autorizados para ser gastados. Cada vez que realizas una transacci\u00f3n, por ejemplo, gastar dinero en Bitcoin, se genera un id de transacci\u00f3n como el resultado de esa transacci\u00f3n. La entrada contiene el id de la transacci\u00f3n anterior realizada, por lo que puedes rastrear el dinero hasta su creaci\u00f3n. Debido a que una transacci\u00f3n anterior puede hacerse con m\u00e1s de una entrada, es necesario un \u00edndice para identificar qu\u00e9 entradas de transacci\u00f3n se est\u00e1n gastando. Esto puede ser algo dif\u00edcil de seguir, as\u00ed que veamos la anatom\u00eda de una transacci\u00f3n:<\/div><\/div><\/div><\/div><\/div>\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>Como puedes ver, se gener\u00f3 un id de transacci\u00f3n (TXID) para esta transacci\u00f3n. En este caso, mi transacci\u00f3n tiene dos salidas a dos billeteras diferentes, y estamos transfiriendo 1 BTC a cada billetera. Tambi\u00e9n tenemos entradas 1 y 2; tienen el id de transacci\u00f3n de la anterior y un \u00edndice llamado \u201cvout\u201d que hace referencia a cu\u00e1l de las salidas de la transacci\u00f3n anterior se est\u00e1 gastando. En este ejemplo, la transacci\u00f3n est\u00e1 gastando la Salida n\u00famero 1 (vout 0) de la transacci\u00f3n anterior <strong>a1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d<\/strong>, y la Salida n\u00famero 3 (vout 2) de la \u00faltima transacci\u00f3n <strong>4ce18f49ba153a51bcda9bb80d7f978e3de6e81b5fc326f00465464530c052f<\/strong> de la transacci\u00f3n anterior 4. Y todo ese dinero gastado est\u00e1 yendo a las direcciones <strong>mvhMvZi4m17c8YR44YB64LisKYA3NbqBvS<\/strong> y <strong>mgYJwtk2SWLcBbuNGnUV4dza1MERoHA9SR.<\/strong><\/p><p>Como se mencion\u00f3 antes, otra pieza vital de informaci\u00f3n que contiene la entrada es un script que demuestra que los fondos que alguien est\u00e1 a punto de gastar est\u00e1n autorizados para ser gastados por esa persona. Esta prueba se realiza proporcionando una firma que coincide con este script. Como puedes ver, las firmas no son como las que haces en un trozo de papel, sino que son una forma de demostrar que eres el propietario de los fondos, y necesitas tener una clave privada para probar esa propiedad. Este script que contiene la entrada se llama \u201cScript de Desbloqueo\u201d porque proporciona la informaci\u00f3n que necesitas verificar para desbloquear los fondos. Y para \u201caprobar\u201d una transacci\u00f3n, necesitas dar esta firma y agregarla a la estructura de datos de la entrada.<\/p><p>Vimos que las entradas hacen referencia a las salidas de transacciones anteriores, que contienen informaci\u00f3n sobre c\u00f3mo se puede gastar el dinero. El nombre de esta salida de transacci\u00f3n no gastada es UTXO. Hablemos de ellas.<\/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>Una Salida de Transacci\u00f3n No Gastada, UTXO por sus siglas en ingl\u00e9s, es la salida de una transacci\u00f3n anterior que a\u00fan no se ha gastado. Si recibiste dinero en tu billetera de Bitcoin y nunca lo gastaste, entonces eres el orgulloso propietario de UTXOs. Si gastas esos UTXOs, se utilizar\u00e1n como entradas para una nueva transacci\u00f3n.<\/p><p>Y lo m\u00e1s importante para lo que necesitamos hacer, un UTXO contiene informaci\u00f3n sobre las condiciones para gastar el dinero. Hay muchos \u201ccontratos\u201d en Bitcoin para gastar dinero. Puedes tener contratos basados en secuencias que definen que el dinero se puede gastar despu\u00e9s de que se hayan minado varios bloques. Puedes tener contratos basados en el tiempo donde solo puedes gastar el dinero despu\u00e9s de un tiempo espec\u00edfico. Puedes tener contratos \u201cpersonalizados\u201d que permiten al propietario del dinero especificar c\u00f3mo satisfacer el contrato para desbloquear los fondos. Estos \u201ccontratos\u201d se llaman \u201cScripts de Desbloqueo\u201d. Para nuestros prop\u00f3sitos, y porque necesitamos asegurarnos de que estamos reuniendo el n\u00famero requerido de firmas, nos interesan los scripts de desbloqueo de m\u00faltiples firmas \u201cPay to Script Hash\u201d, uno de los contratos \u201cpersonalizados\u201d que mencionamos anteriormente. En nuestro caso, el ejecutor de las condiciones de gasto es un script que contiene las claves p\u00fablicas de las personas que pueden firmar y el n\u00famero de firmas requeridas para cumplir con la condici\u00f3n de gasto. Un Pay-to-Script Hash puede verse as\u00ed:<\/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>Veamos esto y veamos qu\u00e9 podemos interpretar de ello. A primera vista, podemos ver <strong>CHECKMULTISIG<\/strong> escrito en el script. Este es el \u201ctipo\u201d del script, y le dice al c\u00f3digo c\u00f3mo interpretar el resto de los n\u00fameros y caracteres que aparecen en el resto del script. Los scripts de Bitcoin se leen de derecha a izquierda, por lo que <strong>CHECKMULTISIG<\/strong> es lo primero que lee el c\u00f3digo. Gracias a <strong>CHECKMULTISIG<\/strong>, el c\u00f3digo puede interpretar los n\u00fameros 2 y 3, que son los descriptores de la billetera permitidos para gastar el dinero. En este caso, estamos viendo una billetera multi-sig de 2-de-3. Necesitamos demostrar que 2 de las 3 claves p\u00fablicas que tambi\u00e9n aparecen en este script pueden derivarse de nuestras claves privadas.<\/p><p>Como ves, entre las entradas y salidas, tenemos toda la informaci\u00f3n necesaria para demostrar qui\u00e9n es el propietario actual de los fondos (el script de bloqueo), que el propietario actual de los fondos permiti\u00f3 la transferencia de fondos a una billetera diferente (por ejemplo, que gastaron el dinero), c\u00f3mo demostrar que somos los nuevos propietarios del dinero despu\u00e9s de que se realiza la transacci\u00f3n (el script de desbloqueo), de d\u00f3nde viene el dinero y a d\u00f3nde va el dinero.<\/p><p>Una cosa que omit\u00ed sobre el script que estamos usando es que hay dos tipos de ellos: aquellos que tienen \u201cSegregated Witness\u201d y aquellos que no. Dado que necesitaremos conocer la diferencia para aprobar esta transacci\u00f3n, explicaremos estos dos tipos como nuestro pr\u00f3ximo concepto.<\/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, o SegWit, es el nombre asignado a una versi\u00f3n mejorada del protocolo de Bitcoin en 2017. Antes de ese momento, y como vimos en el concepto anterior, los datos de la transacci\u00f3n conten\u00edan los ids de las salidas de la \u00faltima transacci\u00f3n que se estaban gastando, junto con las firmas que prueban a qui\u00e9n pertenece el dinero que se va a gastar. Dado que los datos de la firma pueden ser bastante grandes y aumentar sustancialmente el tama\u00f1o de una transacci\u00f3n de Bitcoin, se tom\u00f3 la decisi\u00f3n de cambiar c\u00f3mo se construye una transacci\u00f3n para separar la informaci\u00f3n de la firma en una estructura de datos diferente. Con este cambio, cuando se calcula el tama\u00f1o de la transacci\u00f3n, la informaci\u00f3n de la firma no se cuenta como parte de ese tama\u00f1o (aunque todav\u00eda se incluye en el bloque), y dado que el l\u00edmite de tama\u00f1o de un bloque de Bitcoin es de 4MB, la reducci\u00f3n en el tama\u00f1o de los datos de la transacci\u00f3n permite que se incluyan m\u00e1s transacciones en un solo bloque (\u00bfingenioso, verdad?). Dado que la cadena de bloques tiene registrada la informaci\u00f3n de todas las transacciones realizadas desde el principio, y porque algunas personas podr\u00edan seguir usando la versi\u00f3n anterior, no hay forma de \u201cdepreciar\u201d o imponer este cambio a todos. As\u00ed que las dos versiones de la cadena de bloques (SegWit y no SegWit) coexisten y pueden ser utilizadas. Sin embargo, se recomienda SegWit y tambi\u00e9n incurre en menores tarifas de transacci\u00f3n.<\/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 data-selectable-paragraph=\"\">Un Sighash es un hash de los datos de la transacci\u00f3n que &#8220;combinaremos&#8221; con la firma para firmar las entradas. Esto es \u00fatil para la verificaci\u00f3n porque el hash no coincidir\u00eda con la firma si se modifican los datos dentro de una transacci\u00f3n. Hay diferentes tipos de sighashes: <strong>SIGHASH_ALL, SIGHASH_NONE, SIGHASH_SINGLE<\/strong> y <strong>SIGHASH_ANYONECANPAY<\/strong>. Todos describen qu\u00e9 informaci\u00f3n sobre las entradas y salidas se incluir\u00e1 al crear el hash de la transacci\u00f3n.<\/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>Finalmente, hemos llegado a la parte del art\u00edculo donde explicaremos d\u00f3nde viven todos los conceptos que mencionamos anteriormente. Una de las formas en que se puede firmar una operaci\u00f3n en una billetera multi-sig es a trav\u00e9s de una Transacci\u00f3n Parcialmente Firmada de Bitcoin (PSBT, por sus siglas en ingl\u00e9s). Un PSBT es un papel que contiene toda la informaci\u00f3n relevante de la transacci\u00f3n. Esto incluye la cantidad de Bitcoin a gastar, el n\u00famero total de miembros de una billetera (N), y los miembros requeridos de una billetera (M) que deben firmar para realizar una transacci\u00f3n; las entradas y salidas, los testigos y los UTXOs. Los PSBTs a veces son necesarios para realizar transacciones multi-sig y tambi\u00e9n pueden usarse para firmar transacciones individuales. Un PSBT es \u00fatil porque proporciona otra capa de seguridad y privacidad, ya que puede construirse y firmarse sin conexi\u00f3n, minimizando el riesgo de exponer claves privadas.<\/p><p>La raz\u00f3n por la que se llama &#8220;Parcialmente Firmado&#8221; es porque funciona como un contrato real. Cada parte debe firmar el contrato individualmente y luego pasarlo al siguiente firmante. As\u00ed que si te encuentras con un PSBT en la naturaleza, puede estar en 3 estados: no firmado, parcialmente firmado o completamente firmado. El estado completamente firmado se alcanza una vez que todos los firmantes requeridos han agregado su script de desbloqueo al PSBT. Por lo tanto, para &#8220;firmar&#8221; un PSBT, debes leer las entradas del PSBT y crear los scripts de desbloqueo para cada una. Veamos c\u00f3mo se ve esto en el c\u00f3digo Rust. Para este art\u00edculo, solo firmaremos entradas con testigos segregados.<\/p><p>Los paquetes que utilizaremos para este art\u00edculo son el paquete &#8220;bitcoin&#8221; para manipular nuestro PSBT y el paquete &#8220;anyhow&#8221; para manejar los errores.<\/p><p>Primero, crearemos la firma de nuestra funci\u00f3n. Esta recibir\u00e1 un PSBT, una clave privada y una ruta de derivaci\u00f3n que usaremos para derivar la clave privada para esa ubicaci\u00f3n espec\u00edfica (recuerda el concepto de &#8220;caja fuerte&#8221;).<\/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>A continuaci\u00f3n, iteraremos sobre todas las entradas que necesitamos firmar. Tambi\u00e9n necesitaremos un \u00edndice de la entrada para luego poder construir la firma. Todo lo que haremos a partir de ahora ser\u00e1 dentro de este bucle for a.<\/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>Obtenemos el script de testigo, que contiene las firmas de los propietarios actuales de las salidas que se est\u00e1n gastando en esta transacci\u00f3n. Esto se utilizar\u00e1 para verificar las entradas de la transacci\u00f3n. Dado que estamos codificando solo para testigos segregados, lanzaremos un error si esta informaci\u00f3n no est\u00e1 disponible y dejaremos que la funci\u00f3n principal de esta maneje la situaci\u00f3n.<\/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=\"\">Obtenemos la cantidad del UTXO, y como antes, dejaremos que la funci\u00f3n padre se encargue del testigo que falta.<\/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>Hablamos brevemente sobre el sighash anteriormente; en estas l\u00edneas, crearemos el sighash, pero esperaremos para combinarlo con nuestra firma. Incluiremos toda la informaci\u00f3n relevante y luego obtendremos el sighash para decirle a <strong>segwit_signature_hash<\/strong>\u00a0qu\u00e9 informaci\u00f3n agregar al 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\t<p>En la \u00faltima parte del c\u00f3digo, invocamos una funci\u00f3n llamada <strong>get_sighash_type;<\/strong> esta funci\u00f3n obtiene la informaci\u00f3n del tipo de sighash de la entrada creada cuando se cre\u00f3 el PSBT. Si esa informaci\u00f3n no se incluy\u00f3 en la entrada, por defecto utilizamos SIGHASH_ALL.<\/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-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=\"\">Continuando nuestro camino, veremos d\u00f3nde se vuelve \u00fatil la huella digital que mencionamos antes. La estamos utilizando para compararla con la huella digital de nuestra clave privada en busca de coincidencias. Una coincidencia de huellas digitales significar\u00eda que m\u00e1s tarde podemos demostrar que tenemos la clave privada necesaria para firmar la transacci\u00f3n y ser propietarios de los fondos. Despu\u00e9s de verificar que la huella digital coincide, recopilamos un par de claves (KeyPair), que es una tupla de una clave p\u00fablica y una clave privada. Si no hay huellas digitales coincidentes, entonces no podemos firmar la transacci\u00f3n, lo que significa que los fondos que queremos gastar no nos pertenecen. Es posible que te est\u00e9s preguntando por qu\u00e9 estamos usando un arreglo, y eso se debe a que existe la posibilidad de que la entrada requiera m\u00faltiples firmas que pueden derivarse de la misma clave privada. En caso de encontrar una huella digital coincidente, y antes de continuar con nuestra firma, tenemos que derivar la clave privada para obtener la combinaci\u00f3n correcta para nuestra &#8220;caja fuerte&#8221;. Veamos eso a continuaci\u00f3n.<\/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>Vimos antes que para tener acceso a una caja fuerte, necesitamos conocer el edificio, la habitaci\u00f3n y el n\u00famero de la caja fuerte. Tambi\u00e9n vimos que al tener la contrase\u00f1a de una habitaci\u00f3n, podemos derivar las contrase\u00f1as de las cajas fuertes que hay dentro. Existe la posibilidad de que el propietario de una billetera de Bitcoin conozca la contrase\u00f1a maestra (por ejemplo, del edificio) o solo la contrase\u00f1a de una habitaci\u00f3n. Por esa raz\u00f3n, para saber la contrase\u00f1a que necesitamos usar para abrir una caja fuerte, necesitamos combinar los caminos de derivaci\u00f3n de la contrase\u00f1a que poseemos con el camino absoluto que queremos alcanzar. Y eso es lo que hace la funci\u00f3n <strong>get_partial_derivation<\/strong>. Puedes pensar en los caminos de derivaci\u00f3n como un arreglo con las coordenadas de nuestra caja fuerte. Por ejemplo, [44, 1, 3] podr\u00eda representar el pa\u00eds en el que estamos (44), la ciudad (1) y el edificio (3). Si solo conozco la contrase\u00f1a de la ciudad, entonces s\u00e9 que las coordenadas son [44, 1]. Dado que la entrada nos da la combinaci\u00f3n final para la caja fuerte, por ejemplo, [44, 1, 3, 2, 2], necesitamos derivar la contrase\u00f1a desde la ciudad hasta la caja fuerte. Entonces nuestra funci\u00f3n <strong>get_partial_derivation<\/strong> nos dar\u00e1 exactamente este camino de derivaci\u00f3n parcial: [3, 2, 2]. Nuestra segunda funci\u00f3n, \u2018derive_relative_xpriv\u2019, se encargar\u00e1 de derivar la clave privada en aquella que necesitaremos para firmar.<\/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>La parte final de nuestro c\u00f3digo es s\u00f3lo la &#8220;firma&#8221;. Obtenemos los pares de claves que recogimos en los pasos anteriores. Creamos un <strong>Mensaje,<\/strong> un contenedor para toda la informaci\u00f3n necesaria para crear y firmar una transacci\u00f3n v\u00e1lida. Una vez que construimos nuestro mensaje, podemos finalmente firmarlo y a\u00f1adir la firma parcial a la entrada como otra tupla, una tupla Clave P\u00fablica &#8211; Firma. Pero antes, tendremos que a\u00f1adir a la entrada la informaci\u00f3n sobre qu\u00e9 tipo de sighash hemos utilizado para firmar los datos. Esto se utilizar\u00e1 para verificar la firma m\u00e1s adelante.<\/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>El tipo de sighash se establece utilizando la funci\u00f3n <strong>get_sighash_type<\/strong> que usamos antes y combin\u00e1ndola con la firma.<\/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>Por \u00faltimo, fuera de nuestro bucle for de entradas, devolvemos el PSBT a la persona que llama a la funci\u00f3n <strong>sign_psbt<\/strong> para que el PSBT pueda ser firmado por el siguiente firmante.<\/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=\"\">Puedes ver el c\u00f3digo completo a continuaci\u00f3n:<\/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\">Espero que esto tenga sentido para ti y que disfrutes de este contenido.  \u00a1Nos vemos en el pr\u00f3ximo art\u00edculo!<\/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>Nota: La IA no ha escrito este art\u00edculo. Esto es precisamente lo que dir\u00eda una IA, \u00bfno? Sospechoso ?&#8230;<\/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":[1],"tags":[],"class_list":["post-1647","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust - Clovr Labs<\/title>\n<meta name=\"description\" content=\"Nota: La IA no ha escrito este art\u00edculo. Esto es precisamente lo que dir\u00eda una IA, \u00bfno? Sospechoso ?...\" \/>\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\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust\" \/>\n<meta property=\"og:description\" content=\"Nota: La IA no ha escrito este art\u00edculo. Esto es precisamente lo que dir\u00eda una IA, \u00bfno? Sospechoso ?...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/\" \/>\n<meta property=\"og:site_name\" content=\"Clovr Labs\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-25T15:54:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-28T16:13:53+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post-1024x577.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\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/\"},\"author\":{\"name\":\"clovrblog\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#\\\/schema\\\/person\\\/a6b5b6390ea72a5e384639ee38c0fd88\"},\"headline\":\"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust\",\"datePublished\":\"2023-09-25T15:54:06+00:00\",\"dateModified\":\"2024-06-28T16:13:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/\"},\"wordCount\":3618,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blog.clovrlabs.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/nodeguard-post.webp\",\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/\",\"url\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/\",\"name\":\"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust - Clovr Labs\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/blog.clovrlabs.com\\\/wp-content\\\/uploads\\\/2023\\\/12\\\/nodeguard-post.webp\",\"datePublished\":\"2023-09-25T15:54:06+00:00\",\"dateModified\":\"2024-06-28T16:13:53+00:00\",\"description\":\"Nota: La IA no ha escrito este art\u00edculo. Esto es precisamente lo que dir\u00eda una IA, \u00bfno? Sospechoso ?...\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/#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\\\/es\\\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/clovrlabs.com\\\/blog\\\/es\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en 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":"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust - Clovr Labs","description":"Nota: La IA no ha escrito este art\u00edculo. Esto es precisamente lo que dir\u00eda una IA, \u00bfno? Sospechoso ?...","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\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/","og_locale":"en_GB","og_type":"article","og_title":"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust","og_description":"Nota: La IA no ha escrito este art\u00edculo. Esto es precisamente lo que dir\u00eda una IA, \u00bfno? Sospechoso ?...","og_url":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/","og_site_name":"Clovr Labs","article_published_time":"2023-09-25T15:54:06+00:00","article_modified_time":"2024-06-28T16:13:53+00:00","og_image":[{"url":"http:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post-1024x577.webp","type":"","width":"","height":""}],"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\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/#article","isPartOf":{"@id":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/"},"author":{"name":"clovrblog","@id":"https:\/\/clovrlabs.com\/blog\/#\/schema\/person\/a6b5b6390ea72a5e384639ee38c0fd88"},"headline":"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust","datePublished":"2023-09-25T15:54:06+00:00","dateModified":"2024-06-28T16:13:53+00:00","mainEntityOfPage":{"@id":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/"},"wordCount":3618,"commentCount":0,"publisher":{"@id":"https:\/\/clovrlabs.com\/blog\/#organization"},"image":{"@id":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp","articleSection":["Uncategorized"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/","url":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/","name":"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en Rust - Clovr Labs","isPartOf":{"@id":"https:\/\/clovrlabs.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/#primaryimage"},"image":{"@id":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.clovrlabs.com\/wp-content\/uploads\/2023\/12\/nodeguard-post.webp","datePublished":"2023-09-25T15:54:06+00:00","dateModified":"2024-06-28T16:13:53+00:00","description":"Nota: La IA no ha escrito este art\u00edculo. Esto es precisamente lo que dir\u00eda una IA, \u00bfno? Sospechoso ?...","breadcrumb":{"@id":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/clovrlabs.com\/blog\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/#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\/es\/extension-nodeguard-signer-como-firmar-un-psbt-en-rust\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/clovrlabs.com\/blog\/es\/"},{"@type":"ListItem","position":2,"name":"Extensi\u00f3n NodeGuard Signer: C\u00f3mo firmar un PSBT en 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\/1647","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=1647"}],"version-history":[{"count":4,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/posts\/1647\/revisions"}],"predecessor-version":[{"id":1651,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/posts\/1647\/revisions\/1651"}],"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=1647"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/categories?post=1647"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/clovrlabs.com\/blog\/wp-json\/wp\/v2\/tags?post=1647"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}