Transcripciones
1. Introducción: Hola, Bienvenido al curso para desarrolladores de
Bitcoin. Mi nombre es Alberto, y me complace
presentarte el primer y único curso en el que aprenderás Bitcoin
construyendo una billetera
Bitcoin de escritorio. Entonces comencemos
explicando lo que
aprenderás en este curso. En definitiva, aprenderás cómo funciona
Bitcoin desde un punto de vista
técnico. Más específicamente,
aprenderás cómo funciona
una billetera Bitcoin en detalle. Además, aprenderás cómo funciona
un nodo Bitcoin
y cómo ejecutarlo. Veremos cómo interactúa con nuestra cartera y otros nodos. También aprenderá cómo
funciona
la red Bitcoin y cómo
logra el consenso. conceptos que aprenderemos incluyen
transacciones, direcciones ,
semillas, claves,
saldos , blockchain,
minería y billetera. Dado que construiremos una
aplicación de escritorio a lo largo del curso, el estudiante tendrá la
oportunidad de practicar las siguientes habilidades de
ingeniería de software que tienen una gran demanda
en la industria del software. El paradigma de
programación orientada a objetos en el que se basa nuestra billetera. La mayoría de las características se
construirán, seguirán la forma de
desarrollo impulsada por pruebas de hacer las cosas. Como sugiere el nombre de este
enfoque, para cada característica se construirán sus pruebas primero y
las pruebas guiarán a la característica un mayor
desarrollo también se preocuparán mucho por la aplicación
mejores prácticas de seguridad, y tratar la aplicación como
un sistema de misión crítica. Yo personalmente tengo piel en el
juego en esta aplicación, y pongo mucho esfuerzo en minimizar la posibilidad de que
alguien pierda fondos con ella. Además, este curso tiene muchas mejores prácticas de
programación, ejemplos, principios sólidos y código
limpio que impregnan la
cultura de nuestro código. Ahora, veamos cómo
aprenderás en este curso. Seguiremos la metodología
de aprender haciendo. Alrededor del 17% de este curso
está compuesto por teoría, el resto está compuesto por
clases prácticas. lo que el curso tiene
muy centrado en el código, intercalado con algunas
presentaciones cuando es necesario. Debajo de cada video, puedes
encontrar enlaces adicionales y material de
estudio en la página
Proyectos y Recursos. Construirás una billetera
Bitcoin de escritorio, aprendiendo
conceptos importantes de Bitcoin mientras lo haces. Ahora, enumeremos los requisitos
recomendados para tomar este curso. Se recomienda
que el alumno tenga un buen conocimiento de la programación
orientada a objetos. El alumno debe conocer
Java o idiomas similares antes de tomar este curso. Aunque este curso presenta diferentes conceptos de
ingeniería de software, nuestro enfoque es
entender Bitcoin. Si el alumno quiere
conocer a detalle algunos de
los conceptos de ingeniería de software se tocaron en este curso. Tendrá que
utilizar otras fuentes a lo largo del curso para
entenderlas mejor. Necesitarás una computadora
con Windows, macOS o Linux con conexión
a Internet. Presentaremos este
curso usando Windows. Pero como Java es compatible
multiplataforma, cada código de este curso
funcionará de la misma manera en estos tres sistemas
operativos. La única diferencia
será instalar el software necesario
en cada plataforma, pero puedes
encontrar fácilmente guías para instalarlos en estos sistemas
operativos. Necesitarás al menos
30 gb de espacio libre para ejecutar el nodo Bitcoin en
el entorno de red de prueba. Opcionalmente, si pretendes ejecutar la aplicación en el entorno de red
principal, necesitarás al menos 430 gb de espacio en
disco para descargar
la red blockchain principal. Pero no te preocupes, usaremos el entorno de red principal solo en el último
video del curso. Así que tendrás tiempo de sobra para descargarlo antes de necesitarlo. Ahora, hablemos un poco
más sobre la billetera que construirás a lo largo del curso. Me referiré a esta
cartera como BYOD W, acrónimo para construir
tu propia billetera, empezará a desarrollar esta
aplicación con Java 16, pero la actualizaremos
más adelante en el curso. Diversion 19 utilizará el
marco Spring Boot versión 2.5, 0.4, que proporcionará un
contenedor de inyección de dependencia y muchas facilidades para
ayudarnos a construir nuestra aplicación. Posteriormente en el curso, lo
actualizaremos a la
versión 2.7, 0.5. Usaremos Java FX versión
16 en el proyecto. actualizaremos
más tarde a la versión 19. Esta biblioteca brindará
clases que nos ayudarán a construir la interfaz
gráfica de usuario de las aplicaciones, también conocida como gooey. Para las pruebas, usaremos Groovy, el marco Spark y la
ética de prueba para crear billeteras, direcciones de
semillas, transacciones y otras operaciones de
Bitcoin usarán la biblioteca Java de
Bitcoin de código abierto, que construí especialmente
para este curso. Usaremos el Bitcoin
Core Node versión 22 para la comunicación
con la cadena de bloques. Posteriormente en el curso, lo
actualizaremos a la versión 23. Aunque el nodo Bitcoin
Core puede generar billeteras y direcciones, lo
utilizará únicamente
para recuperar datos y enviar datos
a la cadena de bloques. Operaciones como
generar semillas, direcciones, construcción y firma de
transacciones
serán realizadas por nuestra aplicación. La excepción
será para las pruebas. En estos casos, utilizaremos la API Bitcoin Core Node RPC para generar direcciones,
enviar transacciones y minar bloques en los
entornos de prueba, por lo tanto, nos familiarizaremos con
los más importantes Bitcoin Core Note
RPC API métodos y construir un cliente para comunicarse con él
desde nuestra aplicación. Como la base de datos utilizará la
implementación SQL Java H SQL DB utilizará una
integración fluida con la biblioteca Spring Boot Data JPA para comunicarse
con la base de datos. Finalmente, usaremos la idea IntelliJ como IDE para construir
este proyecto. Todo el código presentado
en este curso es código
abierto y está disponible
en nuestra página de GitHub. Para cada clase práctica, la
página Proyectos y Recursos contendrá un enlace con la diferencia de código entre las dos últimas clases prácticas para conveniencia de los estudiantes. Ahora, vamos a presentar quien soy. Mi nombre es Alberto Salazar, y seré tu
instructor en este curso. Tengo más de cinco años de experiencia como desarrollador de
software profesional, trabajando especialmente en
la industria del comercio electrónico. He sido un
entusiasta de Bitcoin desde 2016. Había estado estudiando mucho
Bitcoins desde entonces. Desarrollo la biblioteca Java
Bitcoin de código abierto, que usaremos en este curso. He construido la
iniciativa de educación de Bitcoin para concentrar mis esfuerzos en brindar educación sobre Bitcoin a
desarrolladores de todo el mundo. Síguenos en Twitter para
recibir nuestras últimas actualizaciones. Concentré todo el
código para este curso, incluyendo la
biblioteca Bitcoin Java en nuestra página de GitHub. También tenemos un sitio web
cuya dirección es www punto bitcoin
educación punto sitio. Allí tenemos algunos
artículos técnicos que pueden servir como material de
estudio adicional. Compruébalo como última palabra. Quiero decir
que se
puso mucho trabajo en hacer este curso. Tomó más de dos años
en la elaboración y casi todo mi tiempo libre
durante este periodo. Así que por favor, si
tienes alguna dificultad o encuentras algún problema
con este curso, contáctame antes de darle una calificación baja para que podamos
ayudarte con tu problema. Con mucho gusto haré
todo lo posible para que tengas una gran experiencia de
aprendizaje. Muchas gracias por su atención y nos
vemos en el siguiente video.
2. 0 Requisitos de instalación Skillshare 2: En este video, te presentaremos el software necesario
que tendrás que descargar e instalar antes de pasar a los siguientes
videos del curso. Entonces comencemos con
el Bitcoin Core Node. El Bitcoin Core Node es la
implementación original de Bitcoin. Es responsable de
comunicarse con la cadena de bloques,
crear, recibir, enviar y validar transacciones de
Bitcoin, recibir bloques y más. Como hemos dicho en
el video anterior, las funciones principales que
dependerán del nodo Bitcoin Core son las relacionadas con la comunicación con
la cadena de bloques. Entonces vayamos al sitio web de
Bitcoin core.org. Instalará Bitcoin
Core versión 22. Te preguntarás ¿por qué no
instalar la versión 23? Cuando empecé a hacer este curso, la última versión
disponible era 22. Hay una pequeña diferencia
en la API de gRPC en la versión 23 que hará que un método de nuestra aplicación no
funcione correctamente. En uno de los últimos
videos del curso, actualizaremos el
nodo Bitcoin dos versión 23 y haremos que nuestra aplicación sea
compatible con él. Pero por ahora,
instalemos la versión 22. Para hacerlo, haga clic en el botón de liberación en
la parte superior de la pantalla, luego haga clic en el enlace
Bitcoin Core 22. A continuación, haga clic en este
enlace en la página. Esta página contiene archivos de
instalación para cada sistema operativo. Ya que estoy usando Windows, descargaré el que
termina con punto EXE. Si estás usando macOS, descargarás el que
termina con dot DNG. Para distribuciones Linux, elija el archivo punto
GZ adecuado de
acuerdo con la distribución que utilizará en la página Proyectos y
Recursos, hay enlaces con instrucciones de
instalación para cada sistema operativo. Para Windows, después de
descargar el archivo, ábralo y sigue las instrucciones de
instalación
en pantalla. No voy a hacer eso porque
ya
lo he instalado en mi máquina. Pero es un proceso
sencillo. En la última fase de
la instalación
, te preguntará si quieres
abrir el software. No lo abras todavía. Interactuará con
el nodo Bitcoin a través de la interfaz de
línea de comandos. Si abres el nodo haciendo
clic en su icono, éste abrirá una interfaz gráfica de
usuario y empezará a descargar la cadena de bloques
en el entorno de la red principal, que aún no queremos hacer. Ahora, vamos a configurar
nuestro nodo Bitcoin. Para ello, tendremos que
crear un archivo llamado bitcoin.com y la carpeta
apropiada de la aplicación Bitcoin. La ubicación de esta carpeta depende del sistema operativo
que estés usando. Este sitio web en la pantalla muestra la ubicación predeterminada
donde se tiene que crear este archivo
para cada sistema operativo. Para crearlo, abre un
archivo de texto y guárdalo con el nombre bitcoin.com de la
carpeta apropiada para tu sistema operativo. Ahora, escribe la
misma configuración que ves en la
pantalla en tu archivo, o copia y pega
el contenido de la página Proyectos y
Recursos en él. No te preocupes, te explicaremos lo que significa
cada línea de este archivo en un video posterior. Por ahora, tendrás que
decidir dónde quieres almacenar los
datos de blockchain en tu computadora, tendrás que elegir
una ruta con acceso a al
menos 30 gb para la red de
prueba blockchain, o una 430 adicional gb para
la cadena de bloques de red principal. Opcionalmente, establezca la configuración DIR de
datos a la ruta elegida en este archivo. En mi caso, decidí almacenar los archivos blockchain en
la unidad E en
la carpeta de datos de
Bitcoin, como se ve en la pantalla. Ahora, si ejecutamos el
nodo Bitcoin con esta configuración, se ejecutará en la red principal y comenzará a descargar la red
principal blockchain. Como su nombre indica, el entorno de red principal es el principal
entorno bitcoin donde la blockchain es grande y
los bitcoins tienen valor, solo
ejecutará el entorno neto
principal en el último video del curso. Antes de eso se ejecutará en
el entorno de red de prueba, que se utiliza para las pruebas. Para ejecutar nuestra nota en el entorno de red de
prueba, agreguemos una línea
escrita de prueba neta igual a una en el archivo
bitcoin.com. Ahora usando el terminal, vayamos a la carpeta donde
instalaste el Bitcoin Core Node. Dentro de la carpeta demonio, ejecuta la
aplicación Bitcoin D así. En los registros de la consola. Observe que estamos
funcionando efectivamente en el entorno de red de prueba y todos sus datos se almacenarán
en la carpeta indicada. Bien, eso significa que nuestro
nodo está trabajando con la configuración que hemos establecido
en el archivo bitcoin.com. Ahora, esperemos a que
nuestro nodo se conecte a otros nodos y
comencemos a descargar y validar la cadena de bloques. Bien, las líneas que comienzan
con el tip de actualización de texto indica que comenzó a
descargar la cadena de bloques. Cada una de estas
líneas indica un bloque de
transacciones de Bitcoin descargadas. El avance en cada línea indica cuánto se hunde la
cadena de bloques. En mi caso, indica que se descargó
cerca del 98% de la cadena de
bloques neta de prueba. Cuando este valor es igual a uno, indica
que nuestra
copia de la cadena de bloques está completamente sincronizada con
las de otros nodos. Para el entorno de red de prueba, puede tomar algunas horas
para que suceda. Puedes dejarlo hundido mientras procedes a ver el
resto del curso, ya que lo usaremos
solo después de algunos videos. Para salir de la aplicación, puedes presionar Control más C o Comando más C si
estás usando Mac OS, si vuelves a iniciar la nota, comenzará a descargar la cadena de bloques donde se detuvo. Después de terminar de descargar
el entorno de red de prueba, opcionalmente
puede cambiar el archivo bitcoin dot conf
y comenzar a descargar la cadena de bloques de red principal
ejecutando la nota en el entorno de red
principal, solo usará el entorno de red
principal en el último video del curso, por lo que tendrás mucho
tiempo para descargarlo. El otro
requisito inicial de este curso es la idea IntelliJ Java IDE. Es el software que
usaremos para escribir el código y ejecutar
nuestra aplicación. Si no lo tienes, ve a la página web en la
pantalla para descargarla. Descargue e instale la edición
comunitaria para su sistema operativo
siguiendo las instrucciones del
sitio web.
3. ¿Qué es Bitcoin?: Hola, bienvenidos de nuevo al curso de desarrolladores de
Bitcoin. En esta sección del curso te
dará una visión general de Bitcoin. Los conceptos presentados
en esta sección, aportaremos los
conocimientos básicos necesarios para entender lo que viene
en el resto del curso. Entonces comenzaré con la
pregunta, ¿qué es Bitcoin? Bitcoin con una B mayúscula
es un protocolo de comunicación. Este protocolo es un conjunto de reglas que permite
el intercambio de mensajes entre las entidades participan en la red
Bitcoin. Bitcoin con
b minúscula es una criptomoneda. Una criptomoneda es una forma de moneda
digital que podemos cambiar por bienes
u otros activos. La parte criptográfica del nombre
proviene de la criptografía, que protege las transacciones
y otras operaciones de Bitcoin. Bitcoin también es un sistema
de pago. Podemos enviar y recibir pagos de
Bitcoin hacia y desde otros participantes
de la red Bitcoin. Hablando de redes, Bitcoin también es una red
peer to peer, lo
que significa que está compuesta por entidades o nodos
que se comunican directamente entre ellos sin la participación de
servidores centralizados. La siguiente pregunta es, cuándo se inventó el bitcoin? Bitcoin fue inventado en 2008 por Satoshi Nakamoto con la
publicación del libro blanco, Bitcoin, uh, sistema de efectivo
electrónico peer-to-peer. En este trabajo, que recomiendo
encarecidamente leer, Satoshi describe las partes
básicas de Bitcoin. Nadie sabe quién es realmente Hitoshi
Nakamoto, o si es incluso un
nombre real o varias personas. Quienquiera que sea Satoshi, en 2009, publicó el primer bloque de
Bitcoin llamado bloque
génesis y puso a trabajar la red
Bitcoin. Si no sabes lo que es un bloque de
Bitcoin, no te preocupes. Voy a explicar en breve. Entonces, ¿qué tiene
de genial Bitcoin? ¿Cuál es la innovación
de Bitcoin? Bitcoin fue la primera moneda digital, bien lograda. Antes de Bitcoin, hubo algunos intentos de crear monedas
digitales, pero todas fallaron debido a problemas que
Bitcoin resolvió más tarde. Uno de estos problemas es el problema del
doble gasto, que bitcoin fue el primero en
resolver de manera descentralizada. Ocurre cuando una persona gasta dos veces una unidad monetaria. Por lo que una de las transacciones
se invalida posteriormente, haciendo que el destinatario de la
transacción invalidada pierda dinero. Bitcoin también se encargó de inventar la cadena de bloques, que se utilizó para resolver el problema del
doble gasto. La cadena de bloques es
una estructura de datos responsable de almacenar
todas las transacciones de Bitcoin. Permite la validación de todas sus transacciones a
cualquiera que tenga acceso a ella, pero más sobre eso más adelante. Bitcoin también introdujo el
concepto de escasez digital. Significa que a diferencia de
los archivos en tu computadora que se pueden copiar y
distribuir indefinidamente, Bitcoin solo puede ser
transferido por su propietario y no puede ser copiado
y distribuido libremente.
4. Transacciones de Bitcoin y llaves privadas: Ahora profundizaremos un
poco más en los
detalles internos de Bitcoin. Voy a explicar Bitcoin
de micro a macro. Es decir, voy a hablar transacciones de
Bitcoin
y claves privadas, luego un poco sobre
blockchain y minería. Después terminaré
el resumen
explicando el ecosistema
Bitcoin. Entonces comencemos
con la pregunta, ¿dónde está la criptomoneda
y el sistema? O en otras palabras, ¿dónde está el Bitcoin con una b
minúscula en el sistema? La respuesta es, está
en una transacción. Esta figura muestra una transacción común de
Bitcoin con una entrada y dos salidas. Una transacción de Bitcoin puede
tener muchas entradas y salidas, pero en muchos casos, solo
tienen una
entrada y dos salidas. En una transacción de Bitcoin, tenemos la información de
dónde vino el Bitcoin en la entrada y hacia dónde
va el Bitcoin en la salida. En este ejemplo, la
entrada cero contiene una instrucción que dice que
esta entrada vino de John, fue firmada por John y
contenía un Bitcoin. La primera salida llamada
la salida cero, dice a María contener
0.9 Bitcoin. En la salida uno, le dice a
John contiene 0.099 Bitcoin. Esta salida es el cambio
de la transacción. En la mayoría de los casos,
necesitamos incluir un cambio porque cuando
gastas Bitcoin de
una transacción, tienes que gastar todas las
unidades de la entrada. Entonces esto genera la necesidad crear una salida adicional, que es el cambio. Entonces, si tu entrada
contiene más bitcoins, entonces quieres enviar
a otra persona, entonces debes crear
una salida adicional, el cambio a ti mismo. Tenemos el concepto de UTXO, lo que significa salida de
transacción no gastada. Un bitcoin está más
específicamente dentro de un UTXO. Una entrada de transacción debe
referirse a un UTXO de una transacción anterior
para poder gastar ese Bitcoin en esta transacción. Si nota la
suma de cantidades de salidas es menor que la
cantidad en la entrada. ¿Por qué es eso? La diferencia se debe
a la cuota menor. Cada transacción de bitcoin
debe separar un monto por la tarifa menor para que
su transacción pueda ser incluida en la
cadena de bloques por un menor. Por lo que el monto de la tarifa de transacción es la diferencia
entre la suma de Bitcoins presentes
en las salidas y la suma de Bitcoins
presentes en las entradas. Otra pieza importante
de información es que Bitcoin se
puede dividir en
100 millones de Satoshi. Por lo tanto, en esta transacción de
ejemplo, podríamos haber dicho que
los insumos que contenían 100 millones de Satoshi
en el cero de salida contienen 90 millones de
Satoshi y el de salida uno contiene
9,900,000 De Satoshi. La cuota menor era de
100 mil Satoshi. Estos son otros ejemplos
de transacciones de Bitcoin. Los pongo aquí solo para
demostrar que se pueden tener transacciones con más de
una entrada y una salida. Por ejemplo, puede tener una transacción con dos
entradas y una salida. Esta transacción
no tiene cambio. Se puede tener una transacción con dos entradas y dos salidas. En este caso, la
transacción tiene entradas de dos personas diferentes y salidas para dos personas
diferentes. Este tipo específico de transacción se llama transacción
Coinjoin, que es un tipo de transacción
que aumenta la privacidad porque no se pueden vincular entradas
específicas a salidas
específicas. Se puede tener una transacción con tres entradas y dos salidas. Hay otros tipos
de transacciones, como las transacciones multifirma de
las que no hablaremos ahora, pero podemos incluirlas más adelante en una sección de curso extra si
hay suficiente demanda. Veamos un poco más sobre los detalles de una transacción. En esta imagen,
hay dos transacciones, transacción uno y
transacción dos. Ambas transacciones
tienen entrada y salida. La entrada tiene tres campos, el
ID de transacción anterior y el
número de salida de una transacción anterior
y una firma válida. La salida tiene dos
campos, destino, dirección y cantidad,
que hace referencia a la cantidad de Bitcoin
dentro de la salida. En este caso, la entrada de
Transacción dos es el gasto de salida cero
de la transacción uno. Para ello, ingrese uno
de la transacción a debe referirse al
ID de transacción de la transacción uno. También debe referirse al número
de salida
de la transacción uno, que en este caso es cero. Finalmente, debe contener una firma
válida producida con la clave privada utilizada para derivar la dirección de destino a
partir de la salida cero. Veremos más detalles sobre esta operación en
la siguiente diapositiva. Como puede notar, las claves privadas son una
parte fundamental de Bitcoin. Las claves privadas
se utilizan para recibir y enviar bitcoins para recibir. Las claves privadas se
transforman en claves
públicas a través de la multiplicación de
curvas elípticas. Entonces, después de una función hash, las claves
públicas se
transforman en direcciones Bitcoin. Estas son las
direcciones de Bitcoin que puedes mostrar a otras personas
para recibir Bitcoins. Las claves privadas también se utilizan para asignar transacciones de Bitcoin. Las firmas son
necesarias para transferir Bitcoins de una
dirección a otra. En esta imagen, tenemos
una transacción sin firmar. Cuando combinamos la clave
privada con una transacción privilegiada usando el algoritmo de
firma digital de curva elíptica, ECDSA, producimos una firma que incluimos en
esa transacción. De esta manera, se convierte en una transacción
firmada. La misma
clave privada que produjo la dirección referida
a una entrada cero
también se utiliza para desbloquear
estos fondos y la transacción actual
produciendo la firma. Así, una clave privada se utiliza
indirectamente para bloquear fondos en una dirección y para
desbloquear fondos de la misma dirección
produciendo una firma. Lo importante de las claves
privadas y sus transformaciones
es que no se puede producir una clave privada
a partir de una clave pública, y no se puede
producir una clave pública a partir de una dirección de Bitcoin. Tampoco se puede producir una clave
privada a partir de una firma. Estas operaciones son
sólo en una dirección, tal como muestran estas flechas. Otra característica importante de las transacciones de
Bitcoin es que cualquier persona con acceso a una transacción puede
validar firmas. Esto es posible porque
si se tiene una clave pública, la firma y el mensaje, que en este caso
es la transacción. Puedes verificar si una firma es válida para esa clave pública. Y una firma es válida para
una clave pública sólo si se produjo con una clave privada que produjo la misma clave pública.
5. Billetes de Bitcoin, la cadena de bloques y la minería: Ahora que tienes un
conocimiento básico sobre claves privadas, podemos empezar a
hablar de billeteras. Una billetera Bitcoin es, en definitiva, una colección
de claves privadas. Hay muchos tipos y
estándares de billeteras. Las billeteras tienen un
desarrollo independiente con respecto a otros programas de Bitcoin
como los nodos. Una regla básica para
poseer Bitcoin no es el mantra. Tus llaves, tus bitcoins, no tus llaves, no
tus Bitcoins. Esto se debe a que el propietario de
una clave privada puede transferir Bitcoins bloqueados por su clave privada y
otras transacciones. ¿Qué cosas tienen en común las
billeteras Bitcoin? Cuentan con una forma segura de generar
y almacenar claves privadas. Pueden comunicarse
con los nodos de Bitcoin. Pueden crear, firmar y
enviar transacciones de Bitcoin. Pueden generar direcciones de
Bitcoin. Observe que la mayoría de
estas habilidades son posibles gracias a
las transformaciones de claves privadas. Cada operación que utilice claves
privadas
se puede realizar sin conexión. Solo necesita estar en línea cuando comunica con los nodos de
Bitcoin para obtener
información de
la cadena de bloques y enviar información
a la cadena de bloques. Hablando de blockchain, veamos finalmente qué significa
esta palabra de moda. El blockchain se utilizó para resolver el problema del doble gasto de
manera descentralizada. Lo hace organizando las transacciones en una
cadena de bloques para que los bloques válidos no puedan
contener transacciones con un UTXO que apareciera en el mismo bloque o
en bloques anteriores. Para entender qué es
la cadena de bloques, veamos esta cifra. Estos bloques representan
bloques de la cadena de bloques. Algunos de sus datos están representados en estos rectángulos
más pequeños. Dentro de cada bloque. Un bloque está compuesto por
muchas transacciones, un campo llamado hash anterior, que como su nombre indica, es el hash del bloque
anterior. Un campo llamado timestamp, que almacena la fecha donde se creó
el bloque, y un campo llamado nonce, del que hablaremos
en la siguiente diapositiva. Cada bloque produce un hash que se inserta
en el siguiente bloque. Los bloques son
creados y añadidos a la cadena de bloques en un
proceso llamado minería. minería es el proceso donde los bloques se incluyen
en la cadena de bloques. los nodos que hacen este
proceso se les llama mineros. Para incluir bloques
en la cadena de bloques, los mineros deben recolectar transacciones y organizarlas en un bloque. Entonces los menores deben resolver
la Prueba de Trabajo, que es un algoritmo necesario
para producir bloques válidos. comprobante de trabajo se compone
de los siguientes pasos. Primero, un bloque es hash, luego se verifica el número de ceros
iniciales del hash resultante. Si este número es
mayor o igual
al número necesario de ceros para incluir el bloque
en la cadena de bloques. El bloque está incluido
en la cadena de bloques. Si no, entonces el menor modifica el nonce y
repite el proceso. Entonces esta es la
función del nonce. Su único propósito es proporcionar variabilidad para que un bloque
produzca diferentes hashes. La prueba de trabajo tiene una característica
interesante. Cuantos más ceros se requieran
para una prueba válida de trabajo, más difícil
es encontrarla. Esto hace que la dificultad minera sea
fácilmente ajustable. En Bitcoin, la dificultad de
minería se ajusta automáticamente, por lo que el tiempo promedio para
extraer un bloque es de 10 min. Cuando un menor
le importa un bloque, gana una recompensa de bloque y
todas las tarifas de transacción de bloque. La recompensa de bloque es la única forma en que se crean nuevos
bitcoins. Disminuye a la mitad cada cuatro años en un
evento llamado tener. Por lo que cada cuatro años
el suministro de nuevos Bitcoins emitidos
se hace más escaso. Y se calcula que el último bitcoin
será minado en alrededor las 21:40 cuando la oferta total de
Bitcoin será igual a 21 millones.
6. La red, los ecosistemas y los principios de Bitcoin: Ahora hablemos de
la red Bitcoin. Veamos los pasos básicos de cómo funciona la red Bitcoin. Primero,
se envían nuevas transacciones a los nodos. Cada minero reúne las
transacciones en un bloque. Cada minero intenta encontrar un bloque de prueba de trabajo
lo más rápido posible. Cuando un minero encuentra
prueba de trabajo, el menor transmite su bloqueo
mental a la red. Otros nodos verifican si
el bloque es válido. Para
que un bloque sea válido, debe seguir todas
las reglas de consenso, como todas las transacciones
y debe ser válido y el
hash de bloque anterior debe ser igual a la caché de bloques
del último bloque válido. Si el bloque es válido, los nodos lo agregan a
su Blockchain. Copia. Comienzo menor a
trabajar en nuevos bloques usando el campo hash
del bloque mental recientemente
como hash anterior. Quizás te estés preguntando
qué pasa si dos mineros extraen un
bloque válido al mismo tiempo. Bueno, cuando esto
sucede, provoca una división
en la red. Parte de los nodos
contendrá una versión de la cadena de bloques
con un bloque de un menor y la otra parte de la red contendrá un
bloque del otro menor. Pero esta división
sólo es temporal. Cuando se mina el siguiente bloque, los dos grupos de nodos
considerarán solo la
blockchain con más bloques ya que
se descarta la blockchain
real y la otra blockchain, la probabilidad de que la división de la red persiste
disminuye con el tiempo. Por lo que es seguro asumir
que después de seis bloques una transacción se liquida
para siempre en la cadena de bloques. La inmutabilidad y seguridad de las transacciones de Bitcoin descansa
en el hecho de que es casi imposible producir una cadena de bloques válida con más bloques que
la original. Tal hazaña requeriría
una inmensa cantidad de potencia computacional necesaria para superar la velocidad de generación de
bloques de la red original
por un tiempo suficiente. Ahora que aprendimos sobre
varias partes de Bitcoin, veamos cómo interactúan dentro del ecosistema Bitcoin. Los usuarios de Bitcoin controlan las billeteras. Las billeteras, como aprendiste, son colecciones de claves privadas. Y estas claves privadas
pueden ser utilizadas para firmar transacciones y para producir direcciones para recibir
transacciones. Los exchanges pueden intercambiar bitcoins por otras criptomonedas y monedas
fiduciarias,
como el dólar. También puedes intercambiar bitcoins
por bienes de comerciantes. Con quien realice transacciones, todas sus transacciones se
envían a los nodos de Bitcoin. Cuando un menor ve
tu transacción, puede incluirla en un bloque. El minero crea un bloque con muchas transacciones y
procede a minar el bloque. Es decir, comienza a calcular la prueba de trabajo de bloque
utilizando su hardware. Cuando un menor finalmente encuentra
la prueba de trabajo del bloque, transmite el bloque
a otros nodos de Bitcoin. Los otros nodos reciben el
bloqueo mental recientemente y validado. Si el bloque es válido, los nodos lo agregan a su
copia de la cadena de bloques. De esta manera, la red logra consensos sobre el
estado actual de la cadena de bloques. Hablemos de los principios de
Bitcoin. Los principios de Bitcoin son
importantes para entender las
decisiones técnicas que se
tomaron durante el desarrollo de
Bitcoin. Uno de estos principios es el suministro máximo de Bitcoin
de 21 millones de Bitcoins. Este límite se fijó al
inicio del proyecto. Cambiarlo provocaría que estos arreglos en
la economía de Bitcoin. Por lo que es importante
mantenerlo así. resistencia a la censura es otro principio importante de
Bitcoin. El hecho de que mucha gente pueda
ejecutar nodos de Bitcoin hace que sea casi imposible
que una autoridad cierre la red. Los desarrolladores de Bitcoin valoran una
alta resistencia a la censura. Ser de código abierto es
otro principio de Bitcoin. Puede encontrar el software
Bitcoin Core forma
gratuita en el sitio web de GitHub. Al igual que muchos otros desarrolladores, puedes verificar el código
y verificarlo en busca de errores. También puedes participar
en su desarrollo. Bitcoin tiene una fuerte
comunidad de desarrolladores responsables de su
seguridad y nuevas características. Y ser de código abierto
es lo que lo permite. Bitcoin no tiene permiso, lo
que significa que
a cualquiera se le permite ejecutar un nodo Bitcoin, minar y realizar transacciones con Bitcoins. Esa es una de las mayores
fortalezas de Bitcoin y lo que lo hace tan popular
hoy en día en todo el mundo. Las transacciones de Bitcoin
son seudónimas. Eso significa que ninguna
información presente en una transacción de Bitcoin puede conectarse
sola con las personas. A diferencia del ejemplo desde el principio de la visión general,
podría haber sugerido que las transacciones de
Bitcoin
no contienen los nombres y los ID de
los destinatarios y remitentes. Una transacción de Bitcoin muestra solo transferencias entre direcciones
bitcoin, que parecían
colecciones aleatorias de caracteres. Si alguien descubre que una dirección pertenece a
una persona específica, puede rastrear la
cantidad de Bitcoin y otras transacciones
de esa persona. Pero esa es otra historia. Bitcoin apunta a una
alta fungibilidad. fungibilidad es una característica
que hace que una unidad de una moneda se valore por igual que cualquier otra unidad de
la misma moneda. Eso significa que idealmente cada Bitcoin es valorado
y tratado por igual. A menudo se argumenta que Bitcoin no
es fungible porque Bitcoins de
diferentes transacciones pueden rastrearse y
tratarse de manera diferente. Yo diría que aunque
es cierto en la práctica, la mayoría de los bitcoins son tratados
por igual y se tienen formas de hacer las transacciones
más privadas y fungibles. irreversibilidad de las transacciones es otro principio de
Bitcoin. Una vez que una transacción se
liquida en la cadena de bloques, no
se puede revertir. Esta es una característica
de seguridad importante porque hace que Bitcoin sea
difícil de confiscar. Pero también traslada
la responsabilidad de una transacción
al centro de Bitcoin. De ahí la necesidad de mantener seguras
tus claves privadas.
7. 5 Comienzo de la skillshare del proyecto: En este video, configuraremos un nuevo proyecto Spring Boot que será nuestra billetera Bitcoin. Para ello, usaremos la herramienta de inicializador Spring
del sitio web start
dot spring dot io. Así que entra al sitio web. Elige el proyecto Maven. El lenguaje es Java, usará esta versión
de Spring Boot, pero si no está disponible para
ti, puedes elegir la predeterminada
como nombre del grupo. Puedes establecer el
nombre que quieras. En mi caso, lo configuraré
como BYOD w dot wallet. Voy a usar BYOD W como
nombre del artefacto, como descripción. Voy a usar billetera Bitcoin. Usaremos la última
versión de Java. Si solo conoces
versiones anteriores de Java, no te preocupes, características
anteriores de Java
aún funcionan en la última versión ya que Java
es compatible con versiones anteriores. Por último, da clic en
Generar para descargar el proyecto, abrirlo y extraer su contenido a la
carpeta que desee. Ahora, abriremos el proyecto
usando idea inteligente. Después de iniciar el programa, haz clic en Abrir, luego elige la
carpeta que acabas de extraer. Haga clic en Trust Project. Espere hasta que IntelliJ idea
indexa todos los archivos del proyecto. Después de eso, puede
explorar los archivos que inicializador de
resorte
creó automáticamente. Para verificar si el proyecto
se configuró correctamente. Da click en Maven en el lado
derecho de la pantalla. Después dentro de la
carpeta de ciclo de vida, haga doble clic en Prueba. Uy, tenemos un error de maven. Para resolver ese error, hagamos clic en el cuadro de diálogo de
configuración. Cambiemos el camino de casa de Maven
para agrupar a Maven tres. Haga clic en Aplicar entonces. Bien. Antes de volver a hacer clic en la prueba, verificaré si la
estructura de mi proyecto se configuró correctamente. Entonces voy a hacer clic en Archivo. Entonces la estructura del proyecto se
asegura de que el
SDK del proyecto tenga la versión Java que eligió el inicializador de
primavera. Si no es el caso, haga clic en Agregar SDK
y descargue SDK, elija la
versión correcta de Java y una de sus implementaciones
haga clic en descargar. En mi caso, no voy a hacer eso porque ya tengo
la versión correcta. Entonces voy a hacer clic en Cancelar. Asegúrese de que el nivel de lenguaje
del proyecto también
esté configurado en la versión
correcta de Java. Ahora, volvamos a hacer la prueba. Espere hasta que pase la prueba. Genial. La consola indica
que la prueba ha pasado. Estamos listos para comenzar a
trabajar en nuestra billetera.
8. 6 Configuración de la repetición de habilidades de la GUI: En este video, comenzaremos a construir la primera
ventana de nuestra billetera. Para ello, primero agregaremos algunas dependencias
a nuestro proyecto. Abra el archivo xml palm dot
en la raíz del proyecto. El archivo xml palm dot contiene todas las dependencias externas
del proyecto. Vamos a añadir algunas dependencias de Java
FX. Java FX es un framework responsable de las características de la interfaz gráfica de
usuario. Es muy conocido
en la comunidad Java. La versión es 16. La siguiente
dependencia es JavaFX, FXML. La versión también es 16. También añadiremos un plugin. Se llama Java
FX Maven plugin. Su versión es 0.0, 0.6. Para cargar estas dependencias
en su proyecto, haga clic en este icono. Project ha cargado
todas las dependencias. Ahora hagamos el código necesario para arrancar
nuestra aplicación. Este proceso requiere
cierta coordinación entre las formas en que arrancan los efectos Spring Boot
y Java. Para ello, primero haremos una nueva clase Java llamada aplicación
GUI. Esta clase debe extender la clase
de aplicación desde los efectos Java. Y debemos implementar
el método start desde la misma clase. Añadiremos una
propiedad privada con el contexto de
aplicación configurable de tipo. Usaremos a continuación. Aquí agregaremos el método init, que se ejecuta antes
del método start, durante la
inicialización de la aplicación. El código que acabo de escribir
es responsable inicializar nuestras dependencias
inyectadas en la aplicación Spring
Boot . Ahora pasemos a la clase de aplicación BYOD
W. Modifiquemos el método principal. El método principal de esta clase es el primer método llamado cuando
ejecutamos nuestra aplicación. Cuando se ejecuta el código que acabo de
escribir, primero llamará
al método init de la clase de aplicación GUI que al método start
de la misma clase. Volvamos a la clase de aplicación
GUI. Sigamos implementando
el método start. Ahora, llamaremos al método
publish event en la propiedad context, pasando un nuevo objeto de evento
iniciado GUI, que creará
next como argumento. Vamos a crear la clase de evento
comenzada pegajosa. Lo crearemos en una
nueva carpeta de eventos. Debido a cómo
creamos esta clase, el ID ya
sabía qué clase
teníamos que extender y
automáticamente creó el código
boilerplate va necesitar muy útil, ¿no es así? Ahora seguiremos
implementando nuestro constructor. Llamaremos al súper
constructor pasando un
objeto de aplicación GUI como argumento. Y asignaremos el argumento etapa
primaria a la etapa. La propiedad privada también
hará un oyente para
esta clase de evento dentro de un paquete
llamado oyentes. Añadiremos la
anotación de componentes a esta clase. Verás mucho esta anotación
a lo largo del curso. Es de Spring
Boot y su propósito es hacer que un objeto
de una clase esté disponible para inyección y
otros objetos
del proyecto también
implementarán la
interfaz de escucha de
aplicaciones para esta clase, pasando el
evento gooey started como parámetro type. Esto es necesario para que
Spring Boot interprete a esta clase como un oyente eventos
para un evento iniciado. Ahora implementaremos el
método requerido de la interfaz. También necesitará un constructor. Este constructor tomará
un objeto de recurso con una anotación de valor apuntando a un archivo llamado
ventana principal punto FXML, que se agregará posteriormente
al proyecto. El constructor también tomará un argumento de contexto de aplicación. Luego inicializaremos a propiedades
privadas
con el mismo nombre que los argumentos del constructor. Hará que ambas propiedades sean Finales. Bien, ahora que tenemos nuestras dependencias
inyectadas en esta clase, implementemos el código del método de
evento de aplicación. Este código se
encargará de mostrar la ventana principal de nuestra billetera
cuando iniciemos el programa. Así que primero vamos a crear
una instancia de un objeto cargador FXML. Entonces obtendremos el objeto stage desde el evento GUI started. Para ello,
agregaremos el método gets stage a la clase de evento
iniciado pegajoso. Este método devolverá
el objeto stage. Añadiremos un título
a la billetera usando el método set title
del objeto stage. Puede ser cualquier cadena que quieras. Lo pondré como cartera BYOD W. Este texto se mostrará en la barra superior de la ventana de
programas. También llamará al
método set scene, pasando un nuevo objeto de escena como su parámetro instanciado con un objeto devuelto
por un nuevo método que creará llamado
initialize FXML. Este método comenzará a declarar una variable del tipo
parent llamada root. Luego dentro de un bloque try catch usaremos el método set
location de la variable de cargador FXML pasando la ubicación URL de
nuestra propiedad FXML. Vamos a establecer la
fábrica de controladores del cargador FXML a una referencia
del método good bean de la propiedad context. Esto es necesario para
que el framework JavaFX
reconozca las clases de controlador anotadas con la anotación Component. También estableceremos la variable raíz al resultado de llamar al método load
del cargador FXML
capturará una IOExcepción y la
lanzaremos envuelta en una excepción de tiempo de
ejecución. Devolveremos la variable raíz. Por último, en el método de
no aplicación se llamará al
método show del escenario, lo que provocará que la ventana
se muestre en la pantalla. Ahora vamos a crear el archivo FXML, pero nos referimos a la anotación de
valor de la propiedad FXML del constructor del
listener. Y el archivo FXML es un
tipo de archivo utilizado para codificar elementos GUI de
una aplicación JavaFX. Al igual que un archivo HTML,
codifica páginas web, archivos
FXML y código Las ventanas de efectos
Java crearán este archivo dentro la nueva ruta FXML
que creará. Este directorio se ubicará
dentro de la ruta de recursos. Lo llamaremos
subrayado principal ventana punto FXML. Eliminemos la
versión abreviada generada automáticamente. Vamos a agregar una etiqueta de panel de borde. Le agregaremos algunos atributos. Se agregará un Fx ID que
permitirá hacer referencia a la etiqueta del panel de borde dentro de
su clase de controlador, que se creará más adelante. Vamos a agregar algunos atributos
para establecer el tamaño de la ventana. Finalmente, agregaremos
algunos atributos de metal para establecer el esquema del archivo. Eso es. Ejecutemos la aplicación
para ver si todo salió bien. Dentro de la pestaña Maven, vamos a hacer clic en plug-ins, Spring Boot y Spring Boot run. Genial. La primera ventana de nuestro monedero ha aparecido en la pantalla. Buen trabajo.
9. 7 Creación de nuestra primera parte 1 skillshare 2: En este video,
comenzaremos a construir una prueba para la primera
característica de nuestra billetera. La primera característica
de nuestra billetera
será la opción de
crear una billetera. Más específicamente, crearemos un menú con un botón
que al hacer clic, hará que
aparezca un cuadro de diálogo en la pantalla. Ese cuadro de diálogo
contendrá inicialmente un TextField donde el usuario definirá
el nombre de la billetera y un botón Crear
que al hacer clic, generará una semilla mnemotécnica
aleatoria. Aprenderá lo que es
la semilla mnemotécnica. En el siguiente video, crearemos todas las funciones
de nuestro Wallet utilizando el enfoque de desarrollo basado en pruebas
o TDD. Este enfoque consiste en crear
primero una prueba de
integración, que es una prueba que describe lo queremos lograr
para esa característica. Después implementaremos la función y ejecutaremos la prueba
hasta que pase. Durante la implementación,
podemos encontrarnos con situaciones que
necesitamos hacer nuevas clases o métodos que nos ayuden a
lograr nuestras metas. Si ese es el caso,
crearemos pruebas unitarias para estas clases fueron métodos
y las implementaremos usando TDD. Al final de cada ciclo TDD, refaccionaremos nuestro
código si es necesario. Veamos cómo
funciona esto en la práctica. Pero primero, agreguemos algunas
dependencias a nuestro proyecto. Vamos a añadir algunas dependencias relacionadas con el framework Spark. El framework Spark es un framework de
pruebas en groovy, un lenguaje de programación
compatible con Java. Contiene características que
facilitan la construcción de pruebas, también
utilizará una versión de
prueba FX compatible con Spock. Test fx es un framework
que proporciona características para probar aplicaciones
JavaFX. Ahora, agreguemos la
maravillosa versión 3.0, 0.6 a nuestro archivo POM. Y vamos a agregarle spock
spring. La versión será
2.0, groovy 3.0. Su alcance será de prueba. La siguiente dependencia
que se agregará es Spark Core. La versión será la
misma que Spock spring. El alcance será de prueba. La siguiente dependencia
será la prueba FX Spock. Su versión será 4.0, 0.16 alpha también
agregará un complemento de G Maven. Bien, olvidé poner el alcance correcto y la
prueba de dependencia FX. También agregaremos algunos objetivos
en el plugin GI Maven. Habrá que que
groovy funcione correctamente. Ahora, haremos un cambio en el archivo de
propiedades de punto de la aplicación. Spring, por defecto
crea un servidor web, pero no necesitaremos uno
en nuestra aplicación. Por lo que debemos establecer esta
propiedad en ninguna. Así que la primavera no creará un servidor
web cuando arranca. Ahora crearemos nuestra primera prueba. Pero primero, eliminemos este archivo BYOD W
application test, que fue generado automáticamente
por el inicializador de resorte, creará un paquete en
esta carpeta llamado gooey que contendrá todo nuestro usuario
gráfico pruebas de interfaz. Dentro de este paquete,
vamos a crear la prueba. Pero primero en el archivo xml
palm dot, da clic en el botón Cargar cambios de
Maven. Ahora el IDE nos permitirá
crear clases groovy. Así que vamos a crear uno llamado
Crear prueba de billetera. Añadiremos a esta clase una anotación de prueba Spring Boot extenderá esta clase con
la clase de especificación de la aplicación. Esto es necesario para que
tanto Spring Boot test fx consideren esta
clase como una clase de prueba. Cada prueba de integración debe contener esta anotación
y extensión. Debemos implementar
el método start desde la especificación de la aplicación. También implementaremos los métodos
de unidad y stop. Dentro del método init se agregará este código que es necesario
para la inicialización de la prueba. Dentro del
método de parada se incluirá un código necesario para
detener la prueba. Dentro del método stark, debemos incluir el
código necesario para mostrar la primera pantalla
de nuestra aplicación. Este código será
similar al código presente en la clase de escucha
iniciada GUI. Así que vamos a crear
una instancia de un cargador FXML pasando la URL FXML
como su argumento, luego
crearemos la propiedad
privada FXML con la misma
anotación de valor presente en la GUI comenzó clase de
escucha. Groovy transforma cada método con getter establecido en
una propiedad de objeto, podemos usar esta URL aquí. En lugar de obtener URL
establecerá la propiedad de
fábrica del controlador el contexto obtener referencia del
método bean. Agreguemos el
campo de contexto a la clase. Arriba. Pondrá la anotación auto
cableada. Esta anotación es necesaria
para que Spring Boot inyecte el objeto de
contexto de aplicación desde su
contenedor de inyección de dependencia a esta variable. A continuación, crearemos
la variable raíz usando el método load
del cargador FXML. Entonces estableceremos el título del escenario, la escena y llamaremos al método
del espectáculo escénico tal como el código dentro del oyente comenzó
gooey. Bien, estamos listos para trabajar en
el código de nuestra primera prueba. El nombre de la prueba
será debe crear billetera. La prueba contendrá
los requisitos de la función que
queremos implementar, utilizará la palabra clave cuándo
describir las acciones que realizará el usuario de la
prueba. Entonces vamos a implementarlo. El usuario dará click en un
botón con el texto conocido. Después harás clic en un
botón con la billetera de texto. Después en un campo de texto
con un FX id de nombre. Cuando queremos
hacer referencia a un ID de FX, ponemos el nombre del ID
después de un signo de libra como este. Entonces el usuario escribirá
las palabras billetera MyText. Después hará clic en un botón
con el texto de creación. A continuación, la prueba
buscará el contenido de un campo de área de texto con una identificación
ética de semilla mnemotécnica. Asignará el contenido de este campo a la variable semilla
mnemotécnica. Finalmente, usaremos la palabra clave entonces para definir lo que esperamos que suceda después de que el usuario realice todas las acciones dentro
del bloque de viento. Esperamos que la variable semilla
mnemónica contenga un valor no nulo. Para ello, solo colocamos la variable semilla mnemónica
dentro del bloque entonces. Si se establece la semilla mnemotécnica, el bloque evaluará a
true y la prueba pasará. De lo contrario, se evaluará como
falso y la prueba no pasará. Ejecutemos esta prueba
para ver qué pasa. Primero, haremos clic en Build
than on build project para asegurarnos de que el IDE cargue todos los cambios que hemos
realizado en el código. Después haremos clic en Test
dentro de la pestaña Maven Config. *****. El IDE volvió a
quejarse de Maven, arreglemos eso rápidamente. Ahora. Realicemos de nuevo la prueba. La prueba ha fallado como se esperaba. ¿Notaste que
una ventana aparecía rápidamente en la pantalla
durante la prueba? Muestra nuestra ventana
abierta, al menos. Comprobemos los resultados de
nuestras pruebas en la consola. Dice que la consulta
nueva no devuelve nodos. La prueba abrió nuestra aplicación, después trató de encontrar un
elemento con el texto conocido ya que no lo encontró, rápidamente falló y
cerró la aplicación. En el siguiente video, aprenderemos qué es una semilla
mnemotécnica. Después en el video posterior al siguiente, crearemos nuestra primera
billetera y haremos que esta prueba pase. Nos vemos.
10. Semillas de Mnemonic: En este video, aprenderemos
más sobre las semillas mnemotécnicas. Entonces, ¿cuál es la semilla mnemotécnica? Una semilla mnemotécnica es una
frase que contiene 121-51-8201 o 24 palabras. Se utiliza para derivar todas las billeteras, claves
privadas y direcciones. Las reglas de generación de
semillas mnemotécnicas que usaremos se describen en la
Propuesta de Mejoramiento de Bitcoin 39 o BIP 39. Muchas carteras utilizaron
las reglas BIP 39 para generar semillas mnemotécnicas. Las semillas mnemotécnicas se combinan
con la cadena mnemotécnica más una contraseña opcional para producir una semilla raíz representada
aquí en formato hexadecimal. La contraseña opcional se conoce
comúnmente como frase de contraseña, pero usaremos la palabra
contraseña para simplificar. Entonces, utilizando otros algoritmos, la semilla de raíces
genera claves privadas, claves
públicas y direcciones, aprenderá los detalles de estas operaciones
en un video posterior. Ahora, centrémonos en cómo se generan las semillas
mnemotécnicas. Para generar una semilla
mnemónica, primero, debemos generar una
secuencia aleatoria de bits llamada entropía de longitud
igual a 128 bits. Si queremos una semilla mnemotécnica
de 12 palabras, 160 bits, si queremos una con 15 palabras, 192 bits, si queremos
una con 18 palabras, 224 bits si queremos una
con 21 palabras o 256 bits, si queremos una con 24 palabras, luego calculamos la suma de comprobación. Para ello, calculamos
la longitud de entropía dividida por 32 y obtenemos
el tamaño de la suma de comprobación. Entonces obtenemos los primeros bits de tamaño de
suma de comprobación del hash SHA-256 de la entropía. El resultado es la suma de comprobación. La suma de comprobación se utiliza para verificar si una semilla mnemotécnica dada es válida. Anexamos la suma de comprobación al
final de la entropía inicial. El resultado se
divide en grupos de 11 bits. Cada grupo de 11 bits se
convierte a un número 0-2047. Estos números se utilizan como
índices en una lista de palabras. Las palabras correspondientes
forman la semilla mnemotécnica.
11. 9 Creación de nuestra primera parte 2 skillshare 2: En este video,
continuaremos implementando la función de creación de billetera
de nuestra aplicación. El primer paso es agregar un botón con el texto
nuevo escrito en él. Hagamos esto. Abra el archivo FXML de punto de la ventana
principal. A partir de ahora, usaremos la herramienta IDE Scene Builder para crear las ventanas
de nuestro proyecto. Scene Builder nos
permite crear la interfaz gráfica de usuario de nuestra aplicación de
forma interactiva y sencilla. Haga clic en el botón Scene
Builder en la parte inferior de la pantalla. En mi caso, esta
ventana apareció. Pero si no tienes
instalado
Java FX o Scene Builder un botón para
descargarlos aparecerá en la
parte superior de tu pantalla. Después de descargarlos
e instalarlos, aparecerá
esta ventana. Ahora agregaremos una
barra de menú superior a la ventana principal. Para ello, haremos
clic en los controles, luego arrastraremos y soltaremos el componente de la barra de
menú a la parte superior del menú del panel de
borde a continuación. Ahora tendremos una barra de menú
con tres elementos de menú. Eliminemos los de
edición y ayudemos. Cambiemos el
menú del archivo etiquetado dos nuevos. Genial. Ahora tenemos
nuestro nuevo botón. Comprobemos nuestra prueba para
ver qué hacer a continuación. La siguiente acción que
hará nuestro usuario es hacer clic en el botón de la billetera.
Vamos a crearlo. De vuelta a la ventana principal. Añadiremos un elemento de menú
dentro del nuevo menú. En este caso, ya
tenemos un elemento del menú. Entonces cambiemos su
etiqueta a billetera. Cuando el usuario hace clic
en el botón de la billetera, debe aparecer
una nueva ventana de diálogo. Vamos a implementarlo en
el Scene Builder. Haga clic en el elemento del menú de la billetera. Vamos a añadir una acción
a este botón. Haga clic en Código, escriba abrir
crear diálogo de billetera. Si hacemos clic en el
botón Texto en la parte inferior de la pantalla y
verificamos el archivo FXML. Notaremos que el IDE
ha agregado el
atributo on action en la etiqueta de elemento de menú con el valor que acabamos de escribir. Ahora, para crear una acción para este botón necesitará
crear un controlador. Pero primero, hagamos un poco de
refactorización en nuestro código. Crearemos un nuevo paquete
dentro del paquete BYOD W. Vamos a llamarlo gooey le
transferirá los paquetes de eventos y
oyeners, agregará todas las
clases relacionadas con la gráfica de usuario de las aplicaciones interfaz gráfica de usuario de las aplicaciones a este paquete. De vuelta a la ventana principal, agregaremos un atributo de
controlador FX a la
etiqueta del panel de borde y lo configuraremos en
el nuevo controlador que
crearemos dentro de un
nuevo paquete de controladores. Dentro del paquete gooey. Su nombre será controlador de
ventana principal. Cada archivo FXML puede tener un controlador que se utiliza
para definir las acciones que ocurren en respuesta a las interacciones del usuario con la ventana codificada por ese FXML. En nuestro caso, el
controlador de ventana principal contendrá código que definirá acciones en respuesta a eventos
en la ventana principal. Volver a la
ventana principal punto archivo FXML. Cuando hacemos clic en el atributo Open create wallet dialogue
y presionamos Alt más enter, el IDE mostrará
la opción de crear un método dentro del controlador de la ventana
principal. Haga clic en esta opción. El IDE generó automáticamente
el método en el controlador de ventana principal. Eliminemos el argumento del evento de
acción porque no lo necesitaremos. En este método se
incluirá el código encargado de abrir el diálogo
crear billetera. Cuando hacemos clic en el elemento del menú de la
billetera, primero
instanciaremos
un objeto
de diálogo de tipo botón tipo. Después estableceremos los
diálogos en su propietario a la ventana del
panel de borde para indicar que el
diálogo pertenece al panel
de borde de la ventana principal. Volver a la
ventana principal punto archivo FXML. Podemos dar clic en el atributo ethics ID de la etiqueta del panel de
borde, presionar Alt más Enter y crear la propiedad border pane dentro del controlador de la
ventana principal. El IDE generó automáticamente
la propiedad. Vamos a configurarlo en privado e
incluir la anotación FXML encima de él para indicar que
se refiere a un componente FXML. Después estableceremos el
título del diálogo para crear una nueva cartera. Ahora, dentro de un bloque try
catch
instanciará un objeto
cargador FXML. Pasando estos argumentos. Luego crearemos la propiedad create
wallet dialogue y la propiedad context. Después crearemos un constructor para inicializar ambas propiedades. Ambas propiedades serán inyectadas
automáticamente por el contenedor de
inyección de dependencia Spring agregará una anotación de valor
al argumento
constructor create wallet dialogue pasando la ruta de un FXML
archivo que creará a continuación. Luego estableceremos el contenido
del dolor de diálogo al resultado de llamar al método load
del cargador FXML
luego capturará una IOException y la
lanzaremos como una excepción en tiempo de ejecución. Por último, llamaremos
al programa de diálogo y método de espera para
abrir el diálogo. No olvides
agregar la
anotación de componentes a esta clase. Ahora, ejecutemos nuestra aplicación para ver qué tenemos hasta el momento. En la pestaña Maven dentro de
plugins y Spring Boot, da clic en Spring Boot run. Tenemos nuestra barra de menú superior con el botón Nuevo y
el botón de billetera. Cuando hacemos clic en
el botón de la billetera, la aplicación
lanza una excepción. Eso se debe a que
no encontró el archivo FXML de punto de diálogo de crear billetera. Vamos a crearlo.
Después de crearlo, da clic en Scene Builder. Eliminemos este panel de anclaje. Arrastre el dolor del diálogo
y suéltelo aquí. Bueno. Ajustemos el tamaño de la misma. Haga clic en Maquetación. Después en el campo de
altura pref tipo 500, en el tipo de
campo ancho pref para 50. Luego establece el tamaño de preparación de uso en los campos min-width
y min-height. Ahora agreguemos un
texto de encabezado a la ventana. En el encabezado tipo de campo de texto. Dale un nombre a tu billetera
y haz clic en Crear. Agreguemos un poco de
relleno a su alrededor. Bueno. Ahora agreguemos un panel de cuadrícula. Arrastre y suelte este componente
al dolor de diálogo a continuación. Dentro de la primera celda
del panel de cuadrícula se agregará
una etiqueta como esta. Y esta etiquetada
contendrá el nombre de la billetera de texto. También agregaremos un
campo de texto al panel de cuadrícula. Cambiemos sus coordenadas, fijemos su índice de columna en uno. Ahora agreguemos un botón
al panel de cuadrícula. Cambie su índice de fila a uno
y su índice de columna a uno. Cambiemos su texto para crear. Volvamos a nuestra prueba para comprobar qué más requiere. Intentará hacer clic en un componente con una identificación
ética de nombre. Así que agreguemos un Fx id de
nombre al campo de texto. Después de eso, intentará escribir mi billetera de texto en
el campo de texto. Después hará clic
en un componente con el texto Crear en él, crear con una
C. mayúscula Cuando haga clic en él, la prueba
buscará el contenido de
un área de texto con una
idea FX de semilla mnemotécnica. Así que vamos a crear esta área de texto. Arrástralo al panel de cuadrícula de abajo. Luego cambia su índice de fila a
dos y su tramo de columna a
dos para que el campo semilla
mnemotécnico ocupe el espacio
de dos columnas. Bueno. También agregaremos una etiqueta para
el campo de semillas mnemotécnicas. Pero primero, agreguemos otra
fila al panel de cuadrícula. Bueno. Aumentemos el índice mnemotécnico de fila de
campo semilla a tres. Después arrastraremos una etiqueta
al panel de cuadrícula. Ajusta su índice de fila a dos, cambia su texto
a semilla mnemotécnica. Ahora agreguemos un Fx id de semilla
mnemotécnica al área de texto. Ahora, ejecutemos nuestra aplicación
y veamos qué pasa. Reconstruya primero el proyecto y
haga clic en Spring Boot run. Genial. Pero cuando hacemos clic en
Crear, no pasa nada. También debemos encargarnos del
cierre de nuestro diálogo. Por ahora, haga clic en detener. El posicionamiento de estos
campos me está molestando un poco. Vamos a arreglar eso. Haga clic en el botón Texto. Hemos incluido el panel de
cuadrícula dentro la etiqueta de encabezado
del dolor de diálogo. El lugar correcto
para incluirlo está en la etiqueta de contenido.
Vamos a cambiarlo. Comprobemos su aparición
ahora en el Scene Builder. Genial, ahora se ve mucho mejor. En el siguiente video, continuaremos implementando
la función de creación de billetera. Nos vemos.
12. 10 Creación de nuestra primera parte 3 skillshare 2: En este video, continuaremos implementando la
función de crear billetera y finalmente, haremos que nuestra primera prueba de GUI pase. Para ello, agreguemos una
dependencia al proyecto. Añadiremos Bitcoin, Java y biblioteca de código abierto hecha
exclusivamente para este curso. Esta biblioteca contiene muchas utilidades relacionadas con
Bitcoin, como métodos para generar semillas mnemotécnicas
aleatorias, construir transacciones
y muchas más. Para el correcto funcionamiento
de esta biblioteca, debemos agregar un
objetivo de complemento que
copiará el archivo word
list dot TXT de Bitcoin Java al
proyecto durante la fase de compilación de las
aplicaciones proceso de construcción. TXT sin palabras contiene todas las palabras válidas para la generación de semillas
mnemotécnicas. Ahora abre el cuadro de diálogo crear
cartera punto FXML. Cambiar a la vista de texto. Añadiremos un controlador a este FXML para agregar una
acción al botón Crear. Así que agreguemos el atributo del
controlador FX a la etiqueta de dolor de diálogo. El nombre del controlador se
creará el controlador de diálogo de billetera, y lo agregaremos al paquete de
controladores. Al igual que con cada controlador, le agregará la
anotación de componentes. Vamos a crear la
propiedad semilla mnemónica en este controlador. En el FXML, agregaremos una
acción al botón Crear. Vamos a agregarlo aquí. Nombraremos la acción como
crear semilla mnemónica. Y lo crearemos en el controlador
correspondiente. Entonces, cuando el usuario haga
clic en el botón Crear, se llamará a
este método y el área de texto mostrará
una semilla mnemotécnica aleatoria. Entonces estableceremos los textos de
semillas mnemotécnicas al resultado del método create
del servicio
de
semillas mnemotécnicas que creará a continuación. Inyectemos el servicio de
semillas mnemotécnicas en esta clase. Ahora, vamos a crear la clase de servicio
semilla mnemónico dentro del nuevo paquete llamado api dot services dentro del paquete
BYOD W. Básicamente, cada
clase empresarial no relacionada con la
interfaz gráfica de usuario se colocará dentro del paquete API. Agreguemos el método create
al servicio de semillas mnemotécnicas. Agregar la
anotación de servicio a esta clase. propósito es idéntico a
la anotación Componente, pero es más adecuado
para las clases de servicio. Ahora, inicialicemos la propiedad
mnemonic seed service en el constructor create
wallet. Ahora, vamos a implementar este método porque estamos usando TDD para
crear nuestra aplicación. Primero crearemos una
prueba unitaria para esta clase. Vamos a crear un paquete API
dentro de la carpeta test. En su interior, cree una clase maravillosa llamada prueba de servicio de
semillas mnemotécnicas. Como prueba unitaria, esta
clase solo necesita
extender la
clase de especificación de Spock. Ahora, vamos a crear una prueba llamada should return random
mnemonic seed. Y esperaremos que el servicio semilla
mnemotécnico devuelva un valor no nulo. Instanciemos aquí el servicio de semillas
mnemotécnicas. Ejecutemos esta prueba para
comprobar qué pasa. Ha fracasado como se esperaba. Implementemos este método. Para ello, usaremos el método generate
random de la
clase generadora
de semillas mnemotécnicas de Bitcoin Java. Debemos pasar las
entropías número de bits que queremos que
la semilla
mnemotécnica tenga como argumento a
este método, vamos a usar a 56. Recuerda que una entropía de 256 bits genera una semilla
mnemotécnica de 24 palabras. Por último, llamaremos al método
get sentenciado a
la devolución de este método
y devolveremos el resultado. Al igual que con cada trabajo, una excepción
comprobada, también
necesitamos agregar
la oración lanza FileNotFoundException a la firma del método
create. Tenemos que hacer lo mismo con el método create mnemonic
seed en el controlador de
diálogo create wallet. Realicemos de nuevo esta prueba. Genial, La prueba ha pasado. Ahora vamos a comprobar qué sucede
cuando ejecutamos nuestra aplicación. Vaya, y se produjo un error. Oh, es sobrescribir con una W
mayúscula en esta etiqueta. Esta etiqueta de identificación de grupo también es incorrecta. En realidad, es solo educación de guiones de
Bitcoin. Volvamos a ejecutar nuestra aplicación. Genial. Hemos
generado con éxito una semilla mnemotécnica, pero quiero su texto
envuelto. Vamos a arreglarlo. Vamos al diálogo crear
cartera punto FXML. En el Generador de escenas, haga clic en el área de texto y haga clic en
la casilla de verificación El texto de Envolver. Volvamos a ejecutar el proyecto. Bien, mucho mejor. Ahora, hagamos todas nuestras pruebas. Genial. Todos han pasado.
13. 11 Creación de nuestra primera parte 4 skillshare 2: En este video,
vamos a desarrollar aún más nuestras aplicaciones
crean función de billetera. Se agregará un botón OK y un botón de cancelación al diálogo de
creación de billetera. Cuando el usuario haga clic
en el botón Aceptar, se creará
su billetera y el nombre de las billeteras aparecerá
en la parte superior de la pantalla. Cuando haga clic en
el botón Cancelar, el diálogo simplemente se cerrará. También agregaremos una restricción
al botón Okay para que
se deshabilite por defecto y solo se habilite cuando se cumplan
los campos de nombre y
semilla mnemotécnicos. Finalmente, agregaremos un campo de contraseña
opcional para que el usuario solo pueda acceder a su billetera
y realizar transacciones con ella después de proporcionar la contraseña
correcta. Agreguemos estas nuevas características primero en nuestra prueba de creación de billetera. Primero, agregaremos un clic
en la acción del botón Aceptar. Entonces esperaremos que el título
escénico sea igual
al nombre de nuestra aplicación
dash el nombre de nuestra billetera, que es mi billetera de prueba. Ahora vamos a crear
la propiedad de escenario. Lo inicializaremos
en el método start. Ahora, vamos a crear otra
prueba para verificar qué sucede cuando el usuario intenta hacer clic en el botón Cancelar. Para ello, vamos a
crear una prueba con el nombre debe cancelar la creación de
monedero. Por lo que esperamos que cuando el usuario haga clic en la nueva billetera y cancele, no se lanzará ninguna excepción. Realicemos estas pruebas
para ver qué pasa. Las pruebas han
fallado como se esperaba. Implementemos estas características. Ir al cuadro de
diálogo crear cartera punto archivo FXML. Haga clic en el
panel de diálogo en el lado izquierdo. Después agrega un botón OK y
este campo de tipos de botón. Haga clic en más, luego
agregue un botón de cancelar. Ahora agregaremos el campo de
contraseña. Pero primero, agreguemos otra
fila en el panel de cuadrícula. Ahora vamos a mover el nombre, etiqueta y el campo
a la primera fila. Después agregaremos una etiqueta de contraseña y un campo de contraseña
en la siguiente fila. También agreguemos una idea Fx de contraseña al campo de
contraseña. Ahora, cambiemos texto
del encabezado del diálogo a lo siguiente. Mientras estamos en ello, hagamos que el
campo semilla mnemotécnico no sea editable. Esta es una medida de seguridad
porque no queremos que el usuario cambie su semilla
mnemotécnica accidentalmente. Cambiar a la vista de texto. Añadiremos algunos cambios
a estos botones, etiquetas en el botón Bien, agregaremos una idea de Fx de bien. El botón Cancelar borrará su contenido y agregará
una idea de Fx de cancelar. También agregaremos el
valor de cancelado cerca de los datos del
botón Atributo. También agregaremos la
cadena cancel al atributo text. Esto es necesario porque cuando
usamos el botón de cancelación predeterminado, su texto se traduce
al idioma de la computadora, y no queremos eso. Ahora, hagamos algunos cambios en el controlador de crear
diálogo. Se le agregará un método llamado
inicializar. Pero primero,
volvamos a su FXML y agreguemos
un Fx id de dolor de diálogo
a la etiqueta de dolor de diálogo. Ahora, agreguemos las propiedades con un FX ID al controlador. Lo hará con la contraseña de
propiedades llamada dolor de diálogo,
OK y Cancelar. Ahora volvamos al método
inicializado. Este método
se ejecutará después de la inicialización
del diálogo. Incluirá código ahí para definir las acciones
de cada botón. Primero, definiremos la
acción del botón Cancelar. Cuando un usuario hace clic en él, el diálogo se ocultará. Entonces llamaremos al Método de Botón de
Búsqueda
del dolor de diálogo pasando el botón de cancelar
como argumento. Después le agregaremos un controlador de
eventos, pasando el argumento action y una callback que llamará al método hide de
la ventana de dolores de
diálogo. Haremos lo mismo
con el botón Bien. Pero llamaremos al método create wallet en la devolución de llamada en su lugar. Vamos a incluir el mismo código para ocultar la ventana
cuando el método create wallet por ahora y ejecutar la aplicación para
ver qué pasa. Cuando hacemos clic en el
botón Cancelar, el diálogo se esconde. Lo mismo sucede cuando hacemos
clic en el botón Bien. Bueno. Pero cuando hacemos clic en la X del
lado del diálogo, no pasa nada. Vamos a arreglar eso. Vaya al controlador de
ventana principal. Habrá que incluir el
siguiente código para cerrar la ventana de diálogo cuando hagamos
clic en el botón X. Ahora, ejecutemos la
aplicación e intentemos de nuevo. Bien, eso lo arregló. Cambiemos también
el
método de show y wait llamado al diálogo para simplemente mostrar que
simplifica un poco las cosas. Ahora, vuelva a ejecutar la aplicación. Todo sigue funcionando
como se esperaba. Pero hay otro
tema con el diálogo. Permite la
creación de billeteras sin nombre y
semilla mnemotécnica. Queremos que cada billetera tenga
un nombre y una semilla mnemotécnica. Por lo que necesitamos desactivar el botón
Bien si uno
no se cumple. Arreglemos esto. Vaya al controlador de
diálogo de creación de billetera. Ahora, vamos a crear una propiedad
privada de tipo Boolean binding llamada
todas las entradas requeridas están llenas. Estableceremos esta propiedad en el método inicializado
con el siguiente código. Aquí usaremos una clase anónima
Java que extiende el enlace booleano. Después inicializaremos la
clase con el método bind, pasando
como argumentos las propiedades name
y mnemonic seed text. Entonces en el método compute value se incluirá un código que
devolverá true solo si los campos name y mnemonic seed
no están vacíos. Ahora, crearemos un
método getter para esta propiedad. Finalmente, llamaremos al método
de propiedad para discapacitados en el botón Okay. Entonces llamaremos a bind en el
resultado y pasaremos el get all required inputs are full method calling
the method on it. Hagamos un pequeño arreglo
en este método primero, debe devolver un enlace
booleano. Y vamos a quitar esto, a buscarlo. Bueno. Ahora volvamos a ejecutar nuestra
aplicación. Bien, el botón Bien
está deshabilitado por defecto. Si tecleamos algo en el campo de nombre de billetera,
permanece deshabilitado. Pero cuando hacemos clic en el
botón Crear, se habilita. Genial. Realicemos nuestras pruebas de nuevo. Eso debería crear la prueba de billetera ha fallado porque aún no habíamos implementado el código para cambiar
el título de la aplicación. Hagámoslo en el siguiente video.
14. 12 Creación de nuestra primera parte 5 skillshare 2: En este video, implementaremos
una función que hará que la Aplicación
Cargue la billetera y muestre su nombre en el título de la
aplicación. Después de que el usuario
crea, la billetera. Crearemos código que será útil más adelante cuando
queramos mostrar otras características de billeteras
como direcciones en la pantalla. Después de implementar esta característica, esta prueba pasará porque el título de la etapa será igual
al espacio de billetera BYOD W, espacio de
tablero, el nombre de las billeteras. Entonces vamos a implementarlo. Primero. Iremos al controlador create
wallet. Entonces en este método, se creará una Wallet utilizando
un nuevo servicio llamado create wallet service y
un método llamado create. Pasaremos el nombre de las billeteras, la contraseña y la
semilla mnemotécnica al método. Ahora vamos a crear
la clase de cartera. Vamos a añadir un nuevo paquete dentro de
BYOD W, llamarlo dominios. En su interior se agregará un nuevo registro
Java llamado wallet. Por ahora, solo agregaremos un
atributo de cadena llamado
name a este registro. Un registro Java es una
característica reciente del lenguaje. Cada atributo record tiene un getter incorporado
y un constructor, así que no necesitamos agregarlos. Ahora, importe el registro de billetera al controlador
de
diálogo de creación de billetera. Ahora, inyectaremos el
servicio create wallet en esta clase. Y crearemos
esta clase dentro
del paquete de servicios API. Se agregará la
anotación de componentes a esta clase. Inyectemos este servicio en el constructor de
esta clase. Ahora, crearemos
el método create dentro del servicio create
wallet. Por ahora, solo devolveremos una nueva billetera pasando el nombre como su parámetro
al controlador de
diálogo Crear billetera. Ahora que hemos creado
la billetera publicaremos un evento que tomará como parámetro
la billetera creada. Este evento será
escuchado por una clase para que cuando el usuario
cree una billetera, el oyente actualice la billetera actual cargada
por la aplicación. Inyectemos el
contexto de la aplicación en esta clase. Ahora, vamos a crear el evento de billetera
creado dentro del paquete de eventos. Luego llamará al
súper constructor pasando el controlador de
diálogo create wallet. Y estableceremos un
nuevo campo de wallet, asignándole el argumento
constructor wallet también incluirá un
getter para este campo. Ahora, vamos a crear un oyente para este evento llamado
creado listener de billetera. Y lo crearemos dentro
del paquete de oyentes. Implementará la clase de escucha de
aplicaciones con el
evento wallet creado como parámetro. Luego implementará el
método en evento de aplicación. Se llamará a un método
de un nuevo servicio llamado actualizar el servicio de
billetera actual. Este método llamado update toma como parámetro la
cartera de eventos. Inyectemos este
nuevo servicio en esta clase y
creemos el servicio. Lo agregaremos dentro de un
nuevo paquete de servicios. Dentro del paquete pegajoso. A continuación se creará el método de
actualización en él. También le agregaremos una
anotación de Servicio. Por ahora, el método de actualización solo
establecerá el nombre de la billetera actual en el nombre de billetera
recién creado. Ahora, vamos a crear un nuevo paquete dentro de BYOD W
llamado observables. Dentro de este paquete se creará
la clase de billetera actual. Volver al servicio de
billetera Update Current
instanciará la
billetera actual en su constructor. En la clase actual de monedero se incluirá la anotación
Componente. Esta clase representará la cartera actual cargada
por la aplicación. Cada cambio
que realice la aplicación a esta instancia de clase aparecerá en la interfaz
gráfica de usuario de las aplicaciones. Lo incluimos en un
paquete llamado observable, porque cada propiedad de esta clase será inobservable. Y observable es
un tipo de objeto en el que cada
cambio de estado puede ser escuchado, promulgado por otros objetos. La primera propiedad observable que le agregaremos es el nombre. Tendrá el tipo de propiedad
string simple. Este tipo implementa la interfaz
observable y desencadena un evento de cambio
cuando su valor de cadena cambia. Lo vamos a instanciar aquí. Y crearemos un
getter para este campo. Intellij idea identificó que
es un observable y
creó dos getters. Uno para la propiedad
llamada name property y el otro para el valor de
propiedad llamado getName también
creará un setter para
este campo para establecer el valor de la propiedad
name. Hagamos que este campo sea definitivo. También hará una prueba para esta clase de
servicio de creación de billetera. Deberíamos haber creado la prueba antes de
implementar este método, ya que estamos usando TDD. Pero considerando vamos a incrementar esta funcionalidad de métodos
donde se perdona. Vamos a crear la prueba. Ahora. Primero crearemos una propiedad para el servicio create
wallet e instanciaremos dentro
del método de configuración que se ejecuta antes de cada prueba. Entonces crearemos una prueba
llamada debería crear billetera. Dado tenemos un nombre, una contraseña, y una semilla mnemotécnica. Cuando llamamos al
método create desde el servicio create wallet
con estos parámetros. Entonces esperaremos que
el nombre
de la billetera sea igual a la variable
name. Vamos a hacer la prueba. La prueba ha pasado. Ahora, recapitulemos
lo que hemos hecho hasta ahora. Cuando el usuario haga
clic en el botón Aceptar, se
llamará al método de crear billetera desde el controlador de
diálogo de crear billetera y
el servicio de billetera
creará la billetera. Para ello, utiliza
el método create, tomando el nombre, la contraseña y la semilla mnemotécnica que
el usuario haya elegido. Por ahora, este método sólo devuelve una nueva cartera
con su nombre. Luego pasamos la billetera
creada a un nuevo evento de billetera creado
y publicamos este evento. Cuando esto sucede,
activará el
método de escucha de billetera creado en el evento de aplicación. Recibirá el evento de wallet
creado como su parámetro. Debemos agregar la
anotación de componente a esta clase e inyectar el servicio de billetera
actual de actualización en su constructor. Por lo que el método de
evento de aplicación llamará
al método de
actualización desde el servicio de billetera actual de actualización, pasando la billetera del
evento como su parámetro. Por último, el método de actualización. Estableceremos el nombre de
la billetera actual el nombre de la billetera recién
creada. Ahora, volvamos al controlador de ventana
principal. Aquí se creará un
método inicializado que se
ejecutará antes de que aparezca la ventana principal de la
aplicación. En su interior, agregará un oyente a la propiedad
actual de billetera. Inyectemos primero la
cartera actual en esta clase. Dentro del
método de escucha de anuncios pasará una devolución que tomará tres parámetros y valor observable y antiguo, y un nuevo valor en
el cuerpo de devolución obtendrá la etapa de Windows y asignarlo a la variable de etapa. Debemos lanzar su tipo a escenario. Después estableceremos su título
en BYOD W wallet space, dash space, new value. La nueva variable de valor contiene el nuevo valor del nombre
de la cartera actual. Siempre que cambie el nombre de la
billetera actual, este cambio será escuchado
por esta devolución de llamada y el título de la etapa también
cambiará a la oración que
acabamos de decir. Ejecutemos la aplicación
para verificar si esto funciona. Crearemos una nueva billetera
con la prueba de nombre, luego una semilla mnemotécnica y haremos clic, Bien, genial, funcionó. El título de la ventana cambia
a BYU OWL una prueba de guión. Vamos a crear otra cartera con un nombre diferente para
ver qué pasa. Como se esperaba. Se ha cambiado para que coincida con la billetera
recién creada. Ahora, hagamos todas nuestras pruebas. Genial. Todas las pruebas han pasado. Buen trabajo.
15. 13 Creación de nuestra primera parte 6 skillshare 2: En este video, comenzaremos a implementar una función
que nos permitirá crear direcciones que serán utilizadas posteriormente para recibir Bitcoins. Lo primero que haremos es
crear la pestaña Recibir. Esta pestaña contendrá las direcciones derivadas
de nuestra billetera. Así que ve a la
ventana principal punto archivo FXML. En el Constructor de escenas
se incluirá una caja V en el centro
del panel de borde. Dentro de la caja V se
incluirá un panel de pestañas. Eliminará la segunda pestaña que se creó, automáticamente. Cambiar el texto de
las pestañas restantes para recibir. Dentro del menú de
configuración de VBox se establecerá la altura pref a 300. Dentro de la pestaña Recibir
se incluirá un panel de cuadrícula. Por alguna razón, no
podemos incluir un panel de cuadrícula en una pestaña
usando el Generador de escenas. No hay problema. Lo haremos
usando el editor de texto. En cambio. Incluiremos una etiqueta. Su texto será igual
a la dirección de recepción. En su interior agregará algunas
etiquetas para establecer sus márgenes. Ahora, incluiremos un campo de texto. No será editable. Tendrá 350 ya
que es ancho pref. Y su índice de columnas
será igual a uno, incluirá las mismas etiquetas de margen de panel de
cuadrícula que usemos anteriormente. El constructor de escenas ya
no funciona debido al panel de cuadrícula que hemos
incluido en la pestaña. No hay problema. Veremos cómo se ve
la aplicación ejecutándola. Genial, nuestra cartera
ya está lista para recibir una dirección en este nuevo
campo que acabamos de crear. Dentro de la prueba de creación de
billetera
incluirá un código para verificar
si se
creó una dirección y se insertó en el campo de dirección de recepción
después de crear la billetera. Entonces, después de que la prueba haga
clic en el botón Aceptar, dará clic en
la pestaña Recibir. Y la prueba
buscará el contenido
del campo de dirección receptora y lo
almacenará en la variable
address. Entonces la prueba afirmará, si no se conoce la dirección, vamos a ejecutar la prueba
para ver qué pasa. La prueba ha fallado como se esperaba. Ahora, hagamos un poco de
refactorización y nuestro archivo FXML de la ventana principal. Vemos ahora que nuestro archivo
FXML principal es cada vez más grande, es mejor crear
un nuevo archivo FXML solo para la pestaña de recepción, que son ventana principal a la que
se referirá más adelante. Así que vamos a crearlo. Lo llamaremos Recibir tab dot FXML copiará todo el contenido de la pestaña
al punto de pestaña Recibir FXML. El único cambio que
haremos es a la etiqueta de tabulación. Lo cambiaremos a
f x raíz de colon. Después usaremos la clase tab
como el atributo type. También necesitamos incluir el
atributo Meta XML y S colon FX. Ahora importaremos las otras etiquetas. Volver a la ventana principal punto FXML eliminará la etiqueta de tabulación
y todo su contenido. Incluirá la etiqueta
Receive tab controller, que creará ahora. Lo crearemos dentro
del paquete de controladores. Y vamos a importarlo dentro de
la ventana principal punto FXML. Volver al controlador de
pestaña Recibir agregará la
anotación de componente a esta clase. Crearemos un constructor
pasando un recurso con
una anotación de valor apuntando
a la pestaña Recibir archivo FXML también
pasará el contexto de la
aplicación. Aquí configuraremos una nueva instancia de cargador
FXML con parámetros similares a los que
hemos usado para los
otros controladores. Entonces pondremos su
controlador a esto. También estableceremos su
ruta a esto. Entonces llamaremos al método
de carga en él. Bien, necesitamos hacer una cosa
más para que funcione. Dentro de la clase de oyente
iniciado gooey, agregue el siguiente código aquí. Este código es necesario para decirle a Java FX cómo construir componentes
personalizados, como el controlador de
pestañas Recibir cuando lo ve dentro de los archivos FXML. Este código hará que Java FX use el contexto para
obtener el método bean para construir un componente
cuando ve una etiqueta de controlador de pestaña Receive. Entonces, siempre que Java FX necesite construir una etiqueta de controlador de
pestañas Recibir, usará la clase de
controlador de pestañas Recibir para construirla. Para otras etiquetas, usará
el generador Java FX predeterminado. Eso es. Ahora Java FX sabe cómo construir nuestra
nueva etiqueta FXML personalizada. Ejecutemos nuestra aplicación
para verificar si todo va bien. ***** y se produjo un error. Es decir que
el controlador raíz no es una instancia de tabulación. Sé cómo arreglarlo. Debemos hacer que el controlador de pestaña
Recibir extienda la clase TAP. Ahora, veamos si funciona. Bien, está funcionando
igual que antes. Entonces, cuando creamos una nueva billetera, esperamos que el campo de
dirección de recepción se llene con la
nueva dirección de Bitcoin. En el siguiente par de videos, entenderemos el
proceso de derivar una dirección de Bitcoin e implementar esta función
en nuestra billetera. Verás, sí.
16. Direcciones de Bitcoin y billetera de alta definición: En este video, aprenderemos sobre billeteras
HD y las direcciones de
Bitcoin. Entonces, ¿qué es una dirección de Bitcoin? Una dirección bitcoin es una palabra
que codifica una clave pública, el hash de una
clave pública o un hash de script. Se utiliza para recibir
bitcoins en una transacción. Para recibir Bitcoins a través de
una transacción de Bitcoin, muestras
tu dirección
a otra persona que esa persona pueda enviar
bitcoins a tu dirección. Existen varios tipos
de direcciones Bitcoin y las reglas para
generarlas están en muchos VIP, como VIP, VIP 3d2 y BIP 44. Hablemos ahora de carteras HD. Las carteras Hd son sinónimo de carteras
deterministas jerárquicas. Son jerárquicos
porque están compuestos por muchos niveles de claves, y son deterministas
porque una sola semilla
siempre generará las mismas
direcciones y claves privadas. Y HD Wallet es un tipo
de wallet donde a partir de una sola semilla
se utilizan pads de derivación para derivar claves privadas, claves
públicas y direcciones. Las especificaciones de las billeteras Hd se
definieron originalmente en BI P32 con otros BIP que se extienden
en esa especificación. Ahora vamos a recapitular una diapositiva de
nuestra última presentación ppt. En esta presentación
aprendimos a generar una semilla mnemotécnica. Y mencionamos
que al combinar una semilla mnemotécnica con una frase de contraseña
opcional, podríamos generar
una semilla raíz usando el algoritmo P vk df two. A partir de esa semilla raíz,
podríamos generar claves privadas, claves
públicas y direcciones. En esta presentación,
profundizaremos en los detalles
de esa última parte sobre cómo se generan claves y
direcciones privadas y
públicas a partir de una semilla raíz. Entonces, comenzando con una semilla raíz, que tiene 512 bits de tamaño, aplicándole el algoritmo
hash HMAC SHA-512, obtenemos la clave maestra, que también tiene 512 bits
de la clave maestra. Al aplicar la función CKD, que significa derivación de claves
secundarias, podemos obtener diferentes claves
extendidas usando diferentes
índices como parámetros. Si n es el índice
para esa función, que n puede variar 0-2 a la
potencia de 32 menos uno. Cada clave extendida puede generar claves
más extendidas mediante
el uso de la función CKD y así ser el padre de muchas teclas
secundarias. Este esquema de derivación permite
la formación de un árbol de claves con un
número indefinido de generaciones. Veamos más detalles
sobre las funciones de la ERC. Hay dos tipos
de llaves extendidas. Pueden ser claves
privadas extendidas
o claves públicas extendidas. Y la clave privada extendida cuya versión serializada
comienza con x PRV, u otra letra más PRV se genera usando la función privada
CKD. Si el paso índice
a esa función es igual o mayor que
dos a la potencia de 31, entonces es una derivación endurecida. Y decía que la clave privada
extendida generada es un hijo endurecido. Las claves endurecidas tienen características de seguridad
adicionales que explicaremos en resumen, es posible generar una clave pública extendida mediante el
uso de la función pública CKD. Asistía a llaves públicas
cuando se serializaba, comenzar con x pub, u otra carta más pub. También es posible
generar una clave
pública extendida a partir de
otra clave pública extendida mediante el
uso de la función pública CKD, dos derivaciones no son posibles. Generar una clave privada
extendida a partir de una clave pública extendida y una clave pública
extendida endurecida a partir de una clave pública extendida. Entonces, ¿cómo obtenemos de las claves
extendidas a las direcciones? Comenzando con una clave privada
extendida, extraemos una
clave privada de ella. Una clave privada es parte de
una clave privada extendida. Por lo que esta extracción es
una operación sencilla. Luego, mediante una operación llamada
multiplicación de curva elíptica, generamos una
clave pública a partir de una clave privada. Finalmente, al hash y
codificación de la clave pública, obtenemos una dirección Bitcoin. Existen diferentes tipos
de hash y codificación de claves
públicas para producir
diferentes tipos de direcciones. Aprenderemos más sobre estas operaciones en los
próximos videos. También utilizamos claves privadas para producir
firmas de transacciones, para transferir Bitcoins
a otras direcciones. Las firmas de transacción se producen utilizando el algoritmo de
firma digital de curva elíptica o ECDSA. También puede generar direcciones con una clave pública
extendida. Eso se hace extrayendo
la clave pública de ella. Entonces
se genera una dirección bitcoin a partir de la clave pública
a través del hashing y la codificación, como se explicó anteriormente. Recuerda que una clave
pública no se puede convertir en una clave privada. Por lo tanto, no se puede utilizar para firmar transacciones y
transferir Bitcoins. Ahora, entendamos el
concepto de rutas de derivación, comenzando por la clave maestra, que tiene la profundidad de cero
en un árbol de claves extendidas. Al derivar una clave
extendida pasando cero como argumento
a una función CKD, obtenemos una
clave extendida con una profundidad de uno. Repitiendo el proceso con la clave extendida
recién generada, obtenemos una
clave extendida con una profundidad de dos. Entonces podemos repetir el proceso, pasando uno como
índice y obteniendo una clave extendida con
una profundidad de tres. De esta última clave extendida, podemos extraer una
clave pública y una dirección. Se dice que esta dirección tiene una ruta de derivación de
cero slash zero slash one porque estas fueron
el índice se usa para
derivar la clave extendida que
generó esa dirección. Aplicando el mismo razonamiento. En este otro ejemplo, obtenemos una dirección
con una
ruta de derivación de una slash
zero slash two. Este otro ejemplo
muestra que se pueden usar otros números como índices para funciones CKD en cualquier clave
extendida en un árbol de claves, permitiendo la generación de un número casi infinito de rutas de derivación y direcciones. Este otro ejemplo
muestra la generación de un hijo endurecido mediante el uso de una
sola comilla después del índice, podemos representar
índices que generan hijos
endurecidos en
una ruta de derivación. Cero seguido de una sola cita, representa el primer índice
endurecido, que es de dos a
la potencia de 3011, seguido de una sola cita es el segundo
índice de endurecimiento y así sucesivamente. Esta notación se utiliza para
facilitar la descripción de una ruta de derivación de manera que podamos usar números pequeños
para describirlos. Es importante agregar eso. Para gastar Bitcoins
desde una dirección, es
necesario producir
una clave privada con la misma ruta de derivación
utilizada para derivar esa dirección. Por lo tanto, puede utilizar las funciones
públicas de CKD para producir
claves y direcciones públicas extendidas. Pero para gastar fondos
de esas direcciones, debes usar funciones
privadas CKD para producir
claves privadas extendidas y claves privadas. Otra característica de las billeteras
HD y son caminos de
derivación es su relación de función de
muerte. cada nivel en un árbol de claves
se le asigna una función. Bi P32 define la profundidad, uno representa cuentas profundidad dos cadenas diferentes y profundidad
tres direcciones diferentes. Bip 44 vino con diferentes definiciones
que son más utilizadas hoy en día en la
mayoría de las billeteras HD. De acuerdo a estar a 44 profundidad una llaves extendidas
endurecidas
representan diferentes propósitos. Profundidad para endurecer llaves
diferentes tipos de monedas, profundidad tres
llaves endurecidas, cuentas diferentes. profundidad para define si las direcciones
descendentes se van
a usar para el cambio
no son de manera booleana y la muerte cinco representa direcciones
diferentes. Para entender mejor cómo funciona
eso en la práctica, veamos algunos ejemplos de caminos de derivación y
sus funciones. Y abordado con una
ruta de derivación de 84 cotizaciones slash slash zero slash zero slash zero tiene un propósito para
encontrar y BIP A14. Vip 84 define que
las direcciones con un propósito de 84 deben ser P2 WP k h direcciones, que significa pagar para presenciar direcciones hash de clave
pública. Hablaremos de
diferentes tipos de direcciones en detalle
en los próximos videos. Pero en definitiva, P2, WP k, h, aka segue, las direcciones
nativas son
el tipo de
direcciones más comunes en las billeteras modernas más
actualizadas. Esta dirección también tiene un tipo de
moneda de cotización cero, lo que significa que es
una dirección de Bitcoin. También tiene una cuenta de cero, lo que significa que forma parte de
la cuenta del primer usuario. Ha cambiado. El índice se establece en cero, lo que significa que no es
una dirección de cambio. Por último, su
índice de direcciones es cero, lo que significa que son los primeros
usuarios que reciben dirección. El siguiente ejemplo tiene una ruta de derivación similar
al ejemplo anterior, excepto que su índice de
direcciones es uno. Por lo que es la segunda dirección de recepción
nativa de Bitcoin segue de
la cuenta del primer usuario, aplicando la misma justificación. El tercer ejemplo es la primera dirección de cambio
nativo de Bitcoin segue de la cuenta del primer usuario. El índice uno en profundidad cuatro indica que es
una dirección de cambio. El último ejemplo es
similar al primero, excepto que su propósito
es 49 entre comillas. Vip 49 define que las direcciones
con ese propósito deben ser P2 WP k-th anidadas
en direcciones P2 SSH. Si eso suena
complicado, no te preocupes, conoceremos detalles al
respecto en los próximos videos. Ahora, hagamos una descripción general
de las funciones de HD Wallet. Con las billeteras HD,
podemos generar fácilmente un número casi infinito de direcciones a partir de una sola semilla. Esto es genial ya que podemos evitar reutilización de
direcciones y
la pérdida de privacidad. Las billeteras HD también permiten la estructura de
cuentas múltiples donde la clave privada extendida principal tiene acceso a los fondos de las claves de sus
hijos, pero los niños pueden
transferir los fondos de los padres. Este esquema puede ser útil para casos como dueños de empresas que tienen acceso a llaves infantiles desde los
departamentos de su compañía. Otra característica útil
que
permiten las billeteras HD es la creación
de billeteras solo para relojes cuyas direcciones
se pueden generar y sus fondos auditados utilizando
solo claves públicas extendidas, pero donde ningún fondo puede ser movido ya que no se
pueden firmar transacciones. Otra característica de HD Wallet
es la posibilidad de generar otras direcciones de
criptomonedas a partir de la misma semilla mnemotécnica. Una lista de diferentes índices de tipo de
moneda se describe en el slip 44, un
sistema de propuestas tipo BIP de Satoshi labs, la empresa
responsable del truss o billetera. Otra característica que
tienen las billeteras HD es que sus direcciones y claves
privadas
pueden reconstruirse con sus semillas y rutas de
derivación. Esto le permite importar una semilla mnemotécnica y una
frase de contraseña en una billetera compatible para recuperar todas sus direcciones
y claves privadas. compartimentación de seguridad es otra característica agradable
de las billeteras HD. Si una
clave privada extendida se filtra por accidente, eso afectaría solo a
los fondos bloqueados en direcciones que descienden
de la clave filtrada. Los fondos encerrados en las llaves de los padres o
hermanos estarían seguros. Por último, las billeteras HD facilitan generación de una organización de
diferentes tipos de direcciones de Bitcoin. Ahora veamos por qué son necesarias
las llaves endurecidas. Durante el desarrollo de HD Wallet, se descubrió que si una clave pública extendida y una clave privada secundaria
no Hodgkin del siguiente nivel,
esto
equivaldría a una fuga esto
equivaldría a aparente clave privada extendida. Esto podría llevar a la
pérdida de fondos por cada dirección desciende de la clave pública
extendida filtrada. De ahí que
se creara la derivación del indulto para evitar
que ese exploit ocurriera a cuenta y profundidades más bajas. Por último, discutamos
cómo implementaremos el
esquema de derivación de direcciones en nuestra billetera. Utilizaremos la
ruta de derivación 84 cotizaciones slash slash slash zero slash zero slash zero para generar nuestra primera dirección de
recepción. Después de recibir Bitcoins,
la siguiente dirección de recepción se
cambiará aumentando
el índice de direcciones en uno. Por lo que las siguientes
direcciones receptoras tendrán índices
de
direcciones de 123 y así sucesivamente. Hacerlo nos impide usar la misma dirección para recibir
Bitcoins más de una vez. Utilizaremos la
ruta de derivación 84 cotizaciones slash, slash, slash one slash zero para generar nuestra primera dirección de
cambio. Después de enviar Bitcoins
y recibir un cambio, la siguiente
dirección de cambio se cambia
aumentando el índice de
direcciones en uno. la misma manera lo haremos
para recibir direcciones. Puede preguntar por qué es
importante evitar la reutilización de
direcciones por dos razones principales. Primero, al hacer eso, aumentamos nuestra privacidad. Al hacerlo, si un tercero descubre que una
dirección nos pertenece, esa información no se replicará a otras direcciones que usemos. La otra razón es la seguridad. Si por alguna razón
se filtra la clave privada de una dirección eso
afectará únicamente a esa dirección. el proverbio que dice, Aquí se aplica el proverbio que dice,
no pongas todos tus huevos en
una sola canasta. Dicho esto,
implementaremos el esquema de derivación
generando primero la clave
pública extendida con una ruta igual a 84 comillas slash
zero slash zero slash zero slash zero
para recibir direcciones. Y la clave pública extendida con una ruta igual a 84 comillas slash slash zero slash
one para cambiar direcciones. Después vamos a derivar sus hijos las claves públicas
extendidas y direcciones. Al hacerlo,
generaremos todas las direcciones que
necesitemos sin exponer ninguna clave
privada a la memoria. Por lo que nuestra principal
política de seguridad es evitar exponer semillas y claves privadas a la memoria tanto como sea posible. Nuestras claves privadas se derivarán solo al firmar
transacciones utilizando los mismos
pads de derivación utilizados para producir las direcciones desde
las que dichas transacciones están
gastando Bitcoins.
17. 15 Creación de nuestra primera parte 7 skillshare 2: En este video, vamos a crear las
claves públicas extendidas que son monedero necesitará para
crear direcciones. Como vimos en el último video, nuestras billeteras
tendrán inicialmente claves extendidas, que serán la clave extendida para direcciones de recepción de segmentos, y la clave extendida para direcciones de cambio de
segue. Primero, arreglemos algunos
problemas con nuestras pruebas de GUI. Si intentas ejecutar la prueba de
crear billetera, ahora, verás
que funcionará. Esto se debe en parte a una instanciación prematura de nuestra nueva clase de
controlador de pestaña Recibir. Para solucionarlo, cree
un nuevo paquete llamado Config dentro del paquete de prueba
BYOD W. Entonces crea una nueva
clase llamada test lazy siendo una
configuración IP en ella. Esta clase implementará el postprocesador bean factory implementará este
método requerido con este código. Este código hará que cada clase durante las pruebas se
inicialice perezosamente. Hay otra pieza
de código que debemos agregar en nuestra
prueba de creación de billetera para que funcione. Añadiremos al
cargador FXML en el método start, la misma
fábrica de constructores que hemos establecido en nuestra clase de
escucha iniciada GUI. Ahora vamos a ejecutar nuestras pruebas GUI. Genial. Ahora las pruebas están funcionando. Vemos que solo ellos
deberían cancelar las pruebas han pasado y el otro
todavía tenemos que hacerlo pasar. Ahora, procedamos a agregar las
claves públicas extendidas a nuestra billetera. Lo primero que
haremos es ajustar nuestra prueba de crear servicio de billetera pasará una
semilla mnemotécnica válida a esta variable. Puedes obtenerlo en la página
Proyecto y Recursos. Después verificaremos si la cartera creada tiene claves públicas
extendidas. Afirmar si tiene dos claves públicas
extendidas, ya que cada billetera tendrá una clave pública
extendida para recibir direcciones y una clave
pública extendida para direcciones de cambio. Ahora, agregaremos una lista de claves públicas
extendidas
al registro de billetera. Vamos a crear nuestra clase
extendida de clave de pub. Tendrá una llave y un tipo. Vamos a agregarlos a un constructor. Ambas propiedades
tendrán un getter. Ahora crearemos una clase de
configuración de direcciones. Primero, vamos a crear
un nuevo paquete de configuración dentro del paquete API. Después crearemos la clase de
configuración de direcciones en ella. Añádele
la anotación Configuración. Esta anotación es necesaria para que Spring Boot inicialice todos los objetos definidos en esta clase durante el inicio de
la aplicación. Ahora vamos a crear una
clase de dominio llamada address config. En realidad, va a ser un disco. Tendrá un tipo de dirección
y la ruta de derivación. Luego crea una enumeración llamada address type en
el mismo paquete. Tendrá dos tipos, segmento y segue con cambio de
subrayado. Ahora volvamos a la clase de
configuración de direcciones. Crearemos un haz para
nuestra dirección de segmento. En Spring Boot, un bean
es solo un objeto que se puede inyectar en
otras clases de proyecto. Instanciará este bean
con estos parámetros. Y agrega la
anotación Bean a este método. Pasando la cadena de segmento como su parámetro duplicará este método y lo modificará para que sea nuestra configuración de dirección de
cambio, cambiará el
parámetro Bean annotation para segue change. El nombre del método será
segue change config. El tipo de dirección
será seg cambiaría. Y la ruta de derivación
tendrá un índice de cambio de uno. Ahora, usaremos estas
configuraciones en nuestro servicio de creación de billetera. Así que vamos a inyectar una lista de configuraciones de direcciones en esta clase. Al hacerlo, Spring
Boot
identifica automáticamente que hay dos beans con el tipo de configuración de
dirección, e inyectará
ambos en esta lista. Ahora, en el método create se creará una variable
semilla mnemónica. Primero, cambiaremos el
parámetro del método de semillas
mnemotécnicas a la
cadena de semillas mnemotécnicas y luego instanciaremos un objeto semilla mnemónico pasando la cadena de semillas mnemotécnicas
como su parámetro. Luego crearemos una clave maestra, que es un tipo de clave privada
extendida. Para ello, llamaremos
al método mnemotécnico seed
a master key y pasaremos la contraseña y esta
constante como sus parámetros. Pero primero, tenemos que actualizar nuestra versión Bitcoin Java a 0.3, 0.0 en el archivo POM. Vamos a hacerlo. Ahora. Haga clic en Load Maven
vuelve a cambiar al método create. Ahora nos permite importar
la constante principal del prefijo neto, pasará su
prefijo privado como parámetro. Ahora agreguemos este código, entonces voy a explicar
qué hace a continuación. Este código comienza a convertir la
lista de configuración de direcciones en una transmisión. En Java ocho o superior, los
flujos se utilizan para aplicar operaciones
funcionales a
una colección de datos. En este caso, cada configuración de
dirección de la lista se está pasando
a esta función lambda, que utilizará el servicio de clave
pub extendido que
creará junto para devolver un objeto de clave pub
extendido. Cada
clave de pub extendida devuelta se recogerá en una lista que se almacenará en la variable de claves de pub extendidas, luego
pasará la
lista de claves de pub
extendidas a la billetera devuelta. Ahora, inyectemos el
servicio extendido de llaves de pub en esta clase. Tendremos que crearlo. Ahora podemos agregarlo
al constructor. Ahora creará
su método de creación. Devolverá una llave
de pub extendida. Siguiendo el TDD. Es momento de crear una
prueba para este método. Vamos a hacerlo. Lo creará dentro
del paquete API de prueba. Debe extender la clase de
especificación. Instanciemos el servicio extendido de llaves de
pub aquí. También necesitamos agregar esta pieza de código al método de configuración. Y vamos a crear una prueba llamada debería crear clave extendida. Cuando se le da una semilla mnemotécnica y una clave maestra
derivada de ella. Cuando llamamos al método
create desde el servicio extendido de claves de pub. Entonces esperamos que la
llave de pub extendida
creada sea igual a la
esperada llave de pub extendida. Bien, entonces, ¿cómo vamos a crear
estas variables en gris? pasaremos usando la cláusula
where así. Se puede preguntar, ¿de dónde
sacé estos valores? conseguí en el sitio web de ES Coleman io slash pip treonina. Este sitio web es muy
útil para generar muchos tipos de
claves y direcciones extendidas. Voy a copiar y pegar
esta semilla mnemotécnica el campo BIP 39 en el sitio web para
demostrar cómo funciona. Inmediatamente después de
pegar la semilla mnemotécnica, la herramienta calculó la clave maestra de semilla
raíz y las claves
extendidas para mostrar el AT BIP derivado
para las teclas extendidas, haga clic en esta pestaña. Vemos que la
esperada clave pub y la prueba es igual a este
valor en la página web. Al aplicar la función CKD a esta clave pública extendida con diferentes números ya que
los índices
obtendrán posteriormente claves
públicas extendidas cuyas claves públicas
extraídas
serán utilizadas para generar recibiendo direcciones
usando el mismo sitio web que creé para más casos de prueba. pegaré aquí y
ajustaré el formato. Los dos últimos
casos de prueba generarán claves de pub
extendidas que se
utilizarán para generar direcciones de
cambio. Puedes copiarlos de los recursos de este
video o hacer tus propios casos de prueba usando
el sitio web de Ian Coleman. Usando la cláusula where, se ejecutará
la misma prueba para cada parametrización
que creamos. Vamos a hacer la prueba. La prueba falló como se esperaba. Ahora implementemos el método. Primero. Crearemos un mapa aquí
que no abordará tipos a prefijos de claves de
pub extendidos. Ambos tipos de dirección se asignarán
al mismo prefijo de
segmento neto principal. Al hacerlo,
facilitamos la ampliación de esta funcionalidad si necesitamos agregar más
tipos abordados más adelante. Ahora en el método create devolverá una nueva clave de pub
extendida. Al pasar estos parámetros se pasará el retorno del
método CKD desde la clave maestra, que tomará una ruta de
derivación. False ya que no es una clave privada extendida y el prefijo
del tipo de dirección. Después serializaremos el resultado. Y el segundo argumento extendido de la clave
pub será el
tipo de dirección y la forma de cadena. Por último, no olvidemos agregar aquí la
anotación de servicio. Ahora, volvamos a ejecutar la prueba extendida de servicio de clave de
pub. Genial, todos han pasado. Ahora ejecutemos nuestras pruebas de servicio de creación de
billetera. Pero primero, hagamos algunos
cambios a esta prueba. Debemos agregar el proveedor
de seguridad, que es necesario para funcionen
las funciones de criptografía Bitcoin Java. También tenemos que establecer los argumentos correctos
para el servicio. Construyamos las configuraciones de direcciones y el servicio extendido de llaves de
pub. Ahora vamos a ejecutarlo. Genial, las pruebas han pasado. Eso significa que nuestra billetera
fue creada con una lista de claves
públicas extendidas de tamaño dos. Uy, el
índice de cambio aquí es uno. No va a afectar esta
prueba ya que solo estamos afirmando que la billetera
tendrá que extender las llaves del pub. Pero cambiémoslo a uno
por el bien de la corrección.
18. 16 Creación de nuestra primera parte 8 skillshare 2: En este video,
crearemos un vestido para cada llave de pub extendida
que hace Wallet. Para ello, cada llave de pub
extendida
se pasará al método de vestidos
generados, que creará ahora. Este método establecerá una lista de direcciones para el registro de clave de pub
extendido. Vamos a crear este centro. Esta lista de direcciones
será creada por un nuevo servicio
generador secuencial de direcciones que creará. Utilizará un
método de generación que tomará la clave de pub extendida y
el tipo de clave de pub extendida. El servicio
generador secuencial de direcciones tendrá este nombre porque generará un vestidos con un índice de
derivación de direcciones creciente. Inyectemos el generador
secuencial de direcciones en esta clase y creémoslo. Ahora, vamos a crear
su método generate que devolverá una
lista de direcciones. Vamos a crear el registro de dirección. Este registro tendrá
un campo de dirección y un campo de índice. Ajustemos el método set
addresses desde la tecla pub extendida. Tomará una lista de
direcciones y establecerá el campo extendido de
direcciones clave de pub. Vamos a crear una prueba para la clase de
generador secuencial de direcciones. Por ahora, su método
devolverá null. La clase de prueba extenderá
la clase de especificación. Vamos a crear una prueba llamada
debe generar 20 direcciones, usaremos el
generador secuencial de direcciones en el bloque eólico. Entonces vamos a agregarlo como
campo a esta clase. Cuando se
llama al método generate con estos parámetros, es
decir, una
clave pública extendida en el tipo de segmento. Entonces esperamos que
el regreso que lista
de vestidos tenga una talla de 20. Puede copiar la clave pública
extendida de esta prueba de los recursos de esta
lección. Instanciemos el generador secuencial de
direcciones en el método de configuración
y ejecutemos la prueba. Falló como se esperaba. Ahora vamos a implementar el servicio declarará una llave de pub
extendida. Entonces dentro de un bloque try
catch se serializará
y se serializará el parámetro clave
recibido. El
método serializado ANS transforma la clave de pub extendida en el objeto de clave de pub extendida de Bitcoin Java luego
envolverá IOException en
una excepción de tiempo de ejecución
en el bloque catch. Ahora usaremos el método range desde la
clase de flujo de pulmones hasta bucle de cero a una variable de número inicial de direcciones
generadas
que se establecerá más adelante. Inyectaremos esta
variable en esta clase. En el constructor se establecerá una anotación calificador
para esta variable, que tomará el mismo nombre de
variable que un parámetro, cambiará su tipo a sugerencia,
mapeará sobre cada índice y llamará el método generate
address. Entonces, para cada índice, llamaremos al método generate
address, pasando como parámetros
el retorno del método Get de
fábrica
del generador de direcciones, la clave pub extendida y el
índice. Por último, convertiremos
el resultado en una lista. Vamos a crear el método generate
addressed. Tomará un
generador de direcciones y clave de pub
extendida y un índice. El generador de direcciones se
pasará de una fábrica de
generadores de direcciones, que inyectará en
esta clase y creará ahora. Cambiemos el
parámetro type a address type. Ahora crearemos el método Get de fábrica
del generador de direcciones . Devolverá una interfaz de
generador de direcciones que creará ahora de nuevo al método de
generar dirección desde el generador
secuencial de direcciones. Primero derivaremos una clave
secundaria extendida de la clave pub extendida
usando el método CKD. Este método aplicará la función de
derivación de claves secundarias que aprendimos hace dos videos. Tomará un índice que
definirá el índice de
derivación del niño. Ahora devolverá un
nuevo registro de dirección. Tomará el resultado
del método generate
del generador de direcciones. Este método tomará
la clave secundaria extendida y derivará una dirección de ella. El segundo parámetro de dirección
será el índice. Ahora agregaremos el método
generate a la interfaz del
generador de direcciones. Ahora implementaremos
el método get desde la fábrica de
generadores de direcciones. Devolverá el resultado
del GetMethod desde un mapa generador de
direcciones. Esta variable será
un campo en esta clase y será inicializada en
este constructor de clase. Será un mapa de cadenas como claves y
generadores de direcciones como valores. En el constructor pasará un
servicio generador de direcciones de segmento, que creará. Después asignaremos cada tipo de dirección al generador de
direcciones de segmento. En el mapa generador de direcciones. El
generador de direcciones de segmento
implementará la interfaz del
generador de direcciones. Vamos a crear el método de
interfaz requerido. Antes de implementarlo,
vamos a crear su prueba. Extenderá la clase de
especificación. Instanciará el generador de
direcciones de segmento aquí. En el método de configuración agregaremos el proveedor de seguridad al
igual que nuestras otras
pruebas que lo necesiten. Entonces crearemos eso debería generar prueba de dirección de segmento. En el bloque dado se
creará una clave de pub extendida utilizando la
clase de clave de pub extendida en el método serializado. El método serializado
tomará una cadena de clave pub extendida, que pasará en
el bloque where. Luego crearemos un cuidado de niños
extendido llamando
al método CKD en la variable de clave de pub
extendida. A este método pasará un parámetro index el cual
pasará por el bloque web. Cuando se llama al método de generación de
generador
de direcciones de segmento con la clave secundaria
extendida. Entonces esperamos que
la dirección de devolución sea igual a la dirección
esperada. Ahora, usemos el bloque
where para inicializar las variables en gris usaremos los datos de prueba que han tomado del
sitio web de E y Coleman para ello. Puede copiar estos parámetros
de los recursos de esta lección. Vamos a hacer la prueba. Ha fracasado como se esperaba. En el siguiente video, conoceremos más sobre
sig qué direcciones. Después en el video posterior al siguiente, implementaremos el generador de
direcciones de segmento y
el generador de direcciones secuenciales y haremos que sus pruebas pasen.
19. Comprender las direcciones de Segwit y la introducción a los entornos de la red de Bitcoin: En esta presentación,
conoceremos más sobre las direcciones de
segmento de Bitcoin, que será el tipo de dirección
predeterminado que proporcionará nuestra billetera. Entonces, ¿qué es un
segue de Bitcoin, qué dirección? Las direcciones de segmento
también se conocen como direcciones
nativas segue atrás 32 direcciones, direcciones segmento versión cero
o P2 WP k-th direcciones, donde P2 WP k h significa pagar
para presenciar hash de clave pública. Cada uno de estos términos se utiliza
para referirse a lo mismo. Fue el
tipo de
dirección de Bitcoin más actualizado hasta noviembre de 2021. Después de noviembre de 2021, cuando se activó
la actualización de raíz
principal en la red Bitcoin, un tipo más nuevo de dirección de Bitcoin
llamada dirección de raíz
principal, puso a disposición
un tipo más nuevo de dirección de Bitcoin
llamada dirección de raíz
principal, también conocida como
dirección segue versión uno. Por ahora, centrémonos en
la dirección del segmento, que la mayoría de las direcciones
segmentadas de soporte de billetera moderna estuvo disponible en 2017 en la red Bitcoin después de la actualización de
testigos segregados. Esta actualización permitió opcionalmente transacciones
más pequeñas
ya que la parte de estas transacciones más nuevas
llamadas testigo se envía por separado y no está
incluida en la cadena de bloques. Las reglas para generar direcciones de
segmento
se describen en VIP un séptimo tres y también se
implementan en métodos de la biblioteca
Bitcoin Java. Las direcciones de segmento permiten a los remitentes de
Bitcoin pagar las tarifas más baratas
por transacciones comunes. La razón de ello es porque las transacciones que envían
bitcoins a direcciones de segmento son efectivas más pequeñas
en comparación con las transacciones que envían a
otro tipo de direcciones. Pero aprenderemos
más detalles sobre las transacciones de
Bitcoin
en futuros videos. Debido a que las direcciones de segmento
están bien respaldadas por mayoría de las billeteras modernas
y porque nos
permiten enviar transacciones
más baratas, las estableceremos como el tipo de
dirección predeterminada de nuestra billetera. Ahora, recapitulemos
una diapositiva de la presentación anterior
sobre las claves extendidas. En ese video aprendimos que podíamos
obtener una clave pública a partir de una clave privada extendida
o una clave pública extendida. Entonces, al hacer hash y
codificar la clave pública, podríamos obtener una dirección. Ahora, veamos
más detalles sobre este proceso de hash y
codificación. Comenzando con una clave pública obtenida como se explicó
anteriormente, aplicando las funciones
hash criptográficas SHA-256 y 160 de la derecha a
la clave pública, obtenemos un hash de clave pública
con un tamaño de 20 bytes. El SHA-256, combinado
con el
160 de la derecha , se denomina algoritmo
hash 160. Finalmente, el hash de clave pública, combinado con un prefijo
y una versión numérica, genera una dirección de segmento
a través de la codificación Beck 32. La codificación Back 32 es reversible por el proceso llamado decodificación
Beck 32. Al construir transacciones,
debemos decodificar 32 direcciones a hashes de clave
pública antes de incluirlas
en las salidas de las transacciones. Es por eso que este
tipo de dirección también se llama pay to witness public key
hash revisitará este tema
con mayor detalle al hablar transacciones para direcciones de
segmento. Cuando Beck 32 codifica hashes de clave
pública, la versión se establece en cero cuando el prefijo se establece
en BC unnamed net. Hablando de la red principal, veamos rápidamente los entornos de red de
Bitcoin. Cada uno de estos entornos
es una red separada con diferentes blockchains y
propósitos, pero reglas similares. El Bitcoin may net es como
se le llama la red principal de
Bitcoin. Es donde tienen valor los
bitcoins. El blockchain es inmutable y la dificultad minera
es la más alta. El entorno de red de prueba es similar a la red principal pero tiene una dificultad minera menor y donde los bitcoins no tienen valor, se utiliza para realizar pruebas
en un entorno donde los nodos interactúan mientras mantener
una cadena de bloques compartida. Test net ha tenido
diferentes versiones desde que se creó con
diferentes blockchains. Por último, el entorno de
prueba reg es una
red individual que puede ser ejecutada por cualquier usuario de nodo Bitcoin con una cadena de bloques no
compartida con otros. Los bloques pueden ser
generados instantáneamente, sin esfuerzo y
libremente por el usuario. Se utiliza para realizar pruebas más rápidas
y automatizadas en un ambiente controlado. Las direcciones en cada red tienen diferentes prefijos y son válidas solo en sus
entornos. Para
las direcciones de segmento, estas C es el prefijo utilizado para los
vestidos rojos en la red principal. Tb se utiliza para direcciones
en la red de prueba. Y BCRP es el prefijo usado para los vestidos rojos
en la prueba reg. Como se dijo antes, la versión cero se utiliza para las direcciones de
segmento. La versión uno se utiliza
para las direcciones de raíz principal.
20. 18 Creación de nuestra primera cartera parte 9 skillshare 2: En este video, realizaremos
todas las pruebas que hemos creado paths para hacerlo primero
implementaremos el método generador de
direcciones de segmento. Para generar una dirección de
segmento se convertirá una
clave extendida en una clave pública. Cambiemos este
nombre de parámetro a clave extendida. Entonces la clave pública se
convertirá a una dirección de segmento utilizando este método ya que su
parámetro pasará un prefijo. Pasemos esta
constante por ahora, que hará que la
dirección sea válida en el
entorno principal de Bitcoin neto. También agreguemos la
anotación de servicio a esta clase. Ahora, ejecutemos la prueba del generador de
direcciones de segmento. Ha fallado porque
tenemos que elevar
la versión Bitcoin Java a 0.4, 0.0, que contiene el método CKD
correcto para esta operación
funcione. Vamos a hacerlo. Haga clic en Cargar cambios de Maven. Volvamos a ejecutar la prueba. Genial, todas las pruebas han pasado. Ahora ajustemos la prueba del generador
secuencial de direcciones. Tenemos dos nuevos parámetros
constructores que tenemos que pasar
al servicio. Primero, instanciemos la fábrica del generador de
direcciones. Al pasar un nuevo seg se
dirigiría al generador. Entonces pasaremos 20 es el número inicial de direcciones
generadas. Ahora volvamos a ejecutar esta prueba. Bien, olvidamos agregar
el proveedor de seguridad en el método de configuración.
Vamos a arreglarlo. Ejecutarlo de nuevo. Bien,
La prueba ha pasado. A algunos servicios les falta
la anotación de servicio. Vamos a arreglar eso. Bien, ahora
agreguemos un nuevo Bean, que será el número
inicial de direcciones
generadas
para cada clave extendida, lo
establecerá arbitrariamente en 20. Ahora vamos a ejecutar nuestra aplicación
para ver cómo está funcionando. Recibimos un error en la
consola indicando que nuestra aplicación le falta
el proveedor de seguridad. Vamos a agregarlo
al método principal en la clase de aplicación BYOD W. Volvamos a ejecutar nuestra aplicación. Bien, el error no ocurrió, pero al campo
de dirección de recepción todavía le falta una dirección. Cambiemos esto. Primero. Realicemos todas nuestras pruebas para verificar qué otras pruebas
necesitan ser arregladas. Las pruebas del servicio de creación de billetera están rotas. Vamos a arreglarlos. Primero, tenemos que
incluir un objeto generador
secuencial de direcciones válido como su tercer parámetro. Vamos a
instanciarlo pasando 20 como primer parámetro y una
fábrica de generadores de direcciones como el segundo. Entonces instanciaremos
la fábrica igual que la prueba anterior. Ahora se asegurará de que el servicio
create wallet esté creando una billetera con
dos llaves de pub extendidas, cada una con 20 direcciones. Afirma que el primer campo
extendido de direcciones clave de pub tiene un tamaño de 20. Vamos a crear un getter
para este campo. Se hará valer lo mismo para la
segunda llave de pub extendida. Ahora hagamos esta prueba. Genial, ya pasó. Ahora hagamos pasar la prueba de
crear billetera. Recuerda que esperamos que la
dirección de recepción TextField contenga una dirección después de
crear una billetera. Entonces vayamos al controlador de pestañas de
recepción. Se agregará un método
llamado initialize, que se ejecutará después de que
la aplicación inicialice este controlador. Entonces inyectaremos la
cartera actual en esta clase. En la
clase de billetera actual se incluirá un nuevo campo de
propiedad de cadena simple llamado dirección de recepción, que se inicializará aquí
mismo, creará setters
y getters para ello. Ahora, vamos a
la pestaña Recibir. Fxml agregará un Fx
ID al TextField. Esta identificación ética se
llamará dirección de recepción, y también la agregaremos al controlador de pestañas de
recepción. Ahora, en el método inicializado vinculará la propiedad actual de
dirección receptora de
billetera a un
oyente que tomará estos tres parámetros
en una función Lambda. En el cuerpo Lambda establecerá el
campo de dirección de recepción al nuevo valor, que será una dirección. Ahora en la actualización el servicio de billetera
actual establecerá la dirección de
recepción de billetera actual a
la primera dirección de la primera billetera
extendida clave pub. Ahora, cuando la
dirección de recepción se cambie de esta manera, activará este
oyente que hemos configurado aquí en el controlador de
pestaña Recibir. Y ojalá agregue la dirección al campo de dirección
receptora. Ahora, hagamos
estas pruebas para ver si funcionan. Grupos. Ha fallado. Averiguemos por qué. Bien, el error ocurrió porque este método debe ser
inicializado, no inicializado. Vamos a arreglarlo y ejecutar
la aplicación. Genial. El monedero hizo lo que
esperábamos y cumplió el campo de dirección de recepción
después de haber creado una billetera. Ahora bien, si le presentamos esta
dirección a
alguien, puede enviarle bitcoins. Ahora, vamos a ejecutar todas las pruebas de
aplicación. Genial, todos han pasado.
21. 19 Creación de nuestra primera parte de la billetera 10 skillshare 2: En este video, haremos un rápido refactor en el generador de direcciones de
segmento. En lugar de codificar duro el prefijo del segmento de red
principal como parámetro para la dirección del
segmento a partir del método de clave pública
comprimida creará un servicio
que
nos permitirá crear direcciones para la red de prueba y los entornos
de prueba reg. Llamaremos a esta
dirección de servicio prefijo de fábrica. Tendrá un método get
donde pasaremos un tipo de dirección y
devolverá un prefijo de dirección. Este valor devuelto
se utilizará como parámetro para la dirección del segmento a partir del método de clave pública
comprimida. Ahora inyectaremos este servicio en esta clase y lo crearemos. Ahora crearemos el método
It's GET. Para implementar este método
se necesitará un mapa auxiliar, que mapeará los
tipos de direcciones a otro mapa, mapeando los tres
entornos a sus prefijos de
dirección correspondientes. Vamos a construirlo y
quedará claro a lo que me refiero. Ahora, cambiemos este nombre de
parámetro a tipo de dirección. En el getMethod devolverá un prefijo de dirección usando el tipo de dirección
como primera clave. Y una variable llamada entorno
Bitcoin como la segunda clave del
mapa que acabamos de crear. La
variable de entorno Bitcoin se
definirá más adelante en nuestro archivo de propiedades de la
aplicación, y la inyectaremos
en esta clase. Ahora. En el constructor, agregaremos
una anotación de valor antes la variable para inyectar su
valor desde el archivo de propiedades. Ahora, vamos a escribir correctamente
el campo de mapa de tipo de dirección. Ahora agreguemos la configuración del
entorno Bitcoin al archivo de propiedades de
punto de la aplicación. Lo pondremos a prueba reg. Ahora arreglemos algunos archivos de prueba para manejar los cambios que
hemos realizado hasta ahora. Comenzando con la prueba del generador de
direcciones de segmento, eliminará esta
parte e instanciará el generador de direcciones de segmento
en el método de configuración, pasando en la
fábrica de prefijos de dirección como su parámetro. Ahora instanciaremos la fábrica de prefijos de
dirección, pasando como parámetro la
constante neta principal. Ahora vamos a ejecutar esta prueba. Genial, sigue funcionando. Ahora arreglemos la prueba del servicio de creación de
billetera. Haremos lo
mismo que en la última prueba. Simplemente inyecte la fábrica de prefijos de
dirección en el generador de
direcciones de segmento. Vamos a hacer la prueba. Genial, Ha pasado. Ahora arreglemos la prueba del generador
secuencial de direcciones. Haremos lo mismo que antes. Ahora, hagamos la prueba. Genial, ya pasaron dos. Ahora vamos a ejecutar todas nuestras pruebas. Algunas pruebas fallaron porque a
la fábrica de prefijos
de dirección le falta una anotación.
Vamos a arreglarlo. Vuelva a ejecutar las pruebas. Genial. Todas las pruebas han pasado. Ahora hagamos este
pequeño refactor de agregar importaciones estáticas
para estas constantes. Ahora, vamos a ejecutar la aplicación para ver qué hemos
logrado hasta ahora. Recuerda que ahora esperamos
que nuestra billetera genere direcciones compatibles con
reg test ya que nuestra
propiedad de entorno Bitcoin está configurada para reg test. Bien, como era de esperar, nuestra billetera generó direcciones
comenzando con BCR t, ya que es el prefijo de direcciones de segmento en el entorno de prueba
reg. Ahora vamos a cambiar el
entorno Bitcoin propiedad dos red principal y ejecutar
la aplicación de nuevo. Ahora tenemos direcciones que
comienzan con BC, que es el
prefijo de dirección de segmento para la red principal. Por último, cambiemos la propiedad del entorno
Bitcoin para probar net y probar lo mismo. Bien, ahora podemos generar
direcciones comenzando por TB, que es el prefijo para las direcciones compatibles con la
red de prueba. Genial, ahora tenemos una manera
fácil de cambiar el entorno de red
compatible con nuestro monedero.
22. 20 nodo de preparación para recibir bitcoins skillshare 2: Ahora contamos con una billetera Bitcoin capaz de generar direcciones compatibles con
diferentes entornos de
red Bitcoin que son reg, test, test net y main net. Ya es posible usar estas direcciones para
recibir Bitcoins. Para ello, solo necesitas
mostrárselos a otros propietarios de
bitcoin, que pueden usar sus billeteras
para enviarte Bitcoins, o muy probablemente a Satoshi, que son fracciones de Bitcoin. Pero por ahora, nuestra billetera está habilitada para detectar
estos pagos. Entonces no pasará nada en nuestra interfaz de usuario de billeteras después una transacción a una
de nuestras direcciones. A partir de ahora, pretendemos
cambiar eso. Comenzaremos a construir una función que nos permitirá escuchar las transacciones que llegan
a nuestro nodo central de Bitcoin. Luego filtraremos las
transacciones con salidas que coincidan con nuestras direcciones
actuales de billetera. Finalmente, modificaremos
nuestra billetera para mostrar información sobre la cantidad
de Bitcoin que tiene nuestra billetera. Ahora asegurémonos de que nuestro nodo Bitcoin esté
correctamente configurado y preparado para enviar y recibir información de
transacción
a nuestra billetera. Para ello, abre el archivo
bitcoin.com. La ubicación de este archivo
dependerá del sistema operativo que estés usando. Como estoy usando Windows ten, mi archivo bitcoin.com se encuentra
en la ruta de acceso en la pantalla. Abre el archivo y
asegúrate de que se vea así. Revisemos el significado de
cada una de estas configuraciones. El primer parámetro,
reg test se establece en
uno para hacer que nuestro nodo se ejecute en
los entornos de prueba reg. Ya que usaremos el entorno de prueba
reg para ayudarnos a desarrollar
nuestra aplicación. El segundo parámetro, los datos allí se establece en la carpeta que
desea que el nodo registre la información de
blockchain y
billetera. Yo puse el mío a los dos puntos
backslash los datos de Bitcoin, pero puedes elegir
cualquier ruta que prefieras. El parámetro del servidor
se establece en uno para permitir que nuestro nodo reciba
llamadas API desde nuestra aplicación. Los parámetros de usuario RPC y contraseña de RPC se pueden
ajustar a lo que quieras. Por ahora, elegiré
BYUI W para ambos. Pero al usar nuestra
aplicación de verdad, es muy recomendable elegir valores
más seguros para
estos parámetros. El índice TX se establece en uno. Esto es necesario para que
nuestro nodo pueda recuperar cualquier información de transacción
de la cadena de bloques. El parámetro de tarifa de reserva se
puede establecer en 0.00 001. Este valor se utilizará
para tarifas de transacción que no
pudieron ser calculadas
adecuadamente por el nodo. Por último, estableceremos la
propiedad z MQ pub Ratti x a este valor. Esta propiedad establece
la dirección TCP donde la información de transacción que va
la información de transacción que
llega al nodo. Nuestra aplicación,
escucharemos la misma dirección TCP y capturaremos nuevas transacciones enviadas a una de nuestras
direcciones Bitcoin de esta manera. Ahora, ejecutemos nuestro nodo
Bitcoin con estas configuraciones
usando el terminal, vaya a la carpeta donde está instalada
tu aplicación Bitcoin. Esto depende de
dónde
lo instalaste y qué SO estés usando. Como estoy usando Windows diez, ya
abrí mi terminal y fui a esta
carpeta en la pantalla. Ahora ejecuta el
nodo Bitcoin escribiendo dot slash Bitcoin D
y presionando Enter. Ahora su nodo central de Bitcoin se está ejecutando con las
configuraciones. Dijimos anteriormente, ya
estamos listos para
las próximas clases.
23. 21 cliente de nodo parte 1 skillshare 2: En este video, crearemos un cliente HTTP que hará algunas llamadas a nuestro nodo central de
Bitcoin. Este cliente será
necesario más adelante cuando lo
usemos para enviar y
recibir transacciones. Primero, vamos a importar una
dependencia en el archivo POM. Esta dependencia es la web de inicio de
Spring Boot, que es necesaria para la implementación del cliente
HTTP, excluirá una
dependencia transitiva de esta biblioteca agregando
una etiqueta de exclusión. La dependencia excluida será el arrancador de Spring Boot Tomcat. Lo haremos para evitar iniciar un servidor web en nuestra aplicación. Ahora, da clic en el botón Cargar cambios de
Maven. Ahora hagamos una
clase de configuración para el cliente de nodo. Cree una clase
llamada Node client configuration dentro
del
paquete api dot config en una
anotación de configuración para él. Ahora, crearemos algunas
propiedades privadas en esta clase, todas precedidas por una anotación de
valor. El primero tendremos
esta anotación de valor. Y se llamará
nodo RPC URI. El siguiente tendrá
esta anotación de valor. Y será el
nodo RPC username tendrá otra propiedad con la siguiente anotación de valor con el nombre igual
nodo contraseña RPC. Todas estas propiedades se
inyectarán a partir de valores
que se agregarán posteriormente en el
archivo de propiedades de punto de la aplicación también se creará una viga con la clase de
plantilla de resto. Tomará un descanso Template
Builder como parámetro. Usaremos este constructor para devolver el objeto de
plantilla de detención con un URI raíz igual a la propiedad URI de RPC de
nota. Tendrá una
autenticación básica con la nota nombre de usuario RPC y las propiedades de
contraseña de nota RPC. Entonces llamaremos a
Build y regresaremos. Ahora vamos a asignar las propiedades que se van a
inyectar en esta clase. Vamos al archivo de propiedades del
punto de la aplicación. Vamos a asignar a la propiedad
nodo punto RPC punto URI la
siguiente dirección. Este URI con puerto
18443 es el
URI predeterminado para la API RPC de Bitcoin
Core Node para el entorno de prueba reg. Como propiedad node dot RPC
dot username, tienes que elegir el
mismo valor que has elegido para la
configuración de usuario RPC en tu archivo
bitcoin.com como la propiedad node dot RPC
dot password, elige el mismo valor
que has establecido para la configuración de contraseña de RPC
en tu bitcoin.com. Ahora dentro del paquete api
dot services, crea el paquete node, incitado, crea el paquete
cliente. Ahora vamos a crear la clase
cliente nodo dentro de ella. Vamos a agregarle la
anotación de servicio. Ahora, vamos a inyectar el resto de frijol
plantilla en esta clase. Añadiremos el siguiente
método para realizar solicitudes a la API de Bitcoin RPC. En cuanto a sus parámetros, tomará un método de cadena, una referencia de tipo parametrizada de tipo node client response, que creará a continuación una URL de cadena y cero
o más objetos. Ahora vamos a crear la respuesta flexible del
nodo dentro del nodo de punto de
dominios de paquete. Volver al método
cliente nodo
instanciará un nuevo objeto de solicitud de
cliente de nodo. Tomará los argumentos del método
y los parámetros en
su constructor. Vamos a crear esta nueva clase dentro de los dominios,
ese paquete de nodos. Vamos a crear su constructor. Ahora, envolveremos la solicitud
dentro de un objeto de entidad HTTP. Luego devolveremos el
resultado de esta llamada al método, que finalmente
hará una solicitud posterior al nodo Bitcoin Core,
ajustará la clase de respuesta del
cliente del nodo, transformará en una registrar y agregarle una propiedad de resultado
hará un ajuste similar
a la solicitud del cliente del nodo, lo
transformará en un registro y le agregará
estos campos. Nos hemos olvidado de
poner una T aquí mismo. Ahora, veremos cómo hacer una llamada importante a la API de
Bitcoin Core Node. Ir a este sitio web
en la pantalla. Es una referencia a
la llamada Create Wallet Bitcoin core RPC. Vemos en la última línea
que esta llamada toma una clave de método con el valor
crear billetera en su cuerpo. Cada llamada a la API de Bitcoin tiene este formato con la
clave de método que contiene el
nombre del método. Las llamadas a la API de Bitcoin también tienen una clave params que contiene
varios tipos de datos. En este caso, su valor es una matriz con un
solo elemento. El nombre de la billetera, la llamada
create wallet crea una billetera dentro del
Bitcoin Core y la carga. requieren muchas llamadas a API que
usaremos más tarde. Pero nuestro nodo central de Bitcoin
tiene una billetera cargada. Volver al nodo cliente. Ahora podemos entender por qué el método make request
construye un objeto request que toma un argumento de cadena
llamado method y un
argumento de tipo variable llamado params. Ahora vamos a crear una clase llamada node create
wallet client. Vamos a agregarle una
anotación de Servicio. Inyectará el
cliente del nodo en él. Ahora vamos a crear un
método llamado create, que tomará un parámetro de
cadena. Ahora para hacer una llamada
al método create wallet
de la API Bitcoin Core. Los llamaremos make request method del
cliente del nodo así, siguiendo la referencia del sitio web de Bitcoin
Core. Ahora vamos a probar este
método para eso. Ejecutemos nuestro Bitcoin Core
Node en la terminal. En lugar de usar nuestra forma tradicional de hacer las cosas con
TDD, probaremos este
método de manera diferente. Volver al nodo crear
cartera cliente creará un método precedido por una anotación
post build. La
anotación Post constructo es útil para ejecutar código cuando se inicia una
aplicación de resorte. También es útil para pruebas
rápidas y aplicaciones
Spring, casi como crear un método
estático principal en una clase Java, pero con todos los beneficios de
los beans administrados
por la aplicación. Dentro de este método se llamará
al método create
pasando cualquier nombre de billetera. Ejecutemos la aplicación. Bien, Al ver los
registros de Bitcoin Core Node en el terminal, vemos que nuestro nodo
creó y cargó una billetera con el nombre que hemos
dicho en la llamada al método. Con eso, sabemos
que nuestro método está funcionando y podemos eliminar este método
post build. Ahora,
volvamos al sitio web de
Bitcoin Core y busquemos el método DIR de cartera de
listas. Este método
no toma parámetros y devuelve todas las
billeteras de nodo creadas hasta ahora. Devuelve una estructura JSON
con un campo de billeteras. Este campo contiene
una matriz de objetos, cada uno de los cuales representa una cartera existente
con un campo de nombre. Vamos a crear un cliente
para este método. Lo llamaremos lista de nodos
mientras sea cliente. Nuevamente, vamos a inyectar el
cliente de nodo en esta clase. Después crearemos
el método list all, que devolverá una
lista de nombres de billetera. Dentro de este método los
llamaremos make
request method from the node client passing list wallet DIR como
el nombre del método. Una nueva
referencia de tipo parametrizada y una URL vacía. No pasaremos ningún parámetro
adicional. El objeto devuelto
será un registro de monederos de nodo, que creará ahora, lo
crearemos dentro del paquete de nodos punto de
dominios. Este registro
tendrá sólo un campo. Será una lista de billeteras de nodo. Su nombre serán billeteras. Vamos a crear el
registro de monedero de nodo en el mismo paquete. Su único campo
será un nombre de cadena. Recuerda que estamos modelando
estos objetos a partir de esta referencia
del sitio web de Bitcoin Core. Pero el campo de billeteras en el registro de billeteras del nodo
coincide con el nombre de este campo en la
respuesta JSON de la llamada API. Lo mismo ocurre con el campo de nombre del registro del monedero del
nodo. El campo de billeteras de
la respuesta
tendrá una lista de objetos
con el campo de nombre. Cada uno de estos objetos se
almacenará como registros NerdWallet en la aplicación de vuelta a la lista de
nodos mientras es cliente. De la lista, todo método
devolverá una lista de nombres de billetera. Para ello, obtendremos las
billeteras de las billeteras de nodo. Luego llamaremos a stream, luego mapearemos pasando una referencia al campo del nombre de la billetera del nodo. Después convertiremos el resultado
a una lista y lo devolveremos. Ahora, vamos a probar el método list all usando un método
anotado con Post build imprimirá cada elemento devuelto por la lista de
todos los métodos de llamada. Vemos por esta línea en
la consola que la aplicación registra el nombre
del monedero de nodo que hemos creado. Genial. Ahora implementaremos
otro cliente para
llamar al método Node API
llamado list wallets. La diferencia
entre este método y la cartera de lista DIR es que las billeteras de lista devolverán solo las
billeteras cargadas actualmente por el nodo. También devuelve una lista de nombres de cartera sin
envolverlos en objetos. Ahora vamos a crear el método
list loaded. Devolverá una lista
de nombres de billetera. Para ello, sólo tenemos que
devolver esta llamada al método. Ahora vamos a probarlo de la misma
manera que hemos probado la lista. Voy a llamar. Vemos desde la consola, pero nuestra aplicación registra dos veces el
nombre de la billetera que hemos creado. El primero se debió a la llamada al método
list all, y el segundo se debió a
la llamada al método list loaded. Ahora bien, para ver la diferencia
entre las dos llamadas a métodos, hagamos lo siguiente. Termine la aplicación Bitcoin
Core Node presionando Control
más C en el terminal. Ahora inicia de nuevo el Bitcoin
Core Note. Ahora hagamos la misma prueba. Pero primero, sumar
estas líneas antes de que el método llame a diferenciar
entre cada método. Desde la consola,
vemos que solo la lista all method call devolvió
la billetera creada. Esto demuestra que después de que
iniciemos la aplicación Bitcoin Core
Node, tenemos que cargar la
billetera que usaremos, para que podamos realizar otras llamadas API que necesiten cargar una billetera de nodo. Pero veremos cómo funciona eso en la práctica en los próximos videos.
24. 22 cliente de nodo parte 2 skillshare 2: En este video,
seguiremos implementando más
métodos que nos
permitirán interactuar con nuestro nodo Bitcoin desde
nuestra aplicación. El primero es un método
que cargará una billetera de nodo. Cuando ejecutas tu nodo, necesitas cargar una
billetera para poder llamar
a muchos otros métodos de nodo. Así que vamos a crear el cliente de cartera
de carga de nodo. Como siempre, en una
anotación de Servicio al mismo. Ahora, inyectaremos el cliente del
nodo en él. Después crearemos
el método load, que tomará como parámetro el
nombre de las billeteras. Entonces simplemente
los llamaremos make request method desde el
cliente del nodo así. Ahora, probemos este método
usando una construcción post. Primero, eliminemos este método post constructo
que hemos creado antes. Ahora llamaremos al método load pasando el nombre de
la billetera que creamos. Antes de ejecutarlo, ejecutemos nuestro nodo Bitcoin
en la terminal. Bien, desde los registros de la terminal, vemos que nuestro nodo cargó
correctamente nuestra billetera. Ahora crearemos un servicio
útil para cargar una cartera de nodo si ya
existe y no está cargada. Si
ya existe una cartera con ese nombre y ya está cargada por el nodo
entonces el método no hará nada
y volveremos. Por último, si no existe una billetera con
ese nombre, el método la creará
y el nodo se cargará automáticamente ya que
carga una billetera
después de su creación. Entonces en el paquete services
dot node, vamos a crear una carga de nodo de
nombre de clase o crear un servicio de billetera. Inyectemos a los siguientes
clientes en él. El nodo crea cliente de billetera, el cliente de billetera de carga nodo
y la lista de nodos
mientras su cliente. Ahora vamos a crear un método
llamado load o crear wallet. Tomará un nombre
como parámetro. En su interior se llamará a la
lista todo método de la lista de nodos
billeteras cliente
almacenará el resultado en una
variable llamada todas las billeteras. Después llamaremos al método
list loaded desde el mismo cliente. Y almacenaremos el resultado en la variable monederos cargados. Ahora, agregaremos una declaración if verificando la
siguiente condición. Si esta condición
se evalúa como true, significa que la
billetera con ese nombre ya existe y es
cargada por el nodo. Si ese es el caso, no
necesitamos hacer
nada y podemos regresar. Ahora, agregaremos la
siguiente declaración if. Si esta declaración devuelve true, significa que ya existe una billetera con
ese nombre, pero no es cargada por el nodo. Si ese es el caso, llamaremos al método load desde el nodo load wallet
client pasando el nombre de la billetera y devolveremos. Finalmente, si la ejecución del código evalúa como falsas las declaraciones IF
anteriores, significa que no existe una billetera con
ese nombre. En ese caso, simplemente
creamos la billetera, llamando al método create
desde el nodo create wallet client y pasando
el nombre de wallets. Bien, El método está terminado. Lo usaremos en los próximos videos. Ahora vamos a crear
otro cliente útil. Se llamará Node
get new address client. Como su nombre indica, se utilizará para generar
una nueva dirección a partir de nuestro monedero de nodo
cargado. Así que vamos a inyectar el cliente del
nodo en él. Ahora, vamos a crear un método
llamado get new address. Devolverá la
dirección en una cadena. Y tomará como parámetro el
nombre de la cartera. Después volveremos a
hacer la
llamada al método request desde el cliente del nodo
con estos parámetros. Observe que hemos establecido
el parámetro
URL la cadena Wallet barra
el nombre de la billetera. Es así como le decimos a
nuestro nodo que
queremos una dirección de
esta cartera específica. Probemos este método. Para eso, crearemos el
siguiente método
anotado Post constructo llamará
al método get new address
pasando el nombre de una billetera que hemos cargado
antes como parámetro. Si llamamos a este método sin
cargar esta billetera First, no
funcionará y el nodo
devolverá un error. Almacenaremos el resultado
de la llamada al método en la variable address
y lo imprimiremos. Vamos a probarlo. El registro de la consola, muestran
que generó e imprimió una dirección de prueba
reg de segmento de Bitcoin. Genial. Toma nota de tu dirección
generada. Lo usaremos para probar el
método que va a implementar a continuación. Ahora, vamos a crear un método
que se utilizará para la mente algunos bloques que producen
Bitcoins a una dirección. Este método solo funciona en
el entorno de prueba reg, y
nos será útil en algunas pruebas que necesitan un número inicial
de monedas para jugar. Vamos a crear una clase llamada no degenerate para dirigirse al cliente. Como de costumbre, inyectaremos
el cliente del nodo en él. Después crearemos un método
llamado generate to address. Tomará como parámetros,
un nombre de billetera, un número de bloques
y una dirección. Después los llamaremos
make request method desde el cliente nodo con los
siguientes parámetros. Nuevamente, pasaremos
la cadena Wallet barra la variable name. Después pasaremos el parámetro
blocks, que indica el número de bloques que se quiere generar. Por último, pasaremos
la variable address, que es la dirección que
recibirá los Bitcoins generados. Ahora, vamos a probar este método. Primero. Eliminemos el método anotado de
construcción post anterior . Ahora, haremos que este método
post constructo llamará al método generate
to address, pasando el nombre de
una billetera cargada. Nuevamente, si pasas
el nombre de una billetera que no existe
o no está cargada, el método funcionará. Crearemos 1,000
bloques y pasaremos la dirección previamente
generada. Vamos a ejecutarlo. Si inspeccionamos nuestros registros de nodos, vemos que muestra algunas líneas que
indican que nuestro
método llamado funcionó. El último cliente que creará para este video se llamará
Node get balanced client. Se utilizará para verificar
el saldo de nuestras billeteras. Inyectemos el cliente del
nodo en él. Después crearemos
el método get, que devolverá el número de bitcoins que tiene nuestra billetera. Tomará como argumento el
nombre de la billetera. Después devolveremos
esta llamada al método. Al igual que los métodos anteriores. Este método enviará a la
Wallet barra el nombre de
la billetera como parámetro URL para definir el retorno del saldo
de esta billetera específica. Probemos este método
usando una construcción post. Llamará al método get pasando el nombre de una billetera previamente
cargada. Nuevamente, este método no va a funcionar. Si el monedero pasado no es
cargado por el nodo, entonces almacenaremos el resultado de la llamada en una variable e
imprimirlo . Vamos a probarlo. Genial. A partir de los registros, vemos que
ahora tenemos miles de Bitcoins. Por supuesto, estos
bitcoins solo son válidos en nuestro entorno de
prueba reg. En los próximos videos, los
usaremos para probar.
25. 23 cliente de nodo parte 3 skillshare 2: En este video, construiremos un cliente que nos
permitirá enviar Bitcoin desde nuestra billetera de nodo a cualquier otro vestido rojo que queramos. Luego usaremos todos los clientes que
hemos construido hasta ahora para crear una prueba para recibir bitcoins a una dirección de nuestra billetera de
aplicaciones. Así que después de eliminar
cualquier método de
construcción post
anterior de lecciones anteriores, vamos a crear una clase llamada
nodos enviados a cliente de dirección. Ahora vamos a inyectar el cliente del
nodo en él. Luego crearemos un
método llamado send to address como parámetros o nombre de
billetera y
dirección y una cantidad. Después los llamaremos
make request method desde el nodo cliente pasando
los siguientes parámetros. Nuevamente, pasaremos Wallet recortando
la variable de nombre de billetera. Será la billetera desde donde se enviarán
los bitcoins. También tomará
una dirección a donde se enviarán
los bitcoins y una cantidad, que es la cantidad que se
transfiere en Bitcoins. Probemos este método. Primero, asegúrate de que
tu nodo se esté ejecutando. En mi caso, voy a
tener que iniciarlo. Ahora, asegurémonos de que nuestra billetera de nodo esté financiada
con Bitcoins para que podamos enviar bitcoins desde ella llamará al
método get balanced para verificar eso. Pero esta vez
lo llamaremos desde la terminal. Cada método API que podamos llamar desde nuestra aplicación
se puede llamar desde el
terminal usando la aplicación Bitcoin CLI. Abre otra ventana de terminal, ve a la misma carpeta donde está instalado
tu nodo. Luego escribe el siguiente
comando para cargar una
cartera previamente creada y presiona Enter. En mi caso, después de cargar billetera, tengo que escribir
testing wallet name, que es el nombre de la billetera creé entre comillas dobles. Bien, ahora que nuestra
cartera está cargada, podemos ingresar otros
comandos que lo requieran. Entonces ingresemos este comando
para verificar nuestro saldo de billetera. Bueno, está equilibrado, es cero. Parece que cada
vez que reiniciamos la nota y el entorno de
prueba reg, nuestros fondos desaparecen. No hay problema. Financiaremos nuestra cartera de nodos. Ahora usando la interfaz de
línea de comandos. Para ello, primero, obtenemos una nueva dirección de
nuestro nodo mientras así es. Entonces llamamos al comando generate to address
para generar 1,000 bloques y destino
el bloque recompensa a la dirección que
acabamos de generar. Ahora, llamemos nuevamente al comando Get
balanced. Genial. Vemos que nuestra cartera ahora contiene miles
de Bitcoins. Otra vez. Ahora de vuelta al nodo
enviar a domicilio cliente. Hagamos un método post
build para probar el método send
to address. Llamará al método de enviar
a dirección, pasando el nombre de la billetera cargada. El segundo parámetro puede
ser cualquier dirección de prueba reg. Usaremos la CLI de Bitcoin
para generar una nueva dirección. Después lo pasaremos como
segundo parámetro al método send to address. Entonces elegiremos
uno como la cantidad. Vamos a ejecutarlo. Bien, si llamamos al
método Get balanced de la CLI de Bitcoin, veremos que nuestro
equilibrado apenas cambió. Hay una pequeña
diferencia entre el saldo actual y
el saldo anterior. Esta diferencia se debe a
la tarifa de transacción ya que
transferimos un Bitcoin a una dirección desde el
mismo monedero de nodo, si llamamos al método get received by address desde la CLI. Pasando la dirección,
hemos enviado un Bitcoin al número cero como
segundo parámetro, lo que indica que
queremos el saldo, incluidas
las transacciones no confirmadas, obtenemos el valor uno, que es la cantidad que lo
transferimos a esta dirección. Bien, por ahora hemos terminado nuestro
CLI jugando. Eliminemos el método de
construcción Post. Ahora dentro del paquete BYOD
w dot gooey creará la prueba
receive Bitcoin. Esta prueba necesitará
muchas cosas en común con la prueba de
crear billetera. Entonces haremos que extienda una clase abstracta que
crearemos llamada prueba GUI. Esta clase tendrá todos los métodos comunes a cualquier prueba GUI que necesitemos. Así que vamos a crearlo. En la prueba create wallet
cortará todas las propiedades y métodos excepto el último y los
transferirá a
la clase de prueba GUI. Luego le agregaremos la anotación de prueba Spring
Boot y extenderá la clase de especificación de la
aplicación. Eliminaremos la
misma anotación de la prueba create wallet y haremos que extienda la clase de prueba
GUI. Eliminemos todas las importaciones no utilizadas. Ahora hará que todas las
propiedades privadas en la prueba GUI estén protegidas e incluirá esta llamada de
proveedor de agregar punto de seguridad en
su método de inicio. Por último, haremos que
esta clase sea abstracta. Ahora, probemos la prueba de
crear billetera para ver si todo sigue funcionando
como antes en el error ocurrido. Mi intuición dice que
es un error de idea IntelliJ. Para resolverlo, llamémoslos método de ciclo de vida limpio
maven. Reconstruyamos también el proyecto y ejecutemos todas las pruebas de aplicación. Todas las pruebas pasaron. Entonces solo fue un error IDE. Ahora, sigamos construyendo nuestra prueba de recepción de Bitcoin inyectará los
siguientes beans en ella. El nodo envía al cliente de dirección, el nodo carga o
crea el servicio de monedero. El nodo se balancea, cliente. Y el nodo consigue
nuevo cliente de dirección. *****. Parece que
olvidamos agregar la palabra cliente y el
nodo obtener nueva dirección. Vamos a cambiarle el nombre. Ahora, vamos a crear un método de configuración que se ejecutará antes de que
esta clase sea test. En su interior llamará al método load o create wallet
desde el nodo load o creará servicio wallet ya que su parámetro
pasará la cadena, probará wallet y
lo almacenará en la constante. Entonces llamaremos al método
create balance si es necesario, que creará a continuación. Este método, primero
comprobaremos el saldo de la cartera de prueba usando el
nodo get balanced client. Si el saldo es
inferior a 100 Bitcoin, entonces obtendremos una nueva dirección
de la billetera de prueba. Usando el nodo generar
para direccionar al cliente, que nos hemos olvidado de
inyectar en esta clase, y lo haremos ahora. Generaremos 1,000 bloques, financiando
así nuestra billetera. Y haremos que este
método sea privado. Con este método
ejecutándose antes de las pruebas, garantizamos que siempre tendremos Bitcoins que podremos
usar en nuestras pruebas. Ahora, vamos a crear una prueba
llamada debería recibir Bitcoin. Es cuando
el bloque
será similar al bloque de viento en la prueba de
crear billetera, llamaremos a los siguientes
métodos para crear una nueva billetera. Haremos clic en la pestaña Recibir. Después buscaremos el valor
en la entrada de la dirección de recepción, que en este punto
contendrá la primera
dirección de nuestra billetera. Y lo almacenaremos en
la variable dirección. Ahora, llamaremos al
método
send to address desde el nodo
enviado al cliente de dirección. Como sus parámetros
pasarán el nombre del monedero de prueba, la dirección que hemos generado
con nuestra cartera de aplicaciones, y la cantidad uno. Después de recibir
Bitcoins, esperamos que nuestra cartera de aplicaciones
detecte la transacción, pero este proceso
no será inmediato. Tomará algunos segundos
para que eso suceda. Por esta razón,
usaremos un método llamado wait-for de test fx. Como sus parámetros pasarán diez, que será el
valor de tiempo de espera para el peso. El tiempo de espera en este contexto es el tiempo máximo que
esperará la
aplicación antes de lanzar
una excepción de tiempo de espera. El segundo parámetro indica la unidad de tiempo del parámetro
anterior. Entonces elegiremos segundos. El último parámetro
será un método de devolución de llamada. En su interior buscará un componente GUI con
un ID de direcciones. Table, consultará
tiene un TableView y almacenará su resultado en una variable
del mismo tipo. Después devolvemos la comparación entre el tamaño
del artículo TableView y uno. Esta tabla TableView con ID
de direcciones
será un componente que almacenará
una tabla que contiene filas, cada una con una
dirección financiada de nuestra billetera. El método callback se ejecutará en un bucle y solo se detendrá si la comparación devuelve true o si se logra el tiempo de espera. En resumen, este peso para la llamada al
método
hará lo siguiente. Se comprobará si hay una tabla con una fila rellenada
en la pantalla. Esto sucederá cuando nuestra billetera detecte que una de
sus direcciones recibió una transacción y llenó una fila de tabla con
esa información. Esperará 10 s a
que eso suceda o menos. Si la tabla se llena
con una fila antes, entonces copiaremos la línea de búsqueda de
vista de tabla y la pegaremos aquí. Entonces block comprobará de nuevo si el
tamaño del elemento TableView es igual a uno. Almacenemos este
valor de tiempo de espera en una constante. Ahora, hagamos la prueba. Como se esperaba. La prueba falló porque no encontró la tabla de direcciones. En el siguiente video, comenzaremos a implementar
esta función en nuestra billetera.
26. 24 Recepción de bitcoin parte 1 skillshare 2: En este video,
crearemos una tabla con información
sobre nuestras direcciones. Esa tabla contendrá
cada dirección financiada, su monto en Bitcoin
y el número mínimo de confirmaciones que tienen las transacciones
a esas direcciones. La idea es llenar
esa tabla justo después nuestras billeteras detecten transacciones
enviadas a nuestras direcciones. Entonces en la ventana principal punto FXML, si hacemos clic en la pestaña
Scene Builder, veremos que está
mostrando un mensaje para descargar Java FX, aunque lo hayamos descargado antes. Esto sucede porque esta función IDE no maneja bien los componentes
externos, como el controlador de
pestañas Recibir. Así que para poder utilizar
el Scene Builder se creará un nuevo archivo FXML
llamado playground. En este archivo, pegaremos todo el contenido de la ventana
principal punto FXML. Pero en lugar de usar componentes
externos como el controlador de
pestañas Recibir, los
incorporará en el archivo. Así que dentro del paquete resources
dot FXML, cree el archivo playground
dot FXML. Eliminar todo su contenido. Después copia todo el contenido de la ventana principal punto FXML
y pégalo ahí. Ahora sustituiremos el
contenido de la etiqueta Recibir tab controller por el contenido de la pestaña Recibir punto FXML. Y modificaremos la etiqueta
raíz FX con la etiqueta tag. Y vamos a eliminar
su atributo type. Importemos la etiqueta de insertos. Ahora, cuando hacemos clic en
el Scene Builder, podemos usarlo normalmente. Ahora, agreguemos un nuevo
panel de pestañas al componente VBox. Ahora, eliminemos una
de las pestañas creadas. Vamos a cambiar el nombre de las dos direcciones de
la pestaña restante. Vamos a darle una ficha FX
id de direcciones. Ahora, dentro de la pestaña Contenido, agregaremos un componente de
vista de tabla. Desafortunadamente, por razones de
errores, Scene Builder
no nos permite agregar una vista de tabla a una pestaña. No hay problema. Vamos a agregarlo
usando el editor de texto. También agreguemos aquí una idea
de Fx de la tabla de direcciones. Volvamos
al Scene Builder. Empezó a funcionar de nuevo. Ahora tenemos una tabla vacía
dentro de la pestaña de direcciones. Ahora agregaremos tres
columnas a la tabla. Cambiaremos el nombre de la primera
columna dos direcciones, la segunda para equilibrar, y la tercera dos confirmaciones. Después haremos clic en
la tabla y cambiaremos esta configuración a redimensionamiento
restringido. Ahora, cada columna tiene el mismo tamaño y ocupan toda
el área de la mesa. Ahora vamos a hacer clic en cada columna de la
tabla y deseleccionar. Son casillas de verificación editables y
clasificables. Ahora, para cada columna de tabla establecerá su ancho máximo en 100. Esto es solo un truco necesario para que podamos ajustar su tamaño. Ahora, ajustemos su tamaño
usando el mouse así. La columna de direcciones
debe ser más grande ya que las direcciones ocuparán
un espacio mayor, las columnas de
saldo y confirmación pueden tener el mismo tamaño. Volver al editor de texto. Cambiemos el
atributo pref height del panel de
tabulación a 355. Volviendo al Scene Builder, podemos ver que se ve mejor. Cambiemos también el mensaje de
marcador de posición, que muestra cuando
la tabla está vacía. Para ello, solo necesitamos agregar una etiqueta de etiqueta vacía dentro de
esta etiqueta de marcador de posición. Ahora que nuestro componente de mesa
está listo en el patio de recreo, vamos a crear un FXML para ello. Vamos a nombrarla tabla de direcciones. Eliminemos todo
su código estándar. Y vamos a copiar todo
el contenido entre la etiqueta TableView
y pegarlo ahí. Ahora, en lugar de usar
la etiqueta de vista de tabla, usemos la etiqueta raíz FX hace referencia a las
plantas de vista de tabla y al atributo type. Importemos las etiquetas restantes. Y agreguemos aquí este atributo XML
y S. Ahora de vuelta a la zona de juegos FXML. la pestaña de direcciones le falta
un FX ID. Vamos a agregarle. Esta idea ya se utilizó en el componente VBox por error. Así que vamos a quitarlo de ahí. Ahora, vamos a copiar estas cuatro líneas y pegarlas en
la ventana principal. Ahora, agreguemos las
etiquetas de cierre y las etiquetas que copiamos. Ahora eliminaremos
la etiqueta de vista de tabla y agregaremos una
etiqueta de contenido en su lugar. En su interior agregará una etiqueta de controlador de
tabla de direcciones. Ahora vamos a crear
este controlador. Vamos a agregarle una
anotación de componente. Debe extender la clase de vista de
tabla con la clase address
como su parámetro type. Ahora de vuelta a la ventana principal. Vamos a importar el controlador
creado recientemente. En el controlador de la
tabla de direcciones, vamos a crear un constructor. Tomará un parámetro FXML
con una anotación de valor. La anotación de valor hará
referencia a la tabla de
direcciones FXML. El segundo
parámetro constructor
será un objeto de
contexto de aplicación. En el cuerpo del constructor se creará un nuevo objeto cargador FXML, inicializándolo con
estos parámetros. Entonces configuraremos su
controlador FXML a esto. Y fijaremos su ruta a esto. Entonces llamaremos a cargar en él. Y agregaremos una
declaración de lanzamientos al constructor. Tenemos que hacer una
cosa más para que funcione. Dentro de esta sentencia if en
la interfaz gráfica de usuario iniciado oyente añadir el siguiente código. Esto es necesario para que Java FX construya correctamente la etiqueta
del controlador de direcciones. Ahora, ejecutemos nuestra aplicación
para ver cómo funciona. Genial, bien, la
mesa de vestidos se ve bien. En los próximos videos, haremos que funcione
para nuestras billeteras.
27. 25 Recepción de bitcoin parte 2 skillshare: En este video,
haremos que nuestras billeteras comiencen a interactuar con
nuestros nodos Bitcoin para que podamos recibir
información sobre transacciones enviadas
a nuestras direcciones. Recuerda que cuando
creamos una billetera, generamos las primeras
20 direcciones para ello. Pero nuestro
nodo Bitcoin
aún no sabe sobre son direcciones
generadas. Son nodo Bitcoin debe
conocer nuestras direcciones para
enviar activamente información sobre sus transacciones
a nuestra aplicación. Por lo tanto, necesitamos importar nuestras direcciones de billetera
a nuestro nodo. Para ello, crearemos un nuevo cliente de nodo que
se encargará de ello. Así que dentro del paquete de
cliente nodo punto se creará una clase llamada nodo
multi import address client. Al igual que otros clientes, tendrá una anotación de servicio e inyectaremos el servicio
al cliente del nodo en él. Antes de crear su método, revisemos la documentación del
sitio web de Bitcoin Core para que
su API utilice el multimétodo
de importación desde la API del nodo Bitcoin. Vemos aquí que toma como parámetro
una matriz de objetos. Cada objeto puede tener
muchas claves diferentes, pero solo usaremos
tres de ellas. La clave pub script, que puede tomar como valor
y objeto con una dirección que el nodo
importará una marca de tiempo, que es la fecha en que se generó la
dirección. Este parámetro es importante para determinar hasta qué punto en el pasado el nodo
buscará transacciones con esa dirección
en la cadena de bloques, también
establecerá el parámetro watch only en true
ya que nuestro nodo solo usará nuestras direcciones para monitorear transacciones
en la cadena de bloques, pero no podrá firmar transacciones con
esas direcciones. Solo nuestra
cartera de aplicaciones
podrá firmar
transacciones salientes, pero ese es un tema
para futuros videos. De vuelta al IDE, vamos a crear un método
llamado direcciones de importación. Tomará como parámetros
un nombre de billetera, una lista de direcciones y una fecha de creación de billetera. Ahora construiremos un
objeto params que modelará el multiparámetro de importación que vimos en la documentación de Bitcoin
Core. Este objeto será una lista
de un nuevo objeto que
crearemos llamado nodo multi
reimportado dress params. Vamos a crearlo ahora. Será un registro y lo
crearemos en el paquete de nodos puntos de
dominios. Contará con un nuevo
nodo multi reimportado, le volverá a
proyectar script pub
key objeto va a crear. También tendrá un campo de marca de
tiempo largo
y un campo de solo reloj booleano. Vamos a crear esta
clase como un registro. Tendrá sólo
un campo de dirección. Volver al nodo cliente de dirección de
importación múltiple. Dado que el método import
addresses recibe una lista de direcciones, debemos usar el siguiente
código para
convertirlo en una lista de nodos multi
reimportados vestido por ohmios. Entonces usaremos el método
make request del cliente del nodo así. Ahora, probemos este código
usando un método de construcción posterior. Importaremos direcciones a la billetera del nodo con el
nombre de la billetera de prueba de nombre. Y usaremos la fecha actual
como fecha de creación del monedero. Como las direcciones. Utilizará estas tres direcciones de prueba reg, que podrás encontrar en
esta clase como recursos. Antes de ejecutar este código, ejecutemos nuestro Bitcoin
Core Node y carguemos la billetera con el
mismo nombre que usaremos. Para cargarlo se utilizará
la CLI de Bitcoin, tal como hicimos en videos
anteriores. Bien, Al mirar
los registros del nodo Bitcoin, parece que funcionó. La última línea del registro muestra que
se completó el reanálisis. El reanálisis ocurre por defecto después de importar
direcciones al nodo. La búsqueda de reanálisis
de transacciones en la cadena de bloques para las direcciones
recientemente importadas. En este proceso, el nodo busca
transacciones y bloques creados hasta 2 h
antes de la fecha que
hemos pasado como parámetro
timestamp. Eliminemos el método de
construcción Post. Ahora dentro del paquete de oyentes de
puntos pegajosos, Vamos a crear una clase llamada cartera
creada oyente
importante. Tendrá una anotación de
componente, e implementará la clase de escucha de
aplicaciones con un parámetro de evento de billetera
creado. Vamos a implementar su método. Al igual que el oyente de
billetera creado, esta clase es método se
llamará después de la creación de una billetera. Inyectemos la carga del nodo o creemos el servicio de billetera en él. Ahora, en el método de
evento no aplicación se llamará al método load o create wallet desde
el servicio inyectado pasando el nombre de la
billetera de eventos como parámetro. También inyectemos el cliente de direcciones de
importación múltiple de nodo en él. Hagamos que ambos
servicios inyectados sean definitivos. Ahora llamaremos al
método
import addresses desde el último servicio
inyectado. Pero primero, vamos a
crear una variable para el monedero del evento y utilizarla en este método. Ahora en la llamada de
direcciones de importación, Pasemos el nombre del monedero. El método wallet get addresses, que creará la
billetera creada en la propiedad, que también crearemos
en el registro de billetera. Vamos a crear la propiedad
CreateDat date, crearemos usando la función IDE de
cambio de firma. Usemos un
valor predeterminado de nueva fecha. Al hacerlo, el IDE
agregará automáticamente este tercer parámetro en cada instancia de una billetera
que encuentre en el proyecto. Vamos a hacer clic en Refactorizar
e importar la clase de fecha. Si vamos al servicio create
wallet, vemos que
agregó una nueva fecha como tercer parámetro en
la instanciación de wallet. Esto hará que el monedero tenga la fecha actual como
fecha de creación. El
controlador de diálogo create wallet utilizará la billetera creada en la llamada al método de evento
público. Esto activará la llamada al método de evento en la
aplicación. Ahora vamos a crear el método
get addresses en el registro de la billetera. Devolverá una lista de direcciones tomando
las direcciones de sus llaves de
pub extendidas, así. Al llamar al
método FlatMap en el flujo de
claves de pub extendidas y devolver el flujo de
direcciones de clave de pub extendido en esta llamada obtendrá un flujo de todos los Objetos
de Dirección de la billetera. Luego llamaremos al método
map para convertir el flujo de objetos de dirección en un flujo de cadenas de
direcciones. Finalmente, llamaremos al método de dos
listas en el resultado y devolveremos una lista de todas las
direcciones de billetera en formato de cadena. Bien, ahora después de
crear nuestra billetera, esperamos que nuestras cargas de
aplicaciones fueran crea una billetera con el
mismo nombre en nuestro nodo. Después de eso, nuestra
aplicación importará todas las direcciones generadas
a nuestro nodo. Ejecutemos nuestra
aplicación para probarla. Vamos a crear una nueva cartera. Yo hice clic en el botón Bien, pero parece que
no había pasado nada. Comprobemos los registros del nodo. Bien, después de algún tiempo, dice
que el reanálisis se completó y el monedero
terminó su creación. En el siguiente video, haremos que este proceso sea asincrónico
ejecutando las llamadas al
nodo en otro hilo. Al hacerlo, el pegajoso no se quedará atascado y la
creación de la billetera será más suave. Cia.
28. 26 Recepción de bitcoin parte 3 skillshare 2: En el último video, hicimos que
nuestro nodo Bitcoin creara y
cargara nuestra cartera de aplicaciones
y direcciones de importancia. Pero este proceso estaba
tardando algunos segundos y estaba bloqueando la interfaz
gráfica de usuario. En este video, lo arreglaremos
haciendo que la comunicación
con el nodo se ejecute en otro hilo de forma asíncrona
dentro del paquete BYU OWL. Vamos a crear un nuevo
paquete llamado Config. Dentro de este paquete, vamos a crear una clase
llamada config asincrónica. Esta clase contendrá
todas las configuraciones relacionadas con la
ejecución de código asincrónico en el proyecto. Vamos a agregarle una
anotación de configuración. Y una
anotación asíncrona habilitada para. Esta anotación es importante para habilitar
entidades asíncronas en el proyecto. Ahora, vamos a crear un método anotado con la anotación
Bean. Devolverá un EjecutorService. Vamos a llamarlo servicio
ejecutor predeterminado. Devolverá un nuevo ejecutor de un
solo hilo de la clase ejecutores. Este bean nos proporcionará un hilo cada vez que queramos
ejecutar código en él. Será un solo hilo, que significa que si dos
o más secciones de código están tratando de ejecutarse en este
hilo simultáneamente, una sección tendremos que
esperar a que la otra termine de ejecutarse. Elegimos usar un solo hilo porque facilita el
control de
los procesos en nuestra
aplicación y nos permite evitar
condiciones de carrera con mayor facilidad. Ahora, hagamos un poco de refactorización de código dentro del paquete
gooey dot services. Vamos a crear una clase
llamada
servicio de monedero de importación y agregarle la anotación de
servicio. Vamos a crear un método
llamado monedero de importación. Transferirá el código
del oyente de
importación de billetera creado al servicio de billetera de importación. Inyectemos también los
servicios requeridos en esta clase. Y agreguemos la billetera como parámetro al método de la billetera de
importación. En el oyente de
importación de billetera creado. Eliminemos todo este código. Inyectemos el servicio de
monedero de importación en él. Ahora en el método de
evento que no es de aplicación, llamemos al método
import wallet desde el servicio inyectado pasando la billetera de eventos
como parámetro. El
método import wallet contiene el código que queremos
ejecutar de forma asincrónica. Para hacerlo asincrónico, solo
tenemos que anotar este método con la anotación
asincrónica, pasando el nombre del bean
del servicio ejecutor que
hemos creado. También debemos devolver un
valor de este método, que nos permitirá administrar esta llamada asincrónica desde
el método color. El valor devuelto
será un futuro. Un tipo de parámetro void devolverá un nuevo objeto de resultado
asíncrono que pasa null a su constructor. Ahora, probemos la
creación de una billetera. Pero primero, ejecutemos
nuestro nodo Bitcoin. Si no está ya funcionando. Vemos que nuestra billetera
se creó de inmediato, pero cuando revisamos los registros de los nodos, sigue
cargando e importando las direcciones de la billetera. Genial. El nodo ha
terminado el reanálisis. Por lo que nuestros
procesos de carga e importación de billeteras son asíncronos. Ahora hagamos algunas afinaciones finas. Vamos al oyente de importación de
billetera creado. En el método de
evento no aplicación se registrará la devolución del método de monedero de importación y lo
almacenará en la variable de resultado. Haremos de esta variable un campo
privado de esta clase. Ahora, agregaremos la
siguiente declaración if. Antes de llamar a la cartera de importación. Si la
variable result no es nula, entonces llamaremos al método
cancel en ella, pasando true como argumento. Esto es necesario porque
si intentamos crear otro monedero cuando uno no haya
terminado de importar primero, tendremos que cancelar
el proceso
de importación de la primera billetera creada. Hagamos otra afinación fina en la clase de aplicación GUI
anulará el método stop. En su interior, se agregará
el siguiente código. Este código asegurará que el
hilo creado por nuestro
ExecutorService predeterminado se cierre después cerrar
nuestra aplicación. Ahora, hay otro problema
con nuestra aplicación. Cuando creamos una billetera sin
nuestro nodo Bitcoin funcionando, las llamadas para crear o cargar una billetera y
direcciones de importancia fallarán. Veamos cómo funciona eso
en la práctica cerrando nuestro nodo Bitcoin y
ejecutando nuestra aplicación. Después de crear una billetera, parece que nuestra aplicación
se está ejecutando normalmente, pero eso es porque
las excepciones y otros hilos no están
siendo reportados. Nuestra billetera no podría
haberse comunicado con nuestro nodo mientras
nuestro nodo estaba apagado. Cuando intentó hacer eso, arrojó
una excepción hilo arrojó
una excepción y un hilo
terminó de funcionar. Arreglemos esto. Lo que
queremos que haga nuestra aplicación cuando crea una billetera es intentar comunicarnos
indefinidamente con nuestra nota. Si por alguna razón no pudo
hacerlo después del primer intento, hágalo, usaremos una
anotación Spring Boot llamada retrial. Esta anotación hace que el método
anotado se ejecute de nuevo, si arroja una excepción. Para usarlo, debemos agregar las siguientes dependencias
a nuestro archivo POM. El primero es el reintento de resorte, el segundo son los aspectos de primavera. Ahora en el método import wallet, agreguemos la anotación de retrial también
le pasará algunos
parámetros. La primera será la expresión de
excepción, que se establecerá como al inicio de
sesión puerto wallet service dot debería reintentar abrir
y cerrar paréntesis. Esto hará que la aplicación llamada un método should
retry antes cada reintento y solo reintente si esta
llamada al método devuelve true. También agregaremos el parámetro
max intentos, configurándolo en la constante de número entero de
valor máximo. Esta configuración
hará que este método se vuelva
a intentar indefinidamente. Por último, agreguemos el parámetro
backoff, configurándolo a la anotación de
retroceso, pasando el
parámetro delay de 1,000. Esto hará que la aplicación
esperara 1,000 milisegundos o 1 s antes de ejecutar
el método en cada intento. Ahora vamos a crear este método
debería reintentar. Su tipo de retorno
será un Booleano. El método devolverá la
negación del resultado de que se interrumpa la llamada al método
del hilo actual. Esta llamada devolverá true si el hilo actual no es
interrumpido o falso en caso contrario. Por lo tanto, si la
aplicación se cierra o si se crea
otra billetera
entre cada reintento, este hilo
se interrumpirá y el método de monedero de importación ya
no se volverá a intentar. Una cosa más para que funcione la anotación de
reprueba, debemos agregar la anotación de
reintento habilitada en la
clase de configuración asíncrona. Vamos a hacerlo. Ahora. Ejecutemos nuestra aplicación con nuestro nodo cerrado
y hagamos algunas pruebas. Vamos a crear una nueva cartera. Ahora, comencemos nuestro nodo. A partir de los registros del nodo, vemos que se
cargó la billetera
creada y se
ha completado el reescaneo. Ahora. Ahora vamos a crear otra cartera. Vemos desde los registros del
nodo que también se ha creado,
cargado e importado
con éxito . Genial.
29. 27 Recepción de bitcoin parte 4 skillshare 2: En este video, seguiremos
integrando nuestra billetera
con nuestro nodo. El siguiente paso en la integración es escuchar los
mensajes que el nodo envía cuando recibe una transacción a una dirección
importada. Para ello, crearemos una
clase llamada node task, que tendrá un método que ejecutará en un bucle infinito
en otro hilo después de que se inicie
la aplicación. Este método
escuchará continuamente las transacciones que son nodo recibe a cualquiera de nuestras aplicaciones direcciones
cargadas actuales. Cuando encuentre uno, hará
que nuestra aplicación lo
maneje en consecuencia. Así que vamos a crear un
nuevo paquete llamado node en el paquete BYOD W. En su interior se creará una clase llamada gooey
started node listener. Vamos a agregarle una
anotación de componente. Esta clase será un oyente
desencadenado por el evento gooey started publicado cuando se inicia
la aplicación. Por lo que implementará el listener de aplicaciones con ese evento como su parámetro
de tipo. Implementemos su método. Vamos a agregar el nuevo servicio de
tareas de nodo que creará como un
campo privado en esta clase. Vamos a crear el nuevo servicio. Ahora, vamos a inyectarlo en el oyente de nodo iniciado
GUI. En el método de
evento que no es de aplicación se llamará al método de ejecución de
tareas de nodo. Vamos a crear este método
en la tarea del nodo. Agreguemos la
anotación de servicio a esta clase. Ahora, agregaremos una
dependencia que la tarea de nodo
necesitará en el archivo POM. Será el héroe de la biblioteca MQ. Vamos a hacer clic en el botón Cargar cambios de
Maven. Esta biblioteca gestiona
la comunicación entre la aplicación
y cero MQ. Zero MQ es un corredor de mensajes que recibe mensajes
del nodo Bitcoin. Estos mensajes serán enviados a una URL local y recopilados por nuestra aplicación a través de cero
MQ de regreso a la tarea del nodo. Agreguemos la
anotación asíncrona al método run. Pasemos el
servicio albacea de notas como su parámetro. Esto hará que
este método se ejecute asincrónicamente en otro
subproceso gestionado por el
servicio ejecutor de nodo que vamos a crear en la clase de
configuración asíncrona, vamos a crear el servicio
ejecutor de nodo. Al igual que el servicio
ejecutor predeterminado, será administrado por un nuevo ejecutor de un
solo hilo. Ahora, vamos a inyectar
el objeto socket desde cero MQ en esta clase. Este campo se llamará
suscriptores ya que
manejará una suscripción
al broker de mensajes MQ cero. En el método run, vamos a establecer el tiempo de
espera de recepción del suscriptor en 1,000. Esto agregará un
retraso de un segundo cada vez nuestra aplicación consulta cero y Q para buscar mensajes. Llamemos a este método de
suscripción de suscriptores, pasando los bytes de la
varilla de cadena TX como parámetro. Esto hará que nuestra aplicación
solo escuche mensajes
relacionados con robar transacciones de
Bitcoin que son envíos de nodo a cero. Mq también llamará al método de conexión de
suscriptores, pasándole la variable
z MQ URL a él. Inyectemos esta
variable en esta clase. Añadiremos una anotación de valor
a su argumento constructor, pasando esta cadena
como parámetro. Por lo tanto, este valor de variable se
inyectará en
esta clase a través una propiedad de aplicación llamada z y q punto URL se establecerá ahora, el valor de esta
variable tiene que coincidir con el mismo valor que hemos establecido
en nuestro archivo bitcoin.com. Así que vamos a copiar el valor
establecido para la configuración z MQ pub rock TX bitcoin.com
y pegarlo aquí. Ahora, de vuelta al método de ejecución de tareas de
nodo vamos a crear nuestro bucle
sin parar. Vamos a crear un bucle while. Se ejecutará mientras no se interrumpa el
hilo actual. Dentro del bucle,
llamaremos a los suscriptores wreck el método STR y almacenaremos el resultado en la variable
topic. El naufragio del
método STR consulta cero MQ para cualquier mensaje y devuelve
una cadena si encuentra uno. En nuestro caso, esa cadena contendrá el
nombre del tema, que será igual a ra
TX para las transacciones en bruto. Luego agregaremos un bucle if
verificando la variable topic. Si su contenido es
diferente a Ratti x, entonces llamaremos a
continue making the loop run again
from the beginning. Si no, entonces llamaremos
al método abonados naufragio V y almacenaremos el contenido
en la variable content. El naufragio del método es
similar al VNTR rec, pero devuelve una matriz de bytes
en lugar de una cadena. En este punto, esa matriz de
bytes contendrá la transacción sin procesar o
nodo enviado a cero MQ. Ahora, convertiremos
la matriz de bytes en el objeto de
transacción Bitcoin Java. Para ello, usaremos
el siguiente código. Debemos agregar una sentencia lanza IOException a
esta firma de método. En la GUI inició
el nodo oyente. También necesitamos
envolver la llamada de ejecución en un bloque try-catch como este. Volver al método run. Ahora usaremos un
servicio de editores de
eventos de aplicaciones para publicar un evento. Inyectemos este
servicio en esta clase. Primero. Pasaremos un nuevo evento de transacción recibida al método
publish event. A la transacción recibida instanciación del
evento
pasará esto y el objeto de transacción antes crear la nueva clase de evento, agreguemos una pieza faltante
para que este método funcione. Vamos a crear una nueva clase
llamada configuración de nodo. Vamos a moverlo a un nuevo paquete
node dot config. Vamos a agregarle una
anotación de configuración. En esta clase,
agregaremos algunos beans para las tareas
del nodo inyectado objeto
Socket funcionen. El primer frijol será
el contexto Z siendo. El segundo haz
será el zócalo MQ cero. Se llamará suscriptor. Y tomará en su método
el contexto Z creado anteriormente. Devolverá los
contextos Z para crear llamada al método
socket pasando la
subconstante de tipo socket como su parámetro. Ahora de vuelta a la tarea nodo se creará el evento de transacción
recibida, lo
creará en el paquete de eventos de punto de
nodo. Pasaremos la tarea de nodo
al súper constructor e
inyectaremos la transacción en
un campo de transacción privado. Creemos también un
método getter para la transacción. Ahora, vamos a crear un paquete de oyentes
en el paquete node. En su interior. Vamos a crear un
oyente de transacciones recibidas para este evento. Vamos a agregarle una
anotación de componente. Este oyente
se encargará de filtrar
las transacciones de recepción
identificando si
tienen direcciones pertenecientes a una cartera actualmente
cargada. Implementará un oyente de
aplicación con el
evento de transacción recibida como su parámetro de tipo. Implementemos su método. En este método, obtengamos transacción
del evento y almacenemos en la variable de
transacción. Ahora, lo primero que
haremos es identificar las direcciones de salida de
la Transacción Recibida. Para hacerlo se creará
la variable addresses, que será una lista de cadenas. Después le asignaremos el resultado de la siguiente expresión. Mapeará las salidas de la transacción pasando un método de análisis de
analizador de direcciones. Ahora, vamos a inyectar y crear
el servicio de analizador de direcciones. Vamos a crearlo en el paquete
node dot services. Vamos a agregarle la
anotación de servicio. Ahora, vamos a crear
el método parse. Devolverá una cadena y tomará una salida de transacción
como su parámetro. Este método se encargará de extraer la dirección de una salida de transacción de vuelta
al oyente de transacción
recibida convertirá el
resultado en una lista. Entonces para fines de prueba se imprimirán todas las direcciones
analizada. Ahora vamos a implementar
el método parse. Lo primero que
haremos es obtener la clave pub del script de transacción y asignarla a esta variable. No te preocupes, te
explicaremos qué es una
clave de pub de guión y otros detalles de la
transacción. En el siguiente video,
devolveremos el resultado de la
siguiente sentencia switch. Si el tipo de la clave pub
script es igual a la constante P2 WP k, h, que es el tipo de nuestras direcciones
actuales de billetera. Después devolveremos el
script pub key P2, WP k h address method call. Pasando el prefijo
de dirección Factory Get method call como parámetro que le pasa
la constante Segway. La sentencia case predeterminada
será una cadena vacía. Inyectemos la
fábrica de prefijos de dirección en esta clase. Ahora, hagamos algunas pruebas. Mi nodo Bitcoin
ya está funcionando. Asegúrate de que el tuyo también. Vamos a la clase de prueba de recibir
Bitcoin y ejecutarla. La prueba falló porque aún no
hemos modificado nuestra prueba GUI para considerar el controlador de tabla de direcciones. Recuerde que nuestro oyente iniciado
GUI maneja el problema de
usar esta condición if. Podríamos usar la misma
condición si en nuestro fijo, pero hagámoslo de una manera más ordenada. Vayamos al evento iniciado
GUI. Cambiemos el tipo de
aplicación GUI a object. Simplemente publicaremos el evento gooey started en
nuestra clase de prueba GUI, la misma manera que lo hicimos aquí
en la clase de aplicación GUI. En la clase de prueba GUI, eliminemos todo este código. Ahora, copiemos esta línea de la aplicación GUI
y péguela aquí. Eliminemos todas
estas importaciones no utilizadas y este campo privado no utilizado. Ahora, volvamos a ejecutar la prueba de recibir
Bitcoin. Nuestra prueba falló,
pero vemos aquí en los registros de prueba que son aplicación
impresa dos direcciones. Esto sucedió porque
imprimimos las direcciones de la transacción que nuestra prueba realizó una de nuestras direcciones de billetera. Una de estas direcciones es la nuestra, la otra es una
dirección de cambio del remitente. Genial. Vemos que lo que hemos
hecho hasta ahora ha funcionado. Hagamos algunas refactorizaciones
en la clase de prueba GUI. Eliminemos estas importaciones
no utilizadas. En la clase de aplicación GUI. Incluyamos esta
línea de código que hará que nuestro hilo de
servicio ejecutor note deje ejecutarse después de cerrar
nuestra aplicación. En el siguiente video,
aprenderemos más sobre las transacciones de
Bitcoin para
prepararnos para lo que viene después.
30. Transacciones de Bitcoin entradas, salidas, guiones y el conjunto UTXO: En esta presentación,
aprenderemos algunos conceptos sobre las transacciones de
Bitcoin. Será útil
para entender mejor la implementación de recibir Bitcoins en nuestra cartera de
aplicaciones. Recapitulemos lo que hemos
aprendido hasta ahora sobre las transacciones de
Bitcoin
y gradualmente agreguemos complejidad a nuestra
comprensión de ellas. Entonces, una transacción
de Bitcoin se usa comúnmente para transferir Bitcoins de
persona a persona B. Una transacción
de Bitcoin
puede estar compuesta por muchas entradas y muchas salidas. Una entrada de transacción indica el propietario anterior de Bitcoin o el remitente de
la transacción. Una salida de transacción indica
el receptor de las monedas o el propietario de las monedas después se publique
la transacción. En esta imagen, tenemos una transacción simple con
una entrada y dos salidas. Dice que un Bitcoin
fue transferido de John, quien firmó el insumo
de esta transacción. La salida cero indica que 0.9 Bitcoins fueron enviados para casarse. Voy a poner uno indica que 0.099 Bitcoins fueron enviados de
vuelta a John como el cambio. Los montos de Bitcoin no
se pueden dividir en entradas. Ya que John quería enviar
0.9 Bitcoins para casarse, pero solo tenía un Bitcoin. Necesitaba crear una
salida de cambio de nuevo a Sí Mismo. Pero su cantidad es de
0.099 Bitcoins, no 0.1 Bitcoins, como cabría
esperar. La diferencia, que
es 0.001 Bitcoins, es la
tarifa de transacción necesaria para que
la transacción se
incluya en la cadena de bloques. Entonces a partir de esta imagen, tomamos tres lecciones. La suma de bitcoins
en entradas no puede ser menor que la suma de
Bitcoins y salidas. El monto de Bitcoin en entradas es fijo mientras que se puede elegir a voluntad y salidas dado
que satisface la regla anterior. Por último, la tarifa de transacción es la diferencia
entre la suma de los montos de Bitcoin en las entradas y la suma de los
montos y salidas de Bitcoin. Incrementando la complejidad. También aprendimos sobre los
campos que forman parte de una entrada de transacción y
una salida de transacción. Y entrada siempre se refiere a una salida de una transacción
anterior. Lo hace usando
el ID de transacción anterior y el índice de salida de la transacción
anterior. Sería redundante que
la entrada tuviera
un campo de cantidad. Estos dos campos son
suficientes para identificar cualquier salida de transacción
en la cadena de bloques. Uh, la entrada de transacción también debe contener una
firma válida producida usando la misma
clave privada utilizada para derivar la dirección de la salida
a la que se refiere la entrada. Observe que una
entrada de transacción no tiene un campo que indique que
es cantidad de Bitcoin. Eso es porque su cantidad es automáticamente igual a la cantidad de
salida a la que se refiere una
salida de transacción tiene dos campos. Una es la dirección que se
utiliza para recibir bitcoins. Y la dirección es una cadena
codificada y por sí misma no revela
al dueño de las monedas. Por eso consideramos a
Bitcoin seudónimo. El otro campo es
la cantidad que indica la cantidad de Bitcoin
bloqueada por la dirección. Ahora, aumentemos la
complejidad una vez más explicando qué contienen exactamente las entradas
y salidas de las
transacciones. La entrada de transacción tiene
los siguientes campos. El ID de transacción anterior, que es una cadena
hexadecimal única, se obtiene mediante hash de la
transacción serializada anterior. El índice de
salida de transacción anterior es un número entero. Dado que una transacción
puede tener muchas salidas, una salida específica
puede
identificarse inequívocamente por su
ID de transacción e índice de salida. El campo ScriptSIG o testigo. La firma de entrada se agrega
al campo ScriptSig en transacciones que
no sean Segway. En las transacciones Segway, la firma se agrega
al campo testigo, que no cuenta al tamaño de
la transacción. La salida de la transacción
tiene los siguientes campos. La clave del pub script. clave de publicación de script contiene
la dirección decodificada y el campo de cantidad
que determina la cantidad de Bitcoin
bloqueada por la dirección. Ahora, veamos cómo construir una transacción de Bitcoin
a través de un ejemplo. Nuestro objetivo en este
ejemplo es enviar 1.5 bitcoins a esta dirección. Antes de comenzar, tenemos
una transacción confirmada, lo que significa que ya está
almacenada en la cadena de bloques. Tiene una salida
con dos bitcoins, que puedo
gastar ya que tengo una clave privada que se utilizó
para crear su dirección, y que se puede usar para firmar una entrada de transacción para
ello en una nueva transacción. Así que vamos a construir una
nueva transacción, le agregará una entrada. La entrada nos referiremos
a nuestra transacción a través del campo ID de
transacción anterior. El índice de
salida de transacción anterior es cero, ya que es el
índice de salida de nuestra salida. El campo ScriptSig está compuesto por
una firma producida usando la misma clave privada utilizada para producir la dirección
de nuestra salida. Y una clave pública, que es la misma clave pública derivada usando nuestra clave privada. La transacción
tendrá dos salidas. El cero de salidas contendrá un
campo de clave de pub de script compuesto, entre otras cosas, la
clave pública hash de la dirección. Queremos enviar nuestros bitcoins a. Este hash es obtenido por Beck
32 decodificando la dirección. Atrás 32 es el algoritmo utilizado para codificar el
hash de una clave pública, produciendo un segundo ¿qué dirección? Base 58 es otro algoritmo utilizado para hacer lo mismo para direcciones que
no son de segmento. Ya que estamos enviando bitcoins
a una dirección de segmento, debemos usar Beck 32. El campo de cantidad de esta
salida será igual a 1.5, que es la
cantidad de Bitcoin que queremos enviar, necesitará una segunda
salida para el cambio. Su clave pub script
contendrá una clave pública hash obtenida por la
decodificación Beck 32 y la dirección
que nos pertenece, que se deriva de una
clave privada sobre la que tenemos control. cantidad
será de 0.49 Bitcoins, que sumado a 1.5 de salida
cero es igual a 1.99. Entonces tenemos una diferencia de 0.01 entre la suma de los
montos de Bitcoin en entradas y salidas. Esa diferencia será la tarifa de
transacción necesaria para la transacción sea incluida en la cadena de bloques por un menor. Hablamos de ScriptSiG
y script pub key, pero aún no explicamos cuáles son
esas cosas realmente. Bitcoin tiene un
lenguaje de contrato inteligente llamado script. Un contrato inteligente es una
forma elegante de referirse a un programa escrito en una transacción y ejecutado por la red Bitcoin. Los campos clave ScriptSIG y
script pub están hechos con código de
lenguaje script. Este lenguaje se
interpreta combinando el scriptSIG de una entrada
y la clave pub script de una salida y comprobando
si el scriptSIG satisface las condiciones
codificadas por la clave pub script. Puedes considerar este mecanismo como un mecanismo de llave y cerradura, donde el ScriptSig
es la llave para desbloquear la clave script pub,
que es la cerradura. Si un ScriptSIG es válido para
desbloquear una clave de pub script, entonces puede gastar los fondos de
salida bloqueados por él. Un ScriptSIG tiene este nombre
porque generalmente contiene una firma que satisface una condición específica de clave de
pub de script. De igual manera, la clave pub script
tiene este nombre porque contenía una clave pública en las
primeras transacciones de Bitcoin. Pero en teoría, cualquier código de script
arbitrario se
puede incluir en ambos campos. La restricción única para que un programa de
script sea válido es que devuelve true
al final de su ejecución. Hay muchos tipos
de programas de script, también conocidos como tipos de script. Uno de ellos es el hash de
pago a clave pública utilizado en transacciones simples no
secuitur. Veamos cómo se
ejecuta en este ejemplo, todos los scripts de Bitcoin se
ejecutan de manera similar, ¿qué cambios entre ellos
o el código que se está ejecutando? Entonces, comenzando con nuestra transacción
confirmada de la diapositiva anterior, aquí, mostramos solo
su salida cero con su
contenido clave de pub script en la caja gris. En las transacciones
hash de pago a clave pública, el
campo script pub key se compone de opcodes y el hash de clave
pública. Y opcode es una instrucción en
lenguaje de escritura. Están identificados por las
letras OP en sus inicios. Subir guión bajo igual, por ejemplo, compara dos elementos y
devuelve true si son iguales. Cada script pub key y pay to public key hash scripts tiene esta secuencia de código
que solo difiere en sus hashes de clave de
pub. Ahora tenemos nuestra nueva transacción, que es la misma que
la diapositiva anterior. En esta ocasión mostramos
solo su aporte aquí. Es el contenido de ScriptSig
está en la caja gris. En pago a scripts hash de
clave pública. El ScriptSiG
sólo tiene una firma seguida de una clave pública. Ahora veamos cómo
se combinan y ejecutan ambos campos. Primero, el contenido ScriptSig de la entrada se concatena con el contenido de la clave pub script de la salida referida por
la entrada en este orden. Luego, cada elemento
del script combinado es empujado a una
pila de ejecución de izquierda a derecha. Si el elemento es un opcode, puede actuar sobre otros
elementos de la pila, procesándolos y agregando
otros elementos a la pila. Entonces veamos cómo se ejecuta este
script. La firma es el primer
elemento de izquierda a derecha. Por lo tanto, primero
se introduce en la pila. El siguiente elemento
es la clave pública, y también se
introduce en la pila. El siguiente elemento es el opcode
arriba subrayado. Arriba, subrayado arriba codifica
una instrucción para duplicar el último elemento agregado a la pila y agregar la
copia a la pila. El siguiente elemento es el opcode op
underscore hash 160. Elimina el último elemento
agregado a la pila, aplica la función hash 160 y
vuelve a agregar el
resultado hash a la pila. Entonces terminamos con el hash de clave pública en la
parte superior de la pila de ejecución. El siguiente elemento que se agregará a la pila es el hash de clave
pública. A continuación, tenemos el guión bajo op
igual verificar opcode. Este opcode elimina dos elementos de la parte superior de la pila de
ejecución y los
compara si son iguales a lo que el script
continúa ejecutándose. Si no es así, su ejecución falla y la transacción
se invalida. Este paso es
importante porque valida que la
clave pública del ScriptSIG es igual a la clave
pública utilizada para generar la dirección de la
salida de la que está gastando. El último elemento
del script es el opcode sig de
verificación de guión bajo op. Elimina dos elementos
de la parte superior de la pila de ejecución
y valida si el primer elemento es
una firma válida para el segundo elemento para
esta transacción específica, si es una firma válida, agrega un verdadero booleano a la pila. Si no es válido que un booleano, se agrega
false a la pila. Finalmente, después de que
se agregaran todos
los elementos del script a la pila de
ejecución, la entrada de transacción se
consideraría válida si el último elemento
agregado es true. De lo contrario, la
entrada de transacción no es válida. Este proceso debe repetirse para cada entrada de transacción. Para que una transacción
se considere válida, todos sus insumos deben ser válidos. Hay muchos tipos de guiones. El script pay to public key fue
el primer script de Bitcoin
creado, pero hoy en día está en desuso
y rara vez se usa. Las primeras transacciones de Bitcoin
contienen el tipo de script. En lugar de usar el
hash de la clave pública, es script pub key, usa
la clave pública directamente. El script hash de pago a
clave pública se ejemplificó en
la última diapositiva. Fue el tipo de
script más utilizado desde el aumento de relevancia de
las transacciones Segway en los últimos años. Hoy en día, sigue siendo de uso común, por lo que es bueno saberlo. El script hash de
clave pública pay to witness es el tipo de script más
utilizado actualmente en las transacciones de Bitcoin. La razón de esto es que es ventajoso usarlo ya que
las transacciones con él son más pequeñas y por lo tanto tienen una tarifa de
transacción más pequeña. Este tipo de script tiene una clave de publicación de script
más pequeña y su contenido de ScriptSig se
mueve al campo testigo, lo que no contribuye
al tamaño de la transacción. Por estas razones, primero
implementaremos este tipo de script en
nuestras billeteras, el hash pay-to-script
es otro script utilizado principalmente para transacciones
multifirma. Las transacciones multifirma requieren más de una firma para gastar una salida. El hash del
script pay to witness es la versión testigo del
script hash pay-to-script. Su firma se traslada
al campo de testigos. Por lo que tiene las mismas
ventajas que tiene el script hash de
clave pública pay to witness. El hash de
clave pública de pago para presenciar envuelto en un script
hash de pago a script también se conoce como segmento anidado
o segmento de rap. También es de uso común y
su función principal es
hacer carteras antiguas que no son compatibles con segmentos
nativos,
compatibles con transacciones
Segway. Aprenderemos más
sobre el tipo de guión más adelante en el curso. Por último, otro tipo de script es el script root pay to tap. Es el tipo de script
creado más recientemente, agregando más capacidades y privacidad a las transacciones de Bitcoin. Ahora, veamos un
resumen de cómo construir entradas y salidas de
transacciones desde el punto de vista de una billetera, comenzando con una
semilla mnemotécnica y una frase de contraseña. A través de un
algoritmo criptográfico, combinamos ambos y
obtenemos una semilla raíz. Después a través de una serie
de transformaciones se producen claves maestras y llaves
extendidas. Obtenemos muchas claves privadas. Aquí te mostramos solo una
de estas claves privadas. Las mismas transformaciones
también pueden producir claves públicas. Una clave pública también se puede producir a partir de una clave privada
específica, que mostramos aquí
en nuestro ejemplo. A partir de una clave pública, obtenemos una dirección usando la función hash 160 y codificando el
resultado a través de la
codificación Beck 32 en el caso de direcciones de
segmento o codificación base 58 en el caso
de direcciones que no son de segmento. Para recibir Bitcoins, le
muestras tu dirección a
alguien para que alguien
pueda enviarle bitcoins. Cuando un remitente pone
su dirección en su billetera y le envía una cantidad de
Bitcoin, su billetera
decodificará la dirección un hash de clave pública. Luego construirá una
transacción con una salida que contenga una clave de publicación de script
equivalente a esa dirección. El tipo de clave pub script
dependerá del tipo
de dirección. En este caso, la
billetera identificó que el tipo de dirección
es compatible con un script hash de pay to public key. Después de recibir Bitcoins
a esa dirección, el receptor puede gastarlos
a través de una nueva transacción. El nuevo contenido de
los campos de entrada de transacción
dependerá del
tipo de clave pub script que se gastará. En este caso, la
billetera construirá una transacción con
una entrada que contenga un ScriptSIG con una firma generada usando la misma clave
privada que había originado la
clave pública que se originó la dirección que recibió
Bitcoins previamente. Detalles de la firma de una transacción los
veremos en un video futuro. La clave pública citada
anteriormente se
agregará después de la firma
en el campo ScriptSiG. Finalmente, la entrada también hará referencia a la salida de
transacción no gastada utilizando el ID de transacción anterior y los campos de índice de
salida de transacción anterior como se explicó anteriormente. Ahora aprendamos el importante
concepto del conjunto UTXO. Recuerde que UTXO significa salida de transacción
no gastada. Bitcoin tiene la característica
importante de no permitir el doble gasto. En otras palabras, solo
puedes gastar Bitcoins de salidas de
transacciones no gastadas. El conjunto UTXO es el conjunto de
todos los UTXO existentes actualmente. Este conjunto es almacenado por nodos en una base de datos separada que permite una rápida
recuperación por monederos. El conjunto UTXO se actualiza
constantemente con cada nueva transacción agregando y eliminando salidas hacia
y desde el conjunto. utxos son salidas a las que nunca
se hizo referencia
en ninguna entrada todavía. Por lo tanto, el conjunto UTXO contiene todas las monedas
disponibles para ser gastadas. El número de bitcoins
en una dirección es igual a la suma
de todos los Bitcoins de
todos los UTXOS cuyas claves de pub de script hacen referencia a la dirección decodificada. Entonces el Bitcoin
Core Node proporciona un método API llamado
list unused que devuelve todos los UTXO que hacen referencia a
las direcciones que le
pasaste como parámetros. Al usar el método list
unused, puede calcular fácilmente el saldo de una
dirección y la información de
transacción descubierta , como el
ID de transacción UTXO y el índice, así
como su script pub key. Para que puedas construir entradas de
transacción para gastar tus Bitcoins
desde el UTXO. Después de gastar el UTXO, se elimina del conjunto UTXO. Ahora veamos un diagrama explicando cómo nuestra
aplicación detectará las transacciones
entrantes
y
nos hará saber sobre los
bitcoins que recibirán. Esa será la última diapositiva
de esta presentación, que ha introducido
mucha información compleja. No te preocupes si no lo
absorviste todo al principio. A lo largo del curso,
estaremos reutilizando la información aprendida para profundizar
en ella, así tendremos muchas oportunidades
para captarla mejor. Ahora, volvamos al diagrama. Aquí tenemos rectángulos
que representan la aplicación son el
nodo Bitcoin y la red Bitcoin. Las transacciones son creadas y difundidas por nodos de
la red Bitcoin. Estas transacciones,
al ser confirmadas, ya
están almacenadas
en la cadena de bloques. Cuando no están confirmados,
permanecen en el templo, una base de datos que contiene todas las transacciones
no confirmadas. Cada nodo tiene una copia de las transacciones mentales eventualmente
son detectadas por nuestros nodos
que ya habían importado nuestras
billeteras y direcciones de aplicaciones. A través de cero notificaciones MQ, las transacciones se
envían a nuestra aplicación. Cuando nuestra aplicación
tenga una billetera cargada, filtrará todas las
transacciones de recepción que no contengan
ninguna de sus direcciones. Entonces enviará una lista llamada
no gastada al nodo, pasando como parámetros
todas las direcciones de
las transacciones de recepción que quedaron después del filtrado. El nodo devolverá todos los UTXOS relacionados con esas direcciones. Nuestra billetera luego
analizará estos UTXO para calcular el saldo de Bitcoin
para cada una de sus direcciones. Después mostraremos la información
obtenida en la tabla de direcciones.
31. 29 Recepción de bitcoin parte 5 skillshare 2: En este video, implementaremos la lista de clientes no gastados
que nos permitirá recopilar información sobre UTXOS después de
recibir transacciones. Así que dentro del paquete de cliente nodo
punto, vamos a crear la
lista de nodos cliente no gastado. Vamos a agregarle una
anotación de Servicio. También inyectemos el cliente del
nodo en él. Ahora vamos a crear el método
de lista no gastada. Devolverá una lista de UTXOS, que es un registro que vamos a crear. Tomará como parámetros una lista de direcciones,
y un nombre de billetera. Vamos a crear el registro UTXO en el paquete BYOD w dot domains. El UTXO contendrá
los siguientes campos. El ID de TX, que es un
acrónimo de ID de transacción. El campo vout, que
representa el índice de salida, la dirección, la etiqueta, que no usaremos en este momento. La clave del pub script. La cantidad que representa
la cantidad de Bitcoin, las conformaciones que
contendrán el número de conformaciones que tiene la transacción
UTXOS. El número de conformaciones de una transacción es el
número de bloques que se agregaron a la cadena de bloques
después de que la transacción se
insertó en un bloque y este bloque se agregó
a la cadena de bloques. Este número incluye el bloque que contiene esa transacción. Entonces, si una transacción
tiene dos confirmaciones, significa que ya estaba
incluida en un bloque. Ese bloque se agregó
a la cadena de bloques y se
agregó otro bloque después de eso. Agreguemos dos campos más. Estos campos no
serán utilizados por ahora, pero pueden ser útiles
en otro tipo de transacciones que
veremos más adelante en el curso. Ellos son el guión de redimir
y el guión testigo. Ahora de vuelta a la
lista de nodos, el cliente no gastado llamará al cliente nodo make request method y
almacenará el resultado en la
variable de matriz UTXOS pasará los siguientes
parámetros al método. Los tres últimos parámetros
formarán parte de la lista de poemas de la API del nodo
Bitcoin. El primero es el número
mínimo de conformaciones que deben tener los UTXOS de
retorno. El segundo es el máximo. Ya que queremos que todos los
UTXOS establecerán cero como mínimo y el valor máximo
entero como máximo. El tercer parámetro es
la lista de direcciones. Ahora, convertiremos
la matriz resultante en una lista usando este
código y la devolveremos. Ahora volvemos a la transacción
recibida oyente. Eliminemos esta línea de código porque era
solo para probar. Vamos a probar la
lista de nodos cliente no utilizado. Consigamos los UTXOS
para estas direcciones. Inyectemos primero al cliente
en esta clase, el método list unused
pasará la variable addresses. El segundo argumento será el nombre de la billetera de la prueba de Bitcoin
receptora. Vamos a copiarlo y usarlo
como segundo parámetro. Ahora, agreguemos
esta línea para imprimir cada UTXO obtenido
en la pantalla. Ahora, ejecutemos nuestro nodo Bitcoin si aún no se está ejecutando. Ahora, vayamos a la prueba de recibir
Bitcoin y ejecutarla. En los registros de prueba, vemos que imprimió un
UTXO con todos sus datos. Observe que su
dirección es la
misma que la
dirección receptora de nuestra billetera. Rebobinar el video para comprobarlo. El monto es uno, que se espera porque es el mismo monto de Bitcoin
enviado y la prueba, tiene cero
conformaciones porque ningún bloque recuerda después del
nodo desde la transacción. Ahora vamos a eliminar estas líneas porque eran
sólo para probar. También eliminemos el
cliente inyectado de esta clase. Ahora, agregaremos un
filtro a esta transmisión. Queremos procesar
solo las transacciones de la
cartera actualmente cargada por la aplicación. Este filtro será el
responsable de ello. El filtro comprobará si
la dirección no está vacía. Si la cartera actual
contiene esa dirección. Entonces, vamos a inyectar la
cartera actual en esta clase. Entonces llamaremos a las
direcciones get como método de cadenas. Después comprobaremos si
contiene la dirección. Oh, aquí faltaba una letra S. Ahora vamos a crear el método get
addresses como cadenas. Devolverá una lista de cadenas. El valor devuelto
resultará de llamar
al método get addresses como cadenas en el campo
addresses que crearemos. Así que vamos a crear este campo. Tendrá una nueva
clase de direcciones como su tipo. Y lo
inicializaremos aquí mismo. Vamos a crearlo en el paquete
observables. También vamos a crear sus
direcciones get como método de cadenas. Primero, agregaremos un campo de direcciones
privadas. Será un mapa donde
el tipo de clave será un tipo de dirección y el tipo de los valores
será otro mapa. El segundo mapa será
un HashMap vinculado con cadenas como claves y dirección
como el tipo de sus valores. Usaremos esta estructura de datos
para almacenar las direcciones. La razón para usar
esta estructura de datos es que nos
permite separar y consultar las direcciones de
la billetera
por tipo de dirección. El segundo mapa es un HashMap
vinculado porque este tipo de mapa mantiene
el orden de inserción. Finalmente, el segundo
mapa nos permite consultar la lista de objetos de dirección por sus secuencias de cadenas de direcciones. Ahora en el método get addresses as strings devolverá
el siguiente código. La función FlatMap se
utilizará para obtener todas las direcciones en el segundo conjunto de claves de mapa y devolver una secuencia
que contenga todas ellas. Luego convertiremos la cadena
resultante en una lista. Ok, Ahora podemos usar
el método get addresses como strings para obtener todas las direcciones creadas
para la cartera actual. Pero falta una cosa. También tenemos que rellenar el campo direcciones desde
la clase direcciones. Para ello, agregaremos el
siguiente código en la actualización. servicio de billetera actual
establecerá las direcciones actuales de
billetera, pasando las claves de
pub extendidas de billetera como parámetro. Ahora vamos a crear el método actual de direcciones de conjunto de
billeteras. Llamará al
método set addresses del campo addresses, pasando las
claves extendidas como parámetro. Después crearemos este método
en la clase addresses. Vamos a agregarle el
siguiente código. Usaremos la
función collect para obtener un mapa de las llaves
extendidas del pub. En su interior se agregará una llamada
al método de mapa. Su primer argumento construirá un tipo de dirección usando el campo tipo de clave pub
extendido. Este argumento define la
clave del mapa resultante. El segundo argumento
definirá el valor
del mapa y contendrá
el siguiente código. Nuevamente, al combinar
las
funciones collect y to map lo configurará
como un Hashmap vinculado. Las claves serán las secuencias de
cadenas de direcciones de claves de pub
extendidas , y los valores estarán allí objetos de dirección
correspondientes. Finalmente, se completa la parte filtrante de
esta corriente. En el siguiente video, usaremos lo que hemos construido
para seguir construyendo la
función C receptora de Bitcoins, sí.
32. 30 Recepción de bitcoin parte 6 skillshare 2: En este video,
pondremos en proceso los UTXOS de las transacciones
que llegan a nuestra billetera. Entonces, en el método de
evento no de aplicación, en el oyente de transacción
recibida, agreguemos la siguiente declaración
if. Si la
lista de direcciones no está vacía, entonces llamaremos al método
update en el
servicio update utxOS que crearemos. Este método
tomará como parámetros las direcciones, el
nombre de la billetera actual. Inyectemos este
servicio en esta clase. Ahora, vamos a crear este servicio en el paquete de servicios punto GUI. Vamos a agregarle la
anotación de servicio. Volver a la transacción
recibida oyente. Terminemos de inyectar
el servicio. Ahora, vamos a crear
el método de actualización en el servicio de actualización UTXOS. Añadiremos una
anotación asíncrona a este método y la ejecutaremos en el subproceso de servicio de
ejecutor predeterminado. La razón para
ejecutar este método y otro hilo es que
llamará al
método API de nodo no gastado de lista, que puede ser lento. Así que lo ejecutaremos asincrónicamente
para evitar bloquear la interfaz de usuario. En el método update llamará
al método list unused desde el cliente no gastado de la lista de nodos. Inyectemos al cliente
en esta clase. Pasaremos las direcciones y el nombre de la billetera como
parámetros a la lista. El método no gastado almacenará el resultado de la
llamada al método en la variable UTXOS. Ahora, inyectaremos una nueva actualización, servicio
actual de direcciones de billetera en esta clase. Vamos a crearlo en el paquete de servicios GUI
dots. Terminemos de inyectar
el servicio. Después llamaremos
al método update pasando UTXOS como
parámetro al mismo. Vamos a crear este método. Vamos a agregarle la
anotación de servicios. Ahora, agregaremos el
siguiente código para crear un mapa
donde las claves son direcciones y los
valores son listas de UTXOS que contienen
esas direcciones. Para ello, llamaremos al método collect
en
el stream UTXO, le pasaremos los colectores
agrupando la llamada MyMethod. Pasando el
método de dirección UTXO como su parámetro. Almacenaremos el valor
devuelto en la variable de grupo UTXOS. Entonces para cada grupo par de valores clave
UTXO establecerá el saldo de
dirección correspondiente. Se trata de confirmaciones
y se utiliza mercado. Implementemos el método
de saldo establecido. Devolverá la suma de todos los montos
UTXOS usando este código. Usando el método map to double
en el flujo de lista UTXO, se obtendrá un stream con todas las cantidades UTXO
de la lista UTXO. Para obtener su suma
simplemente se llamará al
método sum en el resultado. Ahora, vamos a inyectar la
cartera actual en esta clase. Entonces llamaremos
al método balanceado de direcciones de
conjunto de billetera actual , que creará pasar la dirección y la
suma como sus parámetros. Vamos a crearlo. En su interior se llamará al método de
dirección del conjunto de direcciones balanceado, pasándole los mismos
parámetros. Entonces crearemos este método. En su interior se llamará a
las direcciones get como método de mapa, que creará.
Vamos a crearlo. Devolverá un mapa donde
las claves son direcciones, cadenas y los valores
se abordan como objetos. Mediante el uso del siguiente código se devolverá un mapa que contiene
todas las direcciones. Al llamar al método de cadena
en las direcciones, los valores se obtendrá un flujo que contiene todos los mapas del campo privado de
direcciones. Entonces con esta llamada al
método FlatMap se convertirá el flujo de mapas
en un flujo de entradas de mapa. Finalmente, utilizando el método
collect en el stream resultante y el método de dos mapas
con estos parámetros se obtendrá el mapa deseado. En el resultado de las
direcciones get como map call llamará
al método get para obtener
un objeto address por su cadena de direcciones. Después estableceremos el
saldo de direcciones a la variable sum. Ahora, vamos a crear el método
set balance en el registro de direcciones. Ups, no podemos agregar
setters en un registro, así que tendremos que convertir el registro de
dirección en una clase. Hagámoslo con un poco de
ayuda de nuestro IDE. Eliminemos estos métodos
porque no los vamos a necesitar. Vamos a crear el centro de
equilibrio ahora. Y eliminar la palabra clave
final aquí. En el generador
secuencial de direcciones. Vamos a agregar cero como tercer parámetro en la instanciación de
direcciones aquí. Cambiemos también
el nombre de los getters, haciéndolos comenzar con get. Ahora en el servicio de actualización de direcciones de
billetera actual, vamos a crear el método de
confirmaciones establecidas. Confirmación. En este caso, nos referiremos al saldo de
direcciones y se definirá como
igual al número de conformaciones del UTXO con menos conformaciones
para esa dirección. Por ejemplo, digamos que una dirección tiene un saldo
de dos Bitcoins, cada Bitcoin proviene de
una transacción diferente. Una de estas transacciones
tiene dos confirmaciones, la otra solo tiene una. En este caso,
consideraremos que el saldo de direcciones
tiene una conformación. Para lograrlo,
usaremos el siguiente código. Obtendremos un stream que contiene todas las confirmaciones de
la lista de UTXOS pasada. Para obtener este flujo, llamaremos al método map
too long en el flujo de lista UTXO, pasando
como parámetro la referencia del
método de confirmaciones UTXO . Entonces mediante el uso del método Min y el
método bueno es largo devolverá el número mínimo
de confirmaciones en el stream y lo almacenará en
la variable de confirmaciones. Luego pasaremos
las confirmaciones y las variables de dirección a
la llamada actual
del método de
confirmaciones de direcciones del conjunto de billetera. Ahora vamos a crear este método
en la clase de billetera actual. Llamará al método de
confirmaciones de direcciones del
conjunto de direcciones, pasando los mismos
parámetros que recibieron. Vamos a crear este método
en la clase addresses. Usaremos el método get
addresses como método de mapa para obtener la dirección y
establecer sus conformaciones. Ahora, vamos a crear el método
set confirmations en la clase address. Lo usaremos para establecer el campo de
confirmaciones que crearemos. Vamos a crear este campo y
agregarlo al constructor. Entonces agreguemos este parámetro a la clase de
generador secuencial direcciones
en la instanciación de direcciones. Por último, vamos a crear
el
método de marca se utiliza en el servicio de actualización de direcciones de
cartera actual. Uno de los objetivos de
nuestro monedero y muchos otros es evitar reutilizar direcciones
al recibir Bitcoins. Por razones de privacidad. Para ello, primero debemos comercializar vestidos que tenían
transacciones a él como se usaban. La marca como método utilizado
se utilizará para esa visión. Se llamará al actual vestido de mercado
monedero. Como método utilizado se creará pasando la dirección
como su parámetro. Vamos a crearlo. En su interior llamará a la
marca se usa método de la clase de direcciones
pasando la dirección a la misma. Entonces crearemos este método. En su interior utilizará
las direcciones get como método
matemático para obtener la
dirección y se utiliza el mercado. Por último, vamos a crear el método mark se utiliza en
la clase address. Aquí simplemente establecerá
el combustible usado es cierto. Vamos a crear este
campo en esta clase.
33. 31 Recepción de bitcoin parte 7 skillshare 2: En este video, finalmente
conectaremos todo lo que hicimos en las últimas lecciones para mostrar información de
nuestras direcciones
en la pantalla. Así que en el paquete observables se creará la clase de fila de
direcciones. Como su nombre indica, esta clase modelará una
fila en la tabla de direcciones. Vamos a crear los siguientes
campos en esta clase, cada uno para una columna en
la tabla de direcciones. El primer campo será una propiedad de
cadena llamada balance, instanciará aquí con una nueva propiedad de cadena simple. El siguiente campo será una propiedad larga
llamada confirmaciones, y se instanciará con una nueva propiedad larga simple. El último campo será una propiedad de
cadena llamada address. Se instanciará con una
nueva propiedad de cadena simple. Ahora, con la ayuda del IDE, vamos a crear getters
para cada propiedad. Observe que al hacer getters para campos de propiedad Java FX, el IDE crea dos getters, uno para la propiedad y otro para el contenido
de la propiedad. Ahora, vamos a crear el siguiente constructor
para esta clase. Bien, ahora que hemos
modelado la fila de direcciones, vamos a crear código para
rellenarla al actualizar nuestras direcciones. Para ello, vayamos al servicio de
actualización actual de direcciones de monedero. En el método update, después de marcar la
dirección como utilizada, llamemos al método set address row en la billetera
actual, pasando la dirección
como parámetro. Entonces vamos a crear el método
set address row. Para implementar este
método se agregará el
campo de filas de direcciones a esta clase. Vamos a crear la clase de filas de
direcciones en el paquete observables. Vamos a instanciarlo aquí. Ahora vamos a llamar al método set
address row en la propiedad address rows le pasará un
objeto address. Este objeto se obtendrá del campo addresses usando el método get addressed que
crearemos pasándole la cadena de
direcciones. Para crear este método simplemente
seleccionaremos este fragmento de código y extraerá un método de él usando el ID. Sustituyamos todas las
ocurrencias de código con este método, y haremos público el método
generado. Ahora volvemos a la
actual clase de cartera. Vamos a crear el método set
address row en la clase address rows. Para ello,
crearemos una
variable de fila de dirección llamando al método
en la clase address row, pasando el
objeto address como parámetro. Vamos a crear el método form
en la clase de fila de direcciones. Devolverá una nueva fila de direcciones, instanciándola con
estos parámetros. Vamos a crear el método de buenas
confirmaciones en la clase address. Y ahora podemos usarlo aquí. Observe que aquí simplemente estamos creando un objeto de
fila de direcciones
convirtiendo los valores de campo de
dirección en
los valores de campo de fila de dirección. Volver a la clase de filas de direcciones. Crearemos el campo de
conjunto de carreteras de dirección en esta clase. Será un conjunto observable con la fila de direcciones como
parámetro de tipo. Lo instanciará aquí con un nuevo envoltorio de
conjunto observable, pasando un nuevo
conjunto hash vinculado a su constructor. Este objeto
publicará un evento por cada nueva dirección insertada
o eliminada y
será necesario actualizar
la tabla de direcciones a medida que la cartera actual
reciba nuevas transacciones. Ahora llamaremos al método address
row set remove, pasando la
fila de direcciones como su parámetro. Después llamaremos al método
add en él, pasando la misma
fila de direcciones que su parámetro. Quizás te preguntes por qué
estamos eliminando y agregando la misma
fila de direcciones en el conjunto. Bueno, esto es un poco pirateo. Si no eliminamos primero la fila de
direcciones e insertamos una fila de direcciones que ya
está en el conjunto. El conjunto observable
no publicará ningún evento que
indique que se le agregó una
fila de direcciones. Hay otra cosa que
tenemos que hacer para que esto funcione. Cuando eliminamos una fila
de direcciones del conjunto usando
el método remove, este método utilizará
el método equals de la fila de direcciones para definir qué fila de direcciones
eliminará del conjunto. Consideraremos que las
dos filas de vestir son iguales si tienen
la misma dirección. Por lo tanto, debemos implementar
el método equals en la
clase de fila de direcciones. Hagámoslo. Añadiremos los métodos de código equals y hash usando
esta función IDE. Asegúrese de que esta
casilla de verificación esté activada para generar métodos
usando getters. Ahora, elegiremos usar solo el campo address para
generar el método equals. Y el mismo campo para generar el método hashCode y seleccionar el campo address aquí para
definirlo como no nulo. Bien, el IDE ha generado los métodos de código equals
y hash. Ahora vamos a la tabla de
direcciones. Fxml agregará ID de FX a cada
etiqueta de columna de tabla. Las direcciones. El controlador de tabla necesitará estos ID de FX para unir y
manipular estas columnas más adelante. Primero la dirección de la columna, luego el saldo de la columna, y finalmente las conformaciones de
columna. Ahora vamos a ir a la tabla de direcciones el controlador agregará los siguientes campos, cada uno correspondiente
a una etiqueta con un ID de ética en la tabla de
direcciones, FXML. Los nombres de estos
campos deben ser iguales a los FX ID de las etiquetas.
Están destinados a. Primero la tabla de direcciones, luego la dirección de la columna, el saldo de la columna y las confirmaciones de columna. Ahora agregaremos el
método inicializado a esta clase. Recuerde que los métodos
inicializados en los controladores
Java FX
se llaman Cuando el framework está inicializando
estos controladores. En este método,
agregaremos código que vinculará la tabla de direcciones y sus columnas con nuestro rol de
dirección observables. Para ello, llamaremos al
método set items en la tabla de direcciones ya que su argumento pasará
una nueva lista filtrada. Esto es necesario
porque queremos mostrar solo direcciones con un equilibrado mayor que cero en
la tabla de direcciones. Como el primer parámetro de
lista filtrada
pasará las filas de direcciones
observables actuales de la billetera. Entonces, vamos a inyectar la
cartera actual en esta clase. Entonces llamaremos al método get observable address
rows en él. Vamos a crear este método. Devolverá una lista observable con la fila de direcciones como
parámetro de tipo. Luego devolveremos la llamada al
método de filas de direcciones
observables buenas en el campo de filas de
direcciones. Vamos a crear este método
en la clase de filas de direcciones. En su interior devolverá el
campo de lista de filas de direcciones que vamos a crear. Vamos a crearlo. Este campo se
instanciará aquí con un nuevo envoltorio de lista observable pasando una lista enlazada
como parámetro. Ahora, tenemos que hacer que la lista
observable responda a inserciones y eliminaciones de filas de direcciones en el conjunto de filas de
direcciones. Eso lo haremos en el constructor de la
clase. Primero, crearemos una variable de escucha de
cambio de conjunto. Lo estableceremos como esta función
lambda. El parámetro change
aquí representa una inserción o eliminación de
una fila de direcciones en el conjunto. Si el cambio fue una eliminación, entonces eliminaremos
el elemento removido de la lista de filas de direcciones. Si el cambio fue una inserción. Luego agregaremos el elemento agregado a la lista de roles de dirección. Finalmente, agregaremos
este oyente al conjunto
de filas de direcciones
usando este método. Ahora volvamos al controlador de la
tabla de direcciones. El segundo parámetro de
la lista filtrada se utiliza como condición de filtro
para mostrar filas. Será una función lambda con un parámetro address rho. El cuerpo de la función
será este código que
verificará si el
saldo de fila de dirección es mayor que cero. De esa manera, logramos
nuestro objetivo de
mostrar únicamente direcciones con un
equilibrado superior a cero. Ahora, para cada campo de columna, tenemos que establecer una fábrica de
valores de celda que se
utilizará para poblar cada celda
de la tabla de direcciones. Para ello, usaremos
el siguiente código. La fábrica de valor de propiedad se
utilizará para obtener cada dirección propiedad
real y vincular su valor a su celda
correspondiente. Sabe qué dirección
inmobiliaria queremos enlazar a la columna haciendo coincidir el nombre que
estamos pasando como parámetro con el
nombre de la propiedad. Hay una
cosa más que debemos hacer para que nuestra
función de recibir Bitcoin funcione correctamente. Pasemos a la clase de billetera
actual en el método set addresses, que se llama cuando se crea una
nueva billetera, tenemos que incluir este código
para asegurarnos de que la dirección elevó de una previamente
cartera creada se borra. Llamaremos al método address rows clear, que creará. Para ello, vamos a
crearlo. Aquí. Simplemente llamaremos al método clear en
el conjunto de filas de direcciones y
la lista de filas de direcciones. Ahora probemos nuestra función. Asegúrate de que tu nodo
central de Bitcoin esté funcionando. Vayamos a la prueba de recibir
Bitcoin y ejecutarla. Genial, funcionó. Observe que la primera fila de la tabla de direcciones se llenó correctamente con un saldo de
un Bitcoin como se esperaba. Buen trabajo. En los próximos videos, agregaremos más
casos de prueba para asegurarnos de que nuestra función de recepción de Bitcoin funcione correctamente en
diferentes escenarios.
34. 32 Recepción de bitcoin parte 8 skillshare 2: En este video, agregaremos
más casos de prueba para asegurarnos de que nuestra
función de recepción de Bitcoin funcione correctamente en
diferentes escenarios. El primer
escenario adicional probaremos si la misma dirección puede recibir Bitcoins de dos transacciones, una Bitcoin de cada una. Comprobaremos el saldo de la dirección
se actualiza a dos bitcoins. Entonces vamos a copiar el contenido de este método y
pegarlo a continuación. Modifiquemos el
nombre de la prueba para recibir Bitcoins en dos transacciones
a la misma dirección. Ahora, seleccionemos este código y extraigamos un método de él
con la ayuda del id vamos a nombrarlo, enviar
Bitcoin y peso. Llamaremos a este método dos
veces ya que queremos
enviar a transacciones
a esta dirección. Modifiquemos el método send Bitcoin in weight incluyendo
el siguiente código. Comprobaremos si la dirección en la primera fila de la tabla tiene un parámetro balanceado igual al monto
total esperado. Agreguemos este parámetro
a la firma del método. Tendrá un
valor predeterminado de 1.0. En esta llamada al método, agreguemos 2.0 como
segundo parámetro, ya que esperamos que
el saldo de direcciones sea igual a dos. Agreguemos dos al nombre
de la billetera. Hay un problema con
nuestro entorno de prueba. En la prueba reg,
solo es posible extraer 15 mil bloques con recompensas de
bloque. Por lo tanto, en este método, es demasiado
minar 1,000 bloques al llamar al método generate
to address. Solo llamémoslo si el
saldo de la billetera de prueba es menor 50 y generará solo
150 bloques por cada llamada. De esa manera, evitamos la necesidad de
restablecer nuestro
entorno de prueba reg con demasiada frecuencia. También sustituyamos este código con el método send Bitcoin
and wait. Ahora, hagamos que nuestras pruebas sean un poco más resistentes
a las condiciones de la carrera. Me he dado cuenta de que
a veces estas pruebas envían bitcoins a nuestras billeteras de
aplicaciones antes de que estuvieran completamente cargadas. Por lo tanto, estas transacciones no
fueron capturadas por la aplicación y las
pruebas fallan por ese motivo. Entonces después de crear una billetera y antes de enviarles
Bitcoins, llamemos al método sleep
con estos parámetros. La llamada al método sleep hará que la aplicación
espere 10 s antes enviar Bitcoins el tiempo suficiente para que la nueva billetera
se cargue por completo. Dependiendo de su computadora, es posible que necesite aumentar
la constante de tiempo de espera. Ahora, antes de ejecutar las pruebas, restableceré mi entorno
de prueba reg. Necesito hacer eso
porque ya generó 15 mil bloques y la generación de bloques ya
no está produciendo
Bitcoins. Entonces iré a la carpeta
donde está
almacenada la cadena de bloques y eliminaré la carpeta reg
test dentro de ella. En tu caso, puedes encontrar
qué carpeta se encuentra
comprobando el valor DIR de datos
en tu archivo bitcoin.com. Ahora, ejecutemos nuestro nodo Bitcoin y ejecutemos nuestras pruebas de recepción de
Bitcoin. Genial, las pruebas han pasado. Cuando recibamos
Bitcoins en nuestra billetera, queremos que se cambie la siguiente
dirección de recepción. De esa manera evitamos
reutilizar direcciones. Es importante
usar solo una dirección para recibir
transacciones para que un tercero pueda rastrear fácilmente cuántos Bitcoins tiene y con
qué direcciones realiza
transacciones. Para cubrir este escenario, vamos a crear la siguiente prueba. Copia la última prueba
y pégala a continuación. Vamos a cambiarle el nombre a
debería recibir Bitcoins en dos transacciones, dos direcciones
diferentes. Cambiemos el nombre de la billetera
creada a mi billetera de prueba tres. Ahora antes de la segunda llamada al método de envío de
Bitcoin y espera, agreguemos este código para
volver a consultar
el campo de dirección de recepción y almacenar su contenido
en la siguiente variable de dirección. Ahora, cambie el
primer parámetro de este método a la
siguiente variable de dirección. Y esperamos que el monto
total de Bitcoin para esta dirección
sea igual a 1.0. Además, esperamos que
el tamaño de los elementos de la tabla sea igual a 21
filas por cada dirección. Entonces, modifiquemos este
método para aceptar el
tamaño esperado de la tabla como parámetro. Vamos a
agregarle este parámetro con un valor predeterminado de uno. Sustituirá este
valor aquí
para esperar a que el número de
filas de la tabla sea igual a él. Y sustituiremos el índice de ítems de punto de
tabla por el tamaño
total esperado menos uno para esperar
a que la última fila
del saldo de la tabla sea igual al monto
total esperado para esa fila. Por último, vamos a parametrizar
el tercer argumento de este método llamado a dos. Realicemos nuestras pruebas. Como se esperaba. La tercera prueba falló porque aún no
hemos implementado la función de cambiar la dirección de recepción
después de usarla. Hagámoslo ahora. Así que vayamos al servicio de actualización de
direcciones de monedero
actual. Dentro de esto para cada bloque, llamemos al método de
dirección de recepción de actualización que crearemos. Tomará la dirección
como su parámetro. Vamos a crearlo. Lo primero que
haremos es llamar al método
de tipo get addressed
en la billetera actual. Al pasar la dirección
como su parámetro, se
almacenará el resultado
de la llamada al método en la variable de tipo de dirección. Es importante
conocer el tipo
de dirección de la dirección sustituida, ya que tiene que ser sustituida por una dirección del mismo tipo. Entonces, vamos a crear este método
en la clase de billetera actual. Simplemente
llamará a las direcciones get addressed type method. Crearemos pasando la
dirección como su parámetro. Vamos a crearlo. Ahora. Llamaremos al método get addressed y
devolveremos su tipo de dirección. Vamos a crear el método get
address type en la clase address. En su interior devolverá el
campo de tipo de dirección que vamos a crear. Vamos a crear este campo y
agregarlo al constructor. También arreglemos el generador
secuencial de direcciones para agregar el último argumento a
la instanciación de dirección. Vamos a agregar este tipo de dirección
como parámetro a este método. E incluiremos el
tipo de dirección en esta llamada al método llamando al valor de método
en la clase de tipo dirección. Ahora de vuelta al servicio
Actualizar
direcciones de billetera actuales calculará el valor del siguiente índice de
direcciones llamando
al método fine next address index en la billetera actual, pasando la dirección
type ya que su parámetro almacenará el resultado de la llamada al método en la siguiente variable de índice de
dirección. Vamos a crear este método. Aquí. Llamaremos al
índice de dirección siguiente fino en el campo direcciones, pasando el
tipo de dirección como parámetro. Vamos a crear este
método en la
clase de direcciones con el siguiente código, obtendrá la última dirección utilizada en almacenarlo en la variable
address. Obtendrá todos esos objetos de
vestir con el tipo de dirección dado
y obtendrá una transmisión de ella. Después ordenaremos el
flujo obtenido usando el método ordenado con
los siguientes parámetros. Se utilizará el método de comparación de
puntos del comparador, pasando el método address
get indexed como primer parámetro y el
comparador de orden inverso como el segundo. De esa manera obtendremos un flujo de direcciones
ordenado en sentido inverso por sus índices. Ahora, filtraremos
la secuencia para obtener una cadena que contenga
solo direcciones usadas. Para ello, vamos a
crear un getter para el campo usado en
la clase address. Usaron getter se llama se
usa porque así es como el IDE nombra getters
booleanos de vuelta a
la clase addresses
pasarán las direcciones utilizadas método como el prompt a la llamada al método
filter. Ahora llamaremos al
primer método fino sobre el resultado. Para obtener la primera dirección utilizada y la secuencia ordenada invertida, que es igual a la
última utilizada para direccionar. ¿Qué pasa si no se encuentran direcciones usadas? En este caso, usaremos el método
or else para devolver null. Añadiremos la siguiente declaración
if. Si la dirección obtenida es nula, entonces volveremos cero
como el siguiente índice. Si no es así, devolveremos el
último índice de direcciones más uno. Ahora, de vuelta al
servicio Actualizar direcciones de billetera
actuales , obtendrá
la siguiente dirección llamando al método get
address ID en la billetera actual. Pasaremos el
siguiente índice de dirección y el
tipo de dirección como parámetros. Vamos a crear este método
en la cartera actual. Volverán, obtienen la llamada al método de identificación de
dirección en el campo direcciones, pasando los mismos
argumentos recibidos que sus parámetros. Vamos a crear este método
en la clase addresses. Obtendrá todos esos
objetos de vestir con el tipo de dirección
dado. Después lo convertiremos en una lista. Entonces obtendremos la
dirección por índice. Para ello, necesitamos cambiar el tipo de índice de dirección
a un objeto largo, no solo de tipo primitivo. Y luego llamaremos
al valor int, pasándolo como el parámetro
getMethod. Ahora devolveremos
la cadena
de dirección de la dirección obtenida. Ahora, de vuelta al servicio Actualizar direcciones de
billetera actuales simplemente
configurará
la dirección de
recepción de billetera actual como la siguiente dirección
obtenida. Hagamos una cosa más
antes de probar nuestro código. Recuerda que el codón, esta clase se ejecutará
en un nuevo hilo. En Java FX, es
una buena práctica ejecutar código que modifique la interfaz de usuario
solo en el hilo principal. Para ello, llamemos
al método platform dot run later pasándole una función
Lambda. Movamos estas dos
líneas al cuerpo de
la función lambda ya que provocan cambios que
afectarán a la IU. Ahora, volvamos a ejecutar nuestras pruebas de recepción de
Bitcoin. Genial. El
campo de dirección de recepción se actualizó después recibir fondos y
las pruebas han pasado. En el siguiente video,
seguiremos mejorando nuestras pruebas y agregaremos un escenario de prueba
más. C, sí.
35. 33 Recibiendo bitcoin parte 9 skillshare 2: En este video, seguiremos
mejorando nuestras pruebas y agregaremos un escenario de prueba más importante para la función receptora de
Bitcoin. Una cosa falta
en nuestras pruebas. Aún no sabemos si
se están generando las direcciones correctas se están generando y si están respetando la secuencia del
índice de ruta de derivación. Para comprobarlo, vamos a crear
la dirección es método válido. Entonces bloque de la
primera prueba llamada la dirección es método válido
pasando la dirección, la semilla mnemotécnica y el índice de dirección
esperado, que en este caso es
cero como sus parámetros. Vamos a crear este método. Devolverá un booleano. Vamos a establecer los nombres de
parámetros correctos. Aquí. Crearemos un nuevo objeto semilla
mnemotécnico y lo almacenaremos en la variable semilla
mnemónica. Cambiemos el nombre del parámetro de semilla
mnemotécnico a la cadena de semillas mnemotécnicas. Ahora instanciaremos
el objeto semilla mnemotécnico pasando la cadena semilla mnemónica como parámetro constructor. Ahora, vamos a crear la
clave maestra con el siguiente código. Llamará al método de dos claves
maestras en el objeto semilla mnemotécnico, pasando una cadena vacía como primer parámetro y el
prefijo privado de red principal como el segundo. Ahora vamos a crear
la cadena extendida de la
clave pub con el
siguiente código. Usaremos el servicio extendido de llaves de
pub. Así que vamos a
inyectarlo en esta clase. Entonces llamaremos al método
create en él, pasando la clave maestra
como su primer parámetro. El segundo parámetro será una concatenación entre parte de
la ruta de derivación de dirección de segmento y el parámetro de índice. Cambiemos el tipo de parámetro
index a la clase integer, así podemos llamar al método
toString en él. El tercer parámetro será la constante
Segway tipo dirección. Entonces llamaremos al método get
key sobre el resultado. Ahora, obtendremos el objeto de clave pub
extendido de la
biblioteca Java de Bitcoin usando la clave de pub extendida
en el método serializado, pasando la cadena de clave
pub extendida como su parámetro obtendrá la dirección esperada usando el generador de direcciones de
segmento. Vamos a inyectarlo en esta clase. Luego llamaremos al método
generate en él, pasando la
clave pub extendida como su parámetro. Finalmente, devolveremos el
resultado de comparar si la dirección esperada es igual
al parámetro address. Ahora vamos a agregar la dirección
es válida llamada al método para verificar las direcciones en los
otros métodos de esta clase. En este método, vamos a
agregarlo dos veces. La segunda vez comprobaremos
si la siguiente dirección es igual a la
dirección esperada con el índice uno. Realicemos nuestras pruebas. Genial, las pruebas han pasado. Ahora sabemos que las direcciones se están generando correctamente. Ahora vamos a crear otra prueba. La siguiente prueba
intentará transferir más transacciones que el
número de direcciones generadas. Recuerda que hemos establecido el número inicial de direcciones
generadas en 20. Por lo que debemos verificar
qué sucede cuando se utilizan
todas
las direcciones generadas inicialmente. Pero ejecutar una prueba con 20 transacciones
llevaría mucho tiempo. Entonces cambiaremos el número
inicial de direcciones
generadas en
el entorno de prueba a tres más tarde para
acelerar las cosas. Así que vamos a copiar este método
y pegarlo a continuación. Cambiar su nombre
a debería recibir Bitcoin en siete transacciones a diferentes direcciones
con tres direcciones generadas en nuestra billetera y siete transacciones en esta prueba, nuestra billetera necesitaría para
generar cuatro direcciones más que el número inicial
para que pase esta prueba. Cambiemos el nombre de la
billetera creada por mi billetera de prueba. Por ahora, crearemos
un archivo de propiedades para el entorno de prueba para cambiar el número inicial de
direcciones generadas para nuestras pruebas. Así que vamos a crear una
ruta de recursos dentro del paquete de prueba. Seleccione la
opción Recursos a continuación. En su interior se creará un archivo llamado application
test dot properties. Copiaremos el contenido de nuestro
archivo de propiedades de punto de
aplicación y lo pegaremos aquí. Ahora vamos a establecer el número
inicial de propiedad de direcciones
generadas en tres. Ahora vamos a la clase de
configuración de direcciones. El número inicial de direcciones
generadas método actualmente
está devolviendo 20 inyectará este valor
en esta clase desde el archivo de propiedades utilizando
esta anotación de valor y este campo privado. Ahora en este método sólo
devolverá el campo creado. Ahora para usar propiedades de la aplicación probar archivos de
propiedades de punto en nuestras pruebas. Vamos a la clase de prueba GUI. Añádele esta anotación. Bien, ahora cada archivo de prueba que
extienda la prueba GUI
obtendrá sus propiedades
del archivo de propiedades de punto de prueba de aplicación. Ahora volvamos a nuestra última prueba. Cambiemos el nombre de esta
variable a la primera dirección. El nombre de esta variable
a la segunda dirección. Ahora copiemos estas
líneas y generemos cuatro transacciones más para formar direcciones
más recién generadas, modificando su
código en consecuencia. Cambiemos el tamaño esperado de la fila de la
tabla a siete. Copiemos estas líneas también para validar todas las direcciones
generadas en la prueba. Cambiemos los
parámetros de los métodos según sea necesario. Ahora, hagamos nuestras pruebas. Como se esperaba. La
última prueba ha fallado después de la tercera transacción que ocurrió porque la
billetera no pudo encontrar la cuarta dirección ya que generó solo las tres
primeras direcciones. En el siguiente video, lo
arreglaremos. Antes de terminar el video, agreguemos el número inicial de propiedades
de direcciones
generadas al archivo de propiedades de
punto de la aplicación. Vamos a establecerlo en 20 para
que la billetera
funcione como antes en el entorno
no de prueba.
36. 34 Recepción de bitcoin parte 10 skillshare 2: En este video, haremos
nuestro último pase de prueba creado. Para ello, vayamos al servicio de
actualización actual de direcciones de monedero. En este método, agreguemos
la siguiente declaración if. Después de calcular el
siguiente índice de dirección. Dentro de la sentencia if, los
llamaremos método must
import addresses pasando el siguiente
índice de direcciones y el tipo de dirección. Vamos a crear este método. Solo importará direcciones si el siguiente
índice de direcciones es igual
al número total de direcciones en la billetera actual con
un tipo de dirección dado. Si ese es el caso,
significa que nos quedamos sin direcciones y así no podemos rellenar la
siguiente dirección para nuestra billetera sin
crear más direcciones. Dentro de este método
devolverá el resultado de verificar si el siguiente índice de
direcciones es igual
al actual wallet
get addresses count method call pasará el tipo de
dirección a este método. Y vamos a crear este método. Este método devolverá un int y
devolverá las direcciones, obtendrá adresses count method call, pasando el
tipo de dirección como su parámetro. Vamos a crear este método. Aquí simplemente
obtendremos todas las direcciones con el tipo de dirección dado
en una lista y devolveremos el tamaño de la lista al servicio Actualizar direcciones de
billetera actuales. En el bloque if primero obtendrá las billeteras actuales
extendidas las claves de pub, y las almacenará en una variable. Vamos a crear este método. Aquí. Regresaremos el campo
extendido de llaves del pub. Vamos a crearlo. También agreguemos un
setter para este campo. Llamaremos a este conjunto o en el método de actualización del
servicio de billetera actual de actualización. Pasando las billeteras le
extendieron las llaves del pub. Ahora volvamos al servicio Actualizar direcciones de
monedero actuales. Llamaremos al método add
addresses en el servicio de direcciones ADD. Pasando las claves de pub extendidas previamente
obtenidas como su primer parámetro y el siguiente índice de dirección
como su segundo parámetro. Inyectemos este
servicio en esta clase. Vamos a crear este servicio y
el paquete de servicios API. Vamos a agregarle la
anotación de servicio. Ahora, terminemos de inyectar
este servicio a esta clase. Y vamos a crear este método
en el servicio de direcciones de anuncios. Cambiemos este
nombre de parámetro a from index. Lo que planeamos hacer ahora es
generar direcciones para
las claves de pub extendidas que
se pasaron como parámetros. El número de
direcciones generadas será igual
al número inicial de
direcciones generadas campo inyectado. Y el índice de
derivación generado por la primera dirección será determinado por la variable de
índice firme, por ejemplo, supongamos que el número inicial de direcciones
generadas es igual a 20 y la
variable de índice from es igual a 20. En ese caso, este
método
generará vestidos con un
índice de derivación de 20 a 39. Para ello, por cada llave
de pub extendida. Llamaremos al método add
addresses, pasando la clave y el parámetro
from index. Quitemos esta letra S. Ahora, vamos a crear este método de agregar direcciones
privadas. Llamará al método add
addresses en la clave pub extendida
como su parámetro. Utilizaremos el generador
secuencial de direcciones. Entonces vamos a inyectarlo
en esta clase. Llamaremos al método
generate en el generador
secuencial de direcciones, pasando la clave de
pub extendida, el tipo de clave pub extendida y la variable from index
como sus parámetros. Pasemos a la implementación del
método generate. La cambiará para
generar direcciones con índices
de derivación utilizando
el parámetro from index. Entonces agreguemos desde index
como su tercer parámetro. Aquí en el método range
call agregará la variable
from index como
su primer parámetro. Y la suma del parámetro from
index y el número inicial de
direcciones generadas como el segundo. Ahora volvamos al servicio de
direcciones ADD. Vamos a crear el método de
direcciones de anuncios en la clase de clave de pub extendida. Arreglemos este nombre de parámetro. Aquí. Llamaremos al método addresses add all pasándole el parámetro
addresses. Hay un problema
con este código. El campo direcciones es de tipo
list, que es inmutable. Eso significa que
cuando intentemos agregarle elementos a través
del método add all, arrojará un error. Entonces vamos a cambiarlo
al tipo ArrayList,
que es mutable. Hagámoslo también definitivo
e instanciado aquí. Cambiemos también el getter de
direcciones y el método addresses para
obtener y establecer una ArrayList. También eliminemos
el
método set addresses ya que ya no lo
usaremos. Volver al servicio de agregar
direcciones. Vamos a envolver el resultado de
llamada al método generate en una nueva ArrayList, ya que el método de direcciones de anuncios ahora acepta solo una ArrayList. Ahora vamos a ejecutar factores que
crean el servicio de monedero. Ya que hemos hecho
cambios que afectaron. Primero, eliminemos el
servicio generador secuencial de direcciones de esta clase. También eliminemos este método. Eliminemos esta línea de código. Usaremos el servicio de agregar
direcciones para agregar direcciones a las llaves de pub
extendidas. Entonces vamos a inyectarlo
en esta clase. Y llamemos al método add
addresses en él, pasando las claves de pub extendidas
y cero como sus parámetros. Terminemos de
inyectarlo en esta clase. Ahora volvamos al servicio Actualizar direcciones de
monedero actuales. Llamaremos al
método set addresses en la billetera actual, pasando las
claves de pub extendidas como su parámetro. Vamos a eliminar las filas de
direcciones
método clear call en los métodos set
addresses ya que no
queremos eliminar
ninguna fila de tabla de direcciones después de establecer estas direcciones. En su lugar, vamos
a crear un método llamado clear address rows,
que hará eso. Luego, en el método de actualización del servicio de
billetera actual de actualización, llamaremos a este método para borrar las filas de direcciones solo
después de agregar una nueva billetera. Ahora de vuelta al servicio
Actualizar
direcciones actuales de billetera obtendrá todas las direcciones recién
generadas en la billetera actual y
las almacenará en esta variable. Para obtener las direcciones se llamará
al método get addresses como cadenas en
la billetera actual. Pasando el siguiente
índice de dirección como su primer parámetro. Y la suma del
siguiente índice de direcciones y el número inicial de direcciones generadas campo
como segundo parámetro. Inyectemos este
campo en esta clase. Vamos a agregar la anotación
calificador para usar el bean definido en la clase de
configuración de direcciones para inyectar el valor deseado
en este parámetro. Ahora, vamos a crear este método. Cambiemos estos nombres de
parámetros a de índice dos índice. Este método
devolverá las direcciones, obtendrá direcciones como
método de cadenas de llamada pasando los mismos
parámetros que recibió. Vamos a crear este método
en la clase addresses. Este método devolverá
todas sus direcciones con índices entre los parámetros
del índice dos índice, pero sin incluir la escalera. Para ello, devolverá
el siguiente código. Usaremos el
método FlatMap para convertir todas las direcciones en un
flujo de objetos de dirección. Luego filtraremos
el flujo para que solo devuelvan direcciones con
índice
mayor o igual que la variable de índice
firme y menor que las
dos variables de índice. Después llamaremos a un mapa sobre el resultado para devolver un
flujo de cadenas de direcciones. Finalmente,
convertiremos el resultado a una lista y lo devolveremos. Ahora, de vuelta al servicio
Actualizar
direcciones de billetera actuales , usaremos los clientes de
direcciones de importación múltiple de nodo para importar las direcciones recién generadas
en nuestro nodo Bitcoin. Recuerda que esto
es
necesario porque es necesario que el
nodo conozca
nuestras direcciones para que pueda enviar transacciones
relacionadas a
nuestra cartera de aplicaciones. Entonces vamos a inyectarlo
en esta clase. Ahora llamaremos al método de
direcciones de entrada en él, pasando el nombre de la billetera actual, las cadenas de direcciones y una
nueva fecha como sus parámetros. Genial, nuestra
función de rotación de direcciones debería funcionar ahora, incluso después de que se utilicen todas las direcciones
generadas inicialmente. Pero manejemos
otro tema aquí. Estamos estableciendo la
siguiente dirección como la dirección de recepción
en nuestra billetera. Incluso si se trata de
tipo de dirección es un cambio de dirección. Vamos a arreglar eso. Ya que queremos solo direcciones
con el tipo Segway, no el tipo de cambio Segway se dice como
direcciones receptoras en nuestra billetera. Entonces agregaremos esta declaración if. Si el tipo de dirección es igual a la constante de
dirección principal, lo
que la establecerá en segue. Ahora. Luego estableceremos la
siguiente dirección como la siguiente dirección de recepción
en la billetera actual. Una cosa más, vamos a eliminar
esta plataforma run later call will call the run later method only wrapping the code that will really change the UI. Así que vamos a usarlo para envolver sólo el actual conjunto de cartera de
direcciones roll-call. También utilicémoslo para envolver el conjunto de billetera actual
recibiendo la llamada al método de dirección. De esa manera, evitamos
bloquear la interfaz de usuario mientras comunicamos con
nuestro nodo Bitcoin en la llamada al método import
addresses. Ahora vamos al controlador de la tabla de
direcciones. He notado que el
TableView a veces no se actualiza para reflejar el estado
real de sus filas. Para solucionarlo, agreguemos
este código a este método. Agregará un oyente a las filas actuales de direcciones
observables de la billetera. En el cuerpo de esta
lambda simplemente
llamará al método refresh
en la tabla de direcciones. De esa manera, por cada actualización
en nuestras direcciones de billetera, garantizamos que
la vista de tabla, actualizaremos y mostraremos la información actual de nuestras direcciones de billetera
en la pantalla. Ahora, vayamos a la
prueba del generador
secuencial de direcciones y agreguemos cero como tercer
parámetro del método de generación para que esta
prueba siga funcionando. También arreglemos la prueba del servicio de creación de
billetera. En el método de configuración, vamos a instanciar el servicio de direcciones
ADD, pasando el generador
secuencial de direcciones como su parámetro. Y sustituyamos
el tercer parámetro
del servicio create wallet
por el servicio de direcciones ADD. Ahora, en la última prueba
receptora de Bitcoin, hagamos un pequeño cambio. Después de enviar Bitcoin
a la tercera dirección. Vamos a agregar el
método dormido llamada pasando timeout y seconds
como sus argumentos. También agreguemos la
misma llamada después de enviar Bitcoins a
la sexta dirección. El motivo de estas
llamadas es que antes enviar Bitcoins a las direcciones
cuarta y séptima, tenemos que
generarlos e importarlos a nuestros nodos antes de aceptar
transacciones a ellos. Y el
proceso de importación lleva algún tiempo. Por fin ejecutemos todas
nuestras pruebas de aplicación. Genial, todas las pruebas han pasado. Finalmente terminamos
los conceptos básicos de la
función de recepción de Bitcoin de nuestra billetera. Ahora, comenzaremos a implementar la observación de nuevos
bloques que se agreguen a la blockchain para que podamos
actualizar el número de conformaciones que son
direcciones que tienen C, sí.
37. 35 Recepción de bloque parte 1 skillshare 2: En este video,
realizaremos pruebas para asegurar que cuando se
extrae un bloque en la Blockchain, nuestra billetera reciba transacciones
actualizadas con conformaciones crecientes. Entonces movamos los métodos
auxiliares en la clase de prueba
Bitcoin de recibo a la prueba GUI para que podamos usar estos métodos en otras
clases que la extiendan. Ahora, movamos todas
estas propiedades a la clase GUI también
por la misma razón. Ahora, vamos a cortar estas dos líneas y pegarlas a la cartera de
carga y agregar método
balanceado en
la clase de prueba GUI. En el método de configuración en
la clase de prueba recibida, simplemente
llamaremos a este método. Eliminemos todas estas
importaciones no utilizadas en esta clase. En la clase de prueba GUI, vamos a hacer estos métodos
y propiedades protegidos. Ahora en el paquete de prueba GUI, vamos a crear la clase de prueba de
bloque de recepción. Extenderá la clase de prueba GUI. Vamos a copiar el método de configuración y la
prueba de Bitcoin de recepción y pegarla aquí. También copiemos
la primera prueba en
la prueba de recibir Bitcoin
y
pegarla en la clase de prueba de
bloque receptor. Se utilizará como plano para la próxima prueba que creemos. Cambiemos el nombre de la billetera
creada a mi billetera de prueba cinco. Vamos a cambiar el nombre
del tubo de ensayo debe recibir Bitcoin y agregar confirmaciones de
hashtag, confirmaciones para
recibir ese vestido. Las conformaciones de hashtag
serán interpoladas por la
variable de prueba de confirmaciones que crearemos. Ahora, después de enviar Bitcoins llamará al método de
bloques de minas, pasando como parámetro la
variable de confirmaciones. Vamos a crear este método. Tomará un int
como su parámetro. Este método usaremos
el nodo generar para dirigir al cliente
a los bloques de mina. Así que vamos a pegar
un poco de código en él. En la clase de prueba GUI, copie esta línea de código
y peguela aquí. Modificar el
nombre de la variable de dirección para anotar la dirección. Haz lo mismo con
esta otra línea. Cambiar el
segundo parámetro del método de generación a bloques. Por lo que utilizará esta variable para definir el número
de bloques que va a minar y cambiar este
parámetro para anotar dirección. Ahora, vamos a copiar este peso para una llamada de método y pegamos aquí. Eliminar estas partes del código. Este método esperará hasta que el primer valor de celda de
confirmación de fila de la tabla de direcciones sea igual a la variable blocks. En el bloque Venn comprobará si el valor de celda de
confirmación de la primera fila de tabla es igual a la variable de
confirmaciones. Incluyamos una cláusula where. Aquí. Vamos a establecer la
confirmación es variable para algunos valores de prueba. Añadiremos un marcador de posición para la segunda columna
en el WhereClause, porque aparentemente solo funciona cuando tiene
dos o más columnas. Vamos a establecer los
valores de las confirmaciones en 12.3. Ahora, ejecutemos nuestro nodo Bitcoin, y hagamos nuestra nueva prueba. Genial, las pruebas han pasado. Ahora, hagamos otra prueba
para el siguiente escenario. Queremos saber
qué sucede cuando una dirección recibe
dos transacciones. Y la segunda transacción tiene menos conformaciones
que la primera. En este caso, esperamos que el número de dirección de
conformaciones sea igual
al número de conformaciones de la transacción con menos
conformaciones a esa dirección. Así que vamos a duplicar
la primera prueba. Cambiemos su nombre a debería recibir Bitcoin y considerar la transacción con
menos conformaciones
como las confirmaciones de dirección. Cambiemos el nombre de
crear billetera a mi billetera de prueba seis. Ahora, vamos a duplicar
estas líneas de código para enviar bitcoins y
minar bloques de nuevo. En la segunda
llamada de bloques mineros sumar menos uno en su parámetro para minar menos bloques después de la
segunda transacción. En el bloque, esperamos
confirmaciones menos uno como el número de confirmaciones en la
primera fila de la tabla. Eliminemos esta
línea ya que no
queremos este caso de prueba
porque
intentaría pensar en cero bloques en la segunda
llamada de bloques de mina, lo que fallaría. Realicemos nuestras pruebas de nuevo. Genial, las pruebas han pasado. Por lo que concluimos que
nuestra cartera ya está preparada para actualizar el número de conformaciones de nuestras direcciones. Eso es porque después de
cada bloque de mina, el nodo envía un mensaje
a través de cero MQ a nuestra aplicación que contiene las transacciones previamente
importadas, pero con un
número actualizado de confirmaciones.
38. 36 Recepción de la transacción parte 1 skillshare 2: En este video, comenzaremos a hacer la tabla de transacciones. Esta tabla será similar
a la tabla de direcciones, pero en lugar de filas que contengan información sobre direcciones, esta tabla contendrá
información sobre cada transacción que envíe o reciba nuestra
billetera. Entonces comencemos a crear una prueba
GUI para esta tabla. En el paquete GUI, cree una clase llamada prueba de transacción de
recepción. Copie estos métodos de la prueba del bloque receptor
y péguelos aquí. Esta clase extenderá
la clase de prueba GUI. Cambiar este nombre de prueba para tener
debe recibir la transacción. Vamos a formatear este método. Quitar es donde bloquear, cambiar el nombre de crear billetera a mi prueba mientras sea siete. Suprimir esta línea. Ahora, después de llamar
al método sleep, hagamos que la prueba
haga clic en un componente con una pestaña de identificación ética de
transacciones. Ahora, agreguemos otro parámetro
opcional al método send Bitcoin
and wait. Este parámetro será una cadena y se llamará componente de
búsqueda. Su valor predeterminado será la tabla de direcciones de
hashtag. Sustituyamos
este parámetro en la llamada al método de búsqueda por la variable de componente de
búsqueda. Ahora en la prueba, agreguemos estos parámetros
al método send Bitcoin
and wait. El cuarto parámetro será la tabla de transacciones de
hashtag. De esa manera después de enviar
una transacción, esta llamada al método
esperará a que la tabla de transacciones
se complete con una
fila que contenga un saldo de 1.0 Bitcoin. Ahora, cambiemos el
parámetro
del método de búsqueda a la tabla de
transacciones de hashtag, también. En el bloque de entonces, vamos a
dejar la aserción del tamaño de fila de la tabla siendo
igual a uno por ahora. Ahora, diseñemos nuestra mesa. Vayamos al
patio de recreo punto FXML. Vamos a copiar todo este
contenido entre la etiqueta de tabulación y pegarlo a continuación. Ahora cambia su propiedad de texto a transacciones y su
ID de ética a pestaña de transacciones. También cambie el identificador de ética de la etiqueta de
vista de tabla a la tabla de transacciones. Ahora cambiemos el campo
de texto de la primera columna
a ID de transacción. La tabla también tendrá una columna balanceada y una columna de
confirmaciones. Por lo que vamos a mantener estas
etiquetas tal como están. Duplicemos la última etiqueta, cambiemos su texto a la fecha. Esta columna contendrá la fecha de creación de
estas transacciones. Ahora hagamos clic en
el Scene Builder para ver cómo se ve nuestra nueva
pestaña y tabla. Bien, se ve bien. Ahora, vamos a crear un nuevo
FXML para este componente. Llamémoslo tabla de
subrayado de transacciones. Eliminemos
el código estándar. Vamos a copiar este contenido desde el punto de juegos FXML
y pegarlo aquí. Vamos a importar estas etiquetas. Cambia esta etiqueta a
fx colon route. Eliminar este contenido como su tipo. Vamos a establecer la ruta del componente de
vista de tabla y establecer esta URL como el campo XML NS como la tabla de transacciones de
conjunto de propiedades de ID de ética. Ahora borra estas etiquetas, que no necesitábamos copiar. Ahora agreguemos estas
identificaciones de ética a estas etiquetas de columna. Serán útiles
más adelante cuando hagamos el controlador de la
tabla de transacciones. Ahora en la ventana principal punto FXML, vamos a duplicar el contenido
entre estas etiquetas. Cambiemos el texto de la pestaña a transacciones y es FX
ID a pestaña de transacciones. Ahora, cambie esta etiqueta a controlador de tabla de
transacciones. Vamos a crear este controlador en el paquete de controladores de puntos GUI. Vamos a importar a la ventana
principal punto FXML. Ahora agreguemos la
anotación de componente al controlador de la
tabla de transacciones. Extenderá la clase de vista de
tabla parametrizada con la
clase de fila de transacción que crearemos. Vamos a crear la clase real de
transacción en el paquete observables. Ahora, vayamos al controlador de
pestañas Recibir y copiar su constructor
y pegarlo aquí, realizando las
modificaciones correspondientes al mismo. Cambiemos su
anotación de valor para que apunte
al punto de tabla de
subrayado de transacciones FXML. Inyectemos también la
cartera actual en esta clase. Será útil más adelante. Ahora, necesitamos incluir el
controlador de tabla de transacciones en la lista de componentes personalizados en
el listener iniciado GUI, simplemente
podríamos agregar
otra o cláusula en la sentencia if en la
inicialización Método FXML. Pero vamos a refactorizar esta clase
haciendo lo siguiente. Vamos a crear un conjunto estático
privado de objetos de clase llamados componentes
personalizados aquí. Vamos a instanciarlo aquí
con la clase set de método. Incluyamos estas
clases de controlador en el conjunto. Ahora en la sentencia if solo
verificaremos si el conjunto de componentes personalizados
contiene el tipo dado. Ahora vayamos a la prueba de transacción
receptora. Ahora, ejecutemos los objetivos de Maven del ciclo de vida limpio y compilado. En ocasiones esto es
necesario para incluir nuevos archivos FXML en el proyecto
compilado. Ahora, ejecutemos nuestro nodo central de
Bitcoin si aún no se está ejecutando. Por último, hagamos la prueba. La prueba ha fallado
porque no ha encontrado una fila que contenga la información de
transacción en la tabla de transacciones, continuará implementando esta función en el siguiente video. Nos vemos.
39. 37 Recepción de la transacción parte 2 skillshare: En este video, terminaremos
la implementación de
la tabla de transacciones
y haremos que esta prueba pase. Entonces vamos al servicio de
actualización UTXO. Si recuerdas, este método de
actualización se llama después de recibir una
transacción de nuestro nodo, la clase de tarea nodo monitorea nuestro nodo en busca de mensajes de
transacción. Entonces nuestra aplicación
publica un evento de transacción recibida que es escuchado por nuestro oyente de
transacciones. El oyente de transacciones
analiza y filtra el mensaje y llama al método de actualización del servicio
UTXO de actualización. Entonces, después de recuperar UTXOS y actualizar las direcciones actuales de la
billetera, actualicemos las transacciones actuales de
billetera usando este servicio. Vamos a inyectarlo en esta clase. Vamos a crearlo en el paquete de servicios punto
GUI. Vamos a agregarle la
anotación de servicio. Ahora, terminemos de
inyectarlo en esta clase. Ahora, llamemos al
método update en este servicio, pasando
como parámetro la variable UTXOS. Vamos a crear este método. Este método se
ejecutará de forma asíncrona. Así que vamos a agregarle la
anotación asíncrona usando el
servicio ejecutor predeterminado como su parámetro. Hagamos lo mismo con
el método update en el servicio update current wallet
addresses. Ahora vamos a implementar
el método de actualización y el servicio de
transacciones Wallet actual de actualización convertirá la lista
de UTXOS en una lista de
filas de transacciones y almacenará el resultado en las
filas de transacciones el siguiente código filtrará el flujo de UTXOS
manteniendo en el flujo solo los UTXOS con direcciones
en la billetera actual. Entonces, vamos a inyectar la
cartera actual en esta clase. Ahora, en el cuerpo lambda
obtendrá todas las direcciones como cadenas y verificará si
contiene la dirección UTXO. Ahora, llamaremos al método map
en la secuencia resultante, pasando la fila
de transacción del método como su parámetro. Vamos a crear este método. Será un
método estático y
devolverá un objeto de fila de transacción. Similar a la clase
de fila de direcciones. La clase de fila de transacción
representará una fila y
la tabla de transacciones. Así que agreguemos las siguientes
propiedades a esta clase. Cada propiedad representará una columna en la tabla de
transacciones. Eliminemos la palabra clave
final de cada propiedad porque el IDE lo
hace permite crear automáticamente setters para estas
propiedades si su final. Ahora usando esta función de ID, agregue getters y setters
para cada propiedad. Ahora podemos volver a agregar la palabra clave final
a estas propiedades. Ahora, vamos a crear un constructor. El constructor tomará cada propiedad de clase
como sus parámetros. Y usaremos los setters de
propiedades para establecer las propiedades en
el cuerpo del constructor. Ahora, podemos seguir
implementando el método. Devolverá una nueva fila de
transacciones con los siguientes parámetros. Volver al servicio de transacciones Update Current
Wallet. Ahora vamos a convertir la cadena
resultante en una lista. Ahora agregaremos la rosa de
transacción obtenida a la billetera actual usando el método
add transactions rows. Vamos a crear este método. Utilizará el campo de filas de
transacciones. Así que vamos a crearlo ahora. Es tipo serán las
transacciones Rose Class. Vamos a crearlo en el paquete
observables. Volver a la cartera actual. Hagámoslo definitivo e
instanciémoslo aquí. Hagamos también final el campo de filas de
direcciones. En el método ED transactions
rows, llamemos al método add transactions
rows en el campo de filas de transacción. Pasando las
filas de transacción dadas como su parámetro. Vamos a crear este método. Al igual que la
clase de filas de direcciones es responsable administrar la lista de
filas de direcciones que se muestra en la tabla de
direcciones. Esta clase hará lo mismo con las filas
de transacciones
y la tabla de transacciones. Entonces, para cada fila de transacción, verificaremos si el campo de hoja de ruta de
transacciones ya lo contiene. Así que vamos a crear este campo. Será un
mapa observable donde la clave es una cadena y el valor
es una fila de transacción. Vamos a instanciarlo aquí con
un envoltorio de mapa observable, pasando un nuevo
HashMap vinculado como su constructor. Entonces, si la hoja de ruta la transacción
contiene el ID de
fila de transacción en sus claves, entonces estableceremos la
rotación de la transacción a la fecha de la
transacción presente en la hoja de ruta de transacción
que servirá que para preservar la fecha de creación de la
transacción. Luego, después de la declaración if,
eliminará la
fila de transacciones del mapa por su ID y volverá a colocar la
fila de transacciones dada en la hoja de ruta de transacciones
usando su ID como clave. Nuevamente, estamos eliminando y agregando la misma
fila de transacciones para forzar
al mapa observable a publicar eventos de
cambio que
se escucharán más adelante. Ahora, vamos a crear el campo de lista observable
que se utilizará para vincular los cambios en la hoja de ruta de
transacciones al controlador de tabla. Vamos a instanciarlo aquí usando un envoltorio de lista observable instanciado con
una nueva lista enlazada. Ahora vamos a crear el método obtener lista de filas de transacciones
observables. Devolverá la lista
de roles de transacción. Ahora vinculará la hoja de ruta de
transacciones con la
lista de roles de transacción en el constructor, tal como hicimos para
el conjunto de filas de direcciones y la lista de filas de direcciones en
la clase de filas de direcciones. Entonces, para acelerar las cosas, copiemos el constructor de
filas de direcciones y péguelo aquí. Arreglemos su nombre. Ahora, en lugar de llamar a métodos
en la lista de roles de dirección, lo
haremos en la lista de roles de
transacción. En lugar de usar un listener set
change usará un listener de cambio de mapa parametrizado con una cadena
y una fila de transacción. Además, en lugar de usar el elemento
get eliminado aquí, usaremos el getValue removed. Aquí. Usaremos el
get value added. Y aquí agregaremos un oyente
a la hoja de ruta de transacciones. Una cosa más para que esto funcione, tenemos que implementar
el método equals en la clase de fila de transacción. Esto se debe a que la lista de filas de
transacciones, usaremos el método para decidir qué fila de transacciones
eliminar de sí misma. Así que vamos a implementarlo
usando esta función IDE. Asegúrese de marcar la casilla de verificación
use getters en esta ventana utilizará solo la propiedad ID para definir
la igualdad en esta clase. Además, da clic en la casilla de verificación ID aquí para que no pueda ser nulo. Bien, el IDE generó
estos métodos como se esperaba. Volver a la clase de
filas de transacción. Vamos a crear el método clear, que se llamará cuando se cree
una nueva billetera. En su interior llamará
al método claro en la hoja de ruta de transacciones y
en la lista de roles de transacción. En la clase de billetera actual, vamos a crear el método de filas de
transacciones observables buenas. Devolverá que obtienen una llamada al método de lista de filas de
transacciones observables llamada al método de lista de filas de
transacciones en el campo de filas de transacciones. Vamos a crear también el método de
transacciones claras aquí. Llamará al método
claro de filas de transacción que acabamos de crear. Ahora vamos a la actualización
actual del servicio de monedero. Aquí llamaremos
al método actual de transacciones
de compensación de billetera . Al hacerlo, nos
aseguramos de borrar las filas de transacciones
después de crear una billetera. Ahora, vayamos al controlador de la tabla de
transacciones. Vamos a agregar los siguientes campos. Se utilizará en el método
inicializado posteriormente para enlazar la tabla y sus columnas a
las filas de transacciones observables. Ahora vamos a crear el método
inicializado. Aquí, primero estableceremos elementos de
la tabla de transacciones en las filas de transacciones
observables de billetera actuales. Ahora agregaremos un oyente a las filas de transacciones
observables actuales de la billetera. Llamaremos al método de
actualización de la tabla de
transacciones en
el cuerpo para que cada cambio que ocurra en el observable desencadene un
redibujo de la tabla. También vinculará cada campo de
columna
al campo de fila de transacción usando la fábrica de
valores de celda establecida,
tal como lo hicimos en el controlador de la tabla de
direcciones. Como parámetro de
fábrica de valor de propiedad, tenemos que usar los mismos
nombres de propiedad que hemos usado en la clase real de transacción
para hacer el enlace correctamente. Duplicemos esta línea tres veces y cambiemos las
columnas que estamos vinculando. Ahora vayamos a la clase de prueba de
transacción receptora. Asegúrate de que estás ejecutando el Bitcoin Core Node
y ejecuta la prueba. Boops, la prueba ha
fallado. Veamos por qué. Hay un problema con el campo
balanceado de transacciones de
columna en el controlador de la
tabla de transacciones. Para solucionarlo, vamos a ir a la tabla de
subrayado de transacciones punto FXML. El problema es que
mal nombramos el saldo, las confirmaciones y los ID de FX de fecha. los tres les falta la palabra
transacción tras columna. Así que vamos a arreglarlos y volver a
ejecutar la prueba. Genial, La prueba ha pasado. En el siguiente video, agregaremos más
pruebas para asegurarnos la tabla
de transacciones funcione según lo previsto. C, sí.
40. 38 Recepción de la parte 3 de la transacción skillshare: En este video, agregaremos
más pruebas para verificar si nuestra tabla de transacciones
funciona para otros escenarios. Entonces vayamos a la clase de prueba de bloque
receptor. En cada método se agregará código para probar si la tabla de transacciones contiene la información
esperada sobre las
transacciones receptoras. Entonces, cambiemos el nombre de la vista de tabla en esta prueba para abordar
su vista de tabla, para aclarar su significado. Ahora, llamaremos al método
click on pasando como su parámetro,
las transacciones de cadena. Ahora vamos a copiar la línea
con la variable de vista de
tabla de direcciones y pegarla a continuación. Cambiemos este nombre de variable a la vista de tabla de transacciones. En el método de búsqueda, sustituyamos este parámetro por la tabla de transacciones de hashtag. Ahora vamos a copiar estas dos
líneas y pegarlas a continuación y cambiarlas para llamar a estos métodos en la vista de tabla de
transacciones. Hagamos lo mismo con
el otro método de prueba. Pero en este caso, esperamos que la tabla
de transacciones contenga dos líneas, una por cada transacción. Y para la segunda fila, esperamos que el número
de confirmaciones sea igual a la variable de
confirmaciones totales, lo que creará el valor
total de confirmaciones será igual al número
de bloques míos hasta el momento, este número será igual a confirmaciones más
confirmaciones menos uno. Como esperamos que
la segunda fila contenga información sobre
la primera transacción, se confirmará
esta cantidad de veces. Hagamos un pequeño arreglo en
el método de bloques de minas. A veces esta línea de código genera una NullPointerException debido a TableView tiene una propiedad
null items. Para evitar eso, usemos el operador seguro nulo antes de cada propiedad en la vista de tabla. Ahora, hagamos nuestras pruebas. Primero, asegúrate de
ejecutar tu nodo Bitcoin. Vamos a hacer las pruebas. Las dos últimas pruebas han fallado. Eso pasó porque las
transacciones en la tabla, estamos desordenadas, su
orden es aparentemente aleatorio. En ocasiones estas pruebas pueden pasar porque se pueden ordenar
correctamente por casualidad. Entonces arreglemos eso. Nuestro objetivo es ordenar las
transacciones por fecha con las transacciones más recientes
en las primeras filas. Entonces vayamos a la clase de fila de
transacciones. En el método from.
Cambiemos la forma en que pasamos los datos a la instanciación de la
fila de transacciones. En lugar de usar una nueva fecha, usemos el método
instant now. Estamos haciendo eso porque
la clase instantánea es más precisa y más
fácil de ordenar Parson. Ahora vamos al controlador de la tabla de
transacciones. En la tabla de transacciones
establecer artículos método de llamada. Pasemos una nueva
lista ordenada como parámetro. Las filas actuales de
transacciones observables de monedero
serán el primer parámetro que
instancie la lista ordenada. El segundo parámetro será el comparador que
compara la llamada al método. Este método
pasará una lambda como primer parámetro o
una fila de transacción
será el parámetro en
el cuerpo lambda. Llamemos al método de análisis
instantáneo, pasando la transacción
rotate como su parámetro. El método parse generará un objeto de instancia
a partir de la cadena de fecha. El segundo parámetro del
método de comparación
será la llamada al método de
orden inverso del comparador. De esta manera, esperamos que la tabla de
transacciones se ordene primero por la fecha de transacción con las
últimas transacciones. Ahora volvamos a hacer nuestras pruebas. Esta vez sólo
los que han fallado. Lo haremos haciendo
clic en este botón. Genial, las pruebas han pasado. Ahora agreguemos las pruebas de
tabla de transacciones a la clase de prueba de
Bitcoin de recepción. Haremos lo mismo que hicimos en la clase de prueba de bloque receptor. Para cada método,
refaccionaremos el nombre de la vista de tabla, haremos que la prueba haga clic en la pestaña de transacciones y
haremos aserciones sobre el contenido esperado en la
tabla de transacciones. Vamos a hacerlo. Bien, ahora, hagamos estas
pruebas. Genial, las pruebas han pasado. Ahora ejecutaremos nuestra billetera en el entorno de red de prueba
por primera vez. El entorno de la red de prueba es
similar al de la red principal, pero sus monedas carecen de valor. Es mucho más fácil de pensar y
su tiempo de bloqueo es más corto. Requiere que ejecutemos y hundamos nuestro nodo Bitcoin en
este entorno. Cubrimos cómo hacerlo
en la guía de configuración del curso. Entonces, modifiquemos nuestro bitcoin.com para ejecutar nuestro nodo en el entorno
de red de prueba. Simplemente cambie esta clave de
reg test a test net. Dejemos de ejecutar nuestro
nodo en la prueba reg. Y volvamos a ejecutar nuestra nota para
comenzar a hundir nuestra
nota en la red de prueba. Mi nota casi se hunde, así que tardará unos
minutos en ponerse al día. Pero dependiendo de la
última vez que lo
ejecutaste, puede que
nos lleve más tiempo sincronizar
porque nos llevará algún tiempo
descargar los últimos bloques. De todos modos, mientras se está hundiendo, modifiquemos nuestros proyectos
para que podamos ejecutar nuestra aplicación en la red de
pruebas con éxito. En la ruta de recursos, vamos a crear las propiedades de punto
neto de prueba de
aplicación de archivo . Este archivo contendrá
las propiedades utilizadas en nuestro proyecto cuando ejecutemos la aplicación en el entorno de red de
prueba. Vamos a copiar el contenido del
archivo de propiedades
del punto de la aplicación propiedades
del punto de la aplicación y pegarlo aquí. Ahora, cambie el
entorno de Bitcoin para probar net. Y el puerto URI
punto RPC no dot 218332. Este es el
puerto predeterminado de nuestro nodo cuando se ejecuta en el entorno de red de
prueba. Ahora, hagamos una
pequeña mejora. En nuestro monedero, Sería bueno poder copiar
el ID de transacción que se muestra en la tabla de
transacciones
simplemente haciendo clic derecho sobre
ellas y haciendo clic en Copiar. Implementemos esta característica. Para ello, vayamos a la tabla de
subrayado de transacciones punto FXML. Ahora agreguemos aquí el
siguiente código. Primero, agreguemos estas etiquetas de menú
contextual dentro de él. Agreguemos la etiqueta items. Después la etiqueta de los elementos del menú. En esta propiedad de texto etiquetas agregue la copia de cadena y identificador de transacción de café
hashtag
ya que está en la propiedad de acción. Esto le dice a la
aplicación que llame
al método Copy Transaction ID en el controlador de la
tabla de transacciones. Después hacemos clic en el elemento Copiar
menú en el menú contextual. El menú contextual es
un menú que aparece después de que hacemos clic derecho en
algo en la pantalla. Ahora, vayamos al controlador de la tabla de
transacciones. Vamos a crear el método de copia ID de
transacción aquí. Primero, obtendremos la fila de transacciones en
la que se hizo clic
con el botón derecho usando este código. Ahora simplemente llamaremos
al método copy. Crearemos pasar el
ID de fila de transacción como su parámetro. Para crear este método
se creará primero un paquete utils dentro
del paquete BYOD W. En su interior, vamos a crear
una clase llamada Copy. Ahora, vamos a crear el método
copy aquí. Como método estático. Instanciará un objeto de contenido
del portapapeles, almacenándolo en la variable de
contenido. Entonces llamaremos al método put
string en él, pasando la variable
text como su parámetro. Agreguemos esta variable como parámetro
del método copy. Finalmente, llamaremos al método del portapapeles
del sistema get y estableceremos su contenido el contenido variable en el controlador de la
tabla de transacciones. Vamos a importar este
método. Una cosa más. Al ejecutar el nodo Bitcoin en el entorno de red de prueba, nuestro nodo puede recibir diferentes
tipos de transacciones que la
biblioteca Java de Bitcoin
aún no puede analizar y
generan errores al intentar hacerlo . Aunque no analizar
estas transacciones afectará a nuestras billeteras, el error se plantea bien. Para evitar eso, en
la clase de tarea de nodo, envuelva el método de transacción del flujo de bytes en un bloque
try-catch. En el bloque catch, usemos un registrador para
advertirnos del error. En la llamada a un método
pasará una frase que indica el error y un par de llaves al final. Estas llaves serán interpoladas por el
segundo argumento, que será la variable de contenido
codificada hexadecimal. El tercer parámetro
será el objeto de excepción. Así podemos acceder a
toda la traza
de pila del error en los registros. Después del registro, el error
irá directamente a la siguiente iteración
del bucle while usando
la palabra clave continue. Vamos a crear el campo logger. Será una propiedad estática. Vamos a instanciarlo aquí
usando la fábrica de registradores. Arreglemos la importación de la
clase logger. En realidad, tenemos
que importarlo
del paquete 4D dot SELF for J. Ahora vamos a ejecutar nuestra aplicación en el entorno de red de prueba. Primero, comprobemos si nuestro nodo está vinculado en el entorno de
red de prueba. Bien, ya se hunde porque es progreso
es igual a 1.00. Ahora vamos a la clase de aplicación BYOD
W. Haga clic con el botón derecho en este
símbolo y haga
clic en modificar Configuraciones de Ejecución. Ahora, haga clic en modificar opciones y asegúrese de que las
opciones de VM del anuncio estén seleccionadas. Ahora conéctelo a menos d perfiles de puntos de resorte punto
activo es igual a red de prueba. Haga clic en Bien y haga clic
en el botón Ejecutar. Ahora vamos a crear una cartera. Observe que la
dirección de recepción comienza con TB, indicando que es
una dirección neta de prueba. Ahora, copiemos esta dirección. Utilizará un grifo de red de prueba
para obtener Bitcoins netos de prueba. Un grifo de Bitcoin es un sitio web o API que ofrece
Bitcoins de forma gratuita. Fueron muy populares en
los primeros años de Bitcoin, cuando uno Bitcoin era muy barato. Hoy en día, hay forma rápida de
obtener monedas netas de prueba. Vayamos al
sitio web en la pantalla. Es un grifo de red de prueba. Pegemos la
dirección copiada en este campo. Elija una cantidad, y haga clic en este botón
para enviarnos Bitcoin. Esperemos un poco. Bien, la alerta dice que envía algunos Satoshi's
a nuestra cartera. Comprobemos si lo hemos recibido. Genial. Nuestra billetera identificó nuestra transacción y
nuestra transacción y dirección ya
tienen una conformación. hay una cosa rara. El saldo está formateado
en notación científica. Lo arreglaremos más tarde. Por ahora, copiemos
nuestro ID
de transacción haciendo clic derecho sobre él
y haciendo clic en Copiar. Verificaremos la transacción en un explorador de
blockchain de terceros. Un explorador de blockchain
es un sitio web que muestra información sobre direcciones,
bloques y transacciones de
Bitcoin de
una manera agradable y organizada. Si le preocupa su privacidad, buscar sus
vestidos rojos y transacciones en el no es
recomendable
buscar sus
vestidos rojos y transacciones en el
explorador blockchain de
terceros ya que
les permite vincularlo con los datos de
su billetera. Pero como
solo lo estamos usando para fines de
prueba, está bien. Dicho esto, vayamos al sitio web en
la pantalla, que es un explorador blockchain
net de prueba de Bitcoin, peguemos el ID de
transacción copiado en el campo de búsqueda y hagamos clic
en el botón Buscar. Aquí, obtendremos alguna información sobre
nuestra transacción. Observe que ya
tiene dos confirmaciones, pero nuestro monedero indica que solo
tiene una conformación. Resulta que en el entorno de red de
prueba, nuestro nodo Bitcoin solo envía
notificaciones de transacciones a través cero MQ cuando se
envían las
transacciones y cuando
reciben una confirmación. Después de eso, no importa cuántas
confirmaciones más obtengan, el nodo no notifica a
nuestra aplicación al respecto. Tenemos que hacer que nuestra aplicación
comience a escuchar notificaciones de
bloqueo para que
podamos solucionar este problema. Empezaremos a hacer esto
en el siguiente video. Nos vemos.
41. 39 Recibir bloque parte 2 skillshare 2: En este video,
haremos que nuestra aplicación comience a escuchar
mensajes de bloqueo del nodo Bitcoin. De esa manera, podremos
actualizar nuestras
confirmaciones de transacciones correctamente en
el entorno de red de prueba. También modificará el formato de direcciones y
saldos de transacciones, ya que ahora no
se están mostrando muy bien en las tablas. Entonces vamos al archivo
bitcoin.com. Cambiemos esta
clave para reg test. Para comenzar a escuchar
mensajes de bloque, agreguemos aquí la propiedad Z MQ pub
hash block. Su valor será la misma
URL en la propiedad anterior. Así que vamos a pegarlo aquí. Esta configuración hará que los nodos envíen el bloque hash a nuestra aplicación después de que detecte un nuevo bloque, extendiendo
la cadena de bloques. Después de eso, el
código creará, enviará una lista de solicitud
no gastada al nodo que contiene todas las direcciones
actuales de billetera. En respuesta recibirá
una lista de UTXOS actualizados que analizarán
y usarán para actualizar nuestros vestidos rojos y tablas de
transacciones. Guardemos el archivo bitcoin.com. Ahora, vayamos a la clase de tareas de
nodo. Duplicemos esta línea. Cambiemos la
cadena a bloque hash. De esa manera, comenzaremos a recibir mensajes de bloque
hash
desde el nodo. Ahora, en esta declaración if, agreguemos el siguiente código. Si el tema es igual nulo, o la lista con
estos temas
no contiene el tema recibido. Después iremos a la siguiente
iteración del bucle while. Ahora, agreguemos aquí una declaración
switch. En caso de que la variable topic
sea igual a ra t x Luego ejecutamos
el código para analizarlo y procesar la transacción
recibida. Movamos a esta ubicación la línea
que publica el
evento de transacción recibida. De esa manera podremos eliminar esta sentencia redundante
continue en caso de que la variable topic
sea igual al bloque hash. Luego usaremos el editor de eventos de la
aplicación para publicar un nuevo evento recibido por
bloques. Vamos a crear este evento en el paquete BYU w dot sin
duda eventos. Ahora vamos a crear un
oyente para este evento en el paquete BYOD w dot, dot
listeners. Vamos a agregarle una
anotación de componente. Hagamos que implemente la interfaz de
escucha de aplicaciones, pasando el
evento block received como su parámetro type. Implementemos su método. Primero. Obtendremos todas las direcciones actuales de
billetera usando este método y las almacenaremos
en la variable direcciones. Inyectemos la
cartera actual en esta clase. Entonces usando una sentencia if
comprobará si la
variable addresses está vacía. Si no lo es, entonces usaremos el servicio de actualización UTXOS para actualizar nuestras direcciones
y transacciones. Vamos a inyectarlo en esta clase. Llamaremos al método de
actualización en él, pasando la dirección es variable y el
nombre de la billetera actual como sus parámetros. Ahora vamos a ir a la
transacción recibida oyente va a optimizar nuestro código. Recuerde que después de recibir
una confirmación en el entorno de red de prueba y todas las confirmaciones en el entorno de prueba
reg, el nodo envía un mensaje de
transacción a nuestra aplicación a
través de cero MQ. Dado que a partir de ahora nuestro oyente
recibido en bloque
actualizará todas
las direcciones actuales de billetera cuando
reciba confirmaciones, no tiene sentido actualizar la tabla de direcciones y
transacciones en la transacción recibió clase de
oyente después de
recibir mensajes de transacción repetidos más. Por lo tanto, modificaremos
esta clase para
procesar únicamente transacciones si la cartera actual
no las contiene. Entonces agreguemos esta declaración if. Si los ID de
transacción actuales de Wallet contienen el ID de
transacción recibida, entonces simplemente regresamos. Vamos a crear este método. Devolverá una lista de cadenas, y devolverá
las filas de transacción,
obtendrá el método de ID de transacción. Vamos a crear este método. Aquí. Devolveremos el siguiente código de una secuencia de la lista de roles de
transacción. Llamaremos al
método map pasando una referencia al método getID de fila de
transacción. Luego convertiremos el
resultado a una lista y
lo devolveremos al oyente de transacción
recibida. Tenemos que envolver este código en
un bloque try catch porque el método de ID de transacción arroja una excepción marcada
en el bloque catch, utilizará un registrador para
imprimir un mensaje de advertencia. Inyectemos el registrador
en esta clase,
tal como lo hicimos en
la clase de tareas de nodo. También agreguemos una
declaración return al bloque catch. Ahora, solucionemos el problema de
formato equilibrado de fila de direcciones. En lugar de usar el método de cadena de dos
clases dobles, usaremos el
método de
formato o formato Bitcoin pasando el
saldo de direcciones como su parámetro. Vamos a crear esta clase
en el paquete utils. Ahora, vamos a crear
el método format. Aquí, instanciaremos
un nuevo objeto de
símbolos de formato decimal pasando la ruta regional a
su constructor. Luego estableceremos el punto como su separador decimal y la coma como separador de
agrupamiento. Entonces instanciaremos
un nuevo objeto de formato decimal ya que su parámetro constructor
pasará este patrón. Y la variable de símbolos. Después estableceremos el formato
o agrupación utilizado como false. Entonces estableceremos sus dígitos mínimos de
fracción en ocho. Y es la
fracción máxima de dígitos 282. Finalmente, llamaremos al
método format en el formateador, pasando el número recibido como parámetro y lo devolveremos. Mediante este método formateará
cualquier número de pase a él con dígitos decimales y
sin separadores de agrupación. Este tipo de formato
es útil ya que un bitcoin puede tener como
máximo ocho dígitos de fracción. Este formato también facilita la visualización de cuántos Satoshi es un contenido equilibrado. Ahora vamos a la clase de fila de
transacciones. Vamos a usar el
formateador Bitcoin aquí para, para formatear el saldo UTXO
en el método frame. Ahora, ajustemos nuestras pruebas para cubrir este nuevo formato de
saldo. Vamos a la clase de prueba GUI en el método send Bitcoin
in weight, cambiemos el segundo tipo de
parámetro a double y ajustemos su valor
predeterminado en consecuencia. También agreguemos este parámetro de cantidad
opcional con un valor predeterminado de 1.0. Ahora, sustituyamos
este parámetro por la variable amount. Y aquí vamos a envolver la variable de
cantidad total esperada en el formato Bitcoin
o método de formato. Ahora, vayamos a la prueba de
recibir Bitcoin. Modifiquemos esto y Bitcoin
y espere al método de llamada para enviar 0.00 001 Bitcoin. Para que podamos probar el
nuevo formato cuando nuestro monedero reciba fracciones de
Bitcoin. Ahora, comprobemos cada uso
de este método y modifiquemos su parametrización
del parámetro de
cantidad total esperada para pasar un doble
en lugar de una cadena. Ahora, agreguemos estas comprobaciones
nulas a las propiedades de vista de tabla en este método para evitar tener excepciones de puntero
nulo. Ahora, vamos a ejecutar nuestro nodo, y vamos a ejecutar todas las pruebas del proyecto. Genial, las pruebas han pasado. Ahora, ejecutemos nuestra aplicación en el entorno de red de prueba. Para ello, ajustemos
nuestro archivo bitcoin.com. Ahora, reiniciemos nuestro nodo. Después de algunos minutos, mi
nota está completamente hundida. Ahora, ejecutemos nuestra
aplicación en el entorno de red de prueba usando nuestra configuración de
ejecución previamente modificada. Vamos a crear una nueva cartera. Ahora, copiemos nuestra
dirección y utilicemos un grifo de red de prueba para
recibir Satoshi's, tal como hicimos en
un video anterior. Bien, nuestras billeteras identificaron
con éxito la transacción y está
equilibrada es tal como esperábamos. Ahora, comamos un sándwich y dejemos nuestra cartera
funcionando por un tiempo. Después de algunos minutos
son atendidos y transacción ya obtuvo
cuatro confirmaciones. Genial.
42. 40 Saldo total parte 1 skillshare 2: En este video, comenzaremos a desarrollar la función de
saldo total. Básicamente, será un texto encima la pestaña de transacciones y
direcciones que indica que el saldo de la billetera
actualmente cargada mostrará el saldo confirmado, el saldo no confirmado
y el saldo total. El saldo confirmado mostrará la suma del monto de
todos los UTXOS confirmados. El saldo no confirmado es la suma de todos los UTXO
no confirmados. El saldo total
será la suma de saldos no confirmados y
confirmados. Así que vamos al patio de recreo punto FXML para bosquejar algo. Después del primer panel
de pestañas de cierre. Agreguemos esta etiqueta de etiqueta. Ahora, agreguemos esta etiqueta de margen
de punto VBox. En su interior. Agrega esta etiqueta de insertos. Vamos a añadir algunas
propiedades de margen aquí. Vamos a establecer el
margen inferior en 10.0, el margen izquierdo en 10.0 y el margen superior en cero. Ahora, para propósitos de prueba, establecemos la propiedad text de esta etiqueta a esto como una prueba. Veamos cómo se ve
en el Scene Builder. Bien, vemos que aquí
se
ubicarán los textos equilibrados. Eliminemos esta propiedad de texto. Vamos a crear un nuevo archivo FXML llamado saldo de subrayado total. Vamos a quitar este calderero. Ahora, copiemos todo
el contenido y
la etiqueta de etiqueta que acabamos de
crear en el patio de recreo. Y pégalo aquí. También vamos a copiar estas líneas de
importación dos y pegarlas en el punto equilibrado de
subrayado total FXML. Ahora sustituyamos las
etiquetas de etiqueta por la etiqueta de raíz de colon FX. Tendrá un ID FX de balance
total y un
tipo de Java FX dot, dot control dot label. Incluyamos también esta propiedad
XML y S. Ahora en la ventana principal, agreguemos la etiqueta del controlador de
saldo total después del primer panel de pestañas de
cierre. Ahora vamos a crear este controlador en el paquete de controladores. Y vamos a importarlo aquí de
nuevo al controlador. Hagamos que extienda la clase de etiqueta y le agreguemos la anotación de
componente. Ahora, vamos a copiar este constructor y pegarlo aquí,
modificándolo en consecuencia. El valor del recurso FXML será la ubicación del punto equilibrado de
subrayado total FXML. Inyectemos también la
cartera actual en esta clase. Ahora en la GUI comenzó el oyente, agreguemos la clase de controlador de
saldo total al conjunto de componentes personalizados. En el controlador de saldo total. Vamos a agregar el método
inicializado. Usaremos el método
setText heredado para establecer el
texto de la etiqueta dinámicamente. Vamos a configurarlo para que se pruebe con fines de
prueba por ahora. Ahora, vamos a crear la prueba de saldo
total en el paquete GUI. Extenderá la clase de prueba GUI. Vamos a copiar estos dos métodos y pegarlos
en la nueva prueba. Vamos a cambiar el nombre de este método dos deben calcular el saldo total. Ahora, hagamos algunos
ajustes en el cuerpo. El nombre de la cartera creada
será mi prueba validar. Eliminemos esta línea
ya que no la vamos a necesitar. También eliminemos estas líneas. Con este código,
obtendrá el texto presente en la etiqueta de saldo total y lo
almacenará en la variable de texto de
etiqueta. Entonces block comprobará si la variable de texto label es
igual a la siguiente frase. Después de recibir la transacción, esperamos que el
contenido de la etiqueta muestre que nuestros
saldos totales y no confirmados son un Bitcoin. Esperamos que el
saldo confirmado sea cero ya que nuestra transacción
no se incluirá en un bloqueo y mente
durante la prueba. Antes de ejecutar nuestro nodo, asegurémonos de que nuestro entorno
Bitcoin dot conf esté configurado para reg test. Ahora, vamos a ejecutar nuestro nodo. Y hagamos esta prueba. Ha fallado como
se esperaba porque la etiqueta de saldo total contiene la prueba de cadena en lugar
de lo que queríamos. En el siguiente video, implementaremos esta función
y haremos que esta prueba pase. Nos vemos.
43. 41 Saldo total parte 2 skillshare 2: En este video, terminaremos implementar la función de
saldo total. Así que vayamos al servicio de
actualización UTXOS. En el método de actualización se agregará una nueva llamada a método para
actualizar el saldo de la billetera. Para eso, llamaremos al
método de actualización en la actualización que creará el servicio de
saldo de billetera actual. Inyectemos este
servicio en esta clase. Vamos a crear esta clase en
el paquete de servicios punto GUI. Y terminemos de
inyectarlo aquí. Ahora, vamos a crear
su método de actualización. Aquí, primero calcularemos el
saldo no confirmado y lo almacenaremos en la variable de
saldo no confirmado. Para eso, necesitaremos inyectar la billetera actual
en esta clase. Entonces obtendremos sus filas de transacciones
observables
y las convertiremos en un stream. Luego usaremos el
método de filtro en el resultado para excluir las filas de transacciones con confirmaciones
diferentes a cero. Luego usaremos el método
map para convertir el flujo obtenido
en un flujo de saldos de filas de transacciones. Usaremos el método parse
double para convertir cada
cadena balanceada en una doble. Ahora usaremos el método
reducido, pasándole el método de
suma doble, a algunos cada
saldo obtenido en la corriente. Finalmente, usaremos el
método or else pasándole 0.0. Por lo tanto, en caso de que el flujo
obtenido esté vacío, la
variable balanceada no confirmada se establecerá en cero. Ahora, vamos a duplicar
este bloque de código. Vamos a modificarlo para calcular el saldo confirmado y
almacenarlo en la variable
equilibrada confirmada. Sólo tenemos que cambiar
el signo igual y el método de filtro a
este signo mayor que. Con esta simple modificación, obtendremos la suma
de los saldos de todas las transacciones con
al menos una conformación. Finalmente, llamaremos al método de
saldos establecidos en
la billetera actual, pasando el
saldo no confirmado y el saldo confirmado
como sus parámetros. Dado que este código
modificará la interfaz de usuario, vamos a envolverlo en una plataforma
ejecutar más tarde llamada al método. Y vamos a crear el método
set balances en la clase actual de wallet. Para ello, agreguemos el campo de
saldos a esta clase. Su tipo será la clase de
saldos que crearemos. Vamos a crearlo en el paquete
observables. Y vamos a instanciarlo aquí. Aquí llamaremos a este método de
saldos establecidos en
el campo de saldos, pasando los saldos
no confirmados, no confirmados
como sus parámetros. Vamos a crear este método. Primero. Agreguemos algunos
campos privados a esta clase. Añadiremos el campo
balanceado no confirmado de la propiedad type string. Vamos a instanciarlo aquí con una nueva propiedad de
cadena simple. Duplicemos esta
línea dos veces. Cambiemos estos nombres de
campo para confirmar el saldo y el saldo total. Ahora en el
método set balances llamará
al método set en las propiedades
inyectadas para establecer sus valores. Utilizará el
formato o método de formato Bitcoin para formatear los saldos
al formato deseado. Al saldo total
pasará la suma de los saldos no confirmados y
confirmados. Ahora, vamos a crear getters
para estos campos. Creemos también
el método claro. Este método establecerá cada saldo de
propiedad en cero. Llamaremos a este método
después de crear una billetera para borrar los valores de la billetera
previamente cargada. Ahora en la cartera actual, vamos a crear el método de
los buenos saldos. Devolverá el campo de saldos. Y vamos a crear el método de saldos
claros. Llamará al método de
compensación de saldos. En el servicio de
billetera actual de actualización, que se llama después de que se crea
una billetera, llamemos aquí al método actual de saldos
claros de billetera. Ahora, vayamos al controlador de saldo
total. Vamos a quitar esta línea. Obtendremos la propiedad
balanceada no confirmada de los saldos actuales de la
billetera. Llamaremos al método del
oyente de anuncios en él. Pasaremos una lambda
como su parámetro, donde en el cuerpo llamaremos
al método update text. Vamos a crear este método. Llamaremos al
método SetText en él, y pasaremos una llamada al método de
formato de cadena como su parámetro. El primer parámetro
del método de formato
será esta frase. Cada signo de porcentaje
seguido de la letra S será interpolado por los
siguientes parámetros de esta llamada al método. Los siguientes parámetros serán el saldo
total actual de la cartera. El monedero actual
confirmó saldo. Y por último, el saldo actual de la
cartera sin confirmar. Ahora en el método inicializado, vamos a duplicar esta
línea dos veces. Añadiremos el mismo oyente a la propiedad equilibrada confirmada
y a la propiedad de saldo total. Entonces, modifiquemos estas
líneas en consecuencia. Vamos a refacturar esta cadena, incluyéndola en una
constante en esta clase. Llamémoslo
texto equilibrado y hagámoslo privado. Ahora, hagamos una
pequeña modificación en el servicio UTXOS de actualización. Observe que ya tenemos una anotación asíncrona
en el método de actualización. Entonces agregar la misma anotación en el método se llama
un es redundante. Por lo tanto, vamos a eliminarlos. Primero en la actualización actual del servicio de direcciones de
monedero. Luego en la actualización actual del servicio de transacciones
Wallet. Otra cosa que he
notado es que
necesitamos envolver la llamada al
método de filas de
transacción de anuncios y una plataforma aprender más tarde al método de llamada ya que
modifica elementos en la interfaz de usuario. Ahora vamos a la prueba de saldo
total. Asegurémonos de que nuestro nodo
Bitcoin se esté ejecutando. Y vamos a ejecutar nuestros
grupos de prueba . La prueba ha fallado.
Veamos por qué. Resulta que olvidé agregar
la anotación de servicios a la actualización actual del servicio de saldo de
billetera. Vamos a arreglar eso. Y volvamos a hacer nuestra prueba. Genial, La prueba ha pasado. En el siguiente video, agregaremos pruebas más equilibradas en nuestras otras pruebas para asegurarnos de
que funciona según lo previsto.
44. 42 Saldo total parte 3 skillshare 2: En este video,
implementaremos más pruebas para asegurar que la función
de saldo funcione correctamente. Entonces copiemos esta línea y
la prueba de saldo total, primero
agregaremos algunas aserciones de
prueba sobre el saldo y la prueba de bloque
receptor. Así que vamos a pegar la línea aquí. También copiemos esta línea
y la peguemos en el
entonces bloque de esta prueba. En esta prueba, esperamos que el saldo total
sea igual a un Bitcoin. Entonces, ajustemos esta
frase en consecuencia. También esperamos que se confirme todo el
saldo. Hagamos lo mismo
para esta otra prueba. En este caso, esperamos
que el saldo total sea igual a dos
bitcoins, también confirmado. Ahora vamos a comprobar si nuestro nodo
se está ejecutando y ejecutemos la prueba. Ya pasaron las pruebas. Ahora agreguemos algunas afirmaciones de
saldo a la clase de prueba de
Bitcoin receptora. En estas pruebas
sólo se esperarán saldos no confirmados. Vamos a hacer estas pruebas. Genial, las pruebas han pasado.
45. 43 Enviar bitcoin parte 1 skillshare 2: Bien, hasta el momento con nuestra billetera, podemos recibir Bitcoins
usando direcciones generadas. También podemos inspeccionar el
saldo recibido por cada dirección y verificar información sobre
nuestras transacciones. Ahora, comenzaremos a implementar
la capacidad de gastar esos bitcoins enviando transacciones a otras
direcciones que queramos. Así que comencemos a
crear una prueba llamada send Bitcoin test en
el paquete de prueba GUI. Extenderá la clase de prueba GUI. Vamos a añadir el mismo método de configuración. Agregamos otras dos pruebas, llamando a la billetera de carga
y agregamos método balanceado. Vamos a crear una prueba llamada
debería enviar Bitcoin. Ahora en el bloque eólico, creará una nueva
billetera y enviará un Bitcoin a su
primera dirección. El siguiente código será muy similar al código
de las otras pruebas. Después de enviar un Bitcoin
a nuestra dirección de billetera, haremos clic en la pestaña Enviar. Después haremos clic en el campo de cantidad para definir
cuánto queremos enviar. Enviemos 0.5 Bitcoin, que es la mitad de nuestro
saldo en este punto. Ahora, haremos clic en la
dirección para enviar el campo. En esta prueba se enviarán
bitcoins a otra dirección. Entonces usemos el Node get new address client para
obtener una nueva dirección de nodo. Después escribiremos la dirección
obtenida en la entrada clicada. Ahora, haremos clic en
el botón Enviar. Después de eso, esperamos que se abra
un modal con
información sobre la transacción
y un botón Ok para confirmar y enviar
la transacción. Entonces llamemos al
método click on pasando bien,
como su parámetro. Ahora haremos clic en
la pestaña de transacciones. Y con el siguiente código, verificaremos si la
tabla de transacciones tiene dos filas, una para la
transacción receptora y otra para la transacción que
acabamos de enviar. Ahora, vayamos al punto de
juegos FXML para diseñar nuestra pestaña Enviar. Duplicemos el código
para la pestaña Recibir. Y cambiemos
su texto para enviar. Eliminemos estas líneas así
comencemos con una
nueva pestaña nueva y fresca en la que trabajar. Ahora, vayamos
al Scene Builder. Vamos a hacer clic en la pestaña Enviar. Vamos a hacer clic en el
cuerpo de la pestaña para seleccionar el
componente del panel de cuadrícula dentro de ella. Vamos a establecer su
altura pref a 130, y su ancho pref a 600. Ahora agreguemos un control de etiqueta
al panel de cuadrícula dentro de
la pestaña Enviar. Pongamos diez a sus márgenes superior, derecho e izquierdo. Cambiemos su nombre
para abordar este fin. Ahora, agreguemos un
campo de texto a este panel de cuadrícula. Cambiemos su índice de columna
del panel de cuadrícula a uno. No nos está permitiendo hacer eso. Primero, tenemos que agregar una
columna al panel de cuadrícula. Hagamos clic con el botón derecho aquí y agreguemos dos filas y una columna
al panel de cuadrícula. Ahora podemos cambiar el índice de columna
TextField a uno. Pongamos diez a sus márgenes superior, derecho e izquierdo. Cambiemos su ancho
pref a 350. Cambiemos también este ancho de pref
Collins a 600. Agreguemos otra etiqueta
al panel de cuadrícula. Cambiemos su índice de
fila a uno, y pongamos diez en sus márgenes superior, derecho e izquierdo. Cambiemos también su
texto a cantidad a enviar. Agreguemos otro
campo de texto al panel de cuadrícula. Y pongamos su índice de fila uno y su índice de columna en uno. Vamos a establecer su altura pref a 26. Y es ancho pref a 100. Pongamos diez a sus márgenes superior, derecho e izquierdo. Ahora envolveremos el último campo de
texto insertado en un cuadro H. Entonces agreguemos una caja H
al panel de cuadrícula. Y sus
índices de fila y columna a uno. Vamos a mover este
campo de texto al cuadro H. También pongamos diez a
los ocho dólares en los márgenes superior, derecho e izquierdo. Ahora agreguemos una
etiqueta a la caja H. También pongamos estos márgenes diez y cambiemos su texto a BTC. En realidad, volvamos a poner estos
márgenes a cero. lugar, pondremos cinco
a estos paños. Ahora, agreguemos un
botón OK al panel de cuadrícula. Y pongamos su índice de
filas en dos. También pongamos estos
márgenes en diez. Y fijemos su texto para enviar. Ahora, copiemos todo el
contenido de la pestaña Enviar que hemos creado en
el playground dot FXML. Vamos a crear el envío de
subrayado tab dot FXML en el paquete FXML. Y peguemos el
contenido copiado en este archivo. Cambiemos la etiqueta de tabulación por
la etiqueta de raíz de colon ética. Vamos a establecer su tipo
a efectos Java, puntos vistos, control de puntos, pestaña de puntos. Ahora vamos a importar todas
las etiquetas restantes. Vaya, establecimos erróneamente
la propiedad type a etiquetar. Vamos a arreglarlo. Ahora, vamos a establecer el ID de
FX de estas etiquetas. Primero, vamos a establecer este
fx ID para enviar tab. Este fx ID a dirección, para enviar este fx ID
a cantidad a enviar, este fx ID para enviar. Ahora vamos a ir a la ventana de
subrayado principal punto FXML. Duplicemos esta línea y cambiemos esta etiqueta
para enviar el controlador de tabulador. Vamos a crear este controlador
en el paquete de controladores. Y vamos a importarlo aquí. Extenderá la clase tab y vamos a agregarle la
anotación de componente. Vamos a copiar el constructor de la
pestaña Recibir y pegarlo aquí,
ajustándolo en consecuencia. Inyectemos la
cartera actual en esta clase. Ahora agreguemos la clase Send
tab controller
al conjunto de componentes personalizados
en el listener iniciado GUI. Y cambiemos el valor de este parámetro para enviar
guion bajo tab dot FXML. Ahora asegurémonos de que nuestro nodo
Bitcoin se esté ejecutando. Y vamos a ejecutar nuestra prueba de
enviar Bitcoin. Como era de esperar, la
prueba ha fallado. En los próximos videos, seguiremos
implementando esta función. C, sí.
46. 44 transacciones de Bitcoin parte 2 skillshare: En este video, conoceremos más sobre las transacciones de Bitcoin. Más específicamente,
aprenderemos más sobre tamaño de la
transacción y las tarifas de
transacción. Este conocimiento será necesario más adelante cuando empecemos a construir transacciones para
transferir Bitcoins de nuestras billeteras a
otras direcciones. De la presentación anterior, aprendimos que la tarifa de
transacción es igual a la
suma de Bitcoin en entradas menos la suma de Bitcoins y salidas
de una transacción. Recuerda que la tarifa de
transacción es el precio que
pagas para que un menor recoja tu transacción del mental incluido en un
bloque y la mine. Cuanto mayor sea la tarifa de transacción, más rápido se
incluirá la transacción en un bloque. Con una pequeña tarifa de transacción, su transacción permanecerá
en el mental por más tiempo. Por lo tanto, es importante elegir
la tarifa correcta para asegurarse de que su transacción
se confirme en un tiempo razonable
sin pagarla de más. La tarifa de transacción
varía mucho con el tiempo. Su valor sigue la
lógica de la oferta y la demanda. Cuanto mayor sea el número de
transacciones que se envían, mayor tiende a ser
la tarifa de transacción. Y cuanto mayor es el
número de mineros, menor tiende a ser
la tarifa de transacción. Este gráfico muestra la comisión de transacción
promedio en dólares en los
últimos dos años. Observe que en este periodo, la tarifa de transacción
varió de un par de dólares a más de
60 dólares por transacción. Entonces, ¿cómo calculamos
la tarifa de transacción? Teniendo en cuenta que los bloques de
transacción tienen espacio
limitado pero demanda
ilimitada, tiene sentido
que las tarifas se calculen por tamaño de transacción. Existen diferentes
formas de obtener la tasa de comisión de
transacción recomendada. Por ejemplo, puede usar sitios web como Bitcoin
Fees, earned.com. Aquí podemos ver cuántas
transacciones tienen por tasa de comisión en las últimas 24 h. En
la columna de la derecha, vemos una estimación de
cuánto tiempo tardaría en confirmar una transacción con estas
comisiones en bloques y minutos. Si te desplazas hacia abajo, te da una tarifa recomendada para usar. Eso casi garantiza que su transacción será
confirmada en el siguiente bloque. Men pull dot space es otro sitio que junto
con gráficos geniales, muestran la
tasa de tarifa promedio para cada bloque, también muestra la tasa de
tarifa recomendada para usar en transacciones de baja, media y alta
prioridad. Cuanto mayor sea su prioridad, más rápido se espera que
se confirme la transacción. También podemos utilizar nuestro método de tarifa inteligente de
estimación de
Bitcoin Core Note RPC . Según su documentación, toma como parámetro,
un objetivo de confirmación, que es el número de
bloques que esperamos realizar transacciones con
la tasa de devolución tardará en confirmarse. También se necesita un parámetro
opcional para definir el modo de estimación, que puede ser desestablecido,
económico o conservador. La tasa de comisión se
devuelve en Bitcoin por kilo byte virtual o byte KV. Estos ejemplos muestran
que las
tarifas recomendadas pueden variar mucho
entre diferentes herramientas. Por simplicidad, en
nuestra billetera usaremos la llamada RPC de
teléfono inteligente de estimaciones Bitcoin Core, ya que no
requerirá que consultemos herramientas
externas con una tasa de tarifa. Y por lo tanto, podemos calcular la
tarifa de transacción multiplicando el
tamaño de la transacción en v bytes por la tasa de tarifa en
Satoshi es privy bite. Pero espera, ¿qué es
un byte virtual? Para calcular las tarifas de
transacción, hay dos
conceptos importantes a entender primero, tamaño
virtual y el byte virtual. El tamaño virtual, o tamaño V, es el tamaño de la transacción en bits
virtuales o v bytes. Son conceptos
inventados para dar cuenta del menor tamaño de las transacciones
Segway. El tamaño V se calcula de
una
manera compatible con versiones anteriores para que preestablezca qué
tamaños de transacción son iguales a preestablecer qué tamaños de transacción V. Para las transacciones Segway,
el tamaño V es igual
al tamaño de parte no testigo de una transacción más su tamaño
testigo dividido por cuatro. El testigo es un campo presente únicamente en transacciones Segway. Contiene los campos que en las transacciones
pre segmento se
ubicaron en el
campo ScriptSig de cada entrada. Esta forma diferente
de calcular los tamaños de
transacción da como resultado tamaños V de transacción
más pequeños para transacciones
Segway en
comparación con transacciones heredadas. Por ejemplo, para transacciones con
una entrada y una salida, las transacciones
Segway tienen un tamaño de
110 v bytes, mientras que las transacciones heredadas
tienen un tamaño de 192 v bytes. Para transacciones con una
entrada y dos salidas, las transacciones
Segway tienen un tamaño de
141 v bytes, mientras que las transacciones heredadas
tienen un tamaño de 226 v bytes. Finalmente, para transacciones
con dos entradas en salidas, las transacciones
Segway tienen un tamaño de
209 v bytes, mientras que las transacciones heredadas
tienen 374 bytes de tamaño. Entonces digamos que queremos
calcular la tarifa para una transacción segue
con una entrada y dos salidas con
una tasa de comisión de 19. Satoshi es un byte privado. Para ello, multiplicaríamos
su tamaño de transacción v, que es de 141 v bytes, por la tasa de comisión, que es de
19 Satoshi por v bytes. Eso daría 2 mil 679 Satoshi en honorarios por
esa transacción. Entonces, en resumen, para
construir una transacción, necesitaríamos construir
los siguientes ítems. Para una salida, necesitaríamos una dirección y una cantidad
para enviar a esa dirección. Si hay una necesidad de un cambio
y la mayoría de las transacciones lo hacen, entonces tendríamos que
construir una segunda salida que contenga una
dirección de cambio y una cantidad. También necesitaríamos un número
variable de entradas cuya suma de cantidad de Bitcoin
debe ser mayor que la cantidad a enviar más
la tarifa de transacción. Recuerda que una entrada se
referirá a una salida no gastada de una transacción anterior enviada
a una de tus direcciones. Se necesitará un cambio si
la suma de los montos ingresados es mayor que la cantidad a
enviar más la tarifa de transacción. Si por suerte o por diseño, la suma de los montos de entrada es igual a la cantidad a enviar más la tarifa de transacción que la transacción no
tendrá un resultado de cambio. Y el remitente se
beneficiará de pagar menos en tarifa de
transacción por una transacción
con solo una salida. Nuevamente, para calcular
la tarifa de transacción se necesitará la tasa de comisión en
Satoshi por v bytes. Obtendremos este valor
usando la estimación de la API de gRPC para
teléfonos inteligentes
de Bitcoin Core y convertiremos el resultado en Satoshi por mordida V también
necesitará el tamaño de la
transacción en v bytes. En el siguiente video, implementaremos la nota
estima Smart Fee, cliente y un servicio para
calcular el tamaño de la transacción. Posteriormente, combinaremos ambos para
calcular las tarifas de transacción. Verás, sí.
47. 45 Enviar bitcoin parte 2 skillshare 2: En este video, crearemos una
calculadora de tamaño de transacción y construiremos el cliente de nodo para
el método RPC de nodo Bitcoin de
feed inteligente de estimación . En el paquete api dot services, vamos a crear la clase de calculadora de
tamaño de transacción. Esta clase se
encargará de calcular los tamaños de las
transacciones de acuerdo a sus tipos y números
de entradas y salidas. Estos tamaños se
utilizarán posteriormente para calcular el monto de la tarifa que tenemos que
incluir en nuestras transacciones. Vamos a agregarle una
anotación de servicios. Primero, definiremos algunas
constantes en esta clase. Estas constantes contendrán los tamaños de cada parte
de una transacción. Dado que estamos trabajando solo con transacciones
Segway por ahora, estas constantes se referirán solo a partes de transacciones Segway. Entonces comencemos a definir el tamaño de los gastos generales de la
transacción. La sobrecarga es la
parte de la transacción cuyo tamaño no cambia con el número de entradas o salidas. La primera constante
se llamará inversión, que es parte de la sobrecarga. Codifica qué versión tiene
la transacción. Tiene cuatro bytes de tamaño. Entonces tenemos el conteo de entrada, que como su nombre indica, especifica el número de
entradas en la transacción. Tiene un
número variable de bytes, pero para hasta 252 entradas, su tamaño es de un byte. Entonces tenemos el campo
de conteo de salida, que tiene el mismo tamaño y
reglas que el conteo de entrada. Como su nombre indica, especifica el número de
salidas en la transacción. Entonces tenemos el campo de tiempo de
N lote, que tiene cuatro bytes. Este campo se
utiliza a veces para codificar el tiempo después del cual se puede gastar la
transacción. Entonces tenemos el
marcador y bandera Segway, que solo está presente
para transacciones Segway. Tiene dos bytes de tamaño. Ahora vamos a establecer los tamaños
de campo de entrada, comenzando por el outpoint, que tiene 36 bytes de tamaño. El punto es la combinación
del ID de transacción anterior y el índice de salida. Indica el UTXO
utilizado para esa entrada. Entonces tenemos el campo de
longitud ScriptSig, que estamos hasta 252
bytes, tiene un byte. Indica el
tamaño ScriptSig para la entrada. Entonces tenemos el campo
ScriptSiG. Para transacciones Segway. Su talla es cero. Recuerde que para las entradas de
segmento, el contenido de ScriptSig se
mueve al campo testigo. Ahora agreguemos el campo de secuencia
final. Tiene cuatro bytes de tamaño
y se utiliza para establecer si la transacción
es reemplazable en caso de que el remitente quiera
cambiar su tarifa. A continuación, agreguemos el campo de conteo de
testigos hasta
por 250 para atestiguar elementos. Tiene un byte de tamaño. Entonces tenemos el campo de ítems
testigo, que tiene un tamaño de
107 bytes para entradas P2, WP k, h. Este campo está compuesto por
la firma, que puede tener 71 o
72 bytes de tamaño, y la clave pública, que es de 33 bytes
de tamaño, 72 bytes, se elige como tamaño
para las firmas, ya que preferimos sobreestimar un poco el tamaño de la transacción. Por lo que se
garantiza que el F0 calculado sea suficiente
para la transacción. Los dos
bytes restantes que codifican el tamaño de la firma
y la clave pública. Explique los ítems testigo valor
constante de 107. Ahora vamos a establecer las constantes
con los tamaños de salida. El valor n es la cantidad de bitcoin que se envía
en esa salida. Tiene ocho bytes de tamaño. Entonces tenemos la longitud de la clave pub
script, que tiene un byte de tamaño para hasta 252 bytes en longitud de clave pub
script. A continuación, tenemos la clave pub
script, que tiene 22 bytes de tamaño
por un segundo, ¿qué direcciones? Ahora, antes de continuar
implementando el cálculo
del tamaño de transacción, vamos a crear la prueba de la calculadora de
tamaño de transacción en el paquete de prueba API. Extenderá la clase de
especificación. Agreguemos un campo de
calculadora de tamaño de transacción en esta clase. Y usemos un
método de configuración para instanciarlo. Ahora, vamos a crear
un nombre de prueba debe calcular el
tamaño de la transacción para P2, WP k, h
salidas de transacción y entradas. En el bloque de un solo bloque, llamaremos
al método de cálculo en el servicio de
calculadora de tamaño de transacción y almacenaremos el retorno en
la variable de resultado. Como parámetros pasarán
las entradas y salidas, cuales definiremos
en el bloque where. En el bloque se comprobará si el resultado es igual a la variable de tamaño
esperado. En el bloque where se sumarán
los siguientes casos de prueba. Para las entradas y
salidas las variables
establecerán listas con un
número variable de direcciones. Ya que por ahora, no nos
importa el tipo de direcciones, simplemente
agregaremos una carta
que represente cada dirección. Los valores de tamaño
esperados aquí se calcularon previamente para cada combinación de
entradas y salidas y se validaron usando
el Bitcoin Core CLI. Ahora, vamos a crear el método de
cálculo en la clase de
calculadora de tamaño de transacción. Devolverá un entero grande
y recibirá como parámetros una lista de direcciones de entrada y una
lista de direcciones de salida. Ahora, primero calculemos el tamaño
de los gastos generales. Es igual a la suma
de estas constantes. Recuerda que el
valor que queremos calcular aquí es el tamaño V. Por lo que los elementos de las transacciones
Segway, como el Segway,
marcador y bandera, deben dividirse por cuatro. Como tal, dividamos
esta constante por cuatro. Ahora, calculemos
el tamaño de entrada. Será la suma de
estas constantes. Ahora, calculemos el
tamaño de todas las entradas
multiplicando la variable de entrada por el número de direcciones de
entrada. Ahora, calculemos
el tamaño del testigo
agregando las constantes de recuento de
testigos y elementos testigos. Como segue ¿qué elementos? Dividamos su suma por cuatro. El
tamaño total del testigo es igual a la variable testigo multiplicada por el tamaño de las direcciones de entrada. Ahora, calculemos
el tamaño de salida. Será igual a la
suma de estas constantes. La variable de todas las salidas
será igual
al tamaño de salida multiplicado por
el número de salidas. Finalmente, el resultado
del tamaño de transacción será igual
al BigDecimal algunos de los valores calculados
previamente. También pongamos la
escala del resultado a
cero con el modo de redondeo a la mitad hacia arriba. Esto hará que el resultado tenga cero decimales redondeando
al entero más cercano. Si el
valor decimal resultante es cinco, entonces redondeará
al entero anterior. Ahora, devolvemos el resultado
convertido a entero grande. Ahora, vamos a ejecutar la prueba de la calculadora de
tamaño de transacción. Genial, La prueba ha pasado. Ahora vamos a crear el cliente de
tarifa inteligente de estimación de
nodo en el paquete de cliente nodo
punto. Inyectemos el cliente del
nodo en él. Y vamos a crear el método de la tarifa inteligente de
estimaciones. Devolverá un nuevo nodo que creará el objeto
FI, y tomará un entero
como parámetro. Ahora volvamos a hacer llamada al método
request
en el cliente del nodo. El nombre del método será
estimado smart fee. Su segundo parámetro será un nuevo objeto de referencia de
tipo parametrizado. Es tercero será
una cadena vacía y su último parámetro,
la variable blocks. Ahora vamos a crear
el registro del nodo V en el paquete de nodos de punto de dominios. Sus campos serán
una tasa de tarifa doble y una lista de errores. Ahora en el paquete api dot
services, vamos a crear una interfaz
llamada servicio de tarifa de estimación. Vamos a agregarle el
método de estimación. Devolverá un decimal grande. Ahora, vamos a crear una
implementación de esta interfaz. Nombres notan estimación tarifa
de servicio en el mismo paquete. Vamos a implementar su método. Esta clase se
utilizará más adelante para estimar la tarifa usando el nodo
estima el cliente Smart Fee. Si queremos cambiar el método de estimación de
tarifas o agregar más opciones
para hacerlo más adelante, simplemente
creamos otra
implementación de la interfaz de
servicio de tarifas estimadas. Primero, llamaremos al método de estimación del
teléfono inteligente desde el cliente creado previamente y se almacenará en la variable
nodo V. Vamos a inyectar este cliente en esta clase pasará a este método para que intentemos
obtener una tasa de comisión que
hará que nuestra transacción se
confirme en el siguiente bloque. Si por alguna razón
la tasa de tarifa devuelta resulta ser igual a nula, devolveremos la tasa de tarifa de
reserva. Inyectemos esta
variable en esta clase. Lo inyectará desde
los archivos de propiedades. Entonces agreguemos esta
anotación de valor antes de ella. Después de la
declaración if devolverá el gran valor decimal
de la tasa de comisión. Ahora agreguemos la propiedad bitcoin dot fallback fee rate property a todos los archivos
de propiedad del proyecto. Hagámoslo igual a 0.0 002.
48. Selección de monedas y polvo: En esta presentación,
continuaremos explicando conceptos
importantes para comprender
las transacciones de Bitcoin y
continuar construyendo nuestra función de transacción de
pecado. Entonces hablemos de la selección
de monedas. selección de monedas es el
proceso de seleccionar UTXOS para construir una transacción. La regla general para
esta selección es que la suma de
montos UTXOS Bitcoin debe ser mayor que la
cantidad de arena más la tarifa de transacción más
el cambio si es necesario. Hay muchos métodos diferentes de selección de
monedas. Cada uno tiene ventajas
y desventajas. El algoritmo que elegiremos para nuestra billetera se llama sorteo aleatorio
único. Probablemente sea el algoritmo de selección de
monedas más simple y lo suficientemente bueno
para nuestros propósitos. Este algoritmo se
presentó por primera vez en una tesis de
maestría titulada y evaluación de
estrategias de selección de monedas por Mark Earhart. Te recomiendo leer esta
tesis si quieres
saber más sobre estrategias de
selección de monedas. Este método de selección de monedas
se agregó a Bitcoin Core en septiembre de 2021 como una estrategia de selección de
monedas alternativas. Consiste en barajar
el gasto o UTXOS, luego seleccionar UTXOS uno por uno hasta que la suma de los montos UTXOS
seleccionados sea mayor o igual
a la cantidad a enviar más la tarifa de transacción más
el cambiar si es necesario. Si la cantidad de cambio es
menor que el límite de polvo, la salida de cambio
se elimina de la transacción y su monto se agrega a la tarifa de transacción. Pero espera un momento, ¿qué es el polvo? Una salida de polvo es una salida cuya cantidad de Bitcoin es menor que el
costo para gastarlo. El siguiente ejemplo muestra cómo las salidas de
polvo
no son económicas de gastar. Digamos que tienes un
UTXO que contiene 50 Satoshi's y quieres mandar estos 50 Satoshi's a un amigo. Al construir la transacción, descubres
que
la tarifa de transacción requerida para enviarla
equivale a 100 Satoshi's. Por lo tanto, no
tiene sentido que
gastes el UTXO con 50 Satoshi's ya que
pagarás más en cuotas que
la cantidad enviada. Además, tu amigo tampoco se
beneficiará de recibir un UTXO con 50 Satoshi's ya que tendría el mismo problema que tú lo estás gastando. Este ejemplo muestra
que es perjudicial para la red Bitcoin
crear salidas de polvo, ya que nadie en la
red se beneficia de ella. Por lo tanto, la mayoría de los nodos de
Bitcoin no relacionan transacciones
que contienen polvo. Esto ayuda a proteger la
red de los ataques de polvo. ataque de polvo es el proceso
de enviar
polvo maliciosamente a las direcciones de la billetera para
rastrear sus transacciones. Este ataque se muestra
en este ejemplo. Supongamos que la
agencia gubernamental envía polvo a la dirección X que
le pertenece a la persona. ¿Por qué? Cuando la billetera electrónica
construye ingenuamente una transacción, incluye la salida de polvo
y otras cinco como entradas. Ahora bien, la agencia gubernamental sabe por qué cinco direcciones anteriores y todas sus
transacciones anteriores. Además, el gobierno
conoce ahora la dirección de cambio de esa transacción y contrata otras transacciones con ella. Pero, ¿cuáles son los criterios para
considerar una salida como polvo? eso se usa el límite de polvo. Cada salida cuya cantidad de
Bitcoin es menor que el límite de polvo
se considera polvo. núcleo de Bitcoin utiliza la
siguiente fórmula para calcular el límite de polvo. El límite de polvo en Satoshi
de una salida de transacción es igual al tamaño de salida de la
transacción más el tamaño de entrada necesario para gastarlo tanto
en v bytes multiplicado por la industria frondosa
en Satoshi per KV bytes divididos por 1,000. El resultado representa el
costo de salida de transacción que una cantidad de
Bitcoin de salida de transacción debe ser igual o superar para
no ser considerada polvo. La tarifa de relé de polvo es una propiedad
de configuración del nodo Bitcoin. Es la tarifa de transacción utilizada al calcular el límite de polvo. La
tarifa predeterminada por relé de polvo se establece en 3,000 Satoshi por KV bytes o
tres Satoshi por mordida de V. Esto hace que el límite de
polvo predeterminado para las salidas de
segue sea igual a 294. Satoshi. El límite de polvo por defecto para
non segue qué salidas son iguales a 546 Satoshi. Para más detalles sobre el
cálculo del límite de polvo, este enlace del código
Bitcoin Core tiene un comentario explicando cómo se calcula el límite de
polvo. Ahora vamos a resumir
los pasos generales del algoritmo de
sorteo aleatorio único. El primer paso es barajar
todos los UTXOS de cartera en una lista. Después, para cada UTXO disponible
de la lista barajada, agregue ese UTXO a una lista
de UTXO seleccionados. Calcular el objetivo ajustado, que es igual a la
cantidad de arena más la tarifa de transacción más
el cambio si es necesario. Si la cantidad total de Bitcoin en la lista UTXOS seleccionada es mayor o igual
que el objetivo ajustado. Detener. Finalmente, utilice los UTXOS seleccionados como entradas de la transacción
deseada. Algunos puntos de atención
sobre este algoritmo, los objetivos
ajustados
con y sin la salida de cambio deben
calcularse para una mejor precisión ya que las tarifas de
transacción difieren entre las transacciones
con 1.2 salidas, si el cambio generado está entre cero y el límite de polvo, detenemos la iteración ya que
no incluiremos un cambio la transacción y así
no necesitamos más UTXOS. Esto es necesario
para no generar una salida de polvo para el
cambio por accidente. El inconveniente del algoritmo de
sorteo aleatorio único aparece en algunos casos patológicos, por ejemplo, cuando tienes un
único UTXO grande y muchos UTXO pequeños. una transacción con muchos
insumos y una tarifa de puede
crear una transacción con muchos
insumos y una tarifa de
transacción alta en lugar de usar el gran UTXO para evitar la
necesidad de muchos insumos. Cuando ese es el caso, se
recomienda
un enfoque diferente para construir
una transacción. Por ejemplo, elija manualmente los UTXOS que formarán parte de algunas transacciones
específicas. En el siguiente video, implementaremos una calculadora de
polvo y el
algoritmo de sorteo aleatorio único, C, sí.
49. 47 Enviar bitcoin parte 3 skillshare 2: En este video,
comenzaremos a implementar una calculadora de polvo y el algoritmo de sorteo aleatorio
único. Pero primero, vamos a refactorizar
el registro UTXO. Ya que haremos
muchos cálculos
con el campo de cantidad UTXO. Y los cálculos se
hacen mejor con decimales grandes en lugar de dobles cambiarán la cantidad tipo dos decimales grandes. Ahora, tenemos que refactorizar todos los usos del
campo de cantidad en el proyecto. Entonces hagámoslo. Cambiemos el
formato o parámetro de formato de Bitcoin a BigDecimal y ajustemos este
parámetro en consecuencia. Hagamos lo mismo
con todos los métodos que el IDE marcó como
errores en el proyecto. Aquí agregaremos grandes decimales
usando el método add. Y pasemos el gran valor
decimal cero en lugar del cero primitivo
a estas llamadas a métodos. Ahora, tenemos que
cambiar el tipo de este campo equilibrado
y todos sus usos. Vamos a refactorizar este
método para hacer la suma usando valores
decimales grandes. Ajustemos también este
código para hacer lo mismo, pero con grandes valores decimales. Bien, la refactorización está hecha. Ahora en el paquete de
servicios api dot. Vamos a crear la clase de
calculadora de polvo. Vamos a agregarle la
anotación de servicio. Vamos a crear estos métodos de
polvo en él. Como su nombre indica, devolverá true si una cantidad se
considera polvo falso, lo contrario, devolverá
un Booleano y tomará un entero grande como parámetro que representa la
cantidad en De Satoshi. Este método evaluará
si la cantidad en Satoshi's de un producto es menor que el
costo para gastarlo. El costo del gasto es igual
al tamaño V de la salida más el tamaño v de la entrada
necesaria para gastarlo, que almacenará
en estos
tiempos constantes los pies de relé de polvo en
bytes por kilo v de Satoshi dividido por 1,000. Como por ahora trabajaremos solo con salidas
sigmoides, solo nos
preocuparemos por el límite de
polvo para las salidas de segue. Así que vamos a crear esta constante
que será igual a 98. Este valor se toma
directamente
del archivo punto cpp de
política Bitcoin Core mencionado en la
última presentación. Inyectemos también la tarifa del
relé de polvo en esta clase. Estará a lo largo y su valor será inyectado
desde el archivo de propiedades. Vamos a agregar la siguiente anotación de
valor antes de ella. Ahora agreguemos este valor
a todos los archivos de propiedades. Vamos a establecerlo en 3,000, el mismo valor predeterminado utilizado
en el Bitcoin Core Node. Ahora en el paquete api dot
services, vamos a crear la interfaz del
selector de monedas. Creará esta interfaz para que permita
mayor flexibilidad. Si queremos crear más implementaciones de selector de
monedas más adelante. Vamos a agregarle el
método select. Devolverá una lista
de UTXOS seleccionados. Y nos llevará parámetros, una lista de UTXOS, un entero grande por
la cantidad a enviar, un decimal grande para la tasa de tarifa, y dirección a enviar, y una dirección de cambio. Ahora en el mismo paquete, vamos a crear el único selector de monedas de sorteo
aleatorio, que implementará
esta interfaz. Implementemos su método y le agreguemos una
anotación de Servicio. Inyectemos la calculadora de
tamaño de transacción en esta clase. Y vamos a inyectarle la calculadora de
polvo. Antes de continuar
implementando el método de selección, vamos a crear el
único sorteo aleatorio una clase de prueba de selector de monedas. En la clase de prueba API. Extenderá la clase de
especificación. Inyectemos el único sorteo
aleatorio en esta clase. Y usemos el
método de configuración para instanciarlo. Pasemos la calculadora de
tamaño de transacción y la calculadora de polvo con una tarifa de relé de polvo de
3,000 como sus parámetros. Ahora, vamos a crear una prueba Tidal debería seleccionar n entradas esperadas, monedas para transacción con salidas
esperadas y salidas. Ahora vamos a crear una
clase de utilidad que nos ayude a probar e implementar el selector único de monedas de sorteo
aleatorio. Vamos a llamarlo Satoshi y
creado en el paquete utils. Ahora, vamos a crear el método de los
dos Satoshi. Tomará un decimal grande como parámetro y
devuelve un entero grande. Este método
convertirá una cantidad en Bitcoin a la misma
cantidad en Satoshi's. Para ello, simplemente devolvemos
la cantidad en Bitcoin
multiplicada por 100 millones y
convertimos multiplicada por 100 millones y el resultado
a un entero grande. Creemos también un método
para hacer la operación inversa, que es convertir
Satoshi's a Bitcoin. Para eso, solo devolveremos
la cantidad envuelta en un nuevo decimal grande
dividido por 100 millones. En el método de división
pasará ocho como segundo parámetro para hacer que el resultado tenga ocho
decimales. También pasaremos
el modo de redondeo innecesario como
tercer parámetro. Ahora, vamos a crear un método
para convertir una tasa de comisión en Bitcoins por bici KV a
Satoshi por V byte. Se llamará BTC por KB
a los de Satoshi por byte. Devolverá un entero grande y tomará como parámetro
un decimal grande. Primero, multiplicaremos la tasa de
comisión por 100 millones. Después dividiremos el resultado por 1024 con dos decimales
y un modo de redondeo de piso. Entonces vamos a convertir el resultado a un entero grande y
almacenarlo en la variable derecha. Si el resultado es menor que uno, entonces lo hacemos igual a uno. Finalmente, devolvemos
la tasa convertida. En el siguiente video, terminaremos de probar
e implementar el selector único de monedas de
sorteo aleatorio C. Si.
50. 48 Enviar bitcoin parte 4 Skillshare 2: En este video, terminaremos implementar el algoritmo de sorteo
aleatorio único. En la prueba de
selección de monedas de sorteo aleatorio único en un bloque dado, primero
crearemos UTXOS usando este método y almacenaremos el
resultado en la variable UTXOS. Estos serán los UTXOS
disponibles que
pasarán como primer parámetro
al método probado. Así que vamos a crear este método. Tomará como parámetro una lista de
enteros grandes, que definirá la
cantidad de cada UTXO. Entonces, para cada elemento de la lista, llamaremos al método
create UTXO para crear un único UTXO. Vamos a crear este método. Instanciemos un UTXO
con estos parámetros. Puede copiar estos valores
de los recursos de esta lección. Ahora, vamos a crear un UTXO
adicional y agregarlo a la lista de
UTXOS usando este código. La razón para agregar un UTXO adicional a la lista es que
queremos permitir el método select lo agregue erróneamente
a la lista de UTXOS seleccionada. Si ese es el caso,
sabremos que el método probado no está
funcionando como se esperaba. Definamos estas
dos direcciones. Uno para ser la dirección a enviar y el otro para ser
el cambio de dirección. Puedes copiarlos desde la página
Proyecto y Recursos. Fijemos la
tasa de comisión en 0.0 002. En el bloque de viento, llamaremos al método single random
draw select con estos parámetros. En el bloque entonces comprobará si el tamaño UTXOS seleccionado es
igual al número esperado de entradas variable
en el bloque where. Agreguemos estos casos de prueba. Los puedes encontrar en la página
Proyecto y Recursos. Estos casos de prueba cubrieron
transacciones con 12.3 entradas y
con 1.2 salidas. los montos de entrada para
transacciones con Se espera
que los montos de entrada para
transacciones con
una salida no generen cambios o
generen cambios con polvo cuyo valor se
agrega a la comisión. que los montos de entrada para
transacciones con Se espera que los montos de entrada para
transacciones con
dos salidas
generen non does change, que regresa al remitente a
través de una segunda salida. Vamos a hacer la prueba. Ha fracasado como se esperaba. Ahora, vamos a implementar el método de selección de
sorteo aleatorio único. Primero, filtraremos todos los UTXOS
recibidos para crear una lista con solo UTXOS que tengan una o
más conformaciones. Así que vamos a crear este
método. Para hacer eso. Llamaremos al
método de filtro en la transmisión de UTXOS, devolviendo una lista con
solo UTXOS confirmados. Ahora, vamos a crear
esta variable para almacenar la tasa de tarifa en
Satoshi por V byte. Para eso, usaremos
el método BTC por KB a Satoshi por bicicleta
de la clase Satoshi. Ahora, vamos a almacenar los
UTXOS barajados en esta variable, asignándole el retorno de
esta llamada al método. Vamos a crear este método. Primero, instanciaremos
un nuevo ArrayList que contenga el contenido de la lista
UTXOS. Después llamaremos al método de reproducción aleatoria de
colecciones, pasando la nueva lista
como su parámetro. Después devolveremos la lista de monedas
barajadas. Ahora instanciemos
una ArrayList que almacenará los UTXOS
seleccionados. Y vamos a crear esta variable para almacenar el saldo total
de entrada. Ahora, para cada UTXO de
la lista de monedas barajadas, agregaremos el UTXO a
la lista UTXO seleccionada. Y agregaremos su cantidad en Satoshi a la variable balanceada
de entrada total. Si el saldo total de entrada es menor que la cantidad ascendida, continuamos la ejecución
desde la siguiente iteración del bucle. Después de la sentencia if, cuando el
saldo total de entrada supere la cantidad a enviar
instanciará una ArrayList con
las direcciones de salida y agregará la dirección
a enviar a esa lista. Y crearemos una lista
con las direcciones de
las entradas seleccionadas usando
este mapeo de flujo. Ahora, calculemos
la cuota total en Satoshi's y almacenemos
en esta variable. Para eso, llamemos
al método de tarifa total, pasando la tasa de tarifa en
Satoshi's por V mordida las direcciones de entrada y
las direcciones de salida
como sus parámetros. Vamos a crear este método. En su interior devolverá la
calculadora de tamaño de transacción calcular método de llamada pasando
las direcciones de entrada y las direcciones de salida
como sus parámetros. Después multiplicaremos
el resultado con la tasa de comisión en
Satoshi por V mordida. Ahora crearemos la variable objetivo
ajustada, que será igual
a la suma
del monto a enviar
y la tarifa total. Ahora agreguemos la
dirección de cambio a la lista de
direcciones de salida. Calcularemos la tarifa
total con cambio, llamando al método de tarifa total,
pasando estos parámetros. Y calcularemos el objetivo
ajustado con cambio, que será igual a
la suma de la cantidad de arena y la
cuota total con cambio. Ahora bien, si el resultado
del
método de transacción
cumplida balanceada de entrada con estos parámetros es verdadero, saldremos del bucle
usando la palabra clave break. Vamos a crear este método. Devolverá el resultado de
la siguiente declaración. Si el saldo total de entrada
es igual o mayor que el objetivo ajustado y el
generado cambia de polvo, entonces significa que
los UTXO seleccionados son suficientes para cumplir con
esta transacción. Otra condición para que
los UTXOS
seleccionados cumplan con la transacción es que son cantidades que la
suma es igual o mayor que el
objetivo ajustado con cambio. Vamos a crear el método de cambio es polvo devolverá
la calculadora de
polvo es llamada método de polvo pasando la gran
diferencia entera entre el saldo total de entrada y el objetivo ajustado
como su parámetro. Finalmente, simplemente devolvemos los UTXOS seleccionados
de este método. Ahora, vayamos a la prueba del selector de monedas de un solo sorteo
aleatorio y ejecutemos esta prueba. Grado. Ya pasaron las pruebas.
51. Cómo se construyen y validan las transacciones de Segwit: En esta presentación, veremos más detalles sobre cómo
crear una transacción. Entonces digamos que ya
usamos el selector de monedas para seleccionar algunos UTXO para gastar
como entradas en una transacción. En nuestro monedero, también
tenemos la capacidad de
derivar las claves privadas necesarias
para gastar estos UTXOS. Estas claves privadas serán necesarias para firmar la
transacción posteriormente. Ya elegimos una
dirección para enviar algunos Bitcoins. Y tenemos la dirección de cambio a
donde
se enviará el cambio. Después de definir estas cosas, es el momento de construir
nuestra transacción. Veamos los campos que forman parte de una transacción de Bitcoin. En primer lugar, el campo de la versión. Se utiliza para definir las reglas que sigue la transacción. Actualmente, la versión
uno, que
utilizaremos es para transacciones comunes. versión dos es para transacciones que
siguen al BIP 68, que implementa
reglas para validar una transacción solo
después de cierto tiempo. El campo de vida útil se utiliza
para un propósito similar. Su valor puede representar
un cierto tiempo para agregar una transacción a un bloque o
cero para ignorar esta regla, entonces tenemos el seg
sería flag y marcador. Sólo está presente en las transacciones
Segway. Si su valor es 0001, entonces marca esta transacción como habiendo dicho qué entradas, cada transacción tiene una o
más entradas de transacción. Cada entrada de transacción tiene un ID de
transacción que define una transacción anterior
a partir de
la cual la entrada actual está
gastando Bitcoins. El índice de salida indica qué salida de la transacción
anterior. El insumo actual está
gastando Bitcoins de. Juntos, el ID de transacción y el índice de salida
se denominan punto de salida. Puede ver el punto fuera
como una coordenada para
identificar a qué UTXO
y entrada se refiere. A continuación, para cada entrada, tenemos el campo ScriptSig. En entradas de segmento. Este campo está vacío y su contenido se mueve
al campo testigo. En las transacciones no segmentadas, su contenido es necesario para desbloquear
el gasto del UTXO. La entrada se refiere a. El campo de secuencia n define cuándo la entrada es
válida para gastar. Cuando este
valor de campo es igual
al valor hexadecimal máximo para su tamaño, este campo se ignora. Una transacción también tiene
una o más salidas. Cada salida contiene
una clave de pub script, que tiene un código de script que
define las reglas para gastar esa salida en
una transacción futura. Cada salida también contiene
un campo de cantidad que define el número de Satoshi
bloqueado en esa salida. Por último, las transacciones también
contienen un campo testigo. Para transacciones que no sean Segway, este campo está vacío. Para las transacciones Segway, el testigo contiene
todo el contenido que en
las transacciones no secuitur está en el scriptSIG
de cada entrada. Ahora
hablemos de cómo construir entradas de
transacción y el campo testigo
para entradas de segmento. Para cada UTXO seleccionado, tenemos que construir una entrada de
transacción. El campo ID de transacción de la
entrada de transacción será igual al ID de transacción UTXO. El campo de índice de salida será igual al índice de salida UTXO, también conocido como Vout en la documentación de la
API de Bitcoin Core RPC. El scriptSig estará vacío y la secuencia final será igual
a este valor hexadecimal, que es el valor máximo
permitido para ese campo. También tenemos que construir un
testigo por cada entrada, el campo testigo
contendrá una firma obtenida usando la clave privada utilizada
para derivar la dirección UTXO. Y una clave pública que
se derivó utilizando la
clave privada anterior y que también puede generar la misma
dirección UTXO mencionada. Veremos más detalles sobre el proceso de firma en
una presentación futura. Observe las
firmas ficticias y los bupkis, cuyos valores pueden ser
un montón de ceros, se
pueden usar como marcadores de posición para crear y firmar transacciones. Este truco facilita el cálculo
del tamaño de la
transacción v antes de
firmar las transacciones. Ahora hablemos de cómo
crear segue qué salidas. Primero. En una nota al margen, es posible crear
una transacción con diferentes tipos de
entradas y salidas, por ejemplo, en una misma transacción, puede tener entradas y salidas de
segmento y no segmento. Volver al tema principal. Generalmente, queremos crear una salida para la
dirección a la que queremos enviar bitcoins y una salida para la dirección de
cambio. Si la transacción
necesita un cambio. Cada salida de transacción tiene
un campo de clave de pub script. Cada segmento script pub key, también conocido como pay to
witness pub key hash o P2, WP k H tiene una
versión testigo de cero. La versión testigo es
una para guiones de raíz principal. Se pueden agregar nuevas versiones para
futuros scripts si es necesario. El segundo elemento clave
pub script para salidas
sigmoides es
un hash de clave pública, que es obtenido por Beck 32 decodificando la dirección
para esa salida. La salida de la transacción también
tiene un campo de cantidad en Satoshi que representa
la cantidad enviada a esa dirección de salida. Ahora, terminemos esta
presentación hablando sobre la
ejecución y validación del script del segmento. Cuando un nodo recibe
una transacción, comienza a validarla. Para cada entrada en una transacción, el nodo combina
el testigo de una entrada con la clave
pub script del UTXO referido por el
outpoint y net input ejecuta el
script combinado y lo valida . Veamos cómo se hace eso. Aquí está el script pub key de un UTXO y el
campo testigo que quiere gastar ese UTXO ambos generan el
siguiente guión combinado. Es posible que se esté preguntando de
dónde
provienen los códigos de operación del
script combinado. Resulta que cuando
un nodo identifica la versión cero en la clave pub script de
segmento, desencadena una regla especial que genera parte del código
combinado a continuación. A continuación, el script combinado se ejecuta igual que
los scripts que no son secuiturs. A partir del script combinado, la firma y las claves públicas se agregan a una pila de ejecución. Entonces el opcode OPT up duplica la clave pub
en la pila de ejecución. Hasta hash 160 hashes, la última clave de pub
agregada a la pila. Luego, desde el script combinado, se
agrega
el hash de la clave de pub a la pila. Up equal verify opcode elimina los dos últimos elementos de la pila de ejecución
y los compara. Si son iguales, el script
continúa ejecutándose. Finalmente, el opcode
sig objeto comprueba si la firma es válida para la clave pub que queda
en la pila. Si es válido, devuelve
true a la pila de ejecución. Después de agregar todos
los elementos del script a la pila de
ejecución, la entrada de transacción se
consideraría válida si el último elemento
agregado es verdadero. Este proceso debe repetirse para cada entrada de transacción. Para que una transacción
se considere válida, todos sus insumos deben ser válidos. Así como un recordatorio visual, repasemos de
dónde
vino cada elemento en la clave del pub script y testigo la clave del pub script y testigo durante la
construcción de la transacción. El hash de pub key presente en el script pub key
vino de atrás 30 a decodificar la dirección
del UTXO que se está gastando. La firma en
el testigo llegó
aplicando el algoritmo ECDSA, cual necesita una clave privada válida. La clave pública y
el testigo procedían de la clave pública derivada de
la mencionada clave privada. La misma clave pública
se utilizó en el pasado para generar la dirección
del UTXO que se está
gastando aplicando secuencialmente el algoritmo hash 160 y la codificación
back 32.
52. 50 Enviar bitcoin parte 5 skillshare 2: En este video, crearemos un servicio de creación de transacciones. En un principio, este servicio sólo se
ocupará de
entradas y salidas de segmento, pero más adelante en el curso, lo
mejoraremos. Entonces, en el paquete de
servicios api dot, vamos a crear el servicio de
creadores de transacciones. Vamos a agregarle la
anotación de servicio. Inyectemos también la calculadora de
polvo en él. Ahora en el paquete de prueba API, vamos a crear la clase de prueba de servicio de
creadores de transacciones. Extenderá la clase de
especificación. Inyectemos el servicio de
creadores de transacciones en él, y vamos a
instanciarlo en el método de configuración. Necesitará instanciarlo
con una nueva calculadora de polvo pase 3,000 ya que es el parámetro de tarifa de relé de
polvo. Antes de hacer esta prueba, vamos a la prueba de selector de monedas de
sorteo único aleatorio para hacer un poco de refactorización. Cortemos estos dos métodos de esta clase y los peguemos en la nueva
clase utils que crearemos en el paquete de prueba BYOD W. Hagamos estáticos estos
dos métodos. Ahora, arreglemos la
única moneda de droga aleatoria. Seleccione su prueba para usar estos
métodos de esta clase. Ahora, vayamos a la prueba de servicio de
creadores de transacciones. Vamos a crear una prueba
llamada debe crear transacción con
hashtag n entradas, entradas y hashtag esperado
n salidas, salidas. En el cuerpo dado. Primero vamos a
crear esta variable UTXOS y asignarle la
llamada al método utils dot create utxOS que se le devuelve, pasando la
variable input amounts como su parámetro. Ahora, vamos a crear esta
dirección para enviar variable. Su contenido será igual
a la variable con
el mismo nombre en la prueba de selección de monedas de sorteo único aleatorio. También vamos a crear la variable de
cambio de dirección, que será igual
a la variable con el mismo nombre en el único sorteo
aleatorio de una moneda,
seleccione su prueba. Vamos a crear la variable de
tasa de comisión, que será igual a 0.000 a. Definamos también la variable de tarifa total
esperada, que será igual a la variable de tamaño
esperado multiplicada por la tasa de tarifa en
Satoshi por V mordida. Ahora, vamos a crear la
variable cantidad total de entrada. Su valor será igual al
resultado de esta expresión, que devolverá la suma de cada cantidad UTXO en Satoshi. El monto a enviar
variable será igual a 100 millones de Satoshi. Calculemos también la cantidad de cambio
esperada. Será igual a
la cantidad de entrada menos la cantidad de arena menos
la tarifa total esperada. En el bloque de un solo bloque, llamaremos
al creador de transacciones, el método create pasará los siguientes
parámetros a este método. El resultado se almacenará en
la variable de transacción. En el bloque entonces comprobará si el tamaño de la transacción v es igual a la variable de
tamaño esperado. Pero primero, actualicemos la versión
Bitcoin Java a 0.4, 0.2 para hacer disponible el método get v
size. Ahora, verificaremos
si el número de salidas de transacción es igual a la variable esperada y
salidas. También verificaremos si la primera cantidad de salida es igual a la variable cantidad
a enviar. Ahora, si el número esperado de salidas es mayor que uno, comprobará si el
monto de cambio es igual
al segundo monto de salida
en la transacción. En el bloque donde. Agreguemos
los siguientes casos de prueba. Puedes copiarlos desde la página
Proyecto y Recursos. Estos casos de prueba cubren escenarios
con y sin
salidas de cambio y con cantidades de entrada que generan
cambios o no. También cubrieron transacciones
con 12.3 insumos. Ahora vamos a crear el método de creación del
servicio de creadores de transacciones. Cambiemos el nombre de estos parámetros. Antes de implementar este método, vamos a crear la clase de tarifa
en el paquete utils. Aquí crearemos un
método para calcular la
tarifa total de transacciones en Satoshi's, llamémoslo tarifa total
calculada. Recibirá una transacción en la tasa de comisión en Bitcoin por mordida
KV creará el siguiente código dentro de
un bloque try catch. Primero, convertiremos la
tasa de pago de Bitcoins por bicicleta KV a Satoshi
is privy byte. Luego devolveremos el resultado
multiplicando el tamaño de la transacción
v por la tasa de tarifa en Satoshi por mordida de
V atrapará una IOException que
puede ser lanzada por el buen método de tamaño V y rápido en una nueva excepción de tiempo de
ejecución. Volver al servicio de
creadores de transacciones. En este método primero se
construirán las entradas de transacción
utilizando este método, pasando los
UTXOS recibidos como su parámetro. Vamos a crear este método. Devolveremos el resultado de la siguiente transformación
de
flujo UTXOS no la transmisión en una nueva entrada de transacción pasará el
ID UTXO recibido como su primer parámetro. El valor entero grande de la UTXO jurada como su
segundo parámetro. Estos dos parámetros definen el outpoint de entrada de transacción. A continuación, pasaremos un nuevo script instanciado con una lista vacía. Este parámetro es la entrada de
transacción ScriptSig, que está vacía para las entradas de
segmento. A continuación, pasaremos un entero grande instanciado con
estos parámetros, que define la
entrada en secuencia. Este valor es el
valor máximo permitido para este campo, haciendo que los nodos lo ignoren. Ahora, para cada entrada de
transacción en el flujo se utilizará el
método pico para establecer el testigo, se instanciará al testigo
con una lista que contiene constantes para una
firma ficticio y una clave de pub ficticio. Ahora vamos a crear
estas constantes. La firma ficticio
será igual a la cadena hexadecimal
cero repetida 144 veces, cuyo tamaño en bytes
es igual a 72. La clave de pub ficticio será igual
a la cadena hexadecimal cero repetida 66
veces cuyo tamaño en bytes es igual a 33 establecerá estos valores ficticio
porque serán necesarios para hacer
correctamente el transacción
v tamaño cálculo, que hará en
el método create, el proceso de firma se hará por separado más adelante cuando
los valores reales, vamos a sustituir los ficticio. Finalmente,
convertiremos el stream en un ArrayList y lo devolveremos. Ahora, construiremos la salida de la
transacción para la dirección a enviar usando
el método buildup PUT, pasando
como parámetros
la dirección a enviar y la cantidad a enviar. Vamos a crear este método. Primero, vamos a analizar
el prefijo de dirección usando el
método parse prefix, que creará. Este método
verificará si la dirección comienza con uno de los prefijos de segmento
válidos, y devolverá
el prefijo de dirección o una cadena vacía si no se encontró un
prefijo válido. Ahora vamos a construir un objeto script usando la clase de script P2, WP k h método de script. Como su parámetro
pasará el resultado del back 30 para
decodificar la llamada al método, pasando el prefijo y la
dirección a este último. El retorno del método back
30 to decode es una matriz de objetos donde el segundo elemento
es el hash de la clave pub, que pasará al método de script
P2 WP k h. Este método devolverá el equivalente de
la clave pub script, donde el primer
parámetro es cero y el segundo parámetro
es el hash de la clave pub, como explicamos en la
última presentación. Finalmente, devolveremos una
nueva salida de transacción instanciada con la cantidad
y el script creado. Ahora, crearemos una ArrayList para almacenar las salidas de la
transacción, instanciaremos
, agregándole la dirección para enviar la salida que
acabamos de crear. A continuación, crearemos
la transacción pasará como sus parámetros, el entero grande,
que es la versión de la
transacción. Las entradas de transacción,
las salidas de la transacción. El cero entero grande es el tiempo de bloqueo que
será ignorado. Y el booleano verdadero para definir esta transacción como
una transacción segue. Este parámetro hará que la transacción tenga el marcador y el indicador
Segway. Ahora, calculemos la tarifa de transacción
total usando el método
F0 calculado total que hemos creado anteriormente
en la clase FI. Pasaremos la transacción y la tasa de comisión como sus parámetros. Calculemos también
la zona de entrada para eso mapeará el flujo UTXO en
un flujo de cantidades UTXOS. Entonces usaremos el
método reducido para sumarlos. Finalmente,
convertiremos el resultado es una ptosis o cero si
los UTXOS no existen. A continuación, calcularemos el
cambio que será igual a la suma de entrada menos la cantidad de arena menos la tarifa total. A continuación, agregaremos la
siguiente declaración if. Usando la calculadora de polvo comprobará si el
cambio es polvo. Si lo es, entonces devolveremos
la transacción tal cual. Si no lo es,
agregaremos otra salida a la transacción usando
el método de salida de compilación, pasando la dirección de cambio
y el número entero grande ya que sus parámetros pasarán uno a la cantidad de salida
solo como un valor de marcador de posición, ya que tendremos que recalcular
la tarifa de transacción para la transacción que ahora tiene dos salidas lo que
exige una tarifa más alta. Entonces, recalculemos
la tarifa total utilizando el método F0
calculado total. Nuevamente, vamos a
recalcular el cambio que será igual a
la suma de entrada menos la cantidad a enviar menos la
nueva tarifa total calculada. Ahora, eliminemos la última salida de transacción
agregada de las
salidas de transacción ArrayList. Comprobemos de nuevo si el nuevo cambio
calculado es polvo. Si lo es, entonces devolverá la transacción sin cambios. Si no lo es,
agregaremos una nueva salida a la transacción usando
el método de salida de compilación. Esta vez, pasaremos el valor de cambio
real para la transacción con dos
salidas a este método. Por último, devolveremos
la transacción. Ahora vayamos a la prueba de servicio de
creadores de transacciones y ejecutemos esta prueba. Genial, las pruebas
han pasado desde que previamente
cambiamos la prueba de selección de
monedas de sorteo aleatorio único. También volvamos a ejecutarlo para asegurarnos de que no hemos
roto nada. Son geniales. Está funcionando como de costumbre.
53. 51 Enviar bitcoin parte 6 skillshare 2: En este video,
comenzaremos a crear la ventana que aparecerá cuando hagamos clic en
el botón Enviar. Esa ventana contendrá información sobre
la transacción. Estamos enviando un campo de
contraseña y un botón Ok para confirmar
la transmisión de la transacción. Así que en el paquete FXML, vamos a crear el archivo FXML de punto de diálogo de
subrayado de transacción de subrayado de envío . Vamos a borrar la letra estándar
generada. Ahora, vamos a crear una etiqueta de dolor de
diálogo. Ahora, cambiemos la vista
a Scene Builder. Vamos a establecer el diálogo
dolor pref altura a 300. Y es ancho pref a 650. Y hagamos el
min-height min-width para usar el tamaño de la prensa. Ahora, agreguemos un panel de cuadrícula
al contenido del diálogo. Agreguemos cuatro
filas más a este panel de cuadrícula. Ahora agreguemos una etiqueta
a la primera fila. Cambiemos su texto para enviar el signo de interrogación de
transacción. Aumentemos su
tamaño de fuente a 16 píxeles. Para las siguientes filas, la
idea aquí es agregar etiquetas y datos para la transacción de
envío. Agreguemos una etiqueta a la segunda fila y cambiemos su texto a
cantidad para enviar dos puntos. En la segunda columna
de la misma fila. Agreguemos otra etiqueta. Esta vez su texto
estará vacío y le agregaremos un Fx ID para que podamos cambiar su contenido
dinámicamente más tarde. Agreguemos otra etiqueta
en la tercera fila, esta vez con el texto de
las tarifas totales en la celda de la derecha. Agreguemos una etiqueta vacía con otro FX ID. En la fila de abajo. Agreguemos otro par de
etiquetas para el campo total. En la siguiente fila. Agreguemos
estas etiquetas para la tasa de tarifa. Ahora, hagamos lo mismo
para la dirección a enviar. En la última fila. Agreguemos una etiqueta para la contraseña de la billetera. En la celda de la izquierda. Agreguemos un campo de contraseña. Tendrá un ID FX de contraseña
de billetera. las etiquetas repentinas
les falta dos puntos al final.
Vamos a arreglarlos. Ahora. Vamos a la configuración del dolor de
diálogo y agreguemos un botón OK aquí. También agreguemos un botón de cancelación. El texto del botón Cancelar está
en mi lengua materna. Si ese también es tu caso, puedes cambiarlo
haciendo lo siguiente. Vamos a la vista del editor. Primero, agreguemos una idea
de Fx de bien al botón Bien. Y agreguemos una idea de Fx de cancelar a la etiqueta del botón cancelar. Ahora, eliminemos esta propiedad. Vamos a establecer la
propiedad de los datos del botón a este valor, y vamos a establecer su
texto para cancelar. Ahora, en el Scene Builder, podemos ver que el
cambio entró en vigor. Ahora, vamos a
la pestaña Enviar FXML. En el botón Enviar, vamos
a
establecer la propiedad action en hashtag send para que cuando
hagamos clic en este botón, al método send del controlador de
pestañas Enviar se llame
al método send del controlador de
pestañas Enviar. Así que vamos a crear este método. Antes de
implementarlo, vamos a crear un registro DTL de transacción
en el paquete de dominios. Ttl significa objeto de
transferencia de datos, y es un
patrón de diseño común para usar para objetos cuyo propósito principal
es transferir datos entre clases
y métodos. Como tal, el
DTO de transacción se utilizará para transferir
datos de transacción entre nuestros servicios. Vamos a agregarle los siguientes
campos. En este punto, es posible que se esté
preguntando cuál es la diferencia entre la tarifa real total
y el total calculado v? Llegaremos a eso en breve. Ahora, vayamos al controlador de pestañas
Enviar. Vamos a agregarle los siguientes
campos. Estos campos se vincularán a las etiquetas correspondientes en
la pestaña Enviar archivo FXML. Ahora vamos a implementar
el método send. Primero. Convertiremos la cantidad a enviar texto en una cantidad decimal grande. Ahora, crearemos un objeto DTO de
transacción usando el
servicio create transaction que creará. Inyectemos este
servicio en esta clase. Vamos a crearlo en el paquete de servicios GUI
dots. Ahora, terminemos de
inyectarlo en esta clase. Aquí llamaremos al método
create en él, pasando la dirección para enviar
texto y la variable amount. Vamos a crear este método. Ahora, usaremos este método
para abrir la ventana de diálogo, pasando el
DTO de transacción como su parámetro. Vamos a crearlo. Después de
abrir la ventana de diálogo, llamaremos al método clear en la dirección a enviar
y la cantidad a enviar variables para borrar el
contenido en estas entradas. Ahora, vayamos al servicio de creación de
transacciones. Vamos a agregarle la
anotación de servicio. Implementaremos
el método create. Ahora, la idea aquí es utilizar muchos de los
servicios que hemos construido en los videos anteriores para
crear una transacción y algunos datos adicionales para
el DTO de transacción. Para eso,
lo primero que haremos es utilizar el servicio de tarifa estimada para obtener la tasa de tarifa y almacenarla
en la variable de tasa de tarifa. Entonces, vamos a inyectar este
servicio en esta clase. Y llamemos al método de
estimación en él. Ahora, obtendremos las direcciones de billetera
cargadas actualmente usando el objeto wallet actual. Entonces vamos a inyectarlo
en esta clase. Entonces llamaremos a
las direcciones get como método de cadenas en él. A continuación, obtendremos todos
nuestros UTXOS de cartera. Para eso, usaremos la lista de
nodos cliente no gastado. Entonces vamos a inyectarlo
en esta clase. Llamaremos al método list
unused en él, pasando las direcciones y el nombre de
la billetera actual
como sus parámetros. Ahora, usaremos el
selector de monedas para seleccionar los UTXOS que se utilizarán
como entradas en nuestra transacción. Así que vamos a inyectar el
selector de monedas en esta clase. Ahora, llamaremos
al método select en él, pasando los UTXOS, la cantidad convertida en
Satoshi la tasa de tarifa, la dirección a enviar y la dirección de
cambio de billetera actual, llamando al billetera actual obtener el método de cambio de dirección,
que creará. Así que vamos a crear este método. Simplemente devolverá la propiedad de
cambio de dirección. Vamos a crear esta
propiedad como una cadena. Vamos a moverlo hasta aquí. También vamos a crear un setter
para ello. Lo usaremos más tarde. Ahora, usemos el
servicio de creadores de
transacciones para crear una transacción. Entonces, vamos a inyectar este
servicio en esta clase. Llamemos al método
create en él, pasándole los siguientes
parámetros. Ahora que tenemos nuestra
transacción construiremos datos
adicionales para incluir
en la transacción DTL. Siguiente. Primero, usemos el método de tarifa real total
de la clase FI para obtener la tarifa real total pasará la transacción y los
UTXOS seleccionados como sus parámetros. Vamos a crear este método. La diferencia entre
los pies calculados totales y la tasa real total
es que para este último, utilizamos la diferencia entre los
montos de entradas y salidas para calcularlo. Mientras que para el
primero, estimamos
utilizando el
tamaño de la transacción y la tasa de comisión. En teoría, se espera que
ambos valores sean los mismos, pero usemos por defecto los
pies reales totales cuando sea posible, para garantizar que estamos mostrando usuario
la transacción real tarifa y para que el usuario vea
posibles errores de tres valores. Entonces aquí calcularemos
las cantidades de entrada, algunas en Bitcoin usando la siguiente
transformación de flujo. Mapearemos el flujo UTXOS
seleccionado para producir un flujo
de cantidades UTXOS. Luego usa el método reducido para sumar todos los valores en la corriente. Y usa el método or else para devolver cero si la
cadena está vacía. Ahora, calculemos la
salida entre algunos en Satoshi haremos la
misma transformación que
hemos hecho para las entradas, pero con las
salidas de transacción esta vez. Ahora vamos a devolver la
entrada algunos en BTC se convierte a Satoshi
menos la salida algunos. Volver al servicio Crear
transacción. Ahora, vamos a crear la variable F0
calculada total y asignarle el resultado de la llamada al método
F0 calculado total. Esta vez, pasaremos la transacción y la
tasa de comisión como sus parámetros. Ahora, calculemos
el total gastado, que como su nombre indica, es la cantidad total en Satoshi's que el remitente
gastó en esta transacción. Para ello, usemos el método total gastado
pasando
la transacción, como parámetros
el método total gastado
pasando
la transacción, la tarifa total real y la
dirección. Vamos a crear este método. Con esta declaración if. Verifiquemos si la dirección a
enviar pertenece a nuestra billetera. Si no es así, devolveremos la tarifa real total más el monto de
salida de la primera transacción. Si nuestra billetera lo contiene, eso significa que estamos transfiriendo
bitcoins a nosotros mismos, y por lo tanto estamos gastando
solo la tarifa de transacción. Finalmente, devolveremos un
nuevo objeto DTO de transacción instanciado con
estos parámetros, continuará implementando la función de ventana de diálogo
en el siguiente video. Nos vemos.
54. 52 Enviar bitcoin parte 7 skillshare 2: En este video, terminaremos implementar la ventana de diálogo de
transacciones. Entonces vamos al controlador de pestañas
Enviar. En el método del diálogo abierto, instanciemos un nuevo objeto de
diálogo como este. Entonces llamemos al método de
propietario de la unidad en él, pasando el objeto window como
su parámetro, así. Vamos a establecer el
título del diálogo para enviar la transacción. Ahora con el siguiente código, definiremos que
cuando hagamos clic en el botón Cerrar de
la ventana de diálogo,
la ventana de diálogo se cerrará. A continuación, crearemos un objeto cargador
FXML dentro de un bloque try catch. Para instanciarlo
será necesario inyectar el
recurso FXML de diálogo en esta clase. Vamos a hacerlo. Agreguemos una anotación de valor a
este campo indicando la ruta del diálogo de
transacción sin FXML. Aquí llamaremos al método
get URL en él. Entonces usaremos null
en estos parámetros. Y el contexto obtiene la referencia del
método de haz aquí. Primero, hagamos el
contexto objeto de campo en esta clase y asignemos aquí. Ahora, estableceremos el contenido
del dolor de diálogo
al resultado de la llamada al método de carga
del cargador FXML. Ahora con el siguiente código, obtendrá el controlador de
diálogo de transacciones syn del cargador FXML. Vamos a crear este controlador
en la clase de controladores. Finalmente, pasaremos el objeto DTO de
transacción al controlador
de
diálogo de transacción sin usando el método de
transacción set. Vamos a crear este método. Aquí, atraparemos
una IOException que el cargador FXML puede lanzar y envolverla en una nueva excepción de tiempo de
ejecución. Después mostraremos el
diálogo usando este método. Ahora, antes de implementar el segundo controlador de
diálogo de transacciones, vamos a ir a la actualización
actual del servicio de monedero. Cuando actualicemos la cartera
actual, debemos establecer su dirección de cambio, que se utilizará cuando
enviemos una transacción. Entonces hagámoslo. Lo haremos obteniendo la segunda
clave pública extendida de la billetera creada. Recuerde que esta clave
extendida se
derivó para generar direcciones de
cambio. Entonces obtendremos su
primera dirección y la configuraremos como la dirección de cambio de
billetera actual. Ahora, vayamos al
segundo controlador de diálogo de transacciones. Vamos a establecer la
anotación Componente en él. Ahora, vamos al segundo diálogo de
transacción FXML. Vamos a establecer el dolor de
diálogo FX ID. Y vamos a establecer la propiedad del
controlador FX a la ruta del
controlador recientemente creada aquí. Ahora vamos a establecer cada etiqueta con
un ID de ética en este archivo, este campo en el segundo controlador de diálogo de
transacción mediante el uso de esta característica IDE genial. Ahora vamos a establecer cada
campo aquí es privado. Agreguemos la anotación FXML
por encima de todas ellas. Antes de implementar el método
Set Transaction, vamos a crear el dominio de diálogo de
transacción en el paquete de dominios. Pronto va a necesitar este registro. Modelará los campos que se mostrarán en el diálogo de transacción. Así que vamos a crear estos campos. Vamos a crear también
esto a partir del método. Creará un nuevo diálogo de
transacción a partir de un DTO de transacción. Usaremos el formato o método de
formato Bitcoin para
analizar correctamente el monto para enviar la tarifa real total
y el total gastado también
pasará la
tasa de tarifa y la dirección de la transacción DTO a la instancia de
diálogo de transacción. Volver al segundo controlador de
diálogo de transacciones. En el método de transacción establecido, vamos a establecer el
campo Transacción D TO en el DTO de
Transacción Recibida. Vamos a crear este
campo en esta clase. Ahora, vamos a crear el objeto de diálogo de
transacción usando it's from method pasando el DTO de
transacción como su parámetro. Luego estableceremos el
monto a enviar texto al
diálogo de transacción monto a enviar establecerá el texto del campo de tarifas
totales al
diálogo de transacción, tarifa total. El texto total del campo
al diálogo de transacción suma el texto del campo de tasa de tarifa al diálogo de transacción. Tasa de comisión concatenada con
la cadena BTC slash KV. Mordedura. Vamos a establecer la dirección
para enviar los textos de campo a la
dirección de diálogo de transacción a enviar. Ahora vamos a crear el
método inicializado en esta clase. Aquí vinculará el botón de
cancelar a una acción que
cerrará la ventana de diálogo. Para ello, llamemos al método
Lookup Button en el dolor de diálogo pasando
el campo cancel a él. Después llamaremos a
este método para agregar un controlador de eventos
al botón cancelar. El manejador recibirá un evento de acción y un
evento como sus parámetros. Y el cuerpo del controlador utilizará esta declaración para cerrar
la ventana de diálogo. Ahora, vayamos a la prueba de
enviar Bitcoin. Algo falta
en esta prueba. Después de llamar al método send
Bitcoin and wait, tenemos que instruir al
nodo para que mine un bloque para que nuestro UTXO sea confirmado y pueda ser utilizado para
crear una transacción. Para manejar eso, llamemos
al método generate to address en el nodo generar para direccionar al cliente pasándole estos parámetros. Y vamos a mover esta línea de
código a aquí. Ahora, vamos a ejecutar nuestro nodo. Y hagamos esta prueba. Como era de esperar, la
prueba ha fallado, pero el
diálogo de transacción se abrió y se llenó con datos de
transacción. Ahora, vamos a mejorar esta prueba. Verificará si los valores en el
diálogo de transacción son correctos. Pero primero, hagamos que
esta prueba sea más resistente. Después de hacer clic en
el botón enviar agregaremos código para
asegurarnos de que esperamos a que aparezca
el
diálogo de transacción antes de actuar en
la ventana de diálogo. Entonces, vamos a crear el método de peso
para el diálogo. Aquí, llamaremos al
peso para método. Pasando estos parámetros para esperar segundos de
tiempo de espera en el cuerpo
lambda obtendrá el dolor de diálogo y regresará solo después de
que no sea nulo. Ahora, vamos a obtener el
valor de cada etiqueta en el diálogo de transacción y almacenarlos en las
siguientes variables. Agreguemos aquí el tipo de
fila de transacción. Y cambiemos el nombre
de la vista de tabla a tabla de transacciones. En el bloque entonces, agreguemos
las siguientes aserciones para verificar si las etiquetas en el
diálogo de transacción son correctas. Ahora, en el bloque where, agreguemos un
caso de prueba para poblar las variables a
las que acabamos de
hacer referencia en el bloque de entonces. Aquí le falta un signo
igual, igual. Vamos a arreglarlo. Agreguemos
otro caso de prueba. Ahora, eliminemos estas líneas. Adaptará el código para
crear transacciones previas acuerdo con la variable de número
UTXOS anterior. Entonces para cada UTXO definido en esa variable
buscará la dirección de recepción. Después llamaremos al método send Bitcoin and wait
con estos parámetros. Ahora, sustituyamos
el parámetro en la llamada al método correcto por
la variable amount to send. Ahora, tenemos
que asegurarnos de que la tasa de comisión sea igual a 0.0 002 para que funcione la prueba. Para ello, inyectaremos el servicio de tarifa estimada de
nodo en esta clase y le agregaremos la anotación
simulada de Bean. Después en el método de configuración, agreguemos el siguiente código. Se asegurará de que cuando se llame
al método de estimación
del servicio, entonces devolverá el valor de la tasa de
tarifa que queremos. A este método de búsqueda del perímetro le falta la letra S al final. Se trata de honorarios totales. Ahora, hagamos la prueba. Se falla, pero por
la razón equivocada, observe que la cantidad
a enviar etiqueta está vacía. Eso es porque hay
otra etiqueta con el mismo FX ID en el controlador de pestañas
Enviar. También hay un
campo de dirección para enviar con el mismo FX ID. Vamos al
segundo controlador de
diálogo de transacciones para arreglar eso. Cambiemos el nombre de este campo a la
cantidad para enviar diálogo. Y cambiemos
el nombre de la dirección para enviar campo
a dirección para enviar diálogo. Vamos al diálogo de enviar
transacción FXML para cambiar las etiquetas FX IDs. Bien, no tenemos que hacerlo, porque el IDE hizo
ese trabajo por nosotros. Volver a la prueba de enviar Bitcoin. Actualicemos estos parámetros para buscar las etiquetas
correctas. Ahora, hagamos nuestra prueba. Bien, las pruebas han fallado, pero sólo porque la tabla de
transacciones no contiene el
número esperado de transacciones. Eso significa que las etiquetas del
diálogo de transacción son correctas. Genial.
55. Cómo funcionan las firmas de transacciones: En esta presentación, mostraremos cómo funcionan las firmas de transacción. Primero, revisemos los campos
de una entrada de transacción. Las entradas de transacción tienen un
campo de ID de transacción cuyo contenido indica de qué
transacción proviene el UTXO que se está gastando en
esa entrada. El
campo de índice de salida indica qué UTXO de la transacción anterior está gastando
la entrada. En conjunto, ambos campos
hacen un punto de salida que
indica inequívocamente qué UTXO, el insumo es el gasto. El campo ScriptSig está vacío para las entradas de transacción de
segue contiene scripts de desbloqueo para entradas de transacciones no
segue. Ese desbloqueo de scripts
es una firma y una clave pública para transacciones
comunes. Finalmente, la entrada de transacción contiene el campo de secuencia final. El campo de secuencia final define cuándo la entrada es
válida para gastar. Este campo se ignora cuando
su valor es igual
al valor hexadecimal máximo para su tamaño. Para las entradas de transacción de segue, el contenido que para transacciones
no Segway está en ScriptSIG se
mueve al campo testigo. La firma en ese campo
es una firma ECDSA obtenida utilizando la clave
privada utilizada para derivar la
dirección del UTXO. El insumo es el gasto. El otro campo en el
testigo es la clave pública, que se
deriva de la clave privada a la nos acabamos de referir. Pero espera, ¿qué es
una firma ECDSA? Eddsa significa Algoritmo de
firma digital de curva
elíptica. Se trata de un
algoritmo de firma que combina una clave privada y un mensaje
para producir una firma. Y la firma ECDSA
tiene una propiedad que permite verificar
si es válida, es decir, verificar si una firma dada fue producida por una clave privada
dada y un mensaje usando la clave pública derivado
de esa clave privada, el mensaje y la firma. De esa manera, podemos verificar
si una firma es válida sin revelar
la clave privada utilizada para generarla. Puedes usar la ECDSA para
firmar cualquier mensaje que quieras. En el caso de una firma de
transacción, el mensaje que se firma es una versión modificada de la transacción
serializada. Entonces veamos cómo se firman
las transacciones de Bitcoin. Para firmar una transacción, hay
que firmar cada entrada de
transacción por separado. Para cada entrada de transacción comenzando con una transacción
insana, que es una transacción
donde sus entradas tienen script vacío,
CIGS y testigos. Se crea un hash de firma, que es el hash de
una versión modificada de la transacción serializada. Para ello, se utiliza un algoritmo hash de
firma, que explicaremos
en la siguiente diapositiva. El hash de firma
será el mensaje a firmar con una clave privada válida para esa entrada
y el hash de firma utilizará el ECDSA para
generar la firma. Recuerde que la clave
privada válida para una entrada es la misma clave privada
utilizada para generar
la dirección a partir del UTXO
que la entrada está gastando. Si la entrada es una entrada de segmento, agregue la firma
y la clave pública derivada de la clave
privada referida al testigo. De lo contrario, agregue estos elementos al campo ScriptSig de entrada. Cuando los nodos reciben
una transacción, verifican si las
firmas de transacción son válidas. Para ello, utilizan el algoritmo de
verificación de firmas citado en la diapositiva anterior. Lo hacen durante
la ejecución del script como se explicó en la
última presentación. Ahora, veamos cómo se genera el hash de
firma. Existen diferentes algoritmos de
hash de firma para entradas de
transacciones segue, no segmento y raíz de tap. No obstante, los tres
algoritmos modifican la transacción de alguna
manera y producen un hash, que es el mensaje
que se firmará. Veamos el algoritmo
hash de firma para las entradas de un segmento. Para crear un hash de firma para
una entrada de transacción dada, comience con una cadena vacía, luego agregue la
versión de transacción a la cadena, concatene todos los puntos
de salida de las entradas de transacción. Hash los resultados usando el algoritmo hash 256 agrega el hash
resultante a la cadena, luego concatena todas las
entradas y secuencias. Hash 256 el resultado, y agrega el hash
a la cadena. Ahora agregue el punto fuera de la entrada que se está
firmando a la cadena. Agrega la clave de pub script de los UTXOS gastados por la entrada
que se firma a la cadena. Agrega la cantidad de UTXOS gastada por la entrada que se
firma a la cadena. Agregue la secuencia final de la entrada que se
firma a la cadena, concatene todas las salidas de
transacción. Hash 256, el resultado, agrega el
hash resultante a la cadena, agrega el
tiempo de bloqueo de transacción a la cadena. Agregue el tipo de hash,
que es sig hash all para transacciones comunes
a la cadena. Hay otros tipos de hash, pero rara vez se usan. Definen las
entradas y salidas. La entrada que se firma puede
ir dentro de una transacción. Sig hash. Todo significa que la firma
producida es válida solo en una transacción con
todas las entradas y salidas de la transacción
dada. Por último, hash 256,
la cadena obtenida. El resultado es el hash de firma para la entrada que se está firmando. debe obtener un hash de firma para cada
entrada de transacción que se firma. El proceso es
replicado por nodos cuando verifican las firmas de
transacción.
56. Cómo nuestra billetera y nuestro nodo manejarán las transacciones enviadas: Esta presentación
explicará qué sucede cuando enviamos una transacción
a un nodo Bitcoin. Luego veremos cómo
nuestro monedero
maneja actualmente las transacciones de recepción y cómo planeamos cambiarlo
para calcular correctamente las direcciones de
las transacciones y saldos
totales de la billetera después de
enviar una transacción. Entonces veamos cómo un nodo Bitcoin maneja las transacciones
enviadas por nuestra billetera. Nuestro monedero enviará
transacciones a nuestro nodo a través del método note RPC llamado
send raw transactions. Nuestra aplicación enviará la transacción de señal en formato
hexadecimal a nuestro nodo. Después de recibir la transacción, el nodo la valida. Si la validación pasa, el nodo difunde
la transacción a otros nodos de
la red Bitcoin. Los otros nodos
hacen lo mismo hasta que todos los nodos de la red
reconocieron la transacción. La transacción permanece
en el mental por un tiempo, esperando que un menor
la incluya en un bloque y minó
el bloque con él. Finalmente, un menor transmite el bloqueo mental con
la transacción a otros nodos de la red. A medida que los nodos reciben el
bloqueo mental con la transacción, la transacción se
excluye de la mental y se
considera confirmada. Cada bloque agregado
después del bloque con la transacción agrega una
confirmación a la transacción. Se recomienda esperar
seis conformaciones para que una transacción se
considere irreversible. Ahora, veamos un modelo
ingenuo de cómo nuestro monedero puede manejar las transacciones de
envío. Después de que nuestro monedero envíe una
transacción a nuestro nodo, el nodo enviará de
vuelta a través de cero MQ, la misma transacción
a nuestra aplicación. Nuestro
servicio de tareas de nodo detectará la transacción y la enviará a nuestro oyente de transacciones
recibidas. Como la mayoría de las transacciones
tendrán un resultado de cambio, el
oyente de transacciones recibidas generalmente
verificará que la
dirección de cambio es de nuestra billetera. Y usaremos el
servicio UTXOS actualización
para actualizar nuestras direcciones de billetera, transacciones y saldos, pero confiando solo
en el oyente de transacciones recibidas
como lo es actualmente para actualizar nuestro cartera va a
plantear algunos problemas. En primer lugar, el
cálculo del saldo del servicio UTXOS de actualización
no considera los saldos de entrada. Por lo que tendremos que modificar la
forma en que nuestro monedero calcula un vestido y
saldos de transacciones para descontar los montos de entrada
de los montos de cambio. Pero tendremos que lidiar con un problema mayor
con este modelo. ¿Qué pasa con las transacciones
sin cambio? En este caso, el
oyente de
transacción recibida no considerará que
la transacción de recibo es nuestra ya que verifica solo las direcciones de salida y la salida de aroma no
será de nuestra billetera. Por lo tanto, nuestra aplicación
no se actualizaría. Está equilibrado para estos casos, adoptará la siguiente
estrategia para superar
estos problemas a la hora de actualizar nuestra billetera después del
envío de transacciones. Después de enviar la
transacción a nuestro nodo, publicaremos un evento de
transacción enviada que será capturado por un oyente de
transacción enviada. Entonces el oyente de
envío de transacciones utilizará el servicio UTXOS de actualización
para actualizar la billetera con la transacción para eliminar el tema de no actualizar
transacciones sin cambios, tanto la transacción el oyente recibido y el oyente de
recepción de bloque usarán un
cliente de transacciones de lista de nodos para buscar todas las transacciones relacionadas con
nuestra billetera en el nodo, este cliente enviará
una lista de transacciones RPC llamar a nuestro nodo, que devolverá todas
las transacciones relevantes al cliente. Después, utilizando las transacciones de
devolución, el
servicio de actualización UTXOS actualizará todas las transacciones en nuestra billetera y sus saldos correctamente.
57. 55 Enviar bitcoin parte 8 skillshare 2: En este video,
construiremos algunas clases y servicios que nos permitirán
firmar y enviar transacciones. Entonces primero, vamos a crear una
clase llamada transactions signer service en el paquete api
dot services. Agreguemos aquí la
anotación de servicio. Ahora vamos a crear el método de
signo aquí. Tomará un
objeto de transacción en la semilla mnemotécnica, una contraseña y una lista de
DTL UTXO que creará una clase. Así que vamos a crearlo en
el paquete de dominios. Ahora, usaremos el método de rango de
flujo para recorrer cada DTO UTXO. Para cada DTO UTXO, llamaremos al método sign
pasando el parámetro a, que es el índice
de la entrada a firmar, el DTO UTXO, que obtendrá usando
el parámetro i, la transacción,
la semilla mnemotécnica y la contraseña de la billetera. Vamos a crear este método. Cambiemos este nombre de
parámetro a cadena semilla
mnemotécnica para
firmar una entrada de transacción. Primero tenemos que derivar
la clave privada válida para desbloquear el UTXO que
entrada está gastando. Si quieres recordar cómo se hace
eso con mayor detalle, vuelve a ver las carteras HD
y la presentación de las direcciones de Bitcoin. Entonces primero, vamos a crear
una instancia de un objeto semilla mnemotécnico aquí, pasando la
cadena semilla mnemotécnica y la instanciación. Ahora derivaremos una clave maestra usando el método mnemotécnico
seed to master key ya que sus parámetros
pasarán la contraseña. Y este prefijo. Para nuestro caso de uso,
está bien pasar el
prefijo privado de red principal incluso si lo
usamos en otro
entorno porque afecta solo a la serialización de la
clave maestra, no al proceso de derivación. En el proceso de derivación de
la clave maestra que al método de clave maestra primero
deriva la semilla raíz, cual se menciona en la presentación anteriormente
referida. Ahora, derivaremos la clave privada
extendida usando el método CKD de clave maestra ya que su primer parámetro pasará la ruta de derivación UTXO DTO. Primero, vamos a crear este
campo en el UTXO DTO. Y
aprovechemos para sumar el campo de cantidad
que necesitará a continuación. El siguiente parámetro será true, lo que indica que queremos
derivar una clave privada extendida, una clave pública extendida. El último parámetro será
el prefijo privado neto principal. Nuevamente, no hay problema
en usar el prefijo de red principal aquí. Observe que la forma en que derivamos la
clave privada extendida aquí es similar a cómo derivamos la clave pública
extendida y el servicio de clave
pública extendida. Usamos la misma
ruta de derivación que hemos utilizado para crear la
clave pública extendida para derivar la dirección UTXO para nuestra billetera. Ahora, obtendremos la clave
privada deseada simplemente extrayéndola de la clave privada
extendida a través del método de dos claves
privadas. Este método está disponible en la siguiente versión Bitcoin Java. Entonces vayamos al
archivo POM para actualizarlo. Ahora dentro de un bloque try catch, finalmente
podemos usar
el método sign de la
clase de firmante de transacción ECDSA de Bitcoin Java. Este método tomará la
transacción, la clave privada, el índice de entrada, la cantidad
UTXO DTO
convertida a Satoshi. Y el booleano true, que indica que
esta entrada está segmentada. El mismo método obtendrá un hash de firma con
la clave privada. Usaremos la ECDSA para obtener
una firma para esa entrada. Después insertará la
firma y la clave pública derivada de la clave privada
pasada en el testigo de transacción. La cantidad UTXO es necesaria
para el hash de firma, y el último
parámetro true es necesario para la generación correcta del
hash de firma y para agregar
correctamente la firma
y la clave pública al testigo en lugar
de en el scriptSig, que es el caso de entradas que
no son de segmento. Finalmente, capturamos una
posible IOException que el método sign puede lanzar y envolverlo en una nueva excepción de tiempo de
ejecución. Ahora, vamos a crear el nodo send raw transactions client en
el paquete node dot client. Este servicio será
necesario para enviar nuestras transacciones a
nuestro nodo Bitcoin. Vamos a agregarle la
anotación de servicio. Inyectemos el
cliente de nodo en esta clase. Y vamos a crear
el método send. Aceptará una cadena
hexadecimal de transacción como su parámetro. Aquí llamaremos al
cliente nodo make request método. Lo usaremos para
llamar al método RPC del
nodo Bitcoin de
transacción en bruto de envío . Como de costumbre, pasemos un nuevo objeto de referencia de
tipo parametrizado. Aquí. La URL está vacía, y pasaremos el parámetro hexadecimal de
transacción como último parámetro. Ahora en el paquete de
servicios GUI dots, vamos a crear el segundo servicio de
transacción. Este servicio se
encargará de firmar y enviar la transacción
creativa. Después de hacer clic en
el botón Enviar en el diálogo de transacción, agreguemos la
anotación de servicio a esta clase. Y vamos a crear el método de
firmar y enviar. Devolverá un
futuro de tipo nulo. Y tomará
como parámetros el DTO de la
transacción y la contraseña del monedero. Ahora, primero crearemos
una lista de UTXOS, CTO, convirtiendo
los UTXOS
seleccionados del DTO de transacción. Llamaremos al mapa de métodos en el
flujo UTXOS seleccionado y usaremos el generador de DTO UTXO para construir el UTXO d t va desde
cada objeto UTXO. Así que vamos a inyectar el
constructor UTXO DTO en esta clase. Vamos a crearlo en el paquete de servicios punto
GUI. Ahora, vamos a crear
este método de compilación. Devolverá un DTO UTXO de
regreso al servicio de
transacciones del centro. Aquí devolverá el método list llamado en el stream resultante. Vamos a refactorizar aquí para usar la referencia del método
en lugar de una lambda. Ahora, vamos a implementar
este método. Primero. Agreguemos la
anotación de servicio a esta clase. Aquí obtendremos el objeto de dirección de
monedero actual correspondiente a la dirección UTXO
recibida. Entonces, primero inyectemos la
billetera actual en esta clase. Ahora llamaremos al método get
address en él, pasando la dirección UTXO
como su parámetro. Vamos a crear este método. Devolverá un objeto address. Aquí devolverá el
resultado de llamar
al método get addressed
en el campo addresses, pasando la
dirección recibida como su parámetro. Finalmente, obtendremos el índice
actual de direcciones de monedero y lo almacenaremos en la variable de índice de
direcciones. Ahora, obtendremos la
misma dirección de la cartera actual y
obtendremos su tipo de dirección, almacenándola en la variable de tipo de
dirección. Ahora, obtendremos la ruta de
derivación UTXO llamando
al método build derivation
path con el tipo de dirección y
el índice Address. Vamos a crear este método. Aquí. Usaremos el objeto address
configs para obtener parte de la ruta de
derivación. Así que vamos a
inyectarlo en esta clase. En realidad, será una lista de configs de direcciones. Vamos a arreglarlo. Ahora desde el flujo
de configuraciones de direcciones, usaremos el
método de filtro para seleccionar la configuración de dirección válida
para el tipo de dirección. Después usaremos el
método find first y obtendremos
la configuración de dirección que queramos. Finalmente, obtendremos la ruta de
derivación de la configuración de la dirección y concatenaremos con
la siguiente cadena. Añadiremos una barra diagonal hacia adelante y
luego agregaremos el índice de direcciones. Aquí devolverá un nuevo DTO UTXO pasando la
ruta de derivación y la cantidad UTXO. Volver al servicio de envío
de transacciones. Aquí, necesitaremos el servicio de firmante de
transacciones. Así que vamos a
inyectarlo en esta clase. Ahora, llamaremos al
mismo método en él ya que sus parámetros pasarán la
transacción DTO de transacción, la semilla
mnemotécnica de billetera actual. Entonces, vamos a inyectar la
cartera actual en esta clase. Vamos a crear este método
en la cartera actual. Devolverá una cadena. Aquí, devolverá el campo
semillero mnemotécnico. Vamos a crear este campo. Y agreguemos un setter
para este campo. El tercer parámetro de este método es la contraseña de la
billetera. El siguiente parámetro
son los CTO UTXO. Ahora, en un bloque try-catch
usaremos el nodo send raw transactions client para enviar una transacción firmada
a nuestro nodo. Así que vamos a
inyectarlo en esta clase. Llamaremos al método
send en él, pasando la transacción DTL transacción
serializada usando el método serializado capturará una IOException y la envolverá
en una nueva excepción de tiempo de ejecución. Ahora usaremos la
aplicación Event Publisher. Así que vamos a
inyectarlo en esta clase. Lo usaremos para publicar un
nuevo evento de transacciones enviadas pasando esto y el
DTO de transacción como sus parámetros. Así que vamos a crear el evento de transacción enviada en el paquete de eventos de
punto GUI. Cambiemos el
primer parámetro de firma del
constructor para
aceptar un objeto. Y pasemos este objeto
al súper constructor. Y establecemos el campo
DTO de
transacción el DTO de transacción recibida. Agreguemos este campo
a esta clase. Y vamos a crear
un getter para ello. Usaremos este evento más tarde. Volver al método sign and send devolverá aquí un nuevo resultado
asincrónico, pasando null como su parámetro. Vamos a agregar la
anotación asíncrona a este método pasando el
servicio ejecutor predeterminado como su parámetro. Recuerda que
lo estamos haciendo para ejecutar este método de forma asincrónica, que es nuestra política a la hora de
comunicarnos con nuestro nodo. Bien, hemos creado el campo semilla
mnemotécnico en la clase de billetera actual, pero ahora tenemos que configurarlo
después de crear una nueva billetera. Entonces vayamos al registro de billetera y agreguemos el campo
semilla mnemotécnico a él. Ahora vamos al servicio create
wallet y agreguemos aquí
la cadena de semillas mnemotécnicas como último parámetro en la instanciación de
wallet. Ahora en el servicio de billetera
actual de actualización, fijemos la semilla mnemotécnica de
billetera actual
a la semilla mnemónica de billetera. Ahora vamos al
segundo controlador de diálogo de transacciones. En el método inicializado, llamemos al método Lookup
Button en el dolor de diálogo pasándole
el botón Okay. Ahora agreguemos un
manejador de eventos a este botón. El primer parámetro
es un evento de acción, que define el clic en el botón
Okay como la acción. El segundo parámetro es un método
Lambda que toma un objeto de evento y llama al método de
transacción sign and send. Así que vamos a crear este método. Aquí. Necesitaremos el segundo servicio
de transacción. Así que vamos a
inyectarlo en esta clase. Ahora, llamaremos al método sign
and send en él, pasando el
DTO de transacción y el texto de la contraseña de la billetera
como sus parámetros. Finalmente, cerraremos
el dolor de diálogo usando el método hide en
la ventana del panel de diálogo. Vamos a ejecutar nuestro nodo. Y finalmente
probemos lo que hemos hecho ejecutando la prueba de
enviar Bitcoin. Genial, las pruebas han pasado. El monedero, detectó
nuestra transacción y la agregó a la tabla de
transacciones. Pero espera, hay
algo extraño. Rebobinaré el video
y lo pausaré en la vista de tabla de direcciones
para verificar algo. Esta es la
tabla de direcciones después de que nuestra billetera envió nuestra transacción en
el primer caso de prueba, observe que la billetera detectó
que una de nuestras
direcciones de cambio en la segunda
fila recibió Bitcoins. Bueno. Pero como la dirección
en la primera fila tiene su UTXO en la entrada de la
transacción que acabamos de enviar, su saldo actual debería ser cero porque se gastó su
salida. Y dado que nuestra tabla de
direcciones solo muestra que se viste con
saldos mayores a cero, esta tabla solo debe mostrar una fila con la dirección de cambio. Ahora, revisemos la tabla de
transacciones para el mismo caso de prueba. Boops, el saldo de la transacción que
acabamos de enviar es incorrecto. Debe ser igual a -0.5 bitcoin menos la tarifa de
transacción. El signo menos
indicaría que hemos enviado una transacción
desde nuestra billetera. El
texto del saldo total también es incorrecto. Debe ser igual a 0.5
menos la tarifa de transacción. En el siguiente video, solucionaremos esos problemas.
58. 56 Enviar bitcoin parte 9 skillshare 2: En este video, arreglaremos algunos problemas que tuvimos
en el último video. Uno de esos temas es que
la tabla de direcciones muestra saldos
obsoletos para direcciones
cuya salida se gastó. Dado que la dirección
gastada después de ser utilizada tiene un saldo cero, no
debería aparecer en
la tabla de direcciones. Entonces ajustemos esta prueba para verificar si la tabla de
direcciones tiene solo una fila y
si esa fila tiene un equilibrio igual al cambio
esperado en Mount. Aquí, obtendremos la tabla de
direcciones usando el método de búsqueda. Y en el bloque entonces comprobará si la
tabla de direcciones tiene una fila. Comprobemos también si el saldo de la primera fila es
igual a esta variable, que definiremos
en el bloque web. A continuación, definamos
la cantidad de cambio en las cajas de desgaste negro. Otro problema que hemos visto en el último video es
que el saldo de la transacción es incorrecto
en la tabla de transacciones. Eso está sucediendo porque cuando nuestra aplicación recibe una
transacción de nuestro nodo, está considerando solo
el saldo de cambio como
saldo transacción para asegurar que la prueba
detecte este error, agreguemos la siguiente línea
y luego block comprobará si la primera fila de la tabla de
transacciones tiene un balance igual a menos
la variable total gastada. El saldo también es incorrecto
ya que es igual a la suma de todos los saldos de
transacciones. Entonces hagamos que nuestra prueba
detecte este problema. Aquí. Comprobaremos si el texto del
saldo total es correcto. Primero, definamos
esta variable. Será igual al texto presente en
la etiqueta de saldo total de la ventana después de
enviar una transacción. Comprobemos si esta variable es igual al siguiente texto. Y aquí definamos la
variable funds y actualizada en
el stream final lambda. Ahora, vamos a ejecutar nuestro nodo. Y hagamos esta prueba. Bien, La prueba ha fallado porque la
tabla de direcciones tiene dos filas. Arreglemos esos problemas. Para ello, vamos a crear el oyente de
transacciones enviadas. Pero primero, arreglemos
algo totalmente ajeno. El bloque de
escucha recibido está en el paquete de eventos de punto de nodo en lugar
del
paquete de oyentes
de punto de nodo. Vamos a arreglar eso. Con eso fuera del camino, vamos a crear un
oyente de envío de transacciones en el paquete de escucha de
puntos GUI. Como su nombre indica, este oyente manejará el evento de transacción enviada que el servicio de transacción
publicará después de
enviar una transacción. Vamos a agregarle la
anotación de componente. Se implementará el listener de
aplicación con el tipo de evento de transacciones
enviadas. Vamos a implementar su método. Aquí liderará la
actualización del servicio UTXOS. Así que vamos a
inyectarlo en esta clase. Ahora, llamemos
al método de actualización pasando la
transacción de evento DTO. Ahora vamos a crear este método. Aquí obtendremos
una lista de UTXOS a partir de la transacción DTO UTXOS
seleccionada. Usaremos un mapa en la transmisión UTXOS
seleccionada e instanciaremos un nuevo
UTXO para cada UTXO
recibido, pasará cada campo UTXO en la instancia UTXO, excepto la cantidad que será cero ya que acabamos de gastarlo. Ahora para actualizar nuestras direcciones de
billetera, llamaremos al método de actualización del
servicio de actualización de direcciones de
billetera actuales , pasándole los UTXOS. Y para actualizar las transacciones del
monedero, llamemos al método de actualización en el servicio de
transacciones Update Current Wallet
pasará el resultado de llamar a la
fila de transacciones del método a misma con el
DTO de transacción como su parámetro. Por último, llamemos al método de
actualización del servicio
balanceado de billetera actual método de
actualización del servicio
balanceado para actualizar el saldo actual de la
billetera. Vamos a crear esto a partir del método en la clase de fila de transacción. Aquí devolverá una
nueva fila de transacciones en un bloque try-catch. instanciaremos con
el ID de transacción DTO de
transacción. La
transacción formateada DTO total gastada negada usando
el método negate. Hará que el valor sea negativo
ya que lo estamos gastando. Tendrá cero confirmaciones. Y su fecha será
la fecha actual. Finalmente, capturaremos una IOException que
puede ser lanzada por el método de ID de transacción y rápida en una nueva excepción de tiempo de
ejecución. Volver al servicio Actualizar
UTXOS. Ahora vamos a crear
el método de actualización que recibirá una fila de
transacción en la actualización actual El servicio de
transacciones Wallet utilizará el método de
ejecución posterior de la plataforma ya que el siguiente código
modificar la interfaz del monedero. Aquí pasaremos una
lambda que
llamará al método add transactions
row en la billetera actual
pasará el
camino de transacción a este método. Ahora, vamos a crear este método. Movamos este método
a esta ubicación cerca del método add
transactions rows. Aquí llamaremos al método add transactions
row en el campo de filas de transacción, pasando la
fila de transacción como su parámetro. Vamos a crear este método en
la clase de filas de transacción. Aquí, pondremos la
transacción escrita en la hoja de ruta de la transacción usando el ID de
fila de transacción como clave. Bien, con estas modificaciones, esperamos que al menos se actualice la tabla de
direcciones. Volvamos a ejecutar la
prueba de enviar Bitcoin para verificar eso. Bien, Las direcciones
presentadas ahora son correctas, pero la prueba falló debido a
la tabla de transacciones. Las transacciones de envío aún están
con un saldo desactualizado. Eso sucedió porque aunque nuestro oyente de transacciones sin está actualizando la
transacción correctamente, cuando nuestra billetera recibe la misma transacción
de nuestro nodo, detecta una actualización es solo
el cambio de dirección UTXO. No descuenta la cuota
y el insumo que hemos gastado. Debemos cambiar la forma en que actualizamos nuestras
transacciones actuales de billetera para solucionarlo. En el método de actualización del
servicio UTXOS, que se llama después de que
nuestra aplicación reciba una transacción, llamará al nodo RPC lista
de transacciones método. Este método devolverá todas
nuestras transacciones de billetera, incluidas las que
le enviamos lo suficientemente inteligentes como para devolver transacciones con saldos
negativos si se envían
desde nuestra billetera. Con estas transacciones en mano, podemos actualizarlas correctamente
en nuestra aplicación. Así que usemos la lista de nodos de transacciones cliente para obtener todas las transacciones
de nuestro monedero y almacenarlas en la variable de
transacciones de nodo. Inyectemos este
servicio en esta clase. Y vamos a crearlo en
el paquete api
dot services dot no dot client. Terminemos de
inyectarlo en esta clase. Ahora, hagamos el registro de
transacción de nodo, que modelará el retorno
del método de transacciones de lista, lo
creará en el paquete de dominio
y nodo de inicio. Aquí llamaremos al método de
transacciones de lista, pasando el nombre de la billetera actual. Construyamos este método. Y agreguemos aquí la anotación de
servicio. Inyectemos el
cliente de nodo en esta clase. Aquí obtendremos una matriz de tipo node transactions llamando
al método
make request client node con los siguientes parámetros. La cadena de transacción de lista, que es el nombre
del método RPC del nodo, una nueva referencia de
tipo parametrizada. La URL de la billetera concatenada
con el nombre de la billetera. Y cadena de asterisco,
que indica que queremos todas las transacciones
de esa cartera. El valor máximo entero, lo que significa que queremos
el número máximo de transacciones en
la respuesta cero, lo que le dice al
método que no
queremos omitir ninguna transacción. Y cierto, lo que indica
que queremos vigilar únicamente las transacciones
incluidas en la respuesta. Ver solo las transacciones
son transacciones. El nodo no tiene la clave
privada para gastar. Esta opción tiene sentido
porque nuestra billetera no pasa ninguna
clave privada a nuestro nodo. Finalmente, devolvimos
la matriz de transacciones convertida en una lista. Ahora vamos a crear los campos de registro de
transacción de nodo agregarán solo los
campos que usarán. Son el T XID,
las confirmaciones, el monto, la dirección, que es la dirección a
la que el remitente
pretende enviar bitcoins, no la dirección de cambio. Y el tiempo, que es la marca de tiempo de la creación de la
transacción. Volver al servicio Actualizar
UTXOS. Llamaremos al método de transacciones del
nodo de actualización en el servicio de transacciones Update Current
Wallet. Como su parámetro pasará
las transacciones del nodo. Vamos a crear este método. Aquí, obtendremos una lista de filas de transacciones de
las no transacciones. Llamaremos al método de filtro en el flujo de transacciones del nodo. Como su parámetro pasará
una lambda que tomará
una transacción de nodo y verificará si la billetera actual contiene
la dirección de transacción del nodo. Luego agregamos un
operador o y verificamos si la billetera actual contiene una transacción con el ID de
no transacción. Este filtro dará como resultado un
flujo de transacciones que contiene solo
las transacciones a las que se dirige enviar
es una de las nuestras, que cubre
las transacciones de recepción. La condición después de que
el operador o realice el flujo de transacciones también incluye transacciones que nuestra aplicación ya tiene. Eso significa que
las transacciones que
anteriormente fueron agregadas por el oyente de
envío de transacciones tendrán su balance correctamente actualizado con saldos
negativos. Ahora, no vamos a la transmisión
resultante usando el método de la
fila de transacción. Vamos a crear este método
y moverlo a aquí. Aquí devolverá una
nueva fila de transacción instanciada con el ID de transacción del
nodo. El monto de
transacción de nodo formateado, las
confirmaciones de transacción nodo
y el
tiempo de transacción de nodo convertido en una cadena. Ahora convertimos el
flujo de transacciones en una lista. Por último, usamos el método platform run later y usando un lambda, llamamos a las filas de
transacción Add en la billetera actual pasando
las filas de transacción a la misma. Eliminemos este método ya que ya
no lo necesitaremos. También eliminemos este método en la fila de transacciones
por el mismo motivo. Una cosa más aquí en el
método de filas de transacciones publicitarias en la clase de filas de
transacciones, tenemos que actualizar el saldo de la fila de
transacciones antes de que nuestros cambios surtan efecto. Entonces, vamos a incluir el
siguiente código para hacer eso. Ahora, vayamos a la prueba de
enviar Bitcoin. Antes de ejecutarlo,
incluyamos la llamada dormida después de que la prueba haga clic en el botón OK en el segundo diálogo de
transacción. Con eso, evitamos que la prueba falle debido a las condiciones de la
carrera. Ahora, hagamos nuestra prueba. Genial, las pruebas han pasado. Ejecutemos todas las pruebas de
aplicación para asegurarnos de que no hemos roto
nada en nuestras billeteras. Voy a acelerar el video ahora, ya que estas pruebas tardarán algunos minutos en ejecutarse en la realidad. Genial. Todas las
pruebas han pasado.
59. 57 Enviar bitcoin parte 10 skillshare 2: En este video, agregaremos más pruebas para verificar
si nuestra billetera funciona como se esperaba al enviar transacciones en
diferentes escenarios. Veamos si nuestro monedero puede enviar dos transacciones,
una tras otra. Para ello, vamos a duplicar esta prueba en la clase de prueba de enviar
Bitcoin. Cambiemos su nombre a. Debería enviar Bitcoin a tiempos. Arreglemos su formato. Cambiemos el nombre de la billetera
a mi prueba mientras esté a las diez. Ahora vamos a extraer esta sección de
código a un método. Lo llamaremos enviar Bitcoin. Vamos a sumar la cantidad a enviar
como su segundo parámetro. Después de crear una transacción, dará clic en el
botón Ok para enviarla. Entonces usaremos esta línea de código para hacer que nuestro nodo mine un bloque. Con esto, esperamos que nuestra segunda transacción
sea confirmada, lo que nos permite utilizar el
cambio UTXO generado por esa transacción como
entrada en la siguiente transacción. Ahora haremos clic en la pestaña Enviar. Y llamaremos al método del
sueño con estos parámetros para esperar a que se confirme
nuestra transacción. Después de enviar la
primera transacción, esperamos que nuestra primera dirección de
cambio se muestre en la tabla de
direcciones. Esperamos que se
use una dirección de
cambio diferente en la segunda
transacción porque es importante no
reutilizar las direcciones al recibir Bitcoins
por razones de privacidad. Entonces compararemos la dirección de
cambio en ambas transacciones y verificaremos
si no son iguales. Para ello, busquemos la tabla de direcciones
con esta línea de código. Cambiemos el tipo TableView a la fila de direcciones por razones de
corrección. Eliminemos la
declaración aquí, y
aprovechemos para solucionar el mismo problema en el método de prueba
anterior. Almacenará la primera
dirección de cambio en esta variable, obtenerla de la tabla de
direcciones. Después volveremos a llamar al método
send Bitcoin para enviar la
segunda transacción. Después de la segunda transacción volveremos a buscar la tabla de
direcciones. Esperemos que la primera
fila de la tabla contenga la
segunda dirección de cambio. Entonces,
volvamos a consultarlo y almacenar la dirección de la primera fila y la segunda variable de
dirección de cambio. En el bloque entonces se agregará
la siguiente aserción para verificar si la dirección del primer
cambio no es igual a la segunda. Aquí, esperaremos que el tamaño de la tabla de
transacciones sea igual al número
UTXOS anterior más dos. Y cambiemos esta parte
del texto del saldo total. Esperamos que el
saldo confirmado sea igual a los fondos
menos el total gastado. Vamos a quitar este caso de prueba, sólo
tendrá un
caso para esta prueba. Cambiemos la
cantidad para enviar un 0.25. Actualicemos el total
gastado en consecuencia. Y cambiemos los
últimos cuatro dígitos de la cantidad de cambio. Esta cantidad de cambio es la suma de los montos de cambio de
las dos transacciones. Ahora, vamos a ejecutar nuestro nodo. Agreguemos la
anotación de ignorar a la primera prueba, ya que queremos ejecutar
sólo la última prueba. Y vamos a ejecutarlo. La prueba ha fallado porque la primera
dirección de cambio es igual a la segunda
dirección de cambio. Arreglemos esto. Vamos a la actualización
actual del
servicio de direcciones de monedero moverá esta
línea de código a esta ubicación. Aquí agregaremos una
declaración if para verificar si la dirección que se
está actualizando es una dirección de cambio. Agreguemos esta constante
a esta clase. Será igual a dirección
tipo seg cambiaría. En el cuerpo de la declaración if, establecerá la
dirección de cambio de
billetera actual a la siguiente dirección. Agreguemos también una declaración de
retorno a este cuerpo de declaración if. Volvamos a ejecutar la prueba. Genial, La prueba ha pasado. Ahora, comenzaremos a implementar algún manejo de errores
para situaciones las que las cosas no van bien cuando intentamos enviar transacciones, por ejemplo, qué debería suceder cuando usamos la contraseña de billetera incorrecta cuando intentando enviar
una transacción. Cuando nuestro monedero envía una transacción con la contraseña
incorrecta, esto hace que la
transacción se construya con firmas
no válidas. Cuando nuestro nodo lo recibe, intenta validar
esa transacción. Como sus firmas están equivocadas, devolverá un
mensaje de error y no retransmitirá la transacción
a otros nodos. Actualmente, nuestra cartera no
está manejando el error devuelto y
fallará silenciosamente. Vamos a crear una solución
para esta situación. Nuestro nodo devuelve un error después de recibir nuestra transacción, mostrará al usuario
una alerta de error diciendo que la billetera no pudo
enviar la transacción. Y y. Primero, vamos a crear una
prueba para este escenario. En la clase de prueba de enviar Bitcoin. Duplicemos
el primer método. Vamos a renombrarlo a no debería enviar Bitcoin con contraseña
incorrecta. Y ajustemos su formato. Cambiemos también el
nombre de la billetera a mi billetera de prueba 11. Aquí haremos clic en
el campo de contraseña. Definamos una variable
para esta contraseña. Vamos a configurarlo a mi contraseña de prueba y escribirlo en el campo de
contraseña. Después de recibir
Bitcoins, almacenemos el saldo formateado en la variable de fondos
formateados. Como no vamos a tener éxito
en el envío de una transacción, esperamos que el
saldo final de nuestra billetera no cambie y siga siendo
igual a esta variable. Ahora, sustituyamos
esta sección de código con una llamada al método send Bitcoin. Después de que aparezca el
diálogo de transacción, haremos clic en el campo de contraseña de la
billetera. Y escribiremos la contraseña
equivocada. Después de hacer clic en
el botón Bien, esperamos que aparezca un
mensaje de error. Definamos este mensaje de error y lo almacenemos en esta variable. Entonces, con este código, intentará almacenar el nodo con este mensaje en la variable de consulta de
nodo. La alerta de error tendrá un botón Ok que
intentará hacer clic. En el bloque entonces, comprobará si los textos de consulta de nodo
son iguales al mensaje de error. También verificará si la dirección
en la tabla de direcciones tiene un equilibrio igual a la variable de fondos
formateados. Esperamos que el tamaño de la
tabla de transacciones sea igual a uno, ya que no mostraremos la
transacción fallida en la tabla. También cambiemos
aquí el saldo
esperado de la transacción para que sea igual a
los fondos formateados. También esperamos que el saldo
total y el
saldo confirmado sean iguales
a la variable de fondos formateados. El
saldo esperado no confirmado debe ser igual a cero con
ocho decimales. Eliminemos el segundo
caso de prueba en el bloque where. Ahora vamos a implementar la función de alerta de
error. En el segundo servicio
de transacción. Agreguemos aquí una declaración catch para detectar un error interno
del servidor. Este es el tipo de error que devolverá
el nodo si algo sale mal cuando
intentemos enviarle una transacción. Ahora, usaremos el registrador
para registrar este error. Así que agreguemos el registrador a
esta clase como un campo estático. instanciará usando el método logger factory
get logger, pasando esta clase
como su parámetro. Entonces llamaremos al método
error en él, pasando el error get response body como llamada al método de
cadena. Después devolvemos la llamada del método de error del
manejador de errores del
nodo que le
pasa el error. Inyectemos el
manejador de errores de nodo en esta clase. Vamos a crear esta clase en el paquete de servicios
GUI dots. Terminemos de
inyectarlo en esta clase. Vamos a crear este método en él. Devolverá un
futuro de tipo error. Volviendo a la ubicación
que lo llamará, vemos que el ID
indica un error de tipo. Para solucionarlo, vamos a cambiar
el tipo de retorno del signo y enviar método
a futuro de tipo error. Pero primero, vamos a crear el registro de error en el paquete de nodos de punto de
dominios. Vamos a copiar esta línea
y pegarla aquí. Lo cambiaremos para importar esta clase de error que
acabamos de crear. Si no hacemos eso, Java utilizará su clase de
error incorporada. Ahora, cambiemos este parámetro
de tipo a error. Pasemos también la
línea de importación a esta clase. Vamos a agregarle una
anotación de Servicio. Ahora, antes de
continuar implementando la función, ejecutemos la última prueba
para verificar el formato del mensaje de error que devuelve el
nodo en los registros. Primero, agreguemos la
anotación de ignorar a esta prueba. Por lo que sólo ejecutamos la última prueba. Aquí, vemos que el nodo
volvió al mensaje JSON. La parte importante
dice que el script falló y 0 p igual
verificar la operación. Eso significa que el nodo falló debido a una firma incorrecta al ejecutar el script combinado para validar la transacción. Ahora que sabemos lo que devuelve
el nodo a la aplicación cuando la contraseña de la
billetera es incorrecta, mapeemos esta respuesta a la respuesta de contraseña incorrecta que
queremos que vea el usuario. En el manejador de errores de nodo. Vamos a agregar un bloque try-catch
convertirá el error recibido en un objeto
envoltorio de error de nodo. Así que vamos a crear este registro en el paquete de nodos de punto de dominios. Siguiendo la respuesta
adyacente al error de nodo como la especificación agregará un campo de error de
tipo de error de nodo aquí. Así que vamos a crear el registro de error de
nodo en el paquete de nodos de punto de dominios. Tendrá un campo de código
y un campo de mensaje. De vuelta al controlador de errores del nodo necesitará el asignador de objetos. Entonces vamos a inyectarlo
en esta clase. Ahora, llamaremos al método
read value en el mapeador de objetos ya que sus parámetros
pasarán el error get response body como llamada al método
string. Y la clase
envolvedora de errores de nodo. Este código convertirá el error recibido en un objeto envoltorio de error de
nodo. Finalmente, devolveremos un
nuevo objeto de resultado asíncrono instanciado con
un objeto de error. Para crear una instancia del objeto error, usaremos el error
from method pasando el error node error wrapper
error como su parámetro. Vamos a crear el método front. Devolverá un objeto de error. Agreguemos el
campo de mensaje a este registro. El método front devolverá un nuevo objeto de error instanciado
con un mensaje de error. Para crear el mensaje de error, agreguemos el
campo de mensajes de error en esta clase. Este campo se
encargará de mapear los mensajes de error
del nodo a los mensajes que queremos mostrar. Será un mapa de
claves de cadena y valores de cadena. Usemos el mapa del
método para crearlo. Su primera clave será el mensaje de error
devuelto por el nodo, que vimos en los registros de la
aplicación anteriormente. El valor será el
mensaje de error que queremos mostrar. Para ello, usaremos la contraseña incorrecta constante de
la
clase de mensajes de error que vamos a crear. Así que vamos a crear esta clase en el paquete de nodos de punto de dominios. Y agreguemos esta
constante con el mensaje que
queremos mostrar. Ahora, llamaremos al método
Get o default en el
campo de mensajes de error en el método form, su primer parámetro
será el mensaje de error. Su segundo parámetro
será un mensaje predeterminado, que definiremos
en esta constante. Entonces, si el nodo devuelve un mensaje de error que aún no
hemos mapeado, el mensaje de error que se muestra
será un error ocurrido. Volver al manejador de errores del nodo. Agreguemos aquí una
declaración catch para capturar la excepción de procesamiento
adyacente que el mapeador de objetos puede lanzar. Después lo envolvemos en una
excepción de tiempo de ejecución y lo lanzamos. Ahora vamos al
segundo controlador de diálogo de transacciones. Aquí, obtendremos el
resultado del método sign and send y lo
almacenaremos en una variable. Solo asegúrate de importar
la clase de error correcta. Ahora, necesitaremos el servicio de error de
alerta. Entonces vamos a inyectarlo
en esta clase. Este servicio se
encargará de mostrar una alerta con
un mensaje de error. Vamos a crearlo en el paquete de servicios GUI
dots. Y terminemos de
inyectarlo en esta clase. Ahora, llamemos al método
handle error en el error de alerta o al
objeto de servicio pasándole el resultado. Vamos a crear este método. Primero. Agreguemos la
anotación de servicio a esta clase. Aquí declararemos
un objeto de error. Entonces en un
bloque try-catch se establecerá la variable de error a la llamada al método
result dot get. Entonces atraparemos una excepción
que el resultado puede arrojar y envolverlo en una
nueva excepción de tiempo de ejecución. Ahora bien, en esta sentencia if
comprobará si el error no
es igual nulo. Si no lo es, entonces llamaremos
al método alert error, pasándole el mensaje de error. Vamos a crear este método. Aquí. Crearemos un nuevo objeto de alerta
con un error de tipo alerta. Después estableceremos el título de la
alerta en error. Y estableceremos el texto del
encabezado de alerta a error o dos. Vamos a establecer el
texto del contenido de alerta en la variable de mensaje. Por último, llamemos al
método show en el objeto alert. Ahora, volvamos a ejecutar la prueba. Genial, La prueba ha pasado.
60. 58 Enviar parte de bitcoin 11 Skillshare 2: En este video, seguiremos
agregando más validaciones y alertas para notificar
al usuario de intentos fallidos de
transferencia. Primero, crearemos algunos
casos de prueba para esos escenarios. Así que vamos a duplicar esta
prueba agregará una prueba para el escenario donde el
usuario quiera enviar una transacción con más
bitcoins que sus fondos. Vamos a renombrarlo a no
debería enviar Bitcoin sin
fondos mayores a cantidad más v.
Vamos a reformatearlo. Y cambiemos el
nombre de la billetera a mi prueba mientras esté a las 12. Eliminemos estas líneas. Aquí. Vamos a establecer una variable de
mensaje de error al contenido que queremos que el
usuario vea por el error, el mensaje
será no se pudo enviar transacción, no hay suficientes fondos. Después con este código, intentaremos almacenar
el elemento UI con este mensaje en la variable de consulta de
nodo. E intentaremos hacer clic en el botón Bien en
el cuadro de diálogo de alerta. En el bloque entonces comprobaremos si el texto de consulta del nodo es igual
al mensaje que
definimos anteriormente. Eliminemos estas variables en el bloque where ya que
no las necesitaremos. Y vamos a crear la variable cantidad
anterior aquí con el siguiente valor. Duplicemos esta línea para
crear un segundo caso de prueba. Este valor de cantidad será
uno Satoshi inferior al necesario para
enviar 0.5 bitcoin. Ahora, eliminemos esta línea. Sustituyamos estos valores con la variable de
cantidad anterior. Ahora, crearemos un escenario de prueba
similar, pero esta vez usando una
billetera sin fondos. Entonces vamos a duplicar esta prueba. Cambiemos su
nombre a no debería enviar Bitcoin sin ningún tipo de fondos. Cambiemos el nombre de la billetera
a mi prueba mientras esté a los 13. Eliminemos estas líneas ya que no vamos a
recibir ningún fondo. Y dejemos
sólo el monto a enviar variable y
el bloque where. Ahora implementemos la característica en la clase de
servicio create transactions. Almacenemos el
DTO de transacción en una variable aquí. Y vamos a devolver esta variable. Ahora. Antes de regresar, llamará al método de validar
fondos, pasando el
DTO de transacción como su parámetro. Vamos a crear este método. Utilizará este método
para validar si la suma de los montos
de entrada de transacción es mayor que la
salida de la transacción entre algunos. Así que vamos a crear esta variable
para almacenar la cantidad de entrada. Algunos le asignarán el resultado de llamar a la transacción DTO, le obtendrán cantidades
de método de entrada. Vamos a crear este método. Aquí. Usaremos un mapa en la secuencia UTXOS seleccionada para crear una secuencia de cantidades UTXO. Entonces usaremos el método
reducido para sumar cada cantidad obtenida. Finalmente, usaremos el método
or else para devolver la suma o cero si no hay
UTXOS disponibles. Ahora, vamos a crear las cantidades de
salida get del método aquí. Usaremos una estrategia similar a algunas de las cantidades de salida. Pero en lugar de usar
los UTXOS seleccionados, utilizará un mapa en el flujo de salida de la
transacción. El método map devolverá los montos de salida
convertidos a Bitcoin. Y usaremos el método reduce y un método Rails de la misma manera que lo hicimos para el método anterior. Volver al método de validar
fondos. Aquí, crearemos la
salida alguna variable para almacenar el resultado de llamar a
las cantidades de salida get. Algún método que acabamos de crear. Ahora agregaremos una sentencia if para verificar si la suma de entrada es menor que la suma de salida
más el total calculado F0. Si es así, lanzamos una nueva excepción de
transacción de creación con el mensaje de no suficientes
fondos. Vamos a crear esta constante
en la clase de mensajes de error. Hagamos ambas constantes definitivas. Y vamos a crear la clase create
transactions exception en el paquete de
excepciones de punto GUI. Extenderá la excepción de tiempo de
ejecución y pasará su mensaje
al súper constructor. Aprovechemos para agregar otra validación aquí. ¿Y si tratamos de enviar una transacción sin
una billetera cargada? Para manejar este caso, usemos esta
declaración if para verificar si la billetera actual
tiene alguna dirección. Si no es así, lanzamos una excepción de transacción de creación con un mensaje de billetera no
cargada. Vamos a crear esta constante
para almacenar este mensaje. Ahora, vamos al controlador de pestañas
Enviar. Envolvamos la creación de DTL de
transacción en un bloque try-catch. El método de diálogo abierto llamado
a. Aquí, lo atraparemos. Crear excepción de transacción. Usaremos el error de alerta o
servicio y el cuerpo de captura. Entonces vamos a inyectarlo
en esta clase. Después llamaremos al método
alert error, pasando el
mensaje de excepción como su parámetro. Hagamos público este método. Vamos a la prueba de
enviar Bitcoin. Agreguemos la
anotación de ignorar a la prueba que hicimos
en el último video. Vamos a ejecutar nuestro nodo. Antes de ejecutar la prueba, ajustemos algunos detalles. Agreguemos un punto al
final de los mensajes de error. En el método send Bitcoin. Vamos a agregar este parámetro. Por defecto será true y
solo llamará al
método de diálogo wafer si es cierto. Ahora, pongámoslo en
falso y estas llamadas, porque el diálogo de transacción no aparecerá en estas pruebas. Por último, hagamos las pruebas. Calificar las pruebas han pasado. Eliminemos todas las
anotaciones de ignorar de esta clase. Ahora, agregaremos un montón de
nuevas pruebas en una nueva clase llamada send Bitcoin
test adicional en este paquete. Pero no te preocupes, esta
vez simplemente copiaremos el contenido de esta clase desde la página Proyecto y Recursos. Todas estas pruebas deben pasar. Ojalá no tengamos que
cambiar nada en
nuestro código para ello. Pero ayudarán a garantizar nuestra billetera
envíe las transacciones
correctamente y detectará posibles rupturas de código que
se harán en el futuro. Vamos a reformatear todos ellos. En la primera prueba
verificaremos si una billetera con contraseña envía
transacciones correctamente. La siguiente prueba generará
transacciones sin necesidad
de cambio y verificará si sus parámetros son correctos. Esta prueba intentará enviar una
transacción a una dirección de nuestra propia billetera y
verificar si la billetera calcula
correctamente sus
montos y saldos. Por último, la última prueba
tendrá muchos casos de prueba
diferentes con diferentes números de UTXOS
anteriores y cantidades. Para que estas pruebas funcionen, movamos el método weight for
dialogue en la prueba
send Bitcoin a
la clase de prueba GUI. Hagámoslo protegido. Eliminemos estas importaciones
en la prueba de enviar Bitcoin. Una cosa más en el método
send Bitcoin, en la prueba send Bitcoin, agreguemos aquí la súper
palabra clave para asegurarnos llamaremos al método de
peso correcto para diálogo, no al parámetro
con el mismo nombre. Haremos otra
prueba en esta clase. Esta vez, comprobaremos
qué sucede cuando
intentamos enviar una transacción
con una cantidad de polvo. Entonces vamos a duplicar esta prueba. Cambiemos su nombre a no
debería enviar polvo Bitcoin. Arreglemos su formato. Cambiemos su nombre de billetera
a mi prueba mientras esté a los 18. Ahora, copiemos este código y lo
agreguemos a nuestro método
para financiar nuestra billetera. Cambiemos el
mensaje de error a no se pudo enviar monto de la
transacción
para enviar es polvo. Cambiemos el bloque where, agregándole las siguientes
variables. Escogeremos una cantidad a
enviar igual a 293 Satoshi's, que sabemos que nuestro nodo no puede aceptar ya que
se considerará polvo. Para la cantidad anterior
elegirá 0.1 bitcoin. Dado que confiaremos en nuestra nota para detectar este tipo de error, esperaremos
a que aparezca el diálogo de
transacción después de hacer clic
en el botón Enviar. Y agreguemos el click en la llamada al método del botón Okay para confirmar la transacción
del diálogo. Ahora, vamos a
la clase de error. Agreguemos la siguiente entrada
al mapa de mensajes de error mapeará el error de mensaje de polvo
recibido de nuestro nodo al mensaje presente en la
constante de polvo en la clase de
mensajes de error. Vamos a crear esta constante. Será igual al mensaje acabamos de definir en la prueba. Agreguemos la
anotación de ignorar a las otras pruebas de esta
clase y ejecutemos nuestra nueva prueba. Genial, La prueba ha pasado. Eliminemos todas las anotaciones de
ignorar que agregamos anteriormente. En este punto, recomiendo ejecutar todas las pruebas de
aplicación. Yo lo hice y todos pasaron. No lo voy a mostrar en este video porque tardaría
varios minutos. Voy a dejar esto como
ejercicio para el alumno.
61. 59 skillshare 2 de la parte 1 de Segwit: En este video, comenzaremos a refactorizar nuestra aplicación
para prepararla, para agregar soporte para
más tipos de direcciones. Será un refactor relativamente
grande, pero veremos más adelante
que nos
permitirá agregar soporte para
otros tipos de direcciones, como el
seg anidado abordaría. La idea de este actor ref
es centralizar todo lo específico de un tipo de dirección
en un objeto de configuración de direcciones. Al hacerlo, podremos
agregar más tipos de direcciones a nuestras billeteras agregando nuevos
objetos de configuración de direcciones al proyecto. Después de hacer este refactor, agregaremos un nuevo
tipo de dirección llamado segmento anidado, cuya importancia
explicaremos en algunos videos. Entonces vayamos al registro de configuración de
direcciones para agregar algunos campos. Añadiremos el campo
generador de direcciones. Lo usaremos para definir
el servicio utilizado para generar direcciones para
diferentes tipos de direcciones. Un mapa con una clave de
enumeración de entorno y un valor de cadena. Utilizaremos este campo para registrar los prefijos de dirección
para cada entorno. Así que vamos a crear esto lo suficiente. En el paquete BYU w dot
domains. Tendrá la red principal, la red prueba y las constantes de prueba reg. Agreguemos aquí el campo de prefijo
ki extendido. Como su nombre indica, definirá el prefijo de la clave extendida que
generará las direcciones. El siguiente campo será una cadena de predicado como
parámetro type. Recibirá una función
lambda con una dirección como
parámetro y una expresión que
devolverá true si la dirección coincide con el tipo de configuración de
dirección y false. De lo contrario, agregaremos un campo de tipo de clave
pub script para que
podamos identificar qué configuración de
dirección
usar usando el tipo de clave pub
script. Luego lo agregaremos por función
con estos parámetros de tipo usaremos este campo para definir una función para analizar una
dirección de un script dado, clave de
pub y un prefijo. Ahora eliminemos el bean conflicto de
direcciones para el cambio de dirección de Segway. En esta refactorización se
utilizará solo un bean de
configuración de direcciones tanto para el segmento las direcciones de
cambio de segmento. Cambiemos la anotación Bean
para reflejar este cambio. Ahora, cambiemos esta instanciación de configuración de
dirección para incluir cada
recurso relacionado con este tipo de dirección cambiará el campo de ruta de derivación a
un mapa donde la clave será un tipo de dirección y
el su ruta de
derivación correspondiente. Aquí agregaremos dos entradas, una para el tipo de dirección de segmento y su ruta de derivación inicial, y la otra para
el cambio de Segway y su ruta de derivación inicial. Ahora, como se aborda, generador agregará un nuevo generador de direcciones de
segmento. Para el campo de
prefijos de dirección se agregará el siguiente mapa se agregará una entrada para cada
entorno y son prefijos de dirección P2, WP k h. El campo de
prefijo ki extendido será la constante principal del
prefijo neto segue. Como el emparejador de direcciones utilizará el comparador de direcciones es
segue con la función Lambda. Así que vamos a crear esta clase
y el paquete utils. Y vamos a crear esta función. Será una función
que tomará una dirección y devolverá
true si la dirección inicia con uno de
estos tres prefijos presentes en las direcciones de segmento. El siguiente campo será igual
al script P2 WP k h constante. Por último, el analizador de direcciones
será una referencia
al script P2 WP k
h método de dirección. Volvamos a la configuración de la
dirección para sustituir el tipo de
ruta de derivación. Será un mapa con tipos de
direcciones como claves y cadenas como valores. Ahora, vamos a crear la clase de buscador de
configuración de direcciones en el paquete de servicios api dot
usaremos este servicio como una forma de recuperar la dirección
correcta puede falsificar y otros servicios
que refaccionaremos a continuación. Entonces, vamos a agregarle la
anotación de servicios. Y vamos a inyectar aquí una lista
de configuraciones de direcciones. Ahora, vamos a crear este
método que nos
permitirá encontrar una configuración de
dirección por dirección. Su tipo de retorno será
opcional de tipo address config. Después filtraremos un flujo
de configuraciones de direcciones y usaremos el comparador de direcciones de los config en el filtro lambda. Después devolvemos la configuración de dirección
opcional correspondiente a la dirección
recibida usando el primer método. Ahora vamos a crear
otro método que devolverá un opcional
de tipo address config. Esta vez, encontrará una configuración de dirección
por su tipo de script. Será similar al
método anterior, pero usaremos el
filtro para verificar si la clave
del script pub pasado coincide con la de la configuración de
la dirección. También usaremos el
primer método definido en este caso. Ahora crearemos
un método para encontrar una configuración de dirección
por tipo de dirección. Nuevamente, usaremos un filtro en
una secuencia de configuraciones de direcciones. Esta vez, el filtro
contendrá una lambda
que verificará si el tipo de dirección config es igual al tipo de dirección
anterior, o si es igual
al cambio correspondiente tipo de dirección. Esta vez, devolveremos la
dirección can fake sin el objeto opcional usando
el método orals throw. Este método lanzará
una excepción si no encuentra la configuración de dirección
apropiada. Ahora estamos listos para comenzar a
refactorizar otros servicios para usar nuestro nuevo buscador de configuración de direcciones
y configuración de direcciones. Comencemos con el servicio
create wallet. Eliminemos estas dos líneas. Aquí. Usaremos un FlatMap
en la lista de configuración de direcciones. Después pasaremos un método
lambda como su parámetro devolviendo
en el cuerpo lambda la siguiente
transformación
obtendrá las rutas de derivación de
la configuración de dirección recibida. Le falta una letra S final. Así que cambiemos el nombre de este campo
a rutas de derivación. Ahora, obtendremos el conjunto
de entrada de las rutas de derivación. Luego llamaremos al
método map en el flujo de entradas de ruta de derivación que
devolverá una
clave de pub extendida para cada entrada usando el método de creación de
servicio de clave de pub extendido. Como sus parámetros
pasarán la clave maestra. El valor de entrada, que será la ruta de derivación,
la clave de entrada, que será el tipo de dirección, y el prefijo ki
extendido Address config. Por último, convertimos
el resultado a una lista. Ahora vamos al servicio
extendido de llaves de pub. Eliminemos estas líneas. Vamos a agregar un cuarto
parámetro a este método. Será un prefijo ki
extendido. Aquí, sustituiremos
este argumento por el
prefijo ki extendido, prefijo público. Ahora vamos al generador de direcciones de
segmento. Aquí, agregaremos el prefijo
como segundo argumento, y lo usaremos
como parámetro aquí. Ahora, eliminemos la
fábrica de prefijos de dirección de esta clase. Y agreguemos el
segundo argumento a esta interfaz,
generemos el método dos. Ahora vamos al generador
secuencial de direcciones. En la llamada al método generate, usaremos la fábrica de
prefijo de dirección. Entonces vamos a inyectarlo
en esta clase. Ahora llamemos al método
get en él, pasando el
tipo de dirección recibida como su parámetro. Ahora refaccionaremos la fábrica de generadores de
direcciones. Eliminemos todas estas líneas. Inyectemos el buscador de
configuración de direcciones en esta clase. Aquí llamaremos al hallazgo por tipo de
dirección en el buscador de configuración de
direcciones, pasando el
tipo de dirección como su parámetro. Después devolvemos el generador de direcciones de configuración de
dirección telefónica. Ahora, refaccionemos la fábrica de prefijos de
dirección. Eliminemos todas estas líneas. Entonces vamos a inyectar la dirección puede pensar Finder
en esta clase. Nuevamente, encontraremos
la configuración de la dirección por tipo de dirección
usando este método. Después obtendremos los prefijos
de
dirección de la configuración de dirección encontrada. Por último, devolvemos
el prefijo de dirección correspondiente al entorno actual de
Bitcoin así. Arreglemos las pruebas para
las clases que
acabamos de
refactorizar, comenzando con la prueba del generador
secuencial de direcciones. Agreguemos el buscador de
configuración de direcciones como campo en esta clase. Y vamos a asignarlo a un
simulacro de esta clase aquí. Ahora, instanciemos una
nueva configuración de dirección, configurándola en esta variable. Entonces usemos el método one para definir un objeto devuelto cuando llamamos al método find by
address type en el buscador de configuración de direcciones. En este caso, devolverá
la configuración de Segway. Entonces hagamos público este método en la clase de
configuración de direcciones. Ahora cambiemos este parámetro de fábrica de
prefijo de dirección a la cadena de red principal. Y pasemos el buscador de configuración de
direcciones a la instanciación de la fábrica de generadores de
direcciones. Hagamos esta prueba. Vaya, la compilación
falló debido a un error en el constructor de DTO UTXO.
Vamos a arreglarlo. Aquí. Obtendremos la configuración de la dirección usando el buscador de configuración de direcciones. Entonces vamos a inyectarlo
en esta clase. Eliminemos la lista de
configuración de direcciones de esta clase. Ahora, encontraremos la
configuración de la dirección por tipo de dirección aquí. Entonces obtendremos la ruta de
derivación usando el tipo de dirección recibida. Finalmente, concatenaremos
la cadena slash y el
índice de direcciones con el resultado. Volvamos a ejecutar la prueba. Genial, La prueba ha pasado. Ahora arreglemos la prueba del servicio de creación de
billetera. Eliminemos estas líneas. Instanciará la configuración de la
dirección aquí. Después crearemos aquí la lista de configuración de
direcciones. Añadiendo el seg
le configuraría. Eliminemos todas estas líneas. Ahora, instanciaremos los objetos
necesarios como este. Hagamos esta prueba. Grado. La prueba ha pasado. Ahora arreglemos la prueba extendida de servicio de clave de
pub. Añadiremos el prefijo main
net seg como el último parámetro
del método create. Y hagamos esta prueba. Genial, ha pasado. Por último, arreglemos la prueba del generador de
direcciones de segmento. Eliminaremos la
fábrica de prefijos de dirección de esta clase. Y pasaremos el prefijo de dirección
principal net P2 WP k h como segundo parámetro
a este método. Hagamos esta prueba. Grado. La prueba ha pasado. En el siguiente video, seguiremos
refactorizando nuestra aplicación.
62. 60 skillshare 2 de Segwit anidado: En este video,
seguiremos refactorizando nuestra aplicación. Entonces comencemos con la clase de analizador de
direcciones. Inyectemos el buscador de
configuración de direcciones en esta clase. Eliminemos este código. Ahora, usaremos el buscador de configuración de
dirección para encontrar una configuración de dirección
por tipo de clave pub script, pasando el tipo de
clave pub script a este método. Después mapearemos el resultado y aplicaremos el analizador de dirección address
config address, pasando
como parámetros
la clave pub script y el prefijo apropiado. Ahora, usaremos el método URL para devolver una cadena vacía si no se puede analizar
una dirección. Regresemos esta
transformación. Ahora, vayamos a la clase
actual de monederos. Eliminemos la dirección de
recepción y cambiemos la dirección
de esta clase. En lugar de usar
un campo para cada dirección de
recepción y cambio, usaremos un
campo de direcciones de recepción para modelar las diferentes
direcciones que usaremos para recibir Bitcoins en nuestra billetera. Entonces agreguemos el campo de
direcciones receptoras a esta clase. Será un mapa observable con tipos de
direcciones como claves
y cadenas como valores. instanciará aquí con un HashMap observable de
la clase de colecciones FX. Eliminemos los métodos
que utilizan los campos eliminados. Ahora vamos a crear el método set de direcciones
receptoras. Pondremos una entrada en el mapa de direcciones de
recepción para cada llave de pub extendida. La clave de cada entrada será un tipo de dirección obtenido
utilizando el valor del método pasando como parámetro
el
tipo de clave pub extendida. El valor será
la primera dirección de la llave de pub extendida. Ahora, vamos a crear el método set de dirección de
recepción. Usaremos este método para actualizar la dirección de recepción actual para un tipo de dirección específico. Aceptará un índice de direcciones y un tipo de dirección
como parámetros. Primero, obtendremos la siguiente
dirección usando el método get address ID pasando
estos parámetros. Después pondremos la dirección
obtenida en las direcciones receptoras usando el tipo de dirección como clave. Vamos a crear el método
get receive address. Tomará un tipo de dirección y devolverá la dirección de
recepción actual para ese tipo la obtendrá de las direcciones receptoras usando el tipo de dirección como
clave para la recuperación. Ahora, vamos a crear un getter
para las direcciones receptoras. Cambiémosle el nombre para obtener direcciones receptoras
observables. Ahora, vayamos al servicio de actualización de
direcciones de billetera
actual. Eliminemos todas estas
líneas dentro de una plataforma
ejecutada más tarde llamada. Agreguemos una
función Lambda que utilizará la
dirección de recepción del conjunto de billetera actual para establecer la siguiente dirección. Eliminemos estos campos
ya que no los necesitaremos. Ahora, vamos a refactorizar la actualización
actual del servicio de monedero. Eliminemos estas dos líneas. Entonces agreguemos una llamada al método set de direcciones
receptoras que
acabamos de crear en la billetera
actual. Ahora, vamos al controlador de pestañas
Recibir. Eliminemos este código. Aquí. Obtendremos las direcciones de
recepción observables de la billetera actual
y le agregaremos un oyente. El oyente será la
siguiente función lambda. Con esta declaración if
comprobará si la dirección receptora que se cambió fue una segue
¿qué dirección? Si es así, estableceremos el texto
del campo
de dirección de recepción en la dirección recién agregada. Ahora refactorizaremos cómo se
usa
la dirección de cambio en el proyecto. Así que vamos a crear una clase llamada tipo de cambio de
dirección Finder. Esta clase será
responsable de encontrar el tipo de dirección de
cambio apropiado para una salida de dirección dada. Aunque podemos usar
diferentes tipos de direcciones como salidas en una transacción, se recomienda usar el
mismo tipo para complicar terceros al descubrir qué salida
se utilizó como cambio. Este servicio nos permitirá
atender esta preocupación. Agreguemos la
anotación de servicio a esta clase. Inyectemos el buscador de
configuración de direcciones en él. Ahora vamos a crear
el método find. Este método
devolverá un tipo de dirección y tomará una dirección
como parámetro. Aquí llamaremos al método find by address en el buscador de configuración de
direcciones. Luego mapearemos el valor
obtenido
al tipo de dirección de cambio equivalente usando el siguiente código. Por último, utilizamos
el método o bien para devolver el seg
cambiaría el tipo de dirección. Si no se encontró el
tipo de dirección. Usaremos la
dirección de cambio de Segway para este caso. Aunque permitiremos que
nuestra aplicación envíe transacciones a la
mayoría de los tipos de direcciones, necesitamos proporcionar este
retroceso porque no implementaremos todos los tipos de direcciones como receptoras direcciones
en nuestra cartera. Ahora, vayamos al servicio de creación de
transacciones. Debemos refactorizar cómo se
obtiene
la dirección de cambio en esta clase. Agreguemos aquí la variable de cambio de
dirección. Su valor será igual al resultado de
la llamada al método de
dirección de cambio fino con la
dirección como parámetro. Así que vamos a crear este método. Primero sustituyamos estas
llamadas de
buen método de dirección de cambio por la nueva variable de
dirección de cambio. Aquí obtendremos el tipo de
dirección
usando el buscador de tipo de
dirección de cambio. Entonces vamos a inyectarlo
en esta clase. Ahora, llamaremos al método find en el buscador de tipo de
dirección de cambio, pasando la dirección
como su parámetro. Después devolvemos una llamada
al método get
Receiver address, pasando como parámetro el
tipo de dirección obtenido. Ahora, vamos a la clase de configuración de
dirección. Añadiremos campos relacionados con la creación
de la transacción. Ahora. El primero será el generador de entrada de transacciones con esta nueva clase como su tipo. Vamos a crear esta clase en
el paquete de servicios API. Será una interfaz. método
se llamará Build, devolverá una entrada de transacción y Su método
se llamará Build,
devolverá una entrada de transacción y
tomará un UTXO como parámetro. Volver a la configuración de la dirección. Vamos a añadir el campo de entrada más tamaño de
salida aquí. Lo usaremos más adelante en la clase de calculadora de
polvo. También agreguemos aquí el campo
ScriptSig size. Se utilizará en la calculadora de tamaño de
transacción. Ahora, agreguemos también el campo firmante de
transacciones. Vamos a crear esta clase en
el paquete api dot services. Será una interfaz. Tendrá un método de signo el cual tendrá los
siguientes parámetros. También lanzará
una IOExcepción. Ahora en la clase de
configuración de direcciones, definamos los nuevos campos en la configuración de dirección de segmento. Añadiremos un nuevo generador de entrada de
segmento
como generador de
entrada de transacción. Vamos a crear esta clase en
el paquete api dot services. Implementará
la interfaz Builder
de entrada de transacción , e implementará
el método de compilación. Para implementarlo, copiemos el siguiente código dentro del método build inputs en
la clase de creador de transacciones y peguémoslo aquí. Cambiemos este parámetro
a un nuevo ArrayList. Almacenaremos esta
entrada de transacción en esta variable. Entonces llamaremos al método
set witness, pasando a un nuevo testigo
con los mismos argumentos que
hemos usado en el servicio de
creadores de transacciones. Finalmente, devolvimos
la entrada de la transacción. Vamos a copiar estas constantes y pegarlas al segue
qué constructor de entrada. Y agreguemos aquí la anotación de
servicio. Volver a la
configuración de la dirección. Añadiremos 98 como
entrada más tamaño de salida,
cero como tamaño de ScriptSig y un nuevo firmante de
transacciones Segway. Vamos a crear esta clase en
el paquete api dot services. Implementemos el método del firmante de
transacciones. Agreguemos aquí la
anotación de servicio. Vamos al servicio de
firmante de transacciones. Copiaremos esta línea
y la pegaremos aquí. Sustituyamos este parámetro
por la variable index. Y sustituyamos aquí
el monto UTXO por la variable amount. Nuestra configuración de dirección finalmente
está lista. Ahora vamos a la calculadora de tamaño de
transacción. Usemos el comando IDE de
código de limpieza para agregar la palabra clave final a cada
campo de esta clase. Inyectemos el buscador de
configuración de direcciones en esta clase. Eliminemos este código. Vamos a redefinir la variable all
inputs mapeará el flujo de direcciones de entrada pasando una referencia
al método de tamaño de entrada. Vamos a crear este método. Devolverá un double y tomará
como parámetro una dirección. Aquí devolverá
un código similar
al anterior que
define el tamaño de entrada. Pero el
parámetro de tamaño ScriptSig se
tomará encontrando la configuración de dirección
adecuada. El uso del buscador de configuración de direcciones arrojará una excepción si
no encontramos la configuración de dirección. Si lo encontramos, le quitaremos
el tamaño de ScriptSig. Después le agregaremos la
secuencia. Finalmente, sumaremos los resultados del tamaño de
entrada usando el método de suma doble. Si no encontramos ninguna entrada, devolverá cero como la suma. Ahora, eliminemos estas líneas. Como el tamaño de entrada. Llamaremos al
método map en el flujo de direcciones de salida usaremos el método de tamaño de salida para
devolver cada tamaño de salida. Aquí devolveremos la
suma del valor n, la longitud de la clave pub script y el resultado del método
script pub key size pasando la dirección
como parámetro. uso de una declaración if
comprobará si la dirección es una dirección seg
utilizaría el método Segway. Si lo es, entonces devolvemos la constante de la clave pub
script. Si no lo es, lanzaremos
la siguiente excepción. Recuerda que no usaremos la configuración de dirección para
calcular el tamaño de salida porque la
configuración de dirección se refiere solo a las direcciones que podemos
aceptar en nuestras billeteras. Ya que planeamos soportar
más direcciones de salida, entonces tomaremos como entradas, tendremos que manejar la construcción de
salida sin usar la configuración de
dirección. Finalmente, utilizamos el método
reducido para calcular la suma
de tamaños de salida. Y existe el método o else para devolver cero sin salidas. Eliminemos esta constante. Ahora. Vamos a la calculadora de polvo. Inyectemos el buscador de
configuración de direcciones en esta clase. Agreguemos la dirección como segundo parámetro
a este método de polvo. Vamos a eliminar esta línea, se creará la variable de tamaño
de entrada más salida. Usaremos el buscador de
configuración de direcciones para encontrar la
configuración de la dirección por dirección. Si no
se encuentra una configuración de dirección. Vamos a lanzar una excepción. Si lo es, entonces
obtenemos su propiedad input plus output size y la
almacenamos en una variable. Finalmente, devolvemos la
fórmula para calcular si una salida es polvo usando la
variable que acabamos de definir. Eliminemos esta
constante de esta clase. Ahora, vamos a refactorizar el único selector de monedas de sorteo
aleatorio agregará el
parámetro de cambio de dirección a estos métodos. Y pasamos la dirección de cambio
a la llamada del método de polvo. Vamos a refactorizar el servicio de creadores de
transacciones. Ahora, eliminemos
estas constantes. Inyectemos una lista de creadores de claves de pub
script
en esta clase. Vamos a crear esta clase en
la ruta de los servicios api dot. Será una interfaz. Tendrá un método de coincidencia
que devolverá un booleano y tomará como
parámetro y dirección. Y tendrá un
método de compilación que devolverá un script y tomará una
dirección como parámetro. Terminemos de inyectar este
campo a esta clase. También vamos a inyectar el buscador de
configuración de direcciones en esta clase. Agreguemos la dirección de cambio
a estas llamadas de método. Eliminemos este código
de este método, crearemos la
variable script y le asignaremos el resultado de la siguiente transformación de
flujo. Se filtrará el script
pub key builders stream para encontrar el que coincida con
la variable address. Si no encontramos ninguna, lanzamos una excepción. Entonces llamamos al método build en el script pub key builder encontrado pasando la dirección
como su parámetro. Finalmente, devolvemos la salida de la
transacción que contiene la cantidad
y la variable script. Ahora vamos a eliminar este método y
usado de esta clase. En el método build inputs, eliminemos este código. Ahora, llamaremos al método map
en el stream de UTXOS. En su interior pasará
la siguiente lambda, encontrará la dirección config
usando la dirección UTXO. Si no lo encontramos, lanzamos una excepción. Después obtenemos el generador de entrada de
transacción desde la configuración de la dirección y lo
llamamos método derramado, pasando el UTXO a él. Finalmente, usamos el método
collect para convertir la
secuencia resultante en una ArrayList. Vamos a crear la clase P2 WP k
h script builder en el paquete api dot services. Se implementará la interfaz script
pub key Builder. Implementemos los métodos
de interfaz. Inyectemos la
fábrica de prefijos de dirección en esta clase. En el método match
devolverá el resultado de llamar a la dirección matcher
es el método de prueba de Segway. En el método build,
primero estableceremos la
variable prefix en el
prefijo address factory Get method call result
pasará la constante Segway
como su parámetro. Después devolvemos el resultado de la llamada al método de script P2 WP k h ya que el parámetro a
este método pasará el resultado de llamar al método back 30 para decodificar al método hex. Primero, vayamos
al archivo POM para actualizar la
biblioteca Bitcoin Java a la versión 0.4, 0.4, que tiene el
mejor método 32 que necesitamos. Pasaremos el prefijo y
la dirección a este método. Ahora, vayamos a la clase de firmante de
transacciones para más refactorización. Inyectemos el buscador de
configuración de direcciones en esta clase. Eliminemos esta línea. En su lugar, llamará
al mismo método pasándole
estos parámetros. Vamos a crear este método creará la variable
firmante de transacción. asignaremos el resultado de la siguiente
transformación. Usaremos el
buscador de configuración de dirección para encontrar una configuración de
dirección
por tipo de dirección pasará el
tipo de dirección UTXO DTO a este método. Pero primero, agreguemos el campo de tipo de dirección
al registro UTXO DTO. Y agreguemos el tipo de
dirección a la instanciación de UTXO DTO
en el generador de DTO UTXO. Volver al servicio de
firmantes de transacciones
obtendrá el firmante de
transacción de configuración de dirección de la configuración de la dirección telefónica. Por último, llamemos al método de firma de firmantes de
transacciones, pasándole estos parámetros. Agreguemos una
cláusula throw a este método para indicar que este método
puede lanzar una IOException. Se realiza la refactorización. Ahora arreglemos algunas pruebas, comenzando con la prueba del selector de monedas de un solo
sorteo aleatorio. Agreguemos la
configuración de la dirección al método de configuración. Entonces agreguemos la
variable de lista de configuraciones de
dirección con el segmento
Config dentro de ella. Ahora instanciemos un
nuevo buscador de configuración de direcciones, pasándole
las configuraciones de direcciones. Ahora hagamos esta prueba. Genial, ha pasado. Ahora, arreglemos la prueba de servicio de
creadores de transacciones. Al igual que la prueba anterior. Instanciemos una
configuración de dirección y creemos
una variable de configuración de direcciones y
una variable de
buscador de configuración de direcciones. También instanciemos un prefijo de
dirección pasando la cadena de prueba reg y el buscador de configuración de
direcciones a la misma. Ahora vamos a crear la variable script pub key
builders le
asignará una lista con un nuevo
generador de scripts P2 WP k h dentro de él. Hagamos esta prueba. Genial, ha pasado. Ahora, arreglemos la prueba de la calculadora de
tamaño de transacción. Al igual que las pruebas anteriores, instanciemos una
configuración de dirección y creemos
una variable de configuración de direcciones y
una variable de
buscador de configuración de direcciones. Cambiemos estas pruebas de caso. Pegaremos los
casos de prueba que puedes encontrar en la página Proyecto y
Recursos. Importemos el método de copias
finales. Estos casos de prueba o
iguales a los anteriores, pero tienen
direcciones reales esta vez, ya que ahora son importantes para la lógica de la
calculadora de tamaño de transacción. Hagamos esta prueba. Genial, ha pasado. Ahora, vayamos a
la clase de prueba GUI. Agreguemos la
constante principal del prefijo del segmento
neto a esta llamada al método. Y agreguemos la constante reg test P2 WP k h address prefix constant como parámetro a
esta llamada al método. Ahora te recomiendo que ejecutes
todas las pruebas de aplicación. Todos deben pasar.
63. Dirigir las direcciones de Segwit: En esta presentación, hablaremos sobre las direcciones de segmentos anidados. Entonces, ¿qué es una segue anidada? ¿Qué dirección? Las direcciones de
segmento anidadas también se conocen como segmento de
rap P2, SSH dash p2, WPA y WPA2. Y direcciones P2 SSH. Este último nombre describe
mejor lo que son y dirección que codifica un script hash de clave de pub pay to witness. Dentro de un script
hash de pago a script. La mayoría de las billeteras modernas
admiten estas direcciones. Su principal ventaja es que
permiten que las billeteras más antiguas, que generalmente admiten direcciones hash de
pago a script, pero no admiten direcciones de
segmento nativas para enviarles bitcoins. Por lo tanto, los propietarios de direcciones de
segmento anidadas pueden beneficiarse de algunas ventajas
de las transacciones Segway, como tarifas de transacción más baratas y recibir fondos
de billeteras antiguas. Entonces, ¿por qué la necesidad de segue direcciones
nativas? Usted puede preguntar. La razón es que las direcciones
nativas de segue hacen transacciones incluso más pequeñas que las direcciones de segmento
anidadas. Las direcciones de segmento anidadas
estuvieron disponibles en 2017 después de que la seg se actualizara, las reglas para generar direcciones de segmento
anidadas
se definieron en BIP 141. Hemos elegido direcciones de
segmento anidadas
como direcciones de
recepción secundarias de nuestras billeteras para permitir recibir Bitcoins
de billeteras antiguas. Entonces, para entender las direcciones de
segmento anidadas, primero
entendamos las direcciones
P2 SSH. P2 SSH es un acrónimo
de hash de pago a script. Las direcciones P2 SSH
son exactamente eso. Codifican un hash generado
a partir de un script de Bitcoin. Veamos el proceso para
generar un tocado P2 SH. Comenzamos con un script de redimir
serializado hexadecimal. Voy a canjear script suele ser un script de
Bitcoin multi-firma, pero puede ser cualquier
otro script Bitcoin. Utilizamos el algoritmo hash 160 para generar un hash de script a partir
del script redeem serializado. Luego combinamos el hash de
script con un prefijo y aplicamos
el
algoritmo de codificación base 58 para producir
una dirección P2 SH a través de la decodificación base 58, podemos obtener el hash de
script back a partir de una P 2 dirección SSH,
una segue anidada. Qué dirección es simplemente una base 58 codificada P2 SSH script fue redimir script es
un script de segmento. Ahora aprendamos a construir
una clave de pub de script P2 SH. Recuerde que una clave de
pub script es parte de una salida de transacción y es como la dirección de recepción está
presente en una transacción. Entonces, comenzando con
una dirección P2 SSH, primero
basamos 58 decodificamos
para obtener un hash de script. Luego construimos un
script que consiste en
un código de operación OP hash 160, el hash de script y
un opcode OP igual. Esta es la clave de pub del
script P2 SH. Para enviar fondos a
una dirección P2 SSH, debes poner este script en la salida de la transacción junto
con la cantidad de cualquier monedero, pero puedes enviar bitcoins
a una dirección P2 SSH, puedes enviar bitcoins
a una segue anidada. ¿Qué dirección? Ahora, veamos cómo construir una entrada de transacción de
segue anidada, comenzando con la
clave de pub válida para una dirección UTXO. Luego aplicamos el algoritmo hash 160 para
obtener un hash de clave de pub. Combinando el hash
con un prefijo cero, obtenemos un script de segmento. Este es el script de redimir, lo
agregará a la entrada de
transacción más adelante. Ahora firmará una transacción. Para hacer eso, primero producimos un hash de firma a partir de
una transacción privilegiada usando el mismo algoritmo de
hash de firma que usamos para firmar una transacción
segue. Después combinamos el hash de
firma con una clave privada válida para generar la firma usando el ECDSA. A continuación, mostramos la entrada de
transacción de signo, el índice de salida de ID de transacción y luego los campos de secuencia funcionan la misma manera que otros tipos de
transacciones. Agregamos el guión redimir
en el campo ScriptSiG, y agregamos la firma y la clave del pub al campo
testigo. Observe que a diferencia de las entradas
nativas de seg, el ScriptSig no está vacío. En este caso. El campo testigo de las entradas de segmento
anidadas tiene los mismos elementos que las entradas de segmento
nativas. Ahora veamos cómo se
ejecuta un script de segmento
anidado durante la
validación de transacciones por los nodos. validación de segmentos anidados requiere la validación de dos scripts
combinados. Dada una clave de pub de
script P2 SSH de algún UTXO y el
correspondiente scriptSig de una entrada de transacción. Ambos guiones se combinan, formando el primer guión
combinado. El script redeem, se pasa
al script combinado como un
solo elemento serializado. En esta primera validación,
de izquierda a derecha, se evalúa
cada elemento del
script combinado, comenzando por el script redeem, que se agrega a
la pila de ejecución. Después el hash OP 160, aplica el hash 160 y
el script redeem, transformándolo en un hash de script. Luego se agrega el hash de script y el script combinado
a la pila de ejecución. Finalmente, el
código de operación igual OP compara ambos hashes de script y devuelve
true si son iguales. Si no son iguales, la
transacción se considera inválida. A continuación, se forma un segundo guión combinando el testigo
y el guiónSiG. Esta vez, el guión redimir en el scriptSiG se evalúa en su totalidad tal como lo es en evaluaciones de guiones nativos de
segue. Y al igual que la evaluación del
script nativo de segue, el dígito cero inicial en
el scriptSig desencadena una regla especial que lo
convierte el script presente en
el script combinado. A partir de ahora, el
script combinado se ejecuta
igual que el script combinado de
las transacciones nativas del segmento. A partir del script combinado, las claves de firma y pub se agregan a una pila de ejecución. Entonces el opcode OPT up duplica la clave pub
en la pila de ejecución. Hasta hash 160 hashes, la última clave de pub
agregada a la pila. Luego, desde el script combinado, se
agrega
el hash de la clave de pub a la pila. Up equal verify opcode elimina los dos últimos elementos de la pila de ejecución
y los compara. Si son iguales, el script
continúa ejecutándose. Finalmente, el opcode
sig objeto comprueba si la firma es válida para la clave pub que queda
en la pila. Si es válido, devuelve
true a la pila de ejecución. Después de agregar todos
los elementos del script a la pila de
ejecución, la
entrada de transacción se considera válida si el último elemento
agregado es verdadero, este proceso debe repetirse para cada entrada de transacción, todas sus entradas deben ser válidas para que
una transacción se
considere válida. Así como un recordatorio visual, repasemos de dónde cada elemento en la clave de pub
script, vino
cada elemento en la clave de pub
script,
ScriptSig y testigo durante la construcción de la transacción. El hash de script presente en la clave pub script
vino de la base 58, decodificando la dirección del
UTXO que se está gastando. El hash de la clave pub y el
ScriptSig provenían del hash 160s de una clave pública válida. La misma clave pública está
presente en el testigo. El testigo es firma vino
aplicando el algoritmo ECDSA, cual necesita una clave privada válida. La clave pública y
el testigo procedían de la clave pública derivada de
la mencionada clave privada. Ahora, veamos algunos parámetros importantes para derivar direcciones de segmento
anidadas. En la red principal de Bitcoin, el prefijo necesario para derivar las direcciones
P2 SSH es C4. Después de que la base 58 codificara un vestidos con ese
prefijo comience con el dígito tres en la red de
prueba de Bitcoin y la prueba reg, el prefijo necesario para derivar las direcciones
P2 SSH es 05. Después de la codificación base 58 direcciones con ese prefijo comienzan
con el dígito a. La ruta de derivación
utilizada para derivar direcciones de segmento
anidadas comienza con la
ruta 49 endurecida para billeteras, siguiendo las pautas BIP 49.
64. 62 skillshare 2 de la parte 3 de Segwit: En este video, implementaremos la
dirección de seg anidada en nuestra billetera, agregaremos como otra opción para recibir Bitcoins en nuestra billetera. Primero preparemos
nuestra aplicación para agregar algunas pruebas relacionadas con
el nuevo tipo de dirección. Entonces vayamos al Nodo, consigamos nuevo cliente de dirección. Necesitamos que nuestra
aplicación pueda llamar a nuestro nodo para generar direcciones
P2 SSH. Así podremos crear pruebas para enviar Bitcoin a estas direcciones. Entonces usemos la opción de
cambio de firma IDE para agregar un nuevo
parámetro a este método. El nuevo parámetro
será una cadena, su nombre será direccionado tipo, y su valor predeterminado
será la cadena atrás 32. Agreguemos una cadena vacía
a esta llamada al método. Este parámetro se usa si
queremos agregar una etiqueta
a nuestra nueva dirección, ya que no la
necesitaremos, la configuraremos en una cadena vacía. Y agreguemos el
tipo de dirección como último parámetro. Bien, ahora podemos pedirle a nuestro
nodo que cree
direcciones P2 SH si el
refactor IDE funcionó. Ahora las llamadas actuales a
este método tendrán la cadena hacia atrás 32 ya
que son menos parámetros. Ahora, vayamos a la prueba de
enviar Bitcoin. Movamos este método
a la clase de prueba GUI. Hagámoslo protegido. En lugar de usar la
palabra clave super aquí, usemos esto. Ahora, vayamos a la clase de prueba
recibir Bitcoin. Copiemos todo el
código de esta clase. En el paquete de prueba GUI. Vamos a crear una nueva clase de
prueba llamada receive Bitcoin
anidado segue test. Y peguemos el
contenido a esta clase. Hagamos algunos
ajustes a esta clase. Cambiemos el nombre de la clase para
recibir la prueba de segue
anidada de Bitcoin. Ahora cambiemos los nombres de los métodos de
prueba. Agreguemos aquí una dirección de
segmento anidada. Hagamos lo mismo con todos los demás métodos de
prueba indicando en sus nombres que recibirán Bitcoins en
segue anidado ¿qué direcciones? Ahora, ajustemos
esta primera prueba. Ajustaremos el nombre de su billetera. Entonces modifiquemos aquí el parámetro de
búsqueda. Entonces la variable address
se asigna
al valor del campo donde se dirige
el segmento anidado. Aquí, en lugar de usar el método
address is valid, usaremos el
segmento anidado address is valid method we will create. Arreglemos este formato de código. Ahora, vamos a crear
el segue anidado qué dirección es el método válido
en la clase de prueba GUI, usaremos como base el método
válido de direcciones. Así que vamos a duplicarlo. Arreglemos su nombre. Ahora. Cambiemos el tipo de dirección aquí a la constante
segmentada anidada. Y cambiemos
aquí
la ruta de derivación para comenzar con 49. Vamos a crear esta constante
en el tipo de dirección enum. Vamos a crear también
la segue anidada para cambiar constante aquí. Aquí, cambiemos el prefijo de la dirección generada al prefijo
de dirección P2 SH
de red de prueba. Y en lugar de usar el generador de direcciones de
segmento, utilizará el generador de direcciones de
segmento anidado. Agreguemos este campo
a esta clase. Usaremos la
anotación auto cableada para
inyectarla en esta clase. Vamos a crear esta clase en
el paquete api dot services. Lo implementará posteriormente. Volver a la clase de prueba segue
anidada Bitcoin recibida. Hagamos los mismos ajustes
a los otros métodos de prueba. Ahora vamos a la clase de
configuración de direcciones. Vamos a duplicar este bean lo
usará como base para crear
la configuración anidada segwayed. Permite cambiar estos parámetros a segmento
anidado y cambio de segue
anidado. Vamos a cambiar este método nombre
dos segmentos anidados config. Ahora cambiemos los parámetros de configuración de
dirección. El primer parámetro será el tipo de dirección seg
anidado. En el segundo argumento, cambiemos las claves de mapa a segmento
anidado y cambio de segmento
anidado. Y ambos caminos de derivación. Empezaremos con 49. Usaremos el generador de
direcciones de segmento anidado
como generador de direcciones. Hagamos que implemente la interfaz del generador de
direcciones. Vamos a agregar el método de interfaz. Ahora, vamos a establecer cada prefijo de dirección de
entorno. El principal entorno neto. Usaremos la constante principal neta P2 del prefijo de dirección
SSH. Los entornos de prueba net y reg
. Usaremos la constante de prefijo de dirección P2
SH net de prueba. Cambiemos el prefijo ki
extendido a la constante principal del prefijo del
segmento anidado neto. El emparejador de direcciones será el predicado segue anidado como. Vamos a crear este campo
en el comparador de direcciones. Será similar al predicado de
segmento anterior. Pero el matcher
volverá verdadero si la dirección empieza con
tres o dos en su lugar. Ahora, vamos a importarlo aquí. Vamos a usar la constante P2
SSH aquí. Vamos a usar el método script anidado segment address
como analizador de script. Utilizará el generador de entrada de
segmento anidado
como generador de
entrada de transacción. Vamos a crear esta clase en
el paquete api dot services. Vamos a agregar el método de interfaz. Como el tamaño de entrada más salida. Estableceremos 180 como el tamaño de
ScriptSiG 23. Y como el
firmante de la transacción
utilizará el firmante de
transacciones de Segway anidado. Vamos a crear esta clase en
el paquete api dot services. Y agreguemos el método
de interfaz. Nuestra
configuración de segue anidada está lista. Ahora necesitamos implementar el generador de
direcciones de segmento anidado, el generador de entradas y el firmante de
transacciones. Empecemos con el
seg anidado que se dirigiría al generador. Primero, agreguemos una
prueba para este servicio en el paquete de prueba api dot
services. Extenderá la clase de
especificación. Vamos a agregar el siguiente método
de configuración. Agreguemos la llamada al método del proveedor de
anuncios de seguridad. Agreguemos el generador de direcciones de
segmento anidado como campo en esta clase. Y vamos a instanciarlo aquí. Ahora, vayamos a la prueba del generador de
direcciones de segmento. Vamos a copiar esta prueba
y pegarla aquí. Lo usaremos como base
para nuestra nueva prueba. En lugar de usar el generador de direcciones de
segmento, utilizará el generador de
direcciones seg anidado aquí. Cambiemos el prefijo
a esta constante. Eliminemos estos casos de
prueba y peguemos los válidos
para las direcciones de segmento anidadas. Están disponibles en la página
Proyecto y Recursos. Volver al generador de
direcciones de segmento anidado. Creé erróneamente esta
clase como una clase maravillosa. Usemos esta característica IDE para
convertir esta clase a Java. Eliminemos este código. Agreguemos la
anotación de servicio a esta clase. Aquí convertiremos la clave secundaria
extendida en una clave pública. Luego devolveremos la dirección del segmento
anidado de llamada al método de
clave pública
comprimida en el objeto
obtain pasándole la variable prefix. Cambiemos el nombre de este
parámetro a clave extendida. Ahora hagamos esta prueba. Genial, ha pasado. Ahora vamos a implementar el
segue anidado qué constructor de entrada. Agreguemos la
anotación de servicio a esta clase. Vamos a copiar el método de compilación en el constructor de entrada de segmento y usarlo como base para
nuestro nuevo método de compilación. También peguemos estas
dos constantes a la clase de constructor de
entrada de segue anidada. Ahora agreguemos la constante
segmentada anidada scriptSig
ficticio en el script ArrayList. Vamos a crear esta constante. Será igual a la cadena
cero repetida 44 veces. Aquí, debemos pasar esta constante dentro de una lista de
método en realidad. Ahora, implementemos el firmante anidado de
transacciones Segway. Agreguemos aquí la
anotación de servicio. Copiemos el método de señal en el
firmante de transacciones Segway y utilicémoslo como base para
nuestro nuevo método de señalización. Aquí, en lugar de usar el método de signo de
firmantes ECDSA de transacción, usaremos el método de segue
anidado sinusoidal
del firmante
ECDSA de transacción P2 SH. Agreguemos el script redeem como cuarto argumento
en este método. Eliminemos este último argumento. Vamos a crear la variable de
script redeem. Esta variable será igual a la llamada al método de
script P2 WP k h. Como su parámetro
pasará el hash 160 de la clave pública
comprimida correspondiente de la clave privada recibida. El método de
segue anidado de signo se
encargará de agregar
el guión redimir
al campo testigo
y la clave pública y la firma al campo
ScriptSIG. Bien, la
configuración de segue anidada finalmente está lista. Ahora agreguemos el nuevo campo de segmento
anidado a la pestaña Recibir FXML. Primero, cambiemos la dirección de recepción
y
el texto de la etiqueta
para la dirección del segmento. Ahora, vamos a duplicar
todo este código y vamos a cambiar este texto de etiqueta a seg anidado abordaría. Cambiemos también esta ética ID dos direcciones de
recepción de segue anidadas. Vamos a mover este campo a la
segunda fila de su contenedor. Para ello, agreguemos el
atributo de índice de fila del panel de cuadrícula a este campo, y vamos a establecerlo en uno. Hagamos lo mismo
con esta etiqueta. Ahora, vayamos al controlador de pestañas
Recibir. Duplicemos esto
si el bloque en esta
declaración if verificará
si el cambio a dirección es una dirección de
segmento anidada. Si es así, entonces
estableceremos la dirección de
recepción de segue anidada contenido
TextField el cambio a dirección. Entonces agreguemos este
campo a esta clase. Y vamos a agregarle una
anotación FXML. Agreguemos también una declaración de
retorno aquí. Ahora, hagamos algunas pruebas. Ejecutemos nuestro nodo Bitcoin. Y hagamos esta prueba. Genial, las pruebas han pasado. En el siguiente video, terminaremos de agregar
el
soporte de segmentos anidados para nuestra billetera. Verás, sí.
65. 63 skillshare parte 4 de Segwit anidado: En este video,
implementaremos la capacidad enviar Bitcoin a
segue anidado qué direcciones. Empezaremos por crear
pruebas para esa función. Entonces, en el paquete de prueba GUI, vamos a crear la clase de prueba segue
anidada de enviar Bitcoin. Extenderá la clase de prueba GUI. Copiemos algunas pruebas de
la prueba de enviar Bitcoin. Servirán como base
para nuestras nuevas pruebas. Vamos a copiar este código
y pegarlo aquí. Ahora, copiaremos esta primera prueba, luego la pegaremos en
nuestra nueva clase. Hagamos lo mismo
con esta prueba. Hagamos lo mismo
con la prueba del anochecer. Ahora, ajustemos las nuevas pruebas. Cambiemos este
nombre de prueba para enviar Bitcoin con entradas de segmento
anidadas y segue
anidado qué salidas. Cambiemos el nombre de la billetera
a mi prueba mientras esté a los 23. Y vamos a cambiar este método de
búsqueda
parámetro de llamada dos
segmentos anidados dirección de recepción. Aquí, cambiemos
este parámetro a segmento de guión P2 SSH. Este parámetro
hará que el nodo devuelva una dirección de segmento anidada para
nosotros para que podamos enviarle Bitcoin. Ahora, ajustemos
los casos de prueba. Anteriormente he calculado los
honorarios totales esperados para estos casos. Se diferencian de las tarifas de
transacción con entradas y salidas nativas de
segue porque sus
tamaños de transacción difieren. Hagamos ajustes similares
para la siguiente prueba. Ahora, vamos a crear el generador de scripts
P2 SH. Se implementará la interfaz script
pub key Builder. Implementemos sus métodos. En el método match
devolverá estas llamadas anidadas al método de
prueba segue pasando la
dirección como su parámetro. Devolveremos la llamada al método de
script P2 SH en el método de compilación ya su parámetro pasará la
dirección descifrada base 58 así. Agreguemos la
anotación de servicio a esta clase. Ahora, vayamos a la prueba de la calculadora de
tamaño de transacción. Duplicemos este método. Lo usaremos como base para
crear una prueba para verificar el cálculo del tamaño
de las transacciones utilizando
entradas y salidas de segmentos anidados. Entonces cambiemos el
nombre del método para que refleje eso. Eliminemos estos
casos de prueba y peguemos los casos de prueba disponibles en la página Proyecto y Recursos. Ahora, en el método setup, agreguemos el seg anidado would config en la lista de configuración de
direcciones. Ahora vamos a la calculadora de tamaño de transacción en el método script pub
key size. Agreguemos lo siguiente si declaración probará si la dirección recibida
es una segue anidada. ¿Qué dirección? Si es así, devolverá el script pub
key anidado segwayed constante. Vamos a crear esta constante. Su valor será de 23. Ahora hagamos esta prueba. Genial, ha pasado. Ahora vamos a ejecutar nuestro nodo. Y vamos a ejecutar la prueba de segue anidada de enviar
Bitcoin. Genial, las pruebas han pasado. Ahora, juguemos un poco con nuestra billetera en el entorno de red de
prueba. Para ello,
cambiemos esta variable en el
archivo bitcoin.com para probar net. Y reiniciemos nuestro nodo. Esperemos
a que se sincronice. Dependiendo de qué tan
actualizada esté tu nota. Puede tomar de minutos a horas. Bien, ponderé la suma de horas. Y por último, mi aviso de sincronización. Ejecutemos nuestra aplicación. Vamos a crear una cartera. Primero. Recibamos algunos Bitcoins en nuestra dirección de segmento anidada. Para ello,
usemos este grifo. Bien, la transacción
apareció en mi billetera. Esperemos un poco
a que se confirme. Bien. Ahora la transacción
tiene una conformación. Ahora, enviemos algunos fondos
a la dirección del grifo. Curiosamente, esta transacción
no necesitó cambios y terminamos sin fondos ya que hemos gastado
nuestro único insumo. Comprobemos la última transacción
en el explorador de bloques. Esperemos un poco
a que se confirme. Esperé algunos minutos, y ahora tiene tres
conformaciones. El Explorador de Bloques
muestra lo mismo. Genial. Todo está
funcionando como se esperaba. Hagamos una prueba más. Vamos a recibir más Satoshi primero en nuestra dirección de segmento, luego en nuestro
seg anidado se dirigiría. Bien, ahora que ambas
transacciones confirmadas, enviemos algunos fondos a una
dirección de segmento anidada desde esta página. Ahora la transacción
generó cambio. Como lo enviamos a una dirección de segmento
anidada, el cambio generado
también se envió a un segue anidado. ¿Qué dirección? Después de un tiempo, se confirmó la transacción. Genial.
66. 64 skillshare 2: En este video,
implementaremos en nuestra billetera la capacidad de enviar bitcoins
a direcciones P2 pKa H, también conocidas como direcciones heredadas. P2, pk h fue el tipo más
utilizado para vestir antes del aumento de popularidad de las direcciones de segmento
en los últimos años. Hoy en día,
sigue siendo muy popular. Por lo que es importante que
nuestra billetera tenga la capacidad de enviar bitcoins
a esas direcciones. Empecemos por refactorizar cómo nuestra billetera construye claves de
pub de script para que
sea más fácil agregar
soporte para enviar bitcoin a otros
tipos de direcciones en el futuro. Para ello, vamos a crear el registro de configuración de script
en el paquete de dominios. Similar a la configuración de la dirección, esta clase contendrá
parámetros importantes para construir transacciones a tipos
específicos de claves de pub de script. Entonces, vamos a agregarle los
siguientes campos. El generador de claves de pub de script, el tamaño de la clave de publicación y el predicado del
comparador de direcciones, lo que ayudará a identificar el
tipo de configuración del script por dirección. Ahora vamos a crear la clase de configuración de
script en el paquete api dot config. Nuevamente, similar a la clase
de configuración de direcciones. Esta clase será
responsable de instanciar y definir todo script pub key es nuestra billetera puede enviar Bitcoin a. Vamos a agregarle la
anotación Configuración. Ahora, vamos a crear el siguiente método anotado de
Bean. Devolverá una configuración de script
y definirá la configuración P2 WP. Es script pub key
builder será el constructor de scripts P2 WP k h. El tamaño del script será igual a 22 y su comparador de direcciones
será el segmento Lambda. Vamos al constructor de scripts P2 WP
k h. Para facilitar la creación de instancias, eliminará del servicio la fábrica de
prefijos de dirección . Construirá la variable de prefijo
mediante el análisis del prefijo de la variable address
usando el método parse prefix. Vamos a crear este método. Primero verificaremos si
la dirección comienza con la constante de prefijo de
dirección P2 WP k h net de prueba. Si es así, devolveremos
esa constante. Entonces haremos la
misma declaración, pero usando la prueba reg P2 WP k-ésima dirección prefijo
constante en su lugar. Finalmente, devolveremos
la constante principal neta P2 WP k h prefijo de dirección si el código se ejecuta
a este punto. Ahora vamos a crear el bean
para la configuración del script P2 SH. Utilizará el generador de scripts P2
SH. Su tamaño será 23 y su comparador de direcciones será
el segmento lambda anidado. Ahora vamos a crear la configuración del
script encontrar su clase en el paquete api
dot services. Como su nombre indica, este servicio se
encargará de encontrar la
configuración de script adecuada para otros servicios. Vamos a agregarle la
anotación de servicio. Ahora, vamos a inyectar la lista de configuraciones de script en esta clase. Spring Boot magic inyectará todos los beans de configuración de script en esta lista después de que se inicie la
aplicación. Ahora, vamos a crear el
hallazgo por método direccionada. Devolverá una configuración de script y tomará una dirección
como parámetro, devolverá la siguiente transformación de
flujo aquí filtrará el script
puede pensar stream usando el comparador
de direcciones de cada script config. Usaremos para encontrar el
primer método para obtener la primera
configuración de script filtrada. Si no encontramos ninguna, usaremos el
método de lanzamiento de URL para lanzar una excepción. Ahora, vamos al servicio de
creadores
de transacciones que
usaremos el buscador de configuración de script
para refactorizar esta clase. Primero, eliminemos la lista de creadores de claves de pub
script de esta clase ya que no la
usaremos. Y vamos a inyectar el script puede pensar Finder en esta clase. Ahora en el método de salida de compilación, eliminemos este código. Se creará esta variable de script utilizando el buscador de configuración de script, encontrar por el método direccionado. Luego llamaremos
al método de compilación script pub key builder
sobre el resultado. Ahora, vamos a refactorizar la calculadora de tamaño de
transacción. Inyectemos el
buscador de configuración de script en esta clase. Ahora, vamos a eliminar el código en el método script pub key size, en su lugar utilizará el
script config Finder para encontrar una configuración de script por dirección y devolver su tamaño de clave pub script. Eliminemos estas importaciones y constantes ya que
no las usaremos. Ahora, vamos a la interfaz script
pub key Builder. Eliminemos el método
match de él y de todas sus
implementaciones, ya que ya no lo usaremos. Se realiza la refactorización. Ahora antes de agregar el
P2 pKa H Script Config permite crear la prueba heredada de enviar Bitcoin en
el paquete de prueba GUI. Extenderá la clase de prueba GUI. Usaremos esta clase para
verificar si nuestra billetera está enviando
correctamente una transacción
a una dirección heredada. Copiemos el siguiente
código de la
prueba de enviar Bitcoin y pegarlo aquí. Lo usaremos como base
para nuestra nueva prueba. Cambiemos su nombre a debería enviar Bitcoin con entradas de
segmento, salida
heredada y
seg cambiaría. Observe que aunque
podremos
enviar fondos a una dirección heredada, no
podremos
recibirlos una dirección heredada
que pertenezca a nuestra billetera. Por lo tanto, utilizará las direcciones nativas de
segue para recibir el cambio en
estas transacciones. Y ese nombre de prueba
refleja eso. Cambiemos el nombre de la billetera
a mi prueba mientras esté a los 26. Cambiemos este parámetro
a legacy para que podamos crear una dirección heredada a la que usaremos para enviar bitcoins. Cambiemos también
los casos de prueba usando
los siguientes valores
calculados previamente. Estos valores difieren de otras transacciones
porque las claves P2, pKa, H script pub son un
poco más grandes que las claves de pub script
nativas de segue , lo que afecta el
tamaño de la transacción y phi. Ahora vamos a la clase de
configuración del script. Agreguemos aquí la
palabra clave pública. Vamos a crear el bean de configuración P2
pKa H ya que su script pub
key builder
establecerá un nuevo generador de
scripts p2 pk H, que creará más adelante. Su tamaño de clave de pub guión
será de 25 y está abordado. Parcher serán estos
Lambda heredados que crearemos más adelante. Vamos a crear el constructor P2
pKa H Script en el paquete api dot services. Vamos a implementar el método
de interfaz. En el método build
devolverá el script P a
P k h la llamada al método script ya su parámetro pasará
la
dirección decodificado hexadecimal base 58 usando la base 58 decodificar con el método checksum a hex. Ahora, vayamos a la clase métrica de
dirección. Duplicemos este campo. Lo usaremos como base
para estos lambda heredados. Aquí se cambiarán estos
parámetros a uno, M y N. Uno es el prefijo de legado que
viste en la red principal. M y n son los prefijos válidos para los demás
entornos. Importemos aquí estos lambda
heredados. Bien, ahora nuestra billetera puede enviar Bitcoin a direcciones
heredadas. Ahora, ajustemos algunas pruebas. Vamos a la prueba de la calculadora de
tamaño de transacción. En el método de configuración, Instanciemos el buscador de configuración del
script. pasaremos una lista de configuraciones de
guiones. Tomará las configuraciones de
script de la clase de configuración de script. Entonces vamos a instanciarlo aquí. Ahora, vamos a agregar el
script puede higos aquí. Ahora, vamos a duplicar esta prueba. Vamos a cambiarle el nombre a debería
calcular el tamaño de la transacción para P2 WP k-ésima entradas de transacción y p2 pk salidas de cada
transacción. Este nombre de prueba describe
bien el escenario probará. Eliminemos estos casos de prueba. Pegará estos
casos de prueba aquí los cuales están disponibles en la página Proyecto
y Recursos. Arreglemos el formato
de estos casos de prueba. Vamos a ejecutar esta prueba. Grado. Ya pasaron las pruebas. Ahora, arreglemos la prueba de servicio de
creadores de transacciones. Vamos a copiar este código
y pegarlo aquí. Eliminemos la fábrica de prefijos de
dirección y los creadores de claves de pub script. Y arreglemos la
instanciación del servicio aquí. Vamos a ejecutar esta prueba. Genial, ha pasado. Ahora arreglemos la prueba del selector de monedas de sorteo
aleatorio único necesitará esta pieza
de código nuevamente. Así que vamos a copiarlo
y pegarlo aquí. Asegúrese de que el selector de monedas de sorteo
aleatorio único esté instanciado correctamente. En mi caso, la identificación
ya lo hizo. Vamos a ejecutar esta prueba. Grado. La prueba ha pasado. Ahora, vamos a ejecutar nuestro nodo. Antes de eso, asegúrese de que el archivo
bitcoin.com tenga el entorno de prueba
reg establecido. Ahora vamos a ejecutar la prueba heredada de enviar
Bitcoin. Genial, La prueba ha pasado.
67. 65 Guardar skillshare 2: En los videos anteriores, implementamos una aplicación completamente funcional
que
ya puedes usar para crear billeteras y enviar y recibir Bitcoins. Pero si cerramos la aplicación, perdemos toda la información
sobre las billeteras que creamos en este
video y en el siguiente, comenzaremos a implementar
la capacidad guardar y cargar billeteras
en nuestra aplicación. Para almacenar los datos de nuestra aplicación, utilizaremos la base de datos H SQL. Sql es una base de datos SQL
implementada en Java. Hemos elegido H SQL por
las siguientes razones. Primero, es una base de datos
ligera. En segundo lugar, es compatible
y fácil de usar con la biblioteca Spring Boot
Data JPA. Por último, se puede
cifrar fácilmente como lo
mostraremos en este video. Vamos al archivo XML poema
punto para agregar las dependencias Spring Boot Data JPA y
H SQL DB. Haga clic en este botón para
cargar las nuevas dependencias. Ahora vamos al archivo de propiedades del
punto de la aplicación. Vamos a establecer algunas configuraciones
necesarias para la base de datos. Esta configuración
determina que cada modificación que hagamos en
nuestras clases de entidad, actualizaremos nuestra
base de datos en consecuencia. En Spring Boot, las clases
anotadas de entidad definían las estructuras de tabla,
como veremos pronto. Duplicemos esta línea para usarla como base para las
otras configuraciones. Tenemos que establecer la clase de controlador llamada config a la
siguiente clase. El nombre de usuario y la contraseña. Puedes ponernos
lo que quieras. Como lo estoy usando
solo para pruebas, estableceré estos campos
para que sean Y0 W por ahora. Pero recuerde cambiar
estos valores a cadenas
más seguras antes de usar esta billetera
en la red principal. Ahora, definamos la
URL de la base de datos. Ya que vamos a utilizar una base de datos basada en
archivos, tendremos que establecer esta configuración JDBC colon colon H SQL DB archivo
colon, la ruta que queremos que residan los archivos de la
base de datos. En mi caso, el camino
comenzaremos con la carpeta BYOD W
ubicada en el asiento dr. Raíz. Dentro de esta carpeta,
quiero crear carpetas
específicas para cada entorno de red
Bitcoin. Para ello, me referiré a
la
variable de entorno Bitcoin en este archivo de propiedades de
punto de aplicación, poniéndolo entre
llaves y después de un signo de $1 así. Finalmente, usaré la subcarpeta de
datos dentro esta carpeta y nombraré
los archivos DB como mi DB. Y terminamos la
línea con punto y coma. Ahora dentro del paquete BYOD W, vamos a crear el paquete de
base de datos. Dentro de este paquete, vamos a
crear el paquete de entidades. Y vamos a crear la clase de
entidad wallet dentro de ella. En esta clase, modelaremos registros en la tabla de la base de datos de
billeteras. Para ello, le agreguemos la anotación de
entidad. Y la anotación de tabla con su parámetro de nombre
igual a Wallet. Ahora, agreguemos algunos
campos a esta clase. Cada campo en esta clase, modelaremos una columna
de la tabla de billetera. Nuestro objetivo es guardar solo los campos
necesarios para obtener los mismos
datos de billetera después de cargarlo. Entonces agreguemos el campo ID. Se agregará este campo para seguir la buena práctica
de agregar siempre un identificador de incremento automático a una tabla de base de datos relacional. Para ello, agreguemos dos
anotaciones a este campo. La primera es la anotación de ID, la segunda es la anotación de valor
generada con el siguiente parámetro. También agreguemos una anotación de
columna con ID como parámetro de nombre. La anotación de columna
determinará el
nombre correspondiente de la columna enlazada a este campo
en la tabla de billetera. Seguiremos el estilo de caso
serpiente para los parámetros de nombre de columna donde todas las letras o minúsculas y subrayado
separan las palabras. Ahora vamos a crear el campo de nombre. Agreguemos también la
anotación de columna a este campo. Además del parámetro name, agreguemos también el parámetro unique equals true y el parámetro nullable
igual a false. Estos parámetros agregarán las restricciones únicas y no
anulables en la tabla para esta columna. Por lo tanto, la aplicación
generará un error si intentas crear un registro sin nombre en
la tabla de billetera. Creemos también el campo semilla
mnemotécnico con la siguiente anotación. El parámetro length limitará la longitud máxima de este
campo a 500 caracteres. Agreguemos también el parámetro nullable
equal false a esta anotación. Ahora, agreguemos el
campo número
de direcciones generadas con la anotación de columna siguiendo el estilo de caso de serpiente. El último campo
será el creado en. Agreguemos la
anotación de fecha creada para indicar que este campo utilizará
la fecha actual para registrar sus valores. Ahora, vamos a crear
algunos constructores. Primero, un constructor vacío, que es necesario
para que Spring Boot instancie esta
clase correctamente. A continuación, vamos a crear
un constructor con todos los
campos de esta clase excepto el id. Vamos a crear getters
para los mismos campos. Nuestra entidad de billetera está hecha. Ahora dentro del paquete de base de datos, vamos a crear el paquete
repositorios. Y vamos a crear la interfaz del
repositorio de billeteras dentro de ella. La interfaz del repositorio de billeteras será
responsable de interactuar con la base de datos
recuperando datos y guardando datos
en la tabla de billetera. Para lograrlo, extenderá interfaz
del repositorio JPA agregará parámetros de tipo
a esta extensión. La primera prueba para ser la entidad que este repositorio
vamos a gestionar. En este caso, será
la clase de entidad wallet. El segundo tiene que ser el tipo de
identificación de la entidad. Por lo tanto,
será la clase larga. Con esta sencilla interfaz, ya
tenemos acceso a operaciones
comunes de base de datos
para la tabla de cartera, como insertar registros
y encontrarlos por ID. Todo esto es
traído automáticamente a usted por la biblioteca Spring Boot
Data JPA. Ahora vamos a crear el paquete de
servicios
en el paquete de base de datos. En su interior, vamos a crear la clase de servicio de
guardar billetera. Esta clase se
encargará de guardar la cartera
después de su creación. Vamos a agregarle la
anotación de servicio. Inyectemos el
repositorio de billeteras en esta clase. Hagamos lo mismo con el número inicial del campo de direcciones
generadas. Ahora, vamos a crear el método de
guardar billetera. Tomará como parámetro un
objeto wallet. Para implementar.
Primero instanciará un nuevo objeto de entidad de billetera con los siguientes parámetros
de la billetera. Después llamaremos al método save del
repositorio de billetera, pasando a la
entidad wallet como su parámetro. *****. Aquí mezclé el orden
de los parámetros. Vamos a arreglarlo. Y agreguemos aquí la anotación
calificador para la correcta inyección
de este campo. Eso es. Con este sencillo código, logramos guardar la información de la
billetera la base de datos SQL fácilmente. Ahora vamos a crear el paquete de
oyentes
en el paquete de base de datos. Y vamos a crear una clase
llamada save wallet listener. En su interior. Esta clase servirá como oyente para
el evento de billetera creado. Para que después de que la aplicación
cree una billetera, se
encargará de llamar
al servicio de guardar billetera
para guardar la billetera. Entonces vamos a agregarle la
anotación de componente. Implementará el oyente de
aplicaciones con el evento de billetera creado
como su parámetro de tipo. Implementemos su método. Aquí, llamaremos al método
guardar billetera, pasando la billetera de eventos
como su parámetro. Vamos a crear este método. Usaremos el servicio de guardar
billetera aquí. Entonces vamos a inyectarlo
en esta clase. Entonces llamaremos aquí al método guardar
billetera, pasando la billetera
como su parámetro. Ahora, si todo
funciona correctamente, nuestra aplicación
guardará billeteras en la base de datos después de
su creación. Así que vamos a ejecutar nuestra
aplicación para probar esta característica probará primero
en el entorno de prueba reg. Asegúrese de que la opción VM en la
configuración de ejecución de la aplicación BYOD W esté vacía. Para esta prueba específica, no necesitaremos ejecutar
nuestro nodo. Vamos a ejecutarlo. Vamos a crear una cartera. Bien, si todo
funcionó correctamente, se guardó
la billetera. Cerremos nuestra aplicación. Ahora. Veamos si los archivos de la
base de datos fueron creados en la carpeta especificada. Genial, la aplicación creó la carpeta reg test y los archivos
DB esperados en ella. Vamos a abrirlos.
Archivo de registro de puntos IDB. Aquí podemos ver todas nuestras
operaciones de bases de datos de
aplicaciones en SQL
escritas en texto plano. Podemos ver que tiene un comando insert que
contiene datos de wallet, incluyendo su semilla mnemotécnica. Bueno. Pero esto no se guarda
ya que cualquiera que obtenga este archivo puede conocer todas nuestras
billeteras, semillas mnemotécnicas. Lo arreglaremos pronto
cifrando estos archivos. Por ahora, veamos los datos de la billetera guardada en
un formato más legible. Para ello, vayamos a esta página web para
descargar el H SQL DB. Haga clic en el enlace de
descarga para descargar la última versión. Después de descargarlo, extrae
su contenido a una carpeta. Vamos a abrir la carpeta bin ubicada dentro de la carpeta
extraída. Ahora vamos a ejecutar los
gerentes de ejecución swing puntear ese archivo. Vamos a la aplicación
dot properties en nuestra aplicación para copiar
la URL de la base de datos. Ahora, vamos a pegar su
contenido en este campo. Y sustituyamos esta
variable por la prueba reg. Agreguemos aquí el mismo nombre de usuario y contraseña que definimos en nuestro archivo de
propiedades de punto de aplicación. Vamos a hacer clic. Bien, genial. Hemos logrado conectarnos
a nuestra base de datos. Ahora, haga clic con el botón derecho en la carpeta de billetera
pública de puntos aquí y haga clic en la instrucción
SQL select. Ejecutemos este comando haciendo
clic en este botón. Genial. Aquí están nuestros datos de billetera
en formato de tabla. Podemos ver que nuestra aplicación guardó
con éxito
los datos de la billetera. Cerremos esta aplicación. Ahora, como dije antes, es
importante que
encriptemos nuestros archivos de base de datos. Para ello, agreguemos
el siguiente sufijo a la URL de
la base de datos en el archivo de propiedades de punto de la
aplicación. Aquí definiremos una
clave criptográfica y encriptaremos el tipo. El tipo cuna será AES, que es una
criptografía simétrica que la aplicación
utilizará para cifrar los datos antes de guardarlos en la base de datos y descifrar
los datos al recuperarlos. La clave cripta será la clave necesaria para ambas operaciones. Volvamos a usar el administrador de bases de
datos SQL para generar
una clave cripta válida. Haga clic en el botón Bien aquí. Ejecutemos el
siguiente comando SQL. Vamos a copiar la
clave generada en un editor de texto, luego copiarla de nuevo al valor de
la clave crypt en las propiedades de punto de la
aplicación. Ahora agreguemos la misma configuración
de base a los otros
archivos de propiedades del proyecto. Vamos a eliminar la carpeta
reg test, crear un distorsiona los archivos de
la base de datos. Y volvamos a ejecutar nuestra
aplicación. Vamos a crear una nueva cartera. Ahora, vamos a abrir la carpeta
reg test y el archivo log generado
my db dot. Su contenido es completamente
ininteligible ahora, eso significa que se cifró
con éxito. Volvamos a copiar la URL de la
base de datos, incluyendo el
sufijo de cifrado y
abrirla usando el administrador H SQL DB. Genial, podemos
volver a ver los datos de la billetera
guardada usando la nueva URL
en esta aplicación.
68. 66 cartera de carga parte 1 skillshare 2: En este video, comenzaremos
a implementar la capacidad de
cargar billeteras previamente guardadas en nuestra aplicación. Primero, hagamos alguna refactorización
necesaria. Vamos al servicio de crear
monedero. Queremos poder
crear billeteras con diferentes fechas y números
de direcciones generadas. Entonces agreguemos estos como
parámetros en este método. Ahora, sustituyamos esta
instanciación de fecha por la variable
created at. Y agreguemos la
variable número
de direcciones generadas como último
parámetro de este método. Ahora, vayamos al controlador de diálogo create
wallet para agregar estos parámetros a
la llamada al método create. Inyectemos el número
inicial de direcciones
generadas
en esta clase. Ahora, cambiemos la
firma del
método de direcciones ADA para incluir
el último parámetro que
acabamos de agregar a esta llamada. En el servicio de direcciones ADD, agreguemos la
variable número
de direcciones generadas a este método
llamada y firma. También pasémoslo como
último parámetro del método
de generación de
generador secuencial de direcciones. Cambiemos la firma de este método para incluir
este parámetro. Ahora, eliminemos el número
inicial de campo de direcciones
generadas de esta clase. Y vamos a sustituirla aquí por la variable número de
direcciones generadas. Ahora vamos a ir a la
actualización actual del servicio de
direcciones de cartera establecerá el número inicial de direcciones
generadas como el último parámetro
de esta llamada al método. Ahora vamos a crear la clase de prueba de billetera de
carga en el paquete de prueba GUI. Extenderá la clase de prueba GUI. Pasemos a la
prueba de enviar Bitcoin para copiar esta parte del código, ya que la necesitaremos
para nuestra nueva prueba. Y vamos a pegarlo aquí. Ahora, vayamos a la clase de prueba de Bitcoin
receptora. Copiemos esta primera prueba y utilicémosla como base
para nuestra nueva prueba. Vamos a renombrarlo a debería cargar billetera y recibir Bitcoin. Vamos a formatear esta prueba. Agreguemos un
bloque dado a esta prueba. Aquí, vamos a definir un
nombre de billetera y variables de contraseña. Definamos también una variable semilla
mnemónica. Usaremos el método de
creación del servicio de semillas
mnemotécnicas para generarlo. Inyectemos el servicio de semillas
mnemotécnicas en la clase de prueba GUI. Ahora, llamemos aquí al método create
wallet, pasando el
nombre de la billetera, la contraseña y la semilla mnemotécnica
como sus parámetros. Vamos a crear este método
en la clase de prueba GUI. Aquí, crearemos un Wallet usando el servicio create wallet. Así que vamos a
inyectarlo en esta clase. Ahora, llamemos
al método create pasándole estos parámetros. Ahora usaremos el servicio de
guardar billetera. Así que vamos a
inyectarlo en esta clase. Y vamos a llamarlo método
guardar billetera, pasando la billetera
como su parámetro. Por último, devolvamos
la cartera aquí. Volver a la prueba de billetera de carga. Ahora que hemos creado y guardado una billetera intentaremos cargarla. Así que vamos a eliminar este código. Llamemos al método load
wallet, pasando el
nombre de la billetera como su parámetro. Vamos a crear este método
en la clase de prueba GUI. También tomará un parámetro de contraseña
opcional con una cadena vacía
como su valor predeterminado. Primero, intentaremos hacer clic en un componente con la carga de textos. Este componente será
el botón de menú de carga, que estará junto
al botón Nuevo en el menú en la parte superior
de la ventana principal. Después moveremos el mouse a un componente con
la billetera de texto. Después de eso,
esperaremos que aparezca un submenú que contenga todos los nombres de
billetera cargados. Después haremos clic en el que tenga
el texto igual a la variable
wallet nombrada. A continuación, esperaremos que
aparezca
una ventana de diálogo con un
campo de entrada de contraseña y un botón Ok. Entonces haremos clic en
este campo que tiene el ID de ética de
contraseña de la billetera de carga. Ahora vamos a escribir la
contraseña en ese campo. Después haremos clic en
el botón Bien. Por último, llamemos
al método sleep para esperar
a que se cargue la billetera. Bien, el resto de la
prueba será igual las pruebas de billetera receptora
que hemos utilizado como base para esta prueba enviarán Bitcoin
a la billetera cargada y esperarán que las direcciones y tablas de
transacciones sean
lleno de valores apropiados. Ahora, vayamos al archivo FXML punto
playground para diseñar el menú de carga. Agreguemos un control de menú
a la barra de menús. Cambiemos su texto para cargar. Ahora, agreguemos un
control de menú al menú de carga. Eliminemos este elemento del menú
que se agregó automáticamente. Cambiemos los textos de este
menú a billetera. Y eliminemos este elemento del menú. Ahora en la vista del editor de texto, agreguemos un Fx ID
a esta etiqueta de menú. Vamos a configurarlo para cargar el menú FXML. Vamos a agregarlo al controlador de ventana
principal. Agregará una anotación FXML y la cambiará a
un campo privado. Ahora, agreguemos la clase de menú de
carga en el paquete observables. Esta clase se encargará de administrar los elementos del menú que se agregarán
para cada billetera que creamos en nuestra aplicación. Vamos a agregarle una
anotación de componente. Vamos a crear el campo de
elementos del menú aquí. Será un conjunto observable
de entidad tipo wallet. Lo instanciaremos usando un
nuevo envoltorio de conjunto observable, pasándole un nuevo
LinkedHashSet. Ahora vamos a crear aquí
el buen método de elementos de
menú observables. Devolverá los elementos del menú. Ahora vamos a crear el listener de menú de
carga en el paquete de
escucha de puntos GUI. Este oyente se
activará por el
evento pegajoso iniciado publicado después de que se inicie
la aplicación. Lo usaremos para cargar
todas las billeteras guardadas en la base de datos y
agregarlas al menú de carga. Vamos a agregarle una
anotación de componente. Implementará la clase de escucha de
aplicaciones con el evento iniciado GUI
como su parámetro de tipo. Implementemos su método. Usaremos el
repositorio de billeteras aquí. Así que vamos a
inyectarlo en esta clase. También vamos a inyectar el
menú de carga en esta clase. Después llamaremos al método final para cargar todas las billeteras
de la base de datos. Para cada monedero se llamará
al método add wallet. Vamos a crear este método envuelto en la plataforma
ejecutar más tarde llamada, vamos a llamar al método load
menu add, pasando la
entidad wallet como su parámetro. Vamos a crear este método
y la clase de menú de carga. Aquí simplemente llamaremos
al
método add items menu pasando la
entidad wallet como su parámetro. Ahora vamos a copiar esta línea. Pasemos a la clase de servicio Guardar
billetera. Lo pegaremos aquí. Inyectemos el
menú de carga en esta clase. Con este código, hará que nuestra billetera recién guardada se
agregue al menú de carga. Ahora, vamos al
patio de recreo punto FXML. Vamos a copiar estas líneas y pegarlas en la ventana
principal FXML. Ahora, vayamos al controlador de ventana
principal. En el
método inicializado vinculará todos los cambios en el menú de carga
observables al menú de carga. componente fxml necesitará
el menú de carga aquí. Así que vamos a
inyectarlo en esta clase. Ahora, llamemos al método get observable menu
items en él. Y llamemos al método de
escucha de anuncios en el resultado como su parámetro. Pasaremos la siguiente Lambda. El cuerpo Lambda
obtendrá el elemento agregado y lo almacenará en la
variable wallet así. Entonces usaremos una
declaración if para verificar si el menú contiene la
billetera así. Vamos a crear este método. Mediante la siguiente
transformación de flujo se verificará si el menú de carga FXML contiene un elemento de menú con el
mismo nombre que la variable de entidad de billetera. Aquí, si el menú de carga FXML
no contiene la cartera, se procederá a agregarla a la misma. Instanciará un objeto de elemento de
menú pasando como su parámetro,
el nombre de la billetera. Después agregaremos el elemento del menú
al menú de carga FXML, así. Ahora, vayamos a la clase de prueba
GUI en el método de inicio
antes de que cada prueba limpie la base de datos
para que las billeteras, los nombres duplicados de
madera
no sean persistidos. De esa manera, evitamos los bloqueos de
prueba debido a la restricción de nombre único
en la tabla de billetera. Aquí necesitaremos el
repositorio de billeteras. Así que vamos a
inyectarlo en esta clase. Después llamaremos al método
delete all en él. Ahora, vamos a ejecutar nuestro nodo. Y vamos a ejecutar la prueba
de billetera de carga. Bien, la prueba corrió hasta la parte
esperada y falló. Pudimos ver que nuestro menú de
carga fue creado y poblado con el nombre de billetera
creado. Bueno. En el siguiente video, seguiremos
implementando esta característica, C. Sí.
69. 67 Cartera de carga parte 2 skillshare: En este video,
continuaremos implementando la función de billetera de
carga. Para comenzar, construiremos una ventana de diálogo que
aparecerá después de
hacer clic en el nombre de la billetera que queremos cargar y el menú de carga como
base para construirla, usaremos el diálogo crear
billetera. Entonces vamos al diálogo crear
billetera FXML. Vamos a copiar todo este contenido. Vamos a crear el archivo
FXML de diálogo de billetera de
carga en el paquete FXML. Y vamos a pagar El contenido
copiado aquí. Cambiemos el texto del encabezado del
diálogo a la siguiente frase. Cambiemos el atributo de
altura pref a 300. También eliminemos estas líneas. Vayamos al Scene Builder
para ver cómo se ve. Cambiemos este
texto de etiqueta a contraseña de billetera. En la vista del editor de texto, cambiemos este fx ID
para cargar la contraseña de la billetera. Y cambiemos el controlador
FX de
la etiqueta de dolor de diálogo para cargar el controlador de diálogo de
billetera. Vamos a crear este controlador. Vamos a agregarle la
anotación de componente. Y agreguemos todos estos
campos FXML al controlador. Ahora, vamos al controlador de la ventana
principal aquí antes de agregar el
elemento de menú al menú de carga FXML, llamaremos al método set on
action en él, pasándole el siguiente
Lambda. Esto hará que la
aplicación ejecute el método de
diálogo de billetera de carga abierta, pasando la billetera como su parámetro después de
hacer clic en este elemento del menú. Así que vamos a crear este método. Copiemos el contenido
del método de diálogo open create wallet y utilicémoslo como base
para nuestro nuevo método. Vamos a establecer el
título del diálogo para cargar billetera. Cambiemos el
primer parámetro de instanciación
del cargador FXML al campo de diálogo de carga de
billetera. Inyectemos este
campo en esta clase. Agreguemos aquí esta
anotación de valor y cambiemos su parámetro al archivo FXML de
la billetera de carga. Ahora, tenemos que
pasar la billetera al controlador de
diálogo de
la billetera de carga. Para ello, primero obtengamos el controlador
del cargador FXML. Entonces llamemos a este método set
wallet en él, pasándole la billetera. Vamos a crear este método. Aquí. Simplemente estableceremos el campo
de entidad de
billetera en la variable wallet. Vamos a crear este campo. Ahora, vamos a crear el método
inicializado que se ejecutará
después de que aparezca el diálogo. Vamos a copiar este código y el
controlador de diálogo create wallet y pegamos aquí. Esto establecerá la
acción de cerrar la ventana de diálogo en
el botón de cancelar. También copiemos y peguemos este código al nuevo método
inicializado. Establecerá la acción del botón
Bien. Pero en lugar de llamar
al método create wallet, llamará al
método load wallet. Vamos a crearlo. Primero. Recuperaremos una nueva entidad de
billetera de
la base de datos y la estableceremos como
el campo de entidad de billetera. Para ello, necesitaremos el repositorio
de monederos. Así que vamos a
inyectarlo en esta clase. Después llamaremos al método
find por su nombre en él, pasándole el nombre de la
entidad monedero. Vamos a crear este método. El método será
así. Spring Boot Data JPA magic traducirá automáticamente
este nombre de método en una consulta SQL y recuperará
la entidad de billetera con el nombre pasado como
parámetro de la base de datos. Ahora, crearemos
un objeto wallet. Para ello, necesitaremos
crear un servicio de monedero. Así que vamos a
inyectarlo en esta clase. Llamaremos al método create pasando los siguientes
parámetros. Todos estos parámetros excepto
la contraseña del monedero, serán tomados de
la entidad wallet que se encuentra en la base de datos. La contraseña se tomará del campo
de contraseña de diálogo. Inyectemos el
objeto context en esta clase. Ahora, usando el
contexto se publicará un evento de billetera cargada pasándole esta y la
billetera creada. Finalmente, llamaremos
al método hide para cerrar así la
ventana de diálogo. Vamos a crear la clase de evento de
billetera cargada. Pasará el parámetro load wallet
dialogue controller al super constructor. Y estableceremos el campo
wallet en
el parámetro constructor wallet. Vamos a crear un getter
para el campo de la billetera. Ahora, hagamos alguna refactorización en el oyente de
importación de billetera creado. Queremos que sea
para escuchar eventos de billetera cargada. Pero tal como es ahora, solo puede escuchar
el evento de billetera creado. Para cambiar eso, vamos a eliminar esta sentencia implement y
esta anotación Override. Cambiemos el nombre de este
método para importar wallet y su
parámetro a un objeto wallet. Cambiemos el
parámetro del método de
importación de billetera a Wallet. Ahora vamos a crear un método anotado con la anotación del
oyente de eventos. Se llamará en el evento de billetera
creado, y recibirá un evento de billetera
creado como su parámetro. Aquí llamaremos al método
import wallet, pasando
como parámetro el monedero del evento. Esta refactorización seguirá haciendo que las cosas funcionen como antes. Pero ahora, si queremos
escuchar otro evento, podemos simplemente crear otro método anotado de oyente pasando el evento que
queremos como su parámetro. Eso es exactamente lo que
haremos ahora usando el evento load wallet también
llamará al método import
wallet aquí, pasando la billetera de eventos
como su parámetro. Eso hará que el
nodo Bitcoin importe la billetera, al
igual que cuando
creamos una nueva billetera. Ahora, vamos a crear la clase de escucha de
billetera cargada en el paquete de oyentes. Vamos a agregarle la
anotación de componente. Vamos a crear un método anotado de
oyente llamado evento de billetera descargada. Tomará como parámetro un
evento de cartera cargado. Aquí llamaremos al método
load wallet pasando el event wallet
como su parámetro. Vamos a crear este método. Aquí. Necesitaremos la actualización
actual del servicio de monedero. Así que vamos a
inyectarlo en esta clase. Y llamaremos al método de
actualización en él. Al pasar la billetera como su parámetro también se necesitará
la actualización del servicio UTXOS. Así que vamos a
inyectarlo en esta clase. Después llamaremos al método de
actualización en él, pasando las direcciones
y el nombre de la billetera como sus parámetros. Con estas dos líneas de código, esperamos que la billetera
actual se cambie a la
billetera cargada y sus direcciones, transacciones y saldos
se actualicen en consecuencia. Ahora arreglemos algunas pruebas. Se rompieron los videos anteriores en la prueba del
generador secuencial de direcciones. Eliminemos este
primer parámetro en la instanciación
del generador secuencial de direcciones. Y fijemos 20 como último
parámetro de este método. Vamos a ejecutar esta prueba. Genial, está funcionando como se esperaba. Hagamos lo mismo con la prueba de
crear el servicio de monedero. Bien, está funcionando. Ahora. Vamos a ejecutar nuestro nodo. Limpiemos y
compilemos el proyecto usando esta función IDE de Maven. Y vamos a ejecutar la prueba
de billetera de carga. Falló. El problema está en el controlador de ventana
principal. Aquí tenemos que llamar
al método FXML loader get
controller en lugar del método load. Realicemos de nuevo la prueba. Genial, Ha pasado.
70. 68 cartera de carga parte 3 skillshare 2: En este video,
agregaremos más pruebas y haremos algunas optimizaciones a
la función de billetera de carga. Una de las características que tendrá
nuestra cartera es la negación
plausible. La negación plausible
en este contexto es una característica de seguridad
que
te permitirá ocultar las direcciones de tu
billetera
ingresando una contraseña diferente
para cargar tu billetera. Eso significa que nuestra billetera no
tendrá contraseñas incorrectas. Cada contraseña ingresada dará acceso a un
conjunto diferente de direcciones, pero observar a terceros
no podrá decir si las direcciones de billetera cargadas
tienen la mayor parte de tus fondos. Vamos a crear una prueba
para este escenario. Duplicemos esta prueba y utilicémosla como base
para nuestra nueva prueba. Vamos a renombrarlo a
debería cargar billetera con diferente contraseña
y recibir Bitcoin. Vamos a reformatear. Aumentemos el número de
billetera con nombre. Ahora definamos esta variable de contraseña
diferente y pasémosla al método
load wallet como su segundo argumento. También pasémoslo como último parámetro del método válido de
direcciones. Vamos a establecer el parámetro
password como un parámetro opcional
para este método, estableciendo su valor
predeterminado en una cadena vacía. Sustituyamos la cadena
vacía y el método de dos claves maestras
por la variable de contraseña. Vamos a ejecutar nuestro nodo. Comentemos este método
y ejecutemos nuestra nueva prueba. Genial, ha pasado. Esta prueba muestra que nuestra aplicación ya
admite cualquier contraseña para cargar una billetera y
que cada contraseña generará un
conjunto separado de direcciones. Vamos a descomentar esta prueba. Dada nuestra forma de ver
una billetera como tener múltiples conjuntos de direcciones de
acuerdo a sus contraseñas. Tenemos que solucionar un problema
en nuestra aplicación. Cuando hacemos llamadas
a nuestro nodo Bitcoin a través de nuestra aplicación, usamos nuestro nombre de billetera. Esto es un problema
ya que para operaciones como recuperar nuestras transacciones de
billetera y UTXOS de nuestro nodo
recopilaremos la misma información para diferentes conjuntos de direcciones generados por
diferentes contraseñas. Para optimizar nuestra nota las llamadas
RPC y recopilar solo información para
las direcciones generadas con una contraseña dada, usaremos la primera
dirección de recepción
generada como el nombre de la
billetera importante para nuestro nodo. Para ello, vayamos
al registro de la cartera. Vamos a crear el buen método de la
primera dirección aquí. Utilizará el método get
addresses para devolver la primera
dirección de la billetera. Ahora, tenemos que sustituir cada llamada al campo de
nombre de billetera que se hizo para comunicarse
con nuestro nodo por una buena llamada al método de primera
dirección, usemos nuestro ID para identificar los usos de el campo de nombre
y hacer la refactorización. Ahora, vayamos a la actualización del servicio de billetera
actual y fijemos la primera dirección
de la billetera actual. Vamos a crear este método. Aquí. Estableceremos el
primer campo
de dirección en el parámetro recibido. Vamos a crear este campo. Y vamos a crear
un getter para ello. Ahora, sustituyamos relevantes
del método getName de la
billetera actual por
las llamadas al método de obtención de la
primera dirección de la billetera actual. Ahora vayamos a la prueba de billetera de
carga, comente la primera prueba y ejecutemos la prueba restante. Grandes cosas
siguen funcionando como antes. Vamos a descomentar esta prueba. Ahora, vayamos a la clase de
configuración de direcciones. Como ahora estamos usando
la primera dirección de billetera para interactuar con nuestro nodo, la primera dirección
siempre debe ser la misma para una combinación de
semilla mnemotécnica y contraseña. Por lo tanto, tenemos que
garantizar que la lista de configuraciones de
direcciones y
sus direcciones siempre estén en el mismo orden. Para ello, usemos la
anotación de orden en ambos frijoles. Agreguemos la
anotación de orden con cero como argumento
en este primer Bean. Esto hará que Spring
inyecte este bean en las listas de configuración de
direcciones
como el primer elemento. Cambiemos también el
segundo argumento
del objeto address config
a un Hashmap vinculado. Contrario a los mapas generados
por el mapa de método, el Hashmap vinculado mantiene
el orden de inserción, lo logrará utilizando
el siguiente código. Ahora hagamos el mismo refactor al otro frijol de configuración
de vestido rojo. Y agreguemos
aquí la anotación de
orden usando uno como su parámetro, garantizando que
se inyectará después el primer bean se alista
de configuraciones de direcciones. Ahora, hagamos otra
optimización. Importar direcciones a nuestro
nodo a veces es lento. Para evitar
importar innecesariamente direcciones a nuestro nodo comprobaremos si ya
están importadas. Para hacerlo, vamos a crear
el nodo recibido por cliente de
dirección en el paquete de cliente
nodo punto. Este cliente recuperará todas las
direcciones cargadas actuales por nuestro nodo. Vamos a agregarle la
anotación de servicio. Y vamos a inyectar el cliente del
nodo en él. Ahora, vamos a crear el método de
direcciones de lista aquí. Devolverá una lista de objetos de dirección de nodo
como sus parámetros. Tomará un nombre de billetera. Amén conf, que definirá el número mínimo
de conformaciones
de las direcciones devueltas. El parámetro include empty, que definirá
si la llamada
devolverá direcciones sin fondos. Y el parámetro include
watch only que le dirá al
nodo si queremos
recuperar direcciones
que el nodo no conoce sus claves
privadas correspondientes. Vamos a crear el registro de dirección de
nodo en el paquete de nodos de punto de dominios. Tendrá sólo
un campo de dirección. Usando el cliente del nodo. Hagamos la llamada RPC aquí. Devolverá una matriz de
direcciones de nodo. El primer parámetro para el método make request será la lista recibida
por cadena de dirección. Luego pasaremos un nuevo objeto de
referencia de tipo
parametrizado. A continuación, la URL de la billetera. Finalmente, los
parámetros del método de vestimenta enumerados los
describimos anteriormente. Ahora devolverá una conversión de la matriz de direcciones de nodo en una lista de direcciones de nodo como esta. Ahora, vayamos al servicio de monederos de
importación. Aquí agregaremos una
declaración if para verificar si las direcciones de
la billetera
no se importaron así. Vamos a crear este método. Dentro del cuerpo if utilizará el
método import addresses para importar las direcciones solo si no
se importaron antes. Vamos a implementar el método
de dirección importante. Obtendremos las
direcciones importadas usando el nodo recibido
por dirección cliente. Así que vamos a
inyectarlo en esta clase. Después llamaremos al método
de direcciones de lista. Al pasar los siguientes parámetros el resultado
se convertirá
en una secuencia y se utilizará el método map para extraer
todas las direcciones de direcciones de nodo. Luego convertiremos
el resultado en un conjunto de direcciones usando
el método collect. A continuación, convertiremos las
direcciones de monedero en un conjunto como este. Ahora, al usar el
método de eliminación en las direcciones de la billetera, eliminará todas las
direcciones importadas de la misma. Por último, vamos a devolver
las direcciones de la billetera es llamada método vacío. Si el resultado es verdadero, ya se
importaron
todas las direcciones de monedero. Oh, nos olvidamos de eliminar
esta línea. Vamos a hacerlo. Ahora. Vamos a la prueba de
enviar Bitcoin. A partir de ahora,
agregaremos algunas afirmaciones con respecto a la
función de billetera de carga a algunas pruebas. Entonces si encontramos algún bug en el proceso, los
corregiremos. Empecemos con la
primera prueba de envío de Bitcoin. Eliminemos esta
línea en su lugar. Agreguemos una llamada al método de
billetera de carga de peso. Mediante este método se intentará
hacer que esta prueba se ejecute más rápido. Vamos a crearlo en
la clase de prueba GUI. Aquí, llamemos al método
de la oblea. Pasando estos parámetros. En cada iteración de esta devolución de llamada se utilizará el método
sleep para esperar 1 s. Luego comprobaremos si se establece la
primera dirección actual de la billetera. Entonces, vamos a inyectar la
cartera actual en esta clase. Usando la lista de nodos, el
cliente verificará si el nodo cargó la dirección con la
primera dirección de billetera actual. Entonces, vamos a inyectar este
servicio en esta clase. Con este código se esperará hasta que
el nodo cargue la cartera. Ahora, arreglemos un problema que puede causar
fallas en las pruebas a veces. Aquí, el parámetro de tamaño
total esperado es igual a la suma del índice de
iteración actual más uno. Ahora vamos a crear la última variable de dirección de
recepción que establecerá su valor a la dirección de recepción
presente en la ventana. Ahora, vamos a establecer algunas otras
variables que nos ayudarán a comparar los valores en la cartera antes y después de que la carguemos. Primero, el tamaño de la
tabla de transacciones. A continuación, la primera fila saldo
de la tabla de transacciones. Ahora llamemos al método
load wallet, pasando el
nombre de wallet como parámetro. Vamos a establecer esta variable aquí. Ahora, estableceremos la tabla de
transacciones después de la variable de carga. Lo obtendremos usando
el método de búsqueda tal como antes de cargarlo. Después haremos clic en la pestaña de direcciones y estableceremos la tabla de direcciones después de variable de
carga de la misma manera. A continuación, haremos clic en la pestaña Recibir y estableceremos la última
dirección de recepción, la variable de postcarga y el texto de la etiqueta
después de la variable de carga. Ahora en el bloque de entonces, eliminemos estas dos líneas. Y comparemos las últimas variables de dirección
receptora antes y después de
cargar la billetera. Entonces vamos a establecer aquí el tamaño de la tabla de
direcciones y las variables
balanceadas de la tabla de direcciones de
primera fila. Y agreguemos estas
dos comparaciones que son iguales a
las que acabamos de eliminar. Ahora, comparemos los tamaños de
las tablas de direcciones antes y después de
cargar la billetera. Y hagamos lo mismo con el balance de
la primera fila de la tabla de direcciones. Ahora vamos a eliminar
estas dos líneas, sustituyéndolas por
las siguientes líneas, que hacen las mismas comparaciones pero utilizan las variables
re-factorizadas. Y agreguemos las
siguientes comparaciones de las variables antes y
después de cargar la billetera. Comentemos todas las demás
pruebas en este archivo. Y vamos a ejecutar la prueba
restante. La prueba falló porque
la última dirección de recepción antes y después de cargar
la billetera son diferentes. En el siguiente video, lo
arreglaremos.
71. 69 Cartera de carga parte 4 skillshare 2: En este video,
solucionaremos el error de tener diferentes
direcciones de recepción antes y después de cargar una billetera. Ocurre porque estamos usando los UTXOS para actualizar el índice de direcciones de
recepción actual. Después de cargar la billetera y
recuperar la billetera UTXOS, las salidas antiguas utilizadas para actualizar la
dirección de recepción ya no forman parte del conjunto UTXO porque ya
estaban gastadas. Así, la dirección receptora
termina por no actualizarse. Lo arreglaremos transfiriendo el código
responsable de actualizar las direcciones de recepción
del servicio de actualización de
direcciones de billetera actual a una nueva clase. La Nueva Clase
usaremos las transacciones recuperadas
del nodo que contiene todas las direcciones de billeteras
utilizadas para actualizar las direcciones de
recepción actuales. Así que vamos a crear esta clase que se llamará
actualizar
billetera actual recibiendo
dirección su servicio en el paquete de servicios punto GUI. Agreguemos aquí la
anotación de servicio. Ahora, copiemos y
peguemos algún código
del servicio de actualización de
direcciones de billetera actual a esta clase. Vamos a agregar esta anotación
calificador. Ahora vamos a crear el método de
actualización aquí. Tomará una lista de transacciones de
nodos. Usando el método map
obtendrá un flujo de direcciones del flujo
de transacciones de nodo. Después filtraremos la
transmisión para que contenga solo direcciones
en la billetera actual. Entonces llamaremos a la marca se
usa método en cada dirección. Tomemos este método del servicio
de actualización de
direcciones de billetera actual. Ahora llamaremos al método
actual de tipos
get addressed wallet . Vamos a crear este método. Devolverá el
resultado de llamar
al método de direcciones get
addressed types. Devolverá un conjunto
de tipos de direcciones. Vamos a crear este método
en la clase addresses. Aquí simplemente devolverá el conjunto de claves del campo de
direcciones. Ahora para cada tipo de dirección, llamaremos al método de dirección de
recepción de actualización. Para ello
cambiará el tipo de
este parámetro de método
a tipo de dirección. Y vamos a eliminar esta línea ya que ya no vamos a necesitar. Ahora, vayamos al servicio de actualización de
direcciones de billetera
actual para eliminar el mismo
código que pegamos a nuestra nueva clase y sus usos. Ahora, vayamos al servicio de
actualización UTXOS. Inyectemos el
servicio de
actualización de direcciones de
recepción de billetera actual en esta clase. Y llamemos al método de
actualización desde el servicio inyectado pasando las transacciones de nodo
como su parámetro. Ahora vamos a la prueba de
enviar Bitcoin. Agreguemos la llamada al método sleep aquí para evitar una
nueva condición de carrera que puede suceder a veces asegura de que su nodo esté funcionando. Y hagamos esta prueba. Se solucionó el
problema de la dirección de recepción, pero la prueba falló
debido a otro error. El
saldo de la transacción después de cargar una billetera no es el calculado
incorrectamente. Arreglemos esto. Para
resolver este error, tenemos que entender mejor cómo funciona
la API de
transacciones de lista Bitcoin Core. Aquí está la documentación de la lista transacciones
bitcoin Core API. Observe que por
cada transacción, la API devuelve solo
un campo de dirección. El monto se refiere únicamente a la cantidad de Bitcoin
enviada a esa dirección sea negativa si
no pertenece a nuestra billetera y
positiva en caso contrario. Si la transacción
tiene un resultado de cambio, la API devuelve más de un registro
por cada transacción. Cada registro con
un campo
de dirección de la salida de la transacción. Veamos un ejemplo
del resultado de esta API para una transacción enviada desde nuestra billetera con una
entrada y dos salidas. Para la misma transacción, la API devolvió
tres registros. Podemos ver que se refieren a la misma transacción
mirando sus ID de transacción. Observe que los dos
primeros registros tienen la misma dirección. Estos registros se refieren
a la salida de cambio. El primero tiene una cantidad positiva indicando que es una dirección
perteneciente a nuestra billetera. Esa es la cantidad de cambio. El segundo registro tiene la
misma cantidad, pero como negativo. Eso significa que nuestras billeteras enviaron
una cantidad a esa dirección. También tiene una comisión negativa, que es la tarifa de transacción que pagamos en la transacción. Si sumamos el monto de
los dos primeros registros, terminamos con cero, que es exactamente el saldo que
pagamos nosotros mismos en
la transacción. Por último, el tercer
registro contiene una cantidad negativa
que indica que enviamos Bitcoin
a esa dirección. También tiene una cuota igual a la tasa en el
segundo registro. Considerando cómo funciona esta API, la forma correcta de calcular el
saldo de la transacción es sumar los montos de registro
devueltos por la misma transacción y la tarifa de una de
esas registra, la transacción balanceada antes cargar una billetera es
correcta porque la estamos calculando de una manera que
toma en consideración la segunda transacción construida antes de enviarla a
nuestro nodo. Después de cargar nuestra billetera, perdemos la
información de transacción que no la está considerando para calcular
el saldo de la transacción. Entonces, vayamos al servicio de
transacciones
Update Current Wallet para solucionar el problema. Nuestra nueva solución ya no
necesitará este filtro. Entonces, eliminemos esta
línea en su lugar. Agreguemos una llamada al
método collect como su parámetro. Llamaremos a los colectores
agrupando por método, pasando una referencia
al nodo Transacción TX ID con este código se
obtendrá un mapa donde las claves serán
los ID de transacción y los valores serán listas de transacciones de nodo
con el mismo ID de transacción. Llamemos al método values en el resultado que al método
stream para obtener un flujo de listas de transacciones de nodo
con el mismo T XID. El resto de este
método se queda tal cual. Vamos a crear la
transacción a partir del método. Tomará una lista
de transacciones de nodo y devolverá una fila de transacciones. Movamos este método aquí. Primero consigamos la tarifa
de transacción. Lo tomará de una corriente sin comisiones
de transacción. Vamos a crear el campo de tarifa
en la transacción del nodo. Después filtraremos la
corriente por tarifas nominales. Luego llamaremos
primero a la multa para que se devuelvan los
primeros y usaremos el método de las URL para devolver cero si no se encuentra tarifa. Ahora, calculemos la cantidad. Usando el método map
obtendrá un flujo que contiene todos los montos de transacción de nodo del flujo de
transacciones de nodo. Luego usaremos el método
reducido, pasando la referencia del
método de suma decimal grande a
algunas cantidades totales. Finalmente, usaremos
el método o else para devolver cero sin que se encuentren
transacciones. Ahora vamos a copiar y
pegar esta línea aquí. Usaremos el ID de TX de
transacción del primer nodo como el primer parámetro de la instanciación de la fila de
transacción. A continuación, agregaremos la tarifa de transacción
obtenida
al monto y pasaremos el
monto como parámetro aquí. Finalmente, pasaremos confirmación de transacción
del primer nodo en tiempo como los parámetros de instanciación de la última
fila de transacción . Eliminemos este método ya que ya
no lo necesitaremos. Volvamos a ejecutar esta prueba de enviar
Bitcoin. Pasó la primera prueba, pero la segunda falló
debido a una condición de carrera. Vamos a arreglarlo rápidamente con
el método sleep call aquí. Haremos una mejor solución para
este error en el siguiente video. Por ahora, vamos a comentar
esta línea para ejecutar sólo la
calificación de prueba fallida . La prueba ha pasado. Vamos a descomentar el
resto de la prueba.
72. 70 cartera de carga parte 5 skillshare 2 1: En este video, agregaremos más aserciones de prueba para verificar
si podemos cargar correctamente una billetera con más
direcciones generadas que el número inicial de direcciones
generadas config. Pero primero, vamos a
optimizar un método de prueba para evitar algunas
condiciones de carrera en algunas pruebas. En la clase de prueba de enviar Bitcoin. Eliminemos estas dos llamadas al
método de suspensión ya que nuestro fijo manejará mejor las condiciones de la
carrera después de que enviemos bitcoins. Vamos a la clase de prueba GUI. Agreguemos este parámetro
opcional en el
método send Bitcoin and wait con el valor predeterminado igual a la dirección de
recepción del hashtag. Entonces agreguemos lo siguiente y condición a este valor de retorno. Con este código
solo dejaremos de esperar si el campo de dirección de recepción es diferente a la variable
address. Por lo tanto, evitamos
el error de enviar Bitcoins a la misma dirección
dos veces secuencialmente. Ahora, vayamos a la prueba de
recibir Bitcoin. En la última prueba de esta clase, agregaremos algunas
aserciones para probar si podemos
cargar correctamente una billetera con más direcciones generadas que el número inicial de direcciones
generadas config. Así que vamos a establecer la billetera
llamada variable y sustituir el parámetro en el método correcto
para esta variable. Ahora llamemos
aquí al método de la billetera de
carga de peso y eliminemos las llamadas al
método sleep de esta prueba. Ahora, después de recibir
Bitcoins siete veces, fijemos la última variable de
dirección de recepción
al valor presente en el campo de dirección de
recepción. Ahora, copiemos esta línea en la prueba de Bitcoin arena
y péguela aquí. Cambiemos esta variable
para abordar su vista de tabla. Hagamos lo mismo
con esta otra línea. Ahora, copiemos y peguemos todas estas líneas desde la prueba de enviar
Bitcoin hasta nuestra prueba. También copiemos y peguemos
esta línea en nuestra nueva prueba para comparar la última dirección de
recepción antes y después de
cargar la billetera. Agreguemos esta línea para comparar el tamaño de la tabla de transacciones antes y después de
cargar la billetera. Esta línea,
haremos lo mismo con el tamaño de
la tabla de direcciones. Y esta otra línea comparará el texto de la etiqueta antes y
después de cargar la billetera. Vamos a ejecutar nuestro nodo. Comentemos las otras pruebas de esta clase y ejecutemos nuestra nueva prueba. La prueba ha fallado debido
a la diferencia entre la última dirección de recepción antes y después de
cargar la billetera. Además, si notaste
el número de direcciones en la
tabla de direcciones después de la carga, solo son tres cuando la
correcta sería siete. Esto se debe a que
no estamos guardando el número de direcciones
generadas
después de generarlas. Arreglemos esto. Vamos a la actualización
actual del servicio de
direcciones de recepción de billetera necesitará
el repositorio de billeteras aquí. Así que vamos a
inyectarlo en esta clase. Ahora, llamaremos al método de
incremento del número de direcciones
generadas
en el repositorio de billetera. Como sus parámetros
pasarán el número inicial de direcciones generadas y
el nombre de la billetera actual. Vamos a crear este método. Cambiemos este parámetro
de tipo a la clase entera y este nombre de
parámetro a incrementar. Como su nombre indica, este método
incrementará el número de direcciones
generadas
en nuestro monedero. Para hacer eso. Vamos a agregarle la
anotación transaccional. Esta anotación es
un requisito de la biblioteca JPA porque
hará la operación SQL
en dos pasos. Agreguemos también la anotación
modificadora. Esta anotación es necesaria
por métodos de repositorio que modifiquen registros y
tablas, que es el caso. Por último, agreguemos la
anotación de consulta a este método. Esta anotación
indicará la operación SQL que queremos realizar
como su parámetro. Vamos a agregar la siguiente cadena. Esta
instrucción similar a SQL agregará
al número de direcciones
generadas, el valor de incremento pasado como primer argumento
al método anotado. La cláusula where hará que
esta operación ocurra sólo en la cartera con el nombre
igual al parámetro name. Para vincular los parámetros del método
a las variables SQL. Agreguemos estas dos
anotaciones de poemas a estos parámetros. Ahora volvamos a hacer nuestra prueba. Genial, ha pasado. Nuestra función de billetera de carga está hecha. Ahora, es importante ejecutar todas nuestras pruebas de aplicación
para verificar si apareció un error. Pero primero, arreglaremos una optimización de
algunas de nuestras pruebas para usar el
método de billetera de carga de peso y eliminar algunas llamadas al método de
suspensión que ya
no son necesarias. Primero infrecuentes
estas pruebas. Y hagamos las optimizaciones
mencionadas. En las pruebas de segmento anidado, como las
de esta clase, debemos agregar algunos parámetros para enviar Bitcoin y
wait method call. Entonces hagámoslo. El último parámetro de
estas llamadas debe ser la cadena hashtag
segmento anidado dirección de recepción. En algunos métodos como este, también
necesitamos establecer
el ID más uno es el tercer argumento de la llamada al método send Bitcoin y wait. Ahora, podemos ejecutar todas
nuestras pruebas de aplicación. Todos deben pasar
en mi máquina. Están tardando media hora. Entonces dejé esto como
ejercicio para el alumno.
73. 71 Habilidad de la cartera de importación 2: En este video, implementaremos la capacidad de importar una billetera
con la semilla mnemotécnica. Es importante tener
esta opción para recuperar tu billetera y los
casos en los que pierdes, destruyes o no tienes acceso al hardware o archivos
que contienen
la aplicación o que contienen
la aplicación o base de datos con los datos de tu billetera. En estos casos, simplemente
ingresaría su
semilla respaldada y opcionalmente su frase de contraseña en
la función de importación de la aplicación para volver a
acceder a su billetera. Una cosa más,
no te restringirán a
recuperar tu billetera. Mediante esta aplicación, podrás utilizar semillas
mnemotécnicas generadas por esta aplicación para
recuperar tu wallet y otras billeteras compatibles con BIP 39. Además, podrás recuperar el acceso
a tus
direcciones de monedero Bitcoin importando tu semilla mnemotécnica BIP 39 esta aplicación
tu semilla mnemotécnica BIP 39
generada por otras billeteras
. Solo asegúrate de que ambas
aplicaciones sean compatibles los pads de derivación de las
direcciones que quieres importar. Entonces comencemos por crear
la prueba de monedero de importación. Extenderá la clase de prueba GUI. Copiemos este código
de la
prueba de enviar Bitcoin y pegarlo aquí. Ahora vamos a crear una prueba llamada debería importar billetera
y recibir Bitcoin. En el bloque de un solo bloque, vamos a establecer
la variable monedero con nombre. Y vamos a crear una semilla
mnemónica usando el método de creación del
servicio de semillas mnemotécnicas. Ahora llamemos al método
import wallet, pasando como parámetros el nombre de la billetera y la semilla
mnemotécnica. Vamos a crear este método. También agreguemos una contraseña como tercer
parámetro opcional a este método. Aquí haremos clic en un menú
con la importación de texto. Después haremos clic en el
elemento Menú con la billetera de texto. Ahora, haremos clic
en el componente con un ID FX del nombre de la billetera. Este componente
será un campo de entrada donde ingresaremos el nombre
de la billetera importada. A continuación, llamaremos al
método write pasando la
variable name como parámetro para
escribir el nombre en ese campo. A continuación, haremos clic en
el campo de contraseña, que tendrá un
ID FX de contraseña de billetera. Después escribiremos la
contraseña en ese campo. A continuación, haremos clic en el campo de semillas mnemotécnicas y escribiremos la
variable semilla mnemónica en ese campo. Por último, haremos clic
en el botón Bien. También agreguemos llamada al método
dormido para esperar
a que se cargue la billetera. Volviendo a la
prueba de monedero de importación usando el método de búsqueda, recuperemos el valor de dirección presente en el campo de
dirección de recepción. Usando el método send Bitcoin
and wait, enviemos 1,000 Satoshi's
a la dirección recuperada. Ahora haremos clic en
la pestaña de direcciones. Después usando el método de búsqueda, obtendremos la tabla de direcciones
y la almacenaremos en una variable. Haremos clic en la pestaña de
transacciones, obtendremos la tabla de transacciones
y la almacenaremos en una variable. Además, hagamos lo mismo con el saldo total etiquetado como texto. Ahora, vamos a establecer dos
variables para almacenar el tamaño de la tabla de direcciones y
el tamaño de la tabla de transacciones. Agreguemos las
siguientes aserciones en ese entonces bloque para verificar si las variables previamente establecidas
tienen los valores esperados. Ahora vamos a duplicar esta prueba. Vamos a renombrarlo a debería importar billetera usada
y bloque recibido. En esta prueba
crearemos una billetera y recibiremos Bitcoins en ella
antes de importar la billetera, luego importaremos la billetera, generaremos un bloque en
nuestra nota y verificaremos si la aplicación se carga correctamente y actualiza la cartera importada. Así que vamos a crear un
bloque dado aquí donde
crearemos una billetera y
le enviaremos un Bitcoin. Ahora, eliminemos esta línea. Cambiemos el nombre de esta
variable para
importar el nombre de la billetera y aumentemos
su número con nombre de billetera. Usaremos esta variable para
nombrar la cartera importada, ya que no podemos crear dos
billeteras con el mismo nombre. Pasemos la
variable de contraseña a esta llamada al método. Después de importar la billetera, generemos un bloque. Para ello, primero vamos a generar una dirección de nota usando el
nodo obtener nueva dirección cliente. Entonces llamamos al método generate
to address, pasando la dirección del nodo como su parámetro para
generar un bloque. Ahora, llamemos al método del sueño para esperar
a que se minara el
bloque. Por último, cambiemos el saldo total
esperado. Se espera un saldo
de un
Bitcoin confirmado y cero Bitcoin
no confirmado. El resto de la prueba
se queda tal cual. Ahora. Vamos al
patio de recreo punto FXML para diseñar el menú de
funciones de importación. Duplicemos la etiqueta
del menú de carga y su contenido. Cambiemos este
atributo de texto para importar. Este fx ID para importar el menú FXML. También agreguemos aquí el
atributo action con
su valor refiriéndose
al método open-end port
wallet dialogue creará este método más adelante para
responder a un clic en este elemento del menú abriendo
un ventana de diálogo. Vayamos al Scene
Builder para ver cómo se ve. Bien, se
agregó el menú Importar junto al menú de carga. Ahora vamos a copiar y pegar este código en la ventana
principal FXML. Vamos a crear este método en
el controlador de ventana principal. Su código será
muy similar al método
de
diálogo open create wallet. Así que vamos a copiarlo
y pegarlo aquí. Cambiemos el
título del diálogo para importar billetera. Y sustituyamos el campo de diálogo de billetera de
carga
por el campo de
diálogo de billetera de importación aquí. Vamos a crear este campo y vamos a
inyectarlo en esta clase. La anotación de valor
aquí apuntará
al diálogo de importación de billetera FXML. Ahora vamos a crear la entrada mientras un diálogo FXML en
el paquete FXML. Usemos el contenido
del diálogo create wallet
FXML como base para construirlo. Ahora cambiemos el texto del encabezado del
diálogo. En lugar de hacer clic en Crear, solicitemos al usuario que ingrese
una semilla mnemotécnica válida. A continuación, cambiemos
el controlador FX
para importar el controlador de
diálogo de billetera. Ahora, vamos
al Scene Builder. Eliminemos el botón Crear. Pongamos aquí una etiqueta y cambiemos su texto
a la fecha de creación. Agreguemos un
control de selección de fecha a la celda. Hagamos clic en el área de texto inicial
mnemotécnico y hagamos que sea editable. Volver al editor de texto. Cambiemos este nombre de
Fxi de toilette y este fx ID por contraseña de
billetera. Vamos a establecer el ID de
FX del picker de fecha a la fecha de creación. Ahora vamos a crear el controlador de diálogo de
monedero de importación en el paquete de controladores. Vamos a agregarle la
anotación de componente. Vamos a agregar todos estos
campos FXML al controlador. Hagamos todos estos
campos privados. Y vamos a agregarles la
anotación FXML. Vamos a copiar y pegar el método
inicializado desde el controlador de
diálogo create wallet a nuestro nuevo controlador. Y hagamos lo mismo con que se cumplan todos los
insumos requeridos. Cambiemos esta
variable de nombre a nombre de billetera. También copiemos y peguemos
este método a nuestra nueva clase. En el manejador de eventos del botón Okay llamaremos al método import
wallet. Este método simplemente creará una Billetera utilizando el tipo de
datos por parte del usuario. Así que usemos el método create
wallet
del controlador de
diálogo create wallet como base para construirlo. Inyectemos el
servicio create wallet en esta clase. Cambiemos estas variables por las de este Controlador. Y vamos a inyectar el número
inicial de direcciones
generadas
en esta clase. Hagamos lo mismo con
este campo de contexto. Ahora, en lugar de usar una nueva fecha como
parámetro de este método, llamará al método de fecha de factura. Vamos a crear este método. Usaremos la
siguiente lógica aquí. Si el usuario
no elige una fecha, usaremos la fecha en la que
Bitcoin comenzó a funcionar. Si él elige, entonces
usaremos la fecha elegida. El parámetro de fecha
definirá hasta qué punto en
el pasado
iremos el nodo para encontrar información sobre las direcciones de
monedero importadas. Cuanto más viejo sea
el estado, más
tardará el nodo en importar la billetera. Entonces usemos el método de fecha
predeterminado para definir la fecha predeterminada. Aquí usaremos el objeto de formato de
fecha simple con el siguiente parámetro. Después intentaremos devolver
la llamada al método de análisis de
formato de fecha simple pasando la
constante de fecha predeterminada como su parámetro. Usaremos el
bloque catch para envolver la excepción de análisis en
una excepción de tiempo de ejecución. Definamos esta constante, que es la fecha en la que
Bitcoin comenzó a funcionar. Aquí. Si la
fecha de creación no es nula, entonces redefinimos la
variable de fecha al siguiente valor. Por último, devolvemos la fecha. Después de crear el monedero se publicará el evento
monedero importado. Vamos a crearlo en el paquete
GUI dot events. Aquí, pasaremos este parámetro
al súper constructor, y estableceremos el campo wallet
al parámetro wallet. Vamos a crear un getter
para este campo. Ahora, vayamos al oyente de
Save wallet. Este oyente responderá a eventos de billeteras
importadas para
guardar billeteras importadas. Vamos a refactorizarlo para que pueda escuchar más de un evento. Para ello, vamos a eliminar
esta declaración implementos. Cambiemos este método llamado
a evento de billetera no creado. Vamos a agregarle la anotación
del oyente de eventos. Ahora vamos a crear el método de evento de
billetera sin importancia, pasando el
evento de billetera importado como su parámetro. Vamos a copiar y pegar
esta línea aquí. Y agreguemos la anotación del
oyente de eventos a este método. Establecer una anotación de orden para los métodos anotados del oyente de
eventos hará que el orden de ejecución de estos oyentes sea predecible. Cuanto menor sea el parámetro de
anotación de orden, mayor será
la prioridad
para que se ejecute este oyente en comparación con otros oyentes
del mismo evento. Entonces agreguemos esta
anotación a este método. Pasemos cero como parámetro para hacer de este oyente el
primero de su tipo en ejecutarse, agreguemos la misma anotación
al método de
evento wallet no creado. Priorizamos guardar
la billetera primero después su creación para garantizar
que si los oyentes posteriores fallan, al
menos guardamos sus datosPrimero. Ahora vamos al oyente de importación de
billetera creado. Queremos que este oyente importe la billetera importada
al nodo Bitcoin. Entonces, vamos a duplicar el método de evento de billetera
descargada. Cambiemos su nombre a evento de billetera
sin importancia y hagamos que sea excepto el evento
apropiado. Ahora agreguemos la
anotación de orden a estos métodos. Los oyentes de eventos de
billetera importados y creados recibirán uno como sus parámetros y el oyente de eventos de
billetera cargado cero. De esta manera,
garantizamos que cuando la billetera intente recuperar
datos del nodo, ya será
importada por el nodo. Ahora, vayamos al oyente de billetera
cargado y agreguemos un método de escucha para
el evento de billetera importado, como acabamos de hacer en
la clase anterior. Ahora agreguemos una
anotación de orden a ambos métodos, pasando como parámetro para
el método de
evento de billetera sin importancia y uno para
el método de
evento de billetera descargada para hacer que estos oyentes se ejecuten después
todos los demás por sus eventos. Ahora, vamos a ejecutar nuestro nodo. Y hagamos esta prueba. Pasó la primera prueba, pero la segunda falló. Veamos por qué. Bien, se produjo una excepción de violación de
restricción porque
intentamos guardar una billetera con el
mismo nombre dos veces. Olvidamos cambiar la variable de nombre de
billetera en la llamada de
método de billetera de importación para la variable de nombre de billetera de importación. Arreglemos esto y volvamos a
ejecutar la prueba defectuosa. Genial, Ha pasado.
74. 72 Validar la habilidad de la cartera 2: En este video, implementaremos
algunas validaciones antes crear carteras de importación
e intentar enviar transacciones. La primera validación
evitará que la creación de la billetera continúe si el nombre de la billetera es igual a uno
creado previamente. Entonces vayamos a la prueba de
crear billetera para crear una prueba
para esta condición. Se llamará no se debe crear cartera con nombre
repetido. Vamos a crear una billetera
en el bloque dado, creando las variables necesarias y usándolas en el método
create wallet. En el bloque de un solo bloque,
agreguemos algún código para crear una billetera con el mismo nombre la creada en
el bloque dado, pero ahora usando la GUI. Después de intentar
crear la billetera, agreguemos aquí la llamada al
método dormido, esperamos que la aplicación
muestre una ventana de diálogo de alerta que contenga un mensaje que diga el nombre de la billetera ya existe. Así que definamos una variable
que contenga el mensaje. Ahora, usaremos el
método de búsqueda para obtener un componente con ese mensaje y
almacenarlo en la variable de consulta de nodo. Finalmente, haremos clic en el botón Bien para cerrar
la ventana de diálogo. En el bloque de entonces. Agreguemos la siguiente
comparación para verificar si el mensaje en la ventana de diálogo de
alerta es igual a la variable de
mensaje de error. Ahora, vayamos al controlador de diálogo create
wallet. En el método create wallet, usaremos una declaración if con
un servicio de validación de billetera para verificar si el
nombre de la billetera es válido. Entonces, vamos a inyectar este
servicio en esta clase. Vamos a crear este servicio y el paquete de
servicios punto base de datos. Y terminemos de
inyectarlo en esta clase. En la sentencia if, vamos a llamar
al método wallet exists en él, pasando el texto del nombre
como su parámetro. Vamos a crear este método. Usaremos el
servicio de error de alerta y el cuerpo if. Así que vamos a
inyectarlo en esta clase. Ahora, llamaremos al método
alert error en él como su parámetro. Pasemos esta constante. Vamos a crear esta constante
en la clase de mensajes de error. Tendrá el mismo texto
que definimos en la prueba. Importemos
aquí esta constante y llamemos a la declaración
return. Ahora, vayamos al servicio de
validar monedero. En el monedero existe el método liderará el repositorio de billeteras. Así que vamos a
inyectarlo en esta clase. Ahora, devolveremos la llamada al método exists
by name en él, pasando el
nombre de la billetera como su parámetro. Vamos a crear este método solo por este método firma
Spring Data JPA magic ya sabe cómo consultar la información deseada
de la base de datos. Vayamos a la prueba de
crear billetera. Comentemos estas pruebas. Ejecuta nuestro nodo y
ejecuta nuestra nueva prueba. Genial, La prueba ha pasado. Vamos a descomentar estas pruebas. Ahora, agreguemos la misma validación del nombre de
billetera en la función de billetera de importación. Así que vamos a copiar esta prueba y pegarla aquí en
la prueba de monedero de importación. Cambiemos su
nombre a no debe importar cartera con nombre
repetido. Hagamos algunas
adaptaciones a esta prueba. Primero, aumentemos
el número de billetera con nombre. Entonces vamos a modificarlo para importar aquí
una billetera en lugar
de crearla. Y cambiemos los parámetros
de estas llamadas a métodos. Ahora, vayamos al controlador de diálogo create wallet
y copiemos este bloque si aquí. Y vamos a pegarlo aquí en el controlador de diálogo de billetera. Inyectemos los
servicios necesarios a esta clase. Cambiemos esta
variable por nombre de billetera. Ahora, comenten estas
pruebas y ejecutemos nuestra nueva prueba. Grado. La prueba ha pasado. Vamos a descomentar estas pruebas. Ahora, agreguemos una validación
de dirección. Al intentar
enviar transacciones. Actualmente, podemos escribir cualquier cosa en el campo de
dirección a enviar. Si intentamos enviar una transacción
a una dirección no válida y
se produce un error y su ignorado
silenciosamente por la aplicación sin que
el usuario se dé cuenta, implementará una
validación que hará aparecerá un cuadro de diálogo de alerta en la pantalla si la dirección
a enviar no es válida. Primero, vayamos a
la
prueba de enviar Bitcoin para crear una prueba
para este escenario. Digamos que no debería enviar
Bitcoin a una dirección inválida. Agreguemos código para crear una Billetera usando la GUI
y el bloque de viento. Esperemos a la creación de la
cartera. Ahora, copiemos y peguemos este código aquí para enviar
fondos a la billetera. Vamos a crear esta variable de cantidad
anterior aquí y establecer su valor en 0.1. Vamos a establecer uno al segundo método
range llamado parámetro. Ahora vamos a crear una dirección de nodo y generar un bloque para ello. Demos clic en la pestaña Enviar y llamemos al
método send Bitcoin para intentar enviar 0.01 Bitcoin a la
dirección para enviar variable. Dado que la
variable dirección a enviar contendrá direcciones
no válidas, esperamos que aparezca una ventana de
diálogo de alerta que contenga un mensaje que diga la dirección a enviar no es válida. Así que vamos a crear una
variable de mensaje de error con el
siguiente mensaje. Ahora, usaremos el
método de búsqueda para obtener un componente con ese mensaje y almacenado
en la variable de consulta de nodo. Finalmente, haremos clic en el botón Bien para cerrar
la ventana de diálogo. Después bloqueemos, agreguemos la siguiente comparación
para verificar si el mensaje en la ventana de diálogo de alerta es igual a la variable de
mensaje de error. Definamos la dirección a enviar variable con algunos
casos de prueba en el bloque where. Aquí, pasemos
estos casos de prueba disponibles en la página Proyecto
y Recursos. Cada caso de prueba tiene un error. Las diferentes partes
del código detectarán. El primer caso de prueba es una cadena con un prefijo inexistente. El segundo caso tiene un prefijo de prueba de registro
correcto, pero una dirección no válida restante. Las siguientes tres direcciones
serían direcciones de prueba reg válidas, pero sus últimos
caracteres fueron cambiados. Durante la construcción de direcciones. Parte de la dirección utiliza el resto de la
dirección para ser construida. Esa parte es la suma de comprobación de
dirección y su función es detectar alteraciones de
dirección. Durante la decodificación de direcciones, se verifica la
suma de comprobación y
esperaríamos que ocurriera un error si esta verificación falla. Las últimas tres
direcciones son válidas, pero no son del entorno de prueba
reg, por lo que deben
considerarse inválidas. Vayamos al buscador de configuración del
script. En la llamada al método de lanzamiento de URL, pasemos una lambda
cuyo cuerpo devolverá una nueva
excepción de transacción de creación con una constante de dirección no válida de la clase de mensajes de error. La excepción de creación de transacción ya
se captura más adelante en el código y su mensaje
ya se muestra en una ventana de diálogo de
alerta. Vamos a crear esta constante
en la clase de mensajes de error. Tendrá el mismo texto
que definimos en la prueba. Con esta modificación,
esperamos que la validación cubra
direcciones con prefijos no válidos. Ahora, vayamos al servicio de creadores de
transacciones. Envolvamos el código en el método de salida de compilación
en un bloque try-catch. En el bloque catch lanzará la excepción de creación de transacción pasando la constante de
dirección no válida. Con esta modificación,
esperamos que la validación cubra los errores de las direcciones de decodificación en las que falla la
verificación de la suma de comprobación. Vamos a la prueba de
enviar Bitcoin. Ahora, comenten estas
pruebas y ejecutemos nuestra nueva prueba. Los últimos tres casos
de prueba fallaron. Nuestra billetera logró enviar
fondos a estas direcciones. Esto sucedió porque
la decodificación de direcciones descarta los prefijos de dirección. Por supuesto, las transacciones se enviaron únicamente en el entorno de
prueba reg. Por lo tanto, hacer que estas direcciones
no sean válidas es importante para evitar situaciones en las que creas que
estás ejecutando tu billetera
en un entorno, pero en realidad se está
ejecutando en otro. Arreglemos esto. Vamos a la clase de matcher de
direcciones. Vamos a crear estos métodos
de segmento. Devolverá un
predicado de cadena. Y va a tomar un ambiente
suficiente como su parámetro. Ahora, crearemos
un objeto de mapa con entornos como claves y
predicados de cadenas como valores. Usaremos el mapa del
método para crear este mapa. Para cada entorno se
establecerá un Lambda para validar si el parámetro address tiene el prefijo esperado
para ese entorno. Para las direcciones de red principales de segue, esperamos que no
comiencen con BCR y comiencen con BC direcciones de red de
prueba
BC. Empezaremos con las pruebas TB y reg. Comenzaremos con BCR t Luego devolvemos la
llamada al método map.get pasando el entorno
como su parámetro. Ahora, vamos a duplicar este método y cambiar su nombre a
su segmento anidado. En este caso, podrán las direcciones netas. Comenzaremos con tres pruebas, direcciones de prueba
net y reg. Empezaremos con dos. Duplicemos este método
y cambiemos su nombre a sus direcciones de red principales heredadas. Empezaremos con uno. Pruebe las direcciones de prueba net y reg. Empezaremos con M o N. Ahora, eliminemos estas
Lambdas de esta clase. Ahora vamos a la clase de
configuración de direcciones. Agreguemos este campo de
entorno de Bitcoin. Agreguemos
aquí una anotación de valor para inyectar el valor de este campo usando la configuración de propiedades de
punto de la aplicación de
entorno Bitcoin . Ahora cambiemos el
parámetro de segmento aquí para llamarlo como método y pasar el campo de
entorno Bitcoin como su parámetro. Hagamos lo mismo con estos parámetros de segmento
anidado aquí. Ahora, vayamos a la clase de
configuración del script. Haremos la misma
modificación que
acabamos de hacer en la clase de
configuración de direcciones. Inyectemos el
entorno de Bitcoin en esta clase y modifiquemos los beans de configuración del
script para llamar a los métodos adecuados del comparador de
direcciones. Ahora, antes de volver
a ejecutar nuestra nueva prueba, arreglemos algunas pruebas. En la prueba del
generador secuencial de direcciones, debemos establecer el entorno
Bitcoin en la
instanciación de configuración de direcciones así. Vamos a ejecutar esta prueba. Genial, sigue pasando. Ahora, hagamos lo mismo con la prueba del servicio de
creación de billetera. Bien, sigue pasando. Hagamos lo mismo con el único sorteo
aleatorio de una prueba de
selector de monedas. Esta vez, tenemos que establecer el entorno Bitcoin en
la configuración del script en. Vamos a ejecutarlo.
Genial, sigue pasando. Ahora, arreglemos la prueba de servicio de
creadores de transacciones. Bien, sigue funcionando. Por último, hagamos lo mismo fijado en
la prueba de
la
calculadora de tamaño de transacción. Pero esta vez tenemos que establecer los entornos Bitcoin
para probar net. Ya que utilizamos
direcciones netas de prueba en esta prueba, grado, las pruebas han pasado. Ahora vamos a la prueba de
enviar Bitcoin. Comentemos estos
casos de prueba para ejecutar sólo los tres
últimos. Vamos a ejecutarlo. Genial, las pruebas han pasado. Vamos a descomentar estas pruebas. Y arreglemos esta
prueba con nombre de letra. Se envía, no se envía.
75. 73 skillshare de barra de progreso 2: En este video, agregaremos una sección de pie de página a la ventana principal de nuestra
aplicación. El pie de página contendrá una barra de
progreso y una etiqueta de texto. La barra de progreso
estará activa cuando nuestra billetera se comunique
con nuestro nodo, lo que a veces puede tomar un tiempo. La etiqueta de texto mostrará
una breve descripción de la actividad que está
realizando nuestra billetera durante esa comunicación. Así que diseñemos esa sección
en el patio de recreo punto FXML. Vayamos al Scene Builder. Primero. Agreguemos una caja H en la
parte inferior de la ventana principal. Cambiemos el
ancho de pref de la caja H a 600 y la altura de pref a 19. Ahora agreguemos una
barra de progreso al cuadro H. También le agreguemos una etiqueta. Estableceremos el margen
izquierdo de la etiqueta en diez, y su texto en una cadena vacía. Ahora en el editor de texto, vamos a copiar este código aquí y pegarlo en la ventana
principal punto FXML. Ahora vamos a encapsular
la barra de progreso y los componentes
etiquetados
en archivos FXML. Primero, vamos a crear
la barra de progreso FXML. Eliminemos este contenido. Vamos a crear una etiqueta
raíz ética con un tipo apuntando a la
barra de progreso clase Java FX. Ahora vamos a copiar los
atributos de la etiqueta y el punto de ventana principal FXML y
pegarlos en nuestro nuevo FXML. Vamos a establecer esta etiqueta XML NSF X en la ventana principal, FXML. Eliminemos esta
barra de progreso en su lugar. Agreguemos la etiqueta del controlador de
barra de progreso, que se creará más adelante. Ahora, vamos a crear un archivo
FXML de punto de pie de página para encapsular
la etiqueta de etiqueta. Eliminemos este código. Vamos a copiar y pegar
el código de etiqueta de la etiqueta de la ventana principal FXML
al nuevo FXML. Cambiemos la etiqueta de etiqueta a una etiqueta raíz ética con un tipo apuntando a la clase etiquetada Java
FX. Agreguemos este
atributo XML NSF x a la nueva etiqueta. Ahora agreguemos las
importaciones faltantes a este archivo. De vuelta a la ventana principal. Sustituyamos la etiqueta de etiqueta
copiada
por la etiqueta del controlador de pie de página. Ahora vamos a crear el controlador de barra de progreso
e importado aquí. Hagamos lo mismo con el controlador
de pie de página. Ahora, vayamos al controlador de barra de
progreso. Vamos a agregarle la
anotación de componente. Usemos el constructor del
controlador de pestañas Recibir como base para construir el constructor del controlador de
barra de progreso. Fijemos su nombre y anotación de
valor para apuntar
a las correctas. Y eliminemos
la cartera actual ya que no la vamos a necesitar. Ahora, vamos a copiar este constructor y pegarlo en el controlador de
pie de página. Arreglemos el nombre del
constructor, y agreguemos la
anotación del componente a esta clase. Hagamos que la anotación de valor
apunte al FXML correcto. Ahora hagamos que esta clase
extienda la clase label. Y la clase de
controlador de barra de progreso extenderá la clase de barra de
progreso. Vamos a la clase de escucha
GUI y agreguemos ambos controladores
al conjunto para que se configuren
como componentes personalizados. Ahora, vamos a crear un observable que
modele el estado de progreso. Será la clase de
progreso asíncrono creada en el paquete
observables. Vamos a agregarle una
anotación de componente. Para definir el estado de la
barra de progreso se creará un
campo de propiedad doble llamado progreso. Vamos a instanciarlo aquí con un nuevo objeto simple double
property usando cero como parámetro. Posteriormente, el parámetro cero, que establece el estado de la
barra de progreso en inactivo, se
pasará a
la barra de progreso. Ahora vamos a crear el campo de descripción de la
tarea. Será una propiedad de cadena y definiremos el texto de la etiqueta de
pie de página. Vamos a instanciarlo usando una
nueva propiedad de cadena simple. Vamos a crear getters
para ambas propiedades. El IDE creó dos
getters para cada campo, uno para la propiedad y
el otro para el valor de la propiedad necesitará solo los getters
para las propiedades. Entonces, eliminemos
a los otros captadores. Ahora, vamos a crear el método
start aquí. Lo usaremos para establecer
el valor de progreso a la constante de
progreso indeterminada. El valor de esta
constante hará que la barra de progreso muestre una barra
moviéndose hacia la izquierda y hacia la derecha, indicando que alguna tarea se está
ejecutando en segundo plano. Definamos también
el método stop, que volverá a establecer el
valor de progreso en cero. Por lo que la barra de progreso
estará inactiva, indicando que ninguna tarea se está
ejecutando en segundo plano. Por último, vamos a crear el método de descripción de la tarea
establecida. Tomará una cadena
como su parámetro. Y establecerá el parámetro
description en el campo
de descripción de la tarea. Ahora para controlar cuándo cambian
la barra de progreso y la etiqueta del
pie de página, usaremos un aspecto. Vamos a crear la clase de aspecto de
progreso en el paquete de servicios de puntos GUI. En Bota Primavera. Y el aspecto es un modificador de método. Usaremos un aspecto para definir que cada
método anotado con una anotación específica iniciará la barra de progreso para encontrar el
texto y la etiqueta del pie de página, ejecutar el código
en el método y revertir el estado de la barra de
progreso y etiquetar. Para ello,
agreguemos las anotaciones de aspecto y componente
a esta clase. Inyectemos el progreso asíncrono observable en esta clase. Ahora vamos a crear el método activate barra de
progreso. Devolverá un objeto. Vamos a agregar la
anotación around a este método ya que su parámetro pasará una cadena con
el texto en la anotación, abrir paréntesis,
activar barra de progreso, cerrar paréntesis. Esta anotación define
que el aspecto
ejecutará código antes y
después de que se modifique los métodos. El parámetro activate
barra de progreso, definiremos que el
aspecto modificará métodos anotados con una
anotación con ese nombre. Ahora, agreguemos dos
parámetros a este método. El primero será el punto de unión
anterior, que será un manejador
para el método anotado. El segundo será la barra de progreso de
activar, que dará acceso a
los parámetros de anotación. Así que vamos a crear esta anotación, crearemos en un nuevo paquete de anotaciones
GUI. Para que sea una anotación, debemos modificar esta
palabra clave a una interfaz. Vamos a agregar la
anotación de destino a este archivo ya que su parámetro
pasará la constante del método. Esto hará que la anotación sea
válida solo en métodos, no clases o campos. También agreguemos la anotación de
retención pasando la
constante de tiempo de ejecución como su parámetro. Esto hará que esta
anotación esté activa en tiempo de ejecución. Finalmente, agreguemos el campo de valor de cadena
a esta anotación. Este campo se rellenará con el parámetro pasado a
esta llamada de anotación. Volver a la clase de
aspecto de progreso. Aquí dentro de una plataforma ejecutar
más tarde, la llamada al método pasará una lambda cuyo cuerpo llamará
al método asincrónico de descripción de
tareas de conjunto de progreso, pasando el valor de la barra de
progreso activate ya que
su parámetro también llame al método de
inicio de progreso asíncrono aquí. Ahora llamaremos al anterior
método
join point proceed y storage
return object en la variable result. El método proceed
hará que el
método anotado se ejecute y
devolverá su resultado. Ahora envuelto en una plataforma
ejecutar más tarde, el método cambiará nuevamente los estados de
los campos de progreso asíncrono. Pero esta vez estableceremos la descripción de
la tarea una cadena vacía y llamaremos al método stop en
el progreso asíncrono. Finalmente, vamos a devolver la variable resultado
que contiene el método
anotado objeto
devuelto. Ahora vamos al controlador de barra de
progreso. Inyectemos el progreso asíncrono observable en esta clase. Se vinculará el campo de
progreso de progreso asincrónico a esta propiedad de
progreso de controladores en el método inicializado. Vamos al controlador de
pie de página. Inyectemos el progreso asíncrono observable en esta clase. En el
método inicializado vinculará el campo de descripción de
tarea de progreso asíncrono a esta propiedad de
texto de controladores. Ahora, para que la
barra de progreso funcione, tenemos que anotar los
métodos que queremos para rastrear el progreso con la anotación de activar barra de
progreso. Hagámoslo primero en el servicio de
monedero de importación. Pasemos la cadena
con la cartera de
carga de textos como su parámetro. Copiemos esta anotación y péguela aquí
en el método de firmar y enviar del servicio de
transacción sin. Cambiemos su parámetro
a la transacción de envío. También agreguemos
esta anotación
al método de actualización de clases de servicio utxOS update como su parámetro. Pasemos la frase
actualizando UTXOS. Ahora, vamos a ejecutar nuestro nodo. Y ejecutemos la prueba heredada de enviar Bitcoin para verificar
la barra de progreso en acción. Como hemos visto, la barra de
progreso y la etiqueta de
pie de página están
funcionando según lo previsto. Genial.
76. 74 Actualización de dependencias skillshare: En este video, actualizaremos las dependencias de nuestro proyecto. Mantener las dependencias de un
proyecto actualizadas es una buena práctica. Al hacerlo, nos
beneficiamos de errores y correcciones de vulnerabilidades de
seguridad
aplicadas a nuestras dependencias, manteniendo nuestra
aplicación más segura. Así que vamos al archivo
palm dot xml aumentará la versión de
nuestras dependencias obsoletas. Dependiendo de cuándo los
estés actualizando, posible que haya
versiones más nuevas disponibles. Aumentemos la versión parental de
arranque Spring Boot. Para mí, la
versión más reciente es 2.7. 0.5 aumentará la versión
Java a 19. Eliminemos ahora esta
versión maravillosa, ya que ya no es
necesaria, su versión se
configurará automáticamente. Vamos a la configuración de la
estructura del proyecto. Actualicemos la versión Java de
los proyectos. Si lo necesitas, la
versión Java no está disponible. Puede hacer clic en agregar
SDK para descargarlo. Vamos a establecer el nivel de
idioma del proyecto a lo último disponible. Ahora, aumentemos la versión de los controles
Java FX. Hagamos lo mismo
con el JavaFX FXML. Ahora, actualicemos el plugin
Java FX Maven y
el plugin G Maven
para que sean correctos. Actualicemos la versión Bitcoin
Java a 0.4,
0.4 en la configuración del
complemento de dependencia de Maven. Ahora vamos a hacer clic en el botón
Cargar cambios de Maven. Ahora vamos a actualizar la versión Bitcoin
Core Node a 23. Descarguémoslo del sitio web
Bitcoin core.org. Descarguemos la versión 23 e instalémosla en la
misma carpeta que la versión anterior. Ya lo hice,
así que me saltaré esta parte. Ahora. Asegúrese de establecer el indicador de entorno de
prueba reg en el archivo bitcoin.com. Antes de ejecutar nuestro nodo, eliminemos las
carpetas de prueba de registro dentro de la carpeta Bitcoin sin datos y la carpeta de la base de datos de nuestra
aplicación. Lo haremos solo para limpiar
nuestro entorno de prueba. Ahora, vamos a ejecutar nuestro nodo
mirando la consola. Observe que nuestro nodo
está ejecutando la versión 23. Bueno. Ahora, debemos hacer una
pequeña modificación para nuestro monedero funcione
correctamente con la nueva versión Bitcoin
Core Node. Pasemos a la documentación del método
RPC create wallet para entenderlo mejor. En Bitcoin Core versión 23, el argumento descriptores
del método create wallet RPC por defecto es true, mientras que en la
versión anterior se fijó en false. Eso hace que nuestra
cartera de aplicaciones no pueda llamar a algunos métodos RPC que
usamos para solucionarlo, configurará manualmente en false para que el cambio ya no nos
afecte. Así que vamos al nodo
crear cliente wallet. Agreguemos aquí los siguientes
parámetros. Vamos a agregarlos a la firma del método create
wallet. Además, el parámetro de
claves privadas deshabilitadas será un booleano y definirá si la billetera de nodo creada
generará claves privadas. Cuando se establece en true,
el parámetro blank crea una billetera de nodo
sin semillas y claves. Los conjuntos de contraseñas y frase de contraseña
opcional para
cifrar el NerdWallet. Como su nombre indica, el
parámetro de evitar reutilización define una política para evitar la reutilización de direcciones. Finalmente, el
parámetro descriptores define si el
monedero de nodo creado es un monedero descriptor. Un monedero descriptor
es un nuevo tipo de billetera en el Bitcoin
Core Node que no usaremos. Ahora, vayamos a la carga del nodo
o creamos el servicio de monedero. Vamos a agregar estas variables
a esta llamada de método. Ahora vamos a copiar este código
y el nodo crear cartera cliente y pegarlo aquí. Ahora vamos al servicio de
monederos. Vamos a agregar los siguientes
valores a esta llamada al método. Aquí, estableceremos las claves privadas
deshabilitadas y los parámetros en blanco en true. Desde nuestra aplicación,
mientras que no va a requerir el nodo para crear
claves privadas y semillas para nosotros. La frase de contraseña
será una cadena vacía. Estableceremos el
parámetro de evitar reutilización en false, ya que nuestro nodo
generará direcciones para nosotros y el
parámetro descriptores será falso. Ahora, vayamos a
la clase de prueba GUI. En esta llamada al método, vamos a pasar los siguientes valores. A diferencia del
caso anterior, esta vez, queremos generar
claves privadas y semillas porque usaremos el monedero de nodo para
enviar bitcoins en nuestras pruebas. Por lo tanto, los dos primeros
parámetros serán falsos. El tercero será
una cadena vacía. El parámetro de evitar reutilización se
establecerá en true. Por lo que el nodo evitará
reutilizar direcciones para nuestro monedero de prueba y el
argumento descriptores será falso. Ahora hagamos una modificación más
por alguna razón después actualizar nuestras dependencias
cuando haya dos botones bien en la
pantalla durante algunas pruebas, test FX termina haciendo clic
en el incorrecto. Para solucionarlo, vamos al error
de alerta o servicio. Se agregará un Fx ID
al botón OK de alerta
mediante programación. Para hacerlo, vamos a crear
la variable ok. aquí. Usaremos el
método de búsqueda para obtener la referencia del botón
y asignarla a la variable ok. así. Después configuraremos el
ID para alertar. Bien. Ahora vayamos a la prueba de
crear billetera. En esta prueba, en lugar de llamar
al método click on con
el parámetro okay, pasemos una referencia al botón Okay
del diálogo de alerta usando su ID. Ahora, esta prueba hará clic
inequívocamente en
el botón correcto ok. Hagamos lo mismo con todas las demás pruebas con el
mismo problema en el proyecto. Arreglemos el que está en
la prueba de monedero de importación. Ahora, hagámoslo en la prueba de segue anidada de enviar
Bitcoin. Por último, arreglemos las pruebas
y la prueba de enviar Bitcoin. Ahora, como ejercicio, dejaré que el alumno ejecute todas las pruebas de aplicación.
77. 75 skillshare de Mainnet: En este video,
instalaremos y ejecutaremos nuestra aplicación en el entorno de red
principal. Ya que trataremos
con dinero real, es muy recomendable
que garantice
que todas las
pruebas de aplicación están pasando. Además, es recomendable
comenzar a jugar con
pequeñas cantidades de Bitcoin. Primero, actualicemos la
biblioteca Bitcoin Java a la versión 0.4, 0.5 en el archivo POM. Esta versión soluciona un
problema al importar el archivo de lista de palabras al ejecutar la aplicación
después de instalarla. Vayamos al servicio de
semillas mnemotécnicas y eliminemos esto arroja declaraciones
ya que ya no lo necesitamos. Hagamos lo mismo con este método create mnemonic seed en el controlador de
diálogo create wallet. Ahora, vamos a ejecutar nuestro nodo en
el entorno de red principal. Para hacerlo, vamos
a nuestro
archivo bitcoin.com y eliminemos la línea de configuración de
prueba reg, guardemos el archivo y ejecutemos
el nodo Bitcoin. Bien, ahora nuestro nodo se está ejecutando en el entorno de
red principal. Aquí viene la parte triste. Puede tardar días
o semanas en sincronizar nuestra nota en el entorno de
red principal ya que, por el momento,
tiene 436 gb de tamaño. En mi caso, la
consola indica que el
progreso de la descarga de blockchain es de aproximadamente 52%. Más adelante en este video, te
mostraré la aplicación se ejecuta en mi otra máquina, que ya se ha
sincronizado por completo. Por ahora, modifiquemos nuestra aplicación para ejecutarla en
el entorno de red principal. En el archivo de propiedades del
punto de la aplicación, modifiquemos el entorno de
Bitcoin configurando dos redes principales. Asignaremos el puerto 83 32
a la nota RPC URI config. Este es el puerto predeterminado que utiliza
el nodo Bitcoin para exponer su API RPC
en la red principal. A continuación, vamos a establecer la clave crypt en la
configuración de URL de fuente de datos de primavera a esta
variable de entorno que nos requiere establecer esta variable de entorno en nuestro sistema operativo antes
de compilar nuestro código. Al hacerlo, aumentamos la
seguridad de nuestra aplicación, evitando exponer
las variables de la base de datos en nuestro código. Hagamos lo mismo
con los valores de
las configuraciones de nombre de
usuario y contraseña de Spring Data Source. Ahora vamos a generar
valores seguros para estas configuraciones. Para ello, usemos el administrador de bases de datos SQL lo logrará llamando así a la
función de clave cripta. Vamos a generar tres valores y copiarlos y pegarlos
en un archivo de texto. Es importante que
mantengas estos valores en un lugar seguro
ya que cualquier cambio en estos valores antes de
compilar
nuevamente la aplicación resultará en la pérdida de
acceso a la base de datos. Si eso sucede, seguirás
teniendo acceso a tu billetera. Si guardas tus billeteras, semilla
mnemotécnica y contraseña, pero tendrás que eliminar
los archivos de la base de datos
y volver a compilar la
aplicación. Ahora, voy a pegar estos valores de variables de
entorno directamente en las propiedades de
punto de la aplicación pueden arreglar. Lo estoy haciendo porque
al menos en mi máquina Windows, la aplicación
no interpola
estos valores con el entorno
del sistema. Uno, el mismo problema
no ocurre en Linux. Entonces creo que es algún tipo de error
extraño durante la compilación. Dime en la sección de
comentarios si experimentaste
el mismo problema. Para que podamos encontrar una solución
para este problema juntos. Por ahora, podemos seguir adelante con la aplicación
dot properties is, is in the Maven tab. Hagamos clic derecho en
el botón Instalar. Haga clic en modificar
configuración de ejecución. En la pestaña corredor. Activemos la
casilla de verificación skip tests para que
el
comando Maven install no ejecute las pruebas de la
aplicación antes de instalar
la aplicación. Si está utilizando versiones más recientes de
IntelliJ AID, esta opción puede estar disponible en el
icono de configuración en esta ventana. Haga clic en el botón Bien. Ahora, haga doble clic en la opción de instalación
personalizada dentro de la sección Ejecutar
configuración. Genial, la aplicación
se
instaló con éxito dentro de la
carpeta indicada en la consola. Antes de ejecutarlo,
asegúrese de instalar el SDK de Java con la misma
versión que la aplicación. Iré al sitio web de Oracle
para descargarlo e instalarlo. Después de instalarlo, cierre
y abra el terminal. Ahora, copia la ruta donde tu aplicación instaló
el archivo JAR de la aplicación. Puede usar el comando java
space double hyphen version para asegurarse de que su terminal ejecute
la versión correcta de Java. Ahora ejecuta el comando java space, hyphen jar space, la
ruta que acabas de copiar. Genial, la aplicación comenzó con éxito en el entorno de red
principal. Intentemos crear una nueva cartera. Creó con éxito una nueva billetera, pero como nuestro nodo aún
se está hundiendo, la
barra de progreso de carga permanecería activa durante mucho tiempo antes de
que pudiéramos probarla. Ahora, voy a mostrar la billetera trabajando en el entorno de
red principal en mi máquina Linux donde el
nodo está 100% sincronizado. Así que acabo de instalar la aplicación de la misma
manera que lo hicimos para Windows. Esto muestra una gran ventaja de
Java, que es la suave compatibilidad
multiplataforma. Ejecutemos la aplicación. A partir de ahora, voy a
ocultar algunos datos que
verás en la pantalla
por motivos de privacidad. Primero, cargo una billetera. Ya lo creé correctamente cargado como se esperaba. Ahora, voy a crear una cartera nueva. Anotaré la semilla
mnemotécnica usando pluma y papel antes de hacer
clic en el botón Aceptar. Ahora, voy a copiar la dirección y pegarla en un editor de texto. Ahora, cargaré la cartera
anterior, que tiene algunos fondos en ella. Ahora vamos a enviar algunos Satoshi's
a la dirección que copiamos de la tabla de direcciones. Podemos ver que una nueva
dirección de cambio recibió algunos fondos. Genial. En la tabla de transacciones, vemos que se creó una nueva
transacción con cero confirmación. Ahora abramos la cartera
que recibió fondos. Podemos ver que tanto
la tabla de direcciones como la tabla de transacciones tienen un nuevo registro que indica que hemos recibido
con éxito
algunos Satoshi's. Genial, todo está
funcionando correctamente.
78. Clase adicional - Bitcoin Core v26: Bienvenido a nuestra primera clase
extra sobre la actualización nuestra aplicación para comunicarnos con Bitcoin core versión 26. Veremos que hay
muy buenas razones para estar al día con la versión
más reciente del núcleo de Bitcoin. Primero, visitemos este sitio web para descargar Bitcoin
core versión 26. Haga clic en la versión apropiada para su sistema operativo. Ya que estoy usando Windows, descargaré el archivo. Esencialmente,
estaremos sobrescribiendo la versión actual del núcleo de
Bitcoin que tenemos Asegúrese de elegir la misma ruta de
instalación
que nuestra actual. En mi caso, no procederé con la instalación ya que
ya la tengo. Pero para ti, debería ser tan
sencillo como hacer clic en
el siguiente botón varias veces antes de ejecutar la versión recién instalada. Exploremos los
beneficios inmediatos que ofrece, comenzando con la versión 25
del núcleo de Bitcoin. Podemos ver en sus
notas de lanzamiento que implementa un nuevo índice que
acelera significativamente los escaneos de billetera Re. Para optar por este nuevo filtro, simplemente
agregamos el filtro de
bloque equivale a una configuración a nuestro archivo de configuración de
Bitcoin. Al reiniciar el nodo, comenzará
a construir
este nuevo índice Puede tardar unas
horas en completarse, pero después notaremos
que cargar una billetera después de algún tiempo sin ejecutar nuestro nodo se vuelve mucho más rápido Ahora vamos a discutir algunos
cambios introducidos en las notas de la
versión 26. Encontramos que para usar billeteras no
descriptoras, necesitamos establecer una configuración
RPC obsoleta en nuestro
archivo de configuración Posteriormente, las billeteras no
descriptoras quedarán desuso en futuras versiones principales.
No te preocupes. Demostraremos cómo migrar nuestra aplicación a billeteras
descriptoras en la siguiente clase extra Por ahora, para asegurarnos de que
nuestras billeteras actuales funcionen con la versión 26 del núcleo de
Bitcoin, agreguemos esta configuración a
nuestro archivo de configuración de Bitcoin. Mientras que en ello,
agreguemos también el filtro de bloque es igual a una configuración que
discutimos anteriormente. Ahora ejecutemos nuestro nodo central de
Bitcoin en el entorno de prueba reg. Casi terminamos, como siempre, con cualquier cambio significativo que
hagamos en nuestra aplicación, debemos ejecutar todas nuestras pruebas para asegurarnos de que todo
funcione correctamente. Ya lo hice por mi
parte y descubrí que una prueba dejó de funcionar cuando se ejecutaba contra la nueva versión del núcleo de
Bitcoin. Resulta que el
no debería enviar Bitcoin con la prueba de contraseña incorrecta de
la clase de prueba de enviar Bitcoin
falló. Sin embargo, no porque la transacción se
haya enviado con éxito, sino porque el error devuelto
real difirió del esperado Lo depuré y
descubrí que la respuesta de error que envía el núcleo de
Bitcoin en la nueva versión ahora contiene un mensaje diferente,
que es este Simplemente eliminamos el non desde el principio y agregamos
falló al final. Ahora el mapeo entre esta respuesta de
error desde el núcleo y nuestra aplicación debería
ser precisa. Eso es. Ahora bien, si ejecutas nuestras pruebas,
deberían pasar todas. En la siguiente clase extra, profundizaremos en
qué es una
billetera descriptora y cómo adaptar
nuestra aplicación para crear este tipo de profundizaremos en
qué es una
billetera descriptora y cómo adaptar
nuestra aplicación para
crear este tipo de
billetera. Nos vemos entonces.