Transcrições
1. Apresentação: Olá, bem-vindo ao curso para desenvolvedores de
Bitcoin. Meu nome é Alberto e tenho o prazer de
apresentar a você
o primeiro e único curso em que você aprenderá Bitcoin
criando uma carteira
Bitcoin para desktop. Então, vamos começar
explicando o que você
aprenderá neste curso. Resumindo, você aprenderá como Bitcoin funciona do ponto de vista
técnico. Mais especificamente,
você aprenderá detalhadamente como uma carteira Bitcoin
funciona. Além disso, você aprenderá como um nó Bitcoin funciona
e como executá-lo. Veremos como ele interage com nossa carteira e outros nós. Também aprenderá como
a rede Bitcoin funciona e como ela
alcança um consenso. conceitos que aprenderemos incluem
transações, endereços ,
sementes, chaves,
saldos , blockchain,
mineração e carteira. Como criaremos um
aplicativo de desktop ao longo do curso, o aluno terá a
oportunidade de praticar as seguintes habilidades de
engenharia de software , que são muito procuradas
na indústria de software. O paradigma
de programação orientada a objetos no qual nossa carteira se baseia. A maioria dos recursos será desenvolvida e seguirá a forma de
desenvolvimento orientada por testes de fazer as coisas. Como o nome dessa
abordagem sugere, pois cada recurso criará seus testes primeiro e os testes guiarão
o recurso,
o
desenvolvimento posterior também se
preocupará muito com aplicação.
melhores práticas de segurança e trate o aplicativo como
um sistema de missão crítica. Pessoalmente, tenho uma skin no
jogo neste aplicativo e me esforcei muito para minimizar a chance de
alguém perder fundos com ela. Além disso, este curso tem muitas das melhores práticas de
programação, exemplos, princípios sólidos e código
limpo que permeiam a
cultura do nosso código. Agora, vamos ver como você
aprenderá neste curso. Seguiremos a metodologia
de aprender fazendo. Cerca de 17% deste curso
é composto por teoria, o restante é
composto por aulas práticas. Portanto, o curso é
altamente focado em código, intercalado com algumas
apresentações quando necessário. Abaixo de cada vídeo, você pode
encontrar links adicionais e material de
estudo na página
Projetos e Recursos. Você construirá uma carteira
Bitcoin para desktop, aprendendo
conceitos importantes de Bitcoin ao mesmo tempo. Agora, vamos listar os requisitos
recomendados para fazer esse curso. É recomendável
que o aluno tenha um bom conhecimento de programação
orientada a objetos. O aluno deve conhecer
Java ou linguagens similares antes de fazer este curso. Embora este curso apresente diferentes conceitos
de engenharia de software, nosso foco é
entender o Bitcoin. Se o aluno quiser
conhecer em detalhes alguns
dos conceitos de
engenharia de software abordados neste curso. Ele terá que
usar outras fontes ao longo do curso para
entendê-las melhor. Você precisará de um computador
com Windows, macOS ou Linux com conexão
à Internet. Apresentaremos este
curso usando o Windows. Mas como o Java é compatível com
várias plataformas, todos os códigos deste curso
funcionarão da mesma forma nesses três sistemas
operacionais. A única diferença
será instalar o software necessário
em cada plataforma, mas você pode
encontrar facilmente guias para instalá-los nesses sistemas
operacionais. Você precisará de pelo menos
30 GB de espaço livre para executar o nó Bitcoin
no ambiente de rede de teste. Opcionalmente, se você pretende executar o aplicativo no ambiente de rede
principal, precisará de pelo menos 430 GB de espaço em
disco para baixar
o blockchain da rede principal. Mas não se preocupe, usaremos o ambiente de rede principal somente no último
vídeo do curso. Portanto, você terá bastante tempo para baixá-lo antes de precisar dele. Agora, vamos falar um pouco
mais sobre a carteira que você construirá ao longo do curso. Vou me referir a essa
carteira como BYOD W, um acrônimo para construir
sua própria carteira, começará a desenvolver esse
aplicativo com o Java 16, mas o atualizaremos
mais tarde no curso. Diversion 19 usará a
estrutura Spring Boot versão 2.5, 0.4, que fornecerá um
contêiner de injeção de dependência e muitos recursos para
nos ajudar a criar nosso aplicativo. Posteriormente no curso, vamos atualizá-lo para a
versão 2.7, 0.5. Usaremos o Java FX versão
16 no projeto. Vamos atualizá-lo
posteriormente para a versão 19. Essa biblioteca fornecerá
classes que nos ajudarão a criar a interface
gráfica do usuário do aplicativo, também conhecida como pegajosa. Para testes, usaremos o Groovy, a estrutura do Spark e a
ética de testes para criar carteiras
, endereços iniciais, transações e outras operações de
Bitcoin usaremos a biblioteca
Bitcoin Java de código aberto, que eu construí especialmente
para este curso. Usaremos o Bitcoin
Core Node versão 22 para comunicação
com o blockchain. Mais tarde no curso, vamos atualizá-lo para a versão 23. Embora o nó Bitcoin
Core possa gerar carteiras e endereços, ele
será usado apenas
para
recuperar dados e enviar dados
para o blockchain. Operações como
geração de sementes, endereços, construção e assinatura de
transações serão feitas por nosso aplicativo. A exceção
será para os testes. Nesses casos, usaremos a API Bitcoin Core Node RPC para gerar endereços,
enviar transações e minerar blocos nos
ambientes de teste, portanto, familiarizaremos com
os mais importantes Métodos de API
RPC do Bitcoin Core Note e crie um cliente para se comunicar com ele
a partir de nosso aplicativo. Como o banco de dados usará a
implementação SQL Java, o H SQL DB usará sua
integração suave com a biblioteca Spring Boot Data JPA para se comunicar
com o banco de dados. Finalmente, usaremos o IntelliJ idea como o IDE para construir
esse projeto. Todo o código apresentado
neste curso é aberto e está disponível
em nossa página do GitHub. Para cada aula prática, a
página de Projetos e Recursos conterá um link com a diferença de código entre
as duas últimas aulas práticas para a conveniência dos alunos. Agora, vamos apresentar quem eu sou. Meu nome é Alberto Salazar e serei seu
instrutor neste curso. Tenho mais de cinco anos de experiência como desenvolvedor profissional de
software, trabalhando especialmente
no setor de comércio eletrônico. Sou
entusiasta do Bitcoin desde 2016. Eu estava estudando muito
Bitcoins desde então. Eu desenvolvo a biblioteca
Bitcoin Java de código aberto, que usaremos neste curso. Eu criei a
iniciativa educacional sobre Bitcoin para concentrar meus esforços em fornecer educação sobre Bitcoin para
desenvolvedores em todo o mundo. Siga-nos no Twitter para
receber nossas atualizações mais recentes. Concentrei todo o
código desse curso, incluindo a
biblioteca Bitcoin Java em nossa página do GitHub. Também temos um site
cujo endereço é www dot bitcoin
education dot site. Temos alguns
artigos técnicos que podem servir como material de
estudo adicional. Confira isso como uma palavra final. Eu gostaria de dizer
que muito trabalho foi feito para fazer este curso. Demorou mais de dois anos
para ser feito e quase todo o meu tempo livre
durante esse período. Então, por favor, se você
tiver alguma dificuldade ou encontrar algum problema
com este curso, entre em contato comigo antes de dar uma classificação baixa para que possamos
ajudá-lo com seu problema. Terei prazer em fazer
todo o possível para que você tenha uma ótima experiência
de aprendizado. Muito obrigado pela atenção e até
o próximo vídeo.
2. 0 Requisitos de instalação Skillshare 2: Neste vídeo, apresentaremos o software necessário
que você precisará baixar e instalar antes de prosseguir com os próximos
vídeos do curso. Então, vamos começar com
o Bitcoin Core Node. O Bitcoin Core Node é a
implementação original do Bitcoin. É responsável por
se comunicar com o blockchain,
criar, receber, enviar e validar transações de
Bitcoin, receber blocos e muito mais. Como dissemos no
vídeo anterior, as principais funções que
dependerão do nó Bitcoin Core são aquelas relacionadas à comunicação com
o blockchain. Então, vamos ao site
Bitcoin core.org. Instalará o Bitcoin
Core versão 22. Você pode perguntar por que não
instalar a versão 23? Quando comecei a fazer este curso, a versão mais recente
disponível era 22. Há uma pequena diferença
na API gRPC na versão 23 que fará com que um método do nosso aplicativo não
funcione corretamente. Em um dos
vídeos mais recentes do curso, atualizaremos a versão
23 do
nó Bitcoin 2 e tornaremos nosso aplicativo
compatível com ela. Mas, por enquanto, vamos
instalar a versão 22. Para fazer isso, clique
no botão de liberação na parte superior
da tela e, em
seguida, clique no link
Bitcoin Core 22. Em seguida, clique neste
link na página. Esta página contém arquivos
de instalação para cada sistema operacional. Como estou usando o Windows, vou baixar aquele que
termina com dot EXE. Se você estiver usando o macOS, você baixará aquele que
termina com dot DNG. Para distribuições Linux, escolha o arquivo dot
GZ adequado de
acordo com a distribuição que você usará na página Projetos e
Recursos Há links com instruções de
instalação para cada uma sistema operacional. Windows, depois de
baixar o arquivo, abra-o e siga as instruções
de instalação
na tela. Não vou fazer isso porque
já o instalei na minha máquina. Mas é um processo
simples. Na última fase
da instalação, ele perguntará se você
deseja abrir o software. Não abra ainda. Interagirá com
o nó Bitcoin por meio da interface da
linha de comando. Se você abrir o nó
clicando em seu ícone, ele abrirá uma interface gráfica de
usuário e começará a
baixar o blockchain
no ambiente de rede principal, que ainda não queremos fazer. Agora, vamos configurar
nosso node Bitcoin. Para fazer isso, teremos que
criar um arquivo chamado bitcoin.com e a pasta
apropriada do aplicativo Bitcoin. localização dessa pasta depende do sistema operacional
que você está usando. Este site na tela mostra o local padrão em que você deve criar esse arquivo
para cada sistema operacional. Para criá-lo, abra um
arquivo de texto e salve-o com o nome bitcoin.com na
pasta apropriada para seu sistema operacional. Agora, escreva a
mesma configuração que você vê na
tela do seu arquivo ou copie e cole
o conteúdo
da página Projetos e
Recursos nela. Não se preocupe, explicaremos o que cada linha desse arquivo
significa em um vídeo posterior. Por enquanto, você terá que
decidir onde deseja armazenar os
dados do blockchain em seu computador, escolher
um caminho com acesso a pelo
menos 30 GB para o blockchain da rede de
teste ou 430 adicionais gb para
o blockchain da rede principal. Opcionalmente, defina a configuração
DIR de
dados para o caminho escolhido nesse arquivo. No meu caso, decidi armazenar os arquivos blockchain
na unidade E na pasta de dados do
Bitcoin, como você vê na tela. Agora, se executarmos o
nó Bitcoin com essa configuração, ele será executado na rede principal e iniciará o download do blockchain da rede
principal. Como o próprio nome sugere, o principal ambiente de rede é o principal
ambiente de bitcoin, onde o blockchain é grande e
os bitcoins têm valor, só
executará o ambiente de rede
principal no último vídeo do curso. Antes disso, ele será executado
no ambiente de rede de teste, que é usado para testes. Para executar nossa nota sobre o ambiente
de rede de teste, vamos adicionar uma linha
escrita de rede de teste igual a uma no arquivo
bitcoin.com. Agora, usando o terminal, vamos para a pasta em que você instalou o Bitcoin Core Node. Dentro da pasta demoníaca, execute o
aplicativo Bitcoin D desta forma. Nos registros do console. Observe que estamos
rodando de fato
no ambiente de rede de teste e todos os seus dados serão armazenados
na pasta indicada. Bom, isso significa que nosso
node está funcionando com a configuração que definimos
no arquivo bitcoin.com. Agora, vamos esperar que
nosso node se conecte a outros nós e
comece a baixar e validar o blockchain. Ok, as linhas que começam
com a dica de atualização de texto indicam que ele começou a
baixar o blockchain. Cada uma dessas
linhas indica um bloco de
transações de Bitcoin baixadas. O progresso em cada linha indica o quanto o
blockchain está afundando. No meu caso, isso indica que cerca de 98% do
blockchain de teste da rede foi baixado. Quando esse valor é igual a um, isso indica que nossa
cópia do blockchain está completamente sincronizada com
as de outros nós. Para o ambiente de rede de teste
, pode levar algumas horas
para que isso aconteça. Você pode deixá-lo
afundando enquanto assiste ao
resto do curso, pois o usaremos
somente após alguns vídeos. Para sair do aplicativo, você pode pressionar Control plus C ou Command plus C se
estiver usando o Mac OS Se você iniciar a nota novamente, ela começará
a baixar o blockchain onde parou. Depois de terminar de baixar
o ambiente de teste da rede, você pode, opcionalmente, alterar o arquivo bitcoin dot conf
e começar
a baixar o blockchain principal da rede
executando a nota no ambiente de rede
principal, usará apenas o ambiente de rede
principal no último vídeo do curso, então você terá bastante
tempo para baixá-lo. O outro
requisito inicial deste curso é o IntelliJ idea Java IDE. É o software que
usaremos para escrever o código e executar
nosso aplicativo. Se você não tiver, acesse
o site na
tela para fazer o download. Baixe e instale a edição
comunitária para seu sistema operacional
seguindo as instruções
no site.
3. O que é o Bitcoin?: Olá, bem-vindo de volta ao curso para desenvolvedores de
Bitcoin. Nesta seção do curso,
você terá uma visão geral do Bitcoin. os conceitos apresentados
nesta seção, forneceremos o
conhecimento básico necessário para entender o que está por vir
no restante do curso. Então, vou começar com a
pergunta: o que é Bitcoin? O Bitcoin com B maiúsculo
é um protocolo de comunicação. Esse protocolo é um conjunto de regras que permite
a troca de mensagens entre as entidades participantes da rede
Bitcoin. Bitcoin com
b minúsculo é uma criptomoeda. Uma criptomoeda é uma forma de moeda
digital que podemos trocar por bens
ou outros ativos. A parte criptográfica do nome
vem da criptografia, que protege transações
e outras operações de Bitcoin. O Bitcoin também é um sistema
de pagamento. Podemos enviar e receber pagamentos em
Bitcoin
de e para outros participantes
da rede Bitcoin. Falando em redes, Bitcoin também é uma
rede ponto a ponto, o que significa que
é composta por entidades ou nós
que se comunicam diretamente entre eles sem a participação de
servidores centralizados. A próxima pergunta é: quando o bitcoin foi inventado? O Bitcoin foi inventado em 2008 por Satoshi Nakamoto com a
publicação do livro branco
Bitcoin, uh, sistema de caixa
eletrônico peer-to-peer. Neste artigo, que eu
recomendo fortemente a leitura, Satoshi descreve as partes
básicas do Bitcoin. Ninguém sabe quem realmente é Hitoshi
Nakamoto, ou se é mesmo um
nome verdadeiro ou várias pessoas. Quem quer que seja Satoshi, em 2009, ele publicou o primeiro bloco
Bitcoin chamado bloco gênese e colocou a rede
Bitcoin em funcionamento. Se você não sabe o que é um bloco de
Bitcoin, não se preocupe. Vou explicar resumidamente. Então, o que há de
tão bom no Bitcoin? Qual é a inovação
do Bitcoin? Bitcoin foi a primeira moeda digital
bem sucedida. Antes do Bitcoin, houve algumas tentativas de criar moedas
digitais, mas todas falharam devido a problemas que o
Bitcoin resolverá posteriormente. Um desses problemas é o problema do
gasto duplo, que o bitcoin foi o primeiro a resolver de forma descentralizada. Isso acontece quando uma pessoa gasta duas vezes uma unidade monetária. Portanto, uma das transações
é invalidada posteriormente, fazendo com que o destinatário
da transação invalidada perca dinheiro. O Bitcoin também foi
responsável pela invenção do blockchain, que foi usado para resolver o problema de
gastos duplos. O blockchain é
uma estrutura de dados responsável por armazenar
todas as transações de Bitcoin. Ele permite a validação de todas as suas transações para
qualquer pessoa com acesso a ela, mas falaremos mais sobre isso posteriormente. O Bitcoin também introduziu o
conceito de escassez digital. Isso significa que, diferentemente dos
arquivos em seu computador que podem ser copiados e
distribuídos indefinidamente, Bitcoin só pode ser
transferido pelo proprietário e não pode ser copiado
e distribuído livremente.
4. Transações de Bitcoin e chaves privadas: Agora vamos nos
aprofundar um
pouco mais nos
detalhes internos do Bitcoin. Vou explicar o Bitcoin
do micro ao macro. Ou seja, falarei sobre transações de
Bitcoin
e chaves privadas, depois um pouco sobre
blockchain e mineração. Em seguida, terminarei
a visão geral
explicando o ecossistema
Bitcoin. Então, vamos começar
com a pergunta: onde estão a criptomoeda
e o sistema? Ou, em outras palavras, onde está o Bitcoin com b
minúsculo no sistema? A resposta é que está
em uma transação. Esta figura mostra uma transação comum de
Bitcoin com uma entrada e duas saídas. Uma transação de Bitcoin pode
ter muitas entradas e saídas, mas em muitos casos, elas têm apenas uma
entrada e duas saídas. Em uma transação de Bitcoin, temos as informações de
onde o Bitcoin veio
na entrada e para onde o Bitcoin
está indo na saída. Neste exemplo, a
entrada zero contém uma instrução que diz que
essa entrada veio de John, foi assinada por John e
continha um Bitcoin. A primeira saída, chamada
de saída zero, diz para Mary, contém
0,9 Bitcoin. Na primeira saída, diz que
John contém 0,099 Bitcoin. Essa saída é a alteração
da transação. Na maioria dos casos,
precisamos incluir uma alteração porque quando você gasta Bitcoin em
uma transação, você precisa gastar todas as
unidades da entrada. Portanto, isso gera
a necessidade de criar uma saída adicional, que é a mudança. Portanto, se sua entrada
contém mais bitcoins, você deseja enviar
para outra pessoa, então você deve criar
uma saída adicional, a alteração para você mesmo. Temos o conceito de UTXO, que significa saída de
transação não gasta. Um bitcoin está mais
especificamente dentro de um UTXO. Uma entrada de transação deve
se referir a
um UTXO de uma transação anterior
para poder gastar esse Bitcoin nessa transação. Se você notar que a
soma das quantidades de saídas é menor do que a
quantidade na entrada. Por que isso? A diferença se deve
à pequena taxa. Cada transação de bitcoin
deve separar um valor
da taxa menor para que
sua transação possa ser incluída no
blockchain por um menor. Portanto, o valor da taxa de transação é a diferença
entre a soma dos Bitcoins presentes
nas saídas e a soma dos Bitcoins
presentes nas entradas. Outra informação
importante é que o Bitcoin pode ser dividido em
100 milhões de Satoshi. Portanto, neste
exemplo de transação, poderíamos dizer que
as entradas continham 100 milhões de Satoshi,
na saída zero contém 90 milhões de
Satoshi e a saída contém
9.900.000 De Satoshi. A taxa menor foi de
100.000 Satoshi. Esses são outros exemplos
de transações de Bitcoin. Eu os coloquei aqui apenas para
mostrar que você pode ter transações com mais de
uma entrada e uma saída. Por exemplo, você pode ter uma transação com duas
entradas e uma saída. Essa transação
não tem nenhuma alteração. Você pode ter uma transação com duas entradas e duas saídas. Nesse caso, a
transação tem entradas de duas pessoas diferentes e saídas para duas pessoas
diferentes. Esse tipo específico de transação é chamado de transação
Coinjoin, que é um tipo de transação
que aumenta a privacidade porque você não pode vincular entradas
específicas a saídas específicas. Você pode ter uma transação com três entradas e duas saídas. Há outros tipos
de transações,
como transações com várias assinaturas, sobre
as quais não falaremos agora, mas poderemos incluí-las posteriormente em uma seção extra do curso, se
houver demanda suficiente. Vamos ver um pouco mais sobre os detalhes de uma transação. Nesta imagem,
há duas transações, transação um e a
transação dois. Ambas as transações têm
uma entrada e uma saída. A entrada tem três campos, o
ID da transação anterior e o
número de saída de uma transação anterior
e uma assinatura válida. A saída tem dois
campos, destino, endereço e quantidade,
que se referem à quantidade de Bitcoin
dentro da saída. Nesse caso, a entrada
da transação dois está gastando a saída
zero da transação um. Para fazer isso, insira um
da transação para deve se referir ao
ID da transação da transação um. Também deve se referir
ao número
de saída da transação um, que nesse caso é zero. Finalmente, ele deve conter uma assinatura
válida produzida com a chave privada usada para derivar o endereço
de destino da saída zero. Veremos mais detalhes sobre essa operação
no próximo slide. Como você pode notar, as chaves privadas são uma
parte fundamental do Bitcoin. As chaves privadas são
usadas para receber e enviar bitcoins para receber. As chaves privadas são
transformadas em chaves
públicas por meio da multiplicação de
curvas elípticas. Depois de uma função de hash, as chaves
públicas são
transformadas em endereços Bitcoin. Esses são os
endereços Bitcoin que você pode mostrar a outras pessoas
para receber Bitcoins. As chaves privadas também são usadas para atribuir transações de Bitcoin. As assinaturas são
necessárias para transferir Bitcoins de um
endereço para outro. Nesta imagem, temos
uma transação não assinada. Quando combinamos a chave
privada com uma transação interna usando o algoritmo de
assinatura digital de curva elíptica, ECDSA, produzimos uma assinatura que incluímos
nessa transação. Assim, ela se torna uma transação
assinada. A mesma
chave privada que produziu o endereço referido
a uma entrada zero
também é usada para desbloquear
esses fundos e a transação atual,
produzindo a assinatura. Assim, uma chave privada é usada
indiretamente para bloquear fundos em um endereço e para
desbloquear fundos
do mesmo endereço
produzindo uma assinatura. O importante sobre chaves
privadas e suas transformações
é que você não pode produzir uma chave privada
a partir de uma chave pública e não pode
produzir uma chave pública a partir de um endereço Bitcoin. Você também não pode produzir uma chave
privada a partir de uma assinatura. Essas operações são
apenas em uma direção, exatamente como mostram essas setas. Outra característica importante das transações de
Bitcoin é que qualquer pessoa com acesso a uma transação pode
validar assinaturas. Isso é possível porque,
se você tiver uma chave pública, a assinatura e a mensagem, que nesse caso
é a transação. Você pode verificar se uma assinatura é válida para essa chave pública. E uma assinatura é válida para
uma chave pública somente se for
produzida com uma chave privada que produziu a mesma chave pública.
5. Carteiras de Bitcoin, o Blockchain e mineração: Agora que você tem um
conhecimento básico sobre chaves privadas, podemos começar a falar
sobre carteiras. Uma carteira Bitcoin é, em resumo, uma coleção
de chaves privadas. Existem muitos tipos e
padrões de carteiras. As carteiras têm
desenvolvimento independente em relação a outros softwares de Bitcoin
, como nós. Uma regra básica para
possuir Bitcoin não é o mantra. Suas chaves, seus bitcoins, não suas chaves, não
seus Bitcoins. Isso ocorre porque o proprietário de
uma chave privada pode transferir Bitcoins bloqueados por sua chave privada e
outras transações. O que as
carteiras de Bitcoin têm em comum? Eles têm uma maneira segura de gerar
e armazenar chaves privadas. Eles podem se comunicar
com os nós do Bitcoin. Eles podem criar, assinar e
enviar transações de Bitcoin. Eles podem gerar endereços
Bitcoin. Observe que a maioria
dessas habilidades é possível graças às transformações de
chaves privadas. Toda operação que usa chaves
privadas pode
ser feita offline. Você só precisa estar on-line ao se comunicar com os nós do
Bitcoin para obter informações
do blockchain e enviar informações
para o blockchain. Falando em blockchain, vamos finalmente ver o que
essa palavra da moda significa. O blockchain foi usado para resolver o problema de gastos duplos de
forma descentralizada. Ele faz isso organizando as transações em uma
cadeia de blocos para que blocos
válidos não possam
conter transações com um UTXO que apareceu
no mesmo bloco ou
em blocos anteriores. Para entender
o que é o blockchain, vamos dar uma olhada nessa figura. Esses blocos representam
blocos do blockchain. Alguns de seus dados são representados nesses retângulos
menores. Dentro de cada bloco. Um bloco é
composto por muitas transações, um campo chamado hash anterior,
que, como o nome sugere, é o hash do bloco
anterior. Um campo chamado timestamp, que armazena a data em que
o bloco foi criado, e um campo chamado nonce, sobre o qual falaremos
no próximo slide. Cada bloco produz um hash que é inserido
no próximo bloco. Os blocos são
criados e adicionados
ao blockchain em um
processo chamado mineração. mineração é o processo em que os
blocos são incluídos
no blockchain. Os nós que realizam esse
processo são chamados de mineradores. Para incluir blocos
no blockchain, os mineradores devem coletar transações e organizá-las em um bloco. Em seguida, os menores devem resolver
o Proof of Work, que é um algoritmo necessário
para produzir blocos válidos. prova de trabalho é
composta pelas seguintes etapas. Primeiro, um bloco é codificado e,
em seguida, o número de zeros
iniciais
do hash resultante é verificado. Se esse número for
maior ou igual
ao número necessário de zeros para incluir o bloco
na blockchain. O bloco está incluído
no blockchain. Caso contrário, o menor modifica o nonce e
repete o processo. Então essa é a
função do nonce. Seu único objetivo é fornecer variabilidade para que um bloco
produza diferentes hashes. A prova de trabalho tem uma característica
interessante. Quanto mais zeros forem necessários
para uma prova de trabalho válida, mais
difícil será encontrá-la. Isso torna a dificuldade de mineração
facilmente ajustável. No Bitcoin, a dificuldade
de mineração é ajustada automaticamente, então o tempo médio para
minerar um bloco é de 10 minutos. Quando um menor se importa com um bloco, ele ganha uma recompensa em bloco e
todas as taxas de transação do bloco. A recompensa do bloco é a única maneira pela qual novos
bitcoins são criados. Ele diminui pela metade a cada quatro anos em um
evento chamado ter. Portanto, a cada quatro anos,
o fornecimento de novos Bitcoins emitidos
fica mais escasso. E calcula-se que o último bitcoin
será extraído por volta 21:40, quando o suprimento total de
Bitcoin será igual a 21 milhões.
6. A rede de Bitcoin, o ecossistema e os princípios: Agora vamos falar sobre
a rede Bitcoin. Vamos ver as etapas básicas de como a rede Bitcoin funciona. Primeiro, novas transações
são enviadas aos nós. Cada minerador reúne as
transações em um bloco. Cada minerador tenta encontrar uma prova de trabalho em bloco o mais
rápido possível. Quando um minerador encontra uma
prova de trabalho, o menor transmite seu bloqueio
mental para a rede. Outros nós verificam se
o bloco é válido. Para que um bloco seja válido, ele deve seguir todas
as regras de consenso, como todas as transações,
e deve ser válido e o
hash do bloco anterior deve ser igual ao cache
do último bloco válido. Se o bloco for válido, os nós o
adicionarão ao Blockchain. Copiar. Pequeno começo a
trabalhar em novos blocos usando o campo hash
do bloco mental recente
como o hash anterior. Você pode estar se perguntando
o que acontece se dois mineradores minerarem um
bloco válido ao mesmo tempo. Bem, quando isso acontece, causa uma divisão
na rede. Parte dos nós
conterá uma versão do blockchain
com um bloco de um menor e a outra parte
da rede conterá um
bloco do outro menor. Mas essa divisão é
apenas temporária. Quando o próximo bloco for minerado, os dois grupos de nós
considerarão apenas o
blockchain com mais blocos, pois o blockchain
real e o outro blockchain
será descartado, a probabilidade de a divisão da rede persiste
diminui com o tempo. Portanto, é seguro presumir
que, após seis blocos uma transação é liquidada
para sempre no blockchain. A imutabilidade e a segurança das transações de Bitcoin
dependem do fato de que é quase impossível produzir um blockchain válido com mais blocos do que
o original. Esse feito exigiria
uma quantidade imensa de potência computacional necessária para
superar a velocidade de geração de
blocos
da rede original
por um tempo suficiente. Agora que aprendemos sobre
várias partes do Bitcoin, vamos ver como elas interagem dentro do ecossistema Bitcoin. Usuários de Bitcoin controlam carteiras. As carteiras, como você aprendeu, são coleções de chaves privadas. E essas chaves privadas
podem ser usadas para assinar transações e produzir endereços para receber
transações. As bolsas podem trocar bitcoins por outras criptomoedas e moedas fiduciárias,
como o dólar. Você também pode trocar bitcoins
por produtos de comerciantes. Com quem você faz transações, todas as suas transações são
enviadas para os nós de Bitcoin. Quando um menor vê
sua transação, ele pode incluí-la em um bloco. O minerador cria um bloco com muitas transações e
passa a minerar o bloco. Ou seja, ele começa a calcular a prova de trabalho do bloco
usando seu hardware. Quando um menor finalmente encontra
a prova de funcionamento do bloco, ele transmite o bloco
para outros nós de Bitcoin. Os outros nós recebem o
bloqueio mental recente e são validados. Se o bloco for válido, os nós o adicionarão à
cópia do blockchain. Dessa forma, a rede alcança um consenso sobre o
estado atual do blockchain. Vamos falar sobre os princípios do
Bitcoin. Os princípios do Bitcoin são
importantes para entender as
decisões técnicas que foram tomadas durante o desenvolvimento do
Bitcoin. Um desses princípios é o fornecimento máximo de Bitcoin
de 21 milhões de Bitcoins. Esse limite foi definido no
início do projeto. Mudá-lo causaria esses arranjos
na economia do Bitcoin. Portanto, é importante
manter as coisas assim. resistência à censura é outro princípio importante
do Bitcoin. O fato de muitas pessoas poderem
executar nós de Bitcoin torna quase impossível
que uma autoridade desligue
a rede. Os desenvolvedores de Bitcoin valorizam uma
alta resistência à censura. Ser de código aberto é
outro princípio do Bitcoin. Você pode encontrar o software
Bitcoin Core gratuitamente no site do GitHub. Como muitos outros desenvolvedores, você pode verificar o código
e verificar se há bugs. Você também pode
participar de seu desenvolvimento. O Bitcoin tem uma forte
comunidade de desenvolvedores responsáveis por sua
segurança e novos recursos. E ser de código aberto
é o que permite isso. O Bitcoin não tem permissão,
o que significa que qualquer pessoa pode
executar um node de Bitcoin, minerar e transacionar Bitcoins. Esse é um dos maiores
pontos fortes do Bitcoin e o que o torna tão popular
hoje em todo o mundo. As transações de Bitcoin
são pseudônimas. Isso significa que nenhuma
informação presente em uma transação de Bitcoin pode se conectar
sozinha com as pessoas. Ao contrário do exemplo
do início da visão geral,
pode ter sugerido que as transações de
Bitcoin
não contêm os nomes e IDs dos
destinatários e remetentes. Uma transação de Bitcoin mostra apenas transferências entre endereços de
bitcoin, que pareciam
coleções aleatórias de caracteres. Se alguém descobrir que um endereço pertence a
uma pessoa específica
, poderá rastrear a
quantidade de Bitcoin e outras transações
dessa pessoa. Mas isso é outra história. O Bitcoin visa
alta fungibilidade. fungibilidade é uma característica
que faz com que
uma unidade de uma moeda seja avaliada igualmente como qualquer outra unidade
da mesma moeda. Isso significa que, idealmente cada Bitcoin é valorizado
e tratado da mesma forma. Costuma-se argumentar que o Bitcoin não
é fungível porque Bitcoins de
diferentes transações podem ser rastreados e
tratados de forma diferente. Eu diria que, embora
seja verdade na prática, maioria dos bitcoins é tratada da
mesma forma e você tem maneiras de tornar as transações
mais privadas e fungíveis. A irreversibilidade das transações é outro princípio
do Bitcoin. Depois que uma transação é
liquidada no blockchain, ela não pode ser revertida. Esse é um recurso
de segurança importante porque torna o Bitcoin
difícil de confiscar. Mas também transfere
a responsabilidade de uma transação para
o centro de Bitcoin. Daí a necessidade de manter
suas chaves privadas seguras.
7. 5 Iniciar o skillshare do projeto 2: Neste vídeo, criaremos um novo projeto Spring Boot que será nossa carteira Bitcoin. Para fazer isso, usaremos a ferramenta de inicialização Spring
do site start
dot spring dot io. Então entre no site. Escolha o projeto Maven. A linguagem é Java, usará essa versão
do Spring Boot, mas se não estiver disponível para você, você poderá escolher a padrão
como nome do grupo. Você pode definir o
nome que quiser. No meu caso, vou defini-la
como BYOD w dot wallet. Vou usar BYOD W como
nome do artefato, como descrição. Vou usar a carteira Bitcoin. Usaremos a
versão mais recente do Java. Se você conhece apenas
as versões anteriores do Java, não se preocupe, recursos
mais antigos do Java
ainda funcionam na versão mais recente, pois
o Java
é compatível com versões anteriores. Por fim, clique em Gerar
para baixar o projeto, abri-lo e extrair seu conteúdo para a
pasta que você deseja. Agora, abriremos o projeto
usando uma ideia inteligente. Depois de iniciar o programa, clique em Abrir e escolha a
pasta que você acabou de extrair. Clique em Trust Project. Espere até que o IntelliJ idea
indexe todos os arquivos do projeto. Depois disso, você pode
explorar os arquivos que o Spring Initializer
criou automaticamente. Para verificar se o projeto
foi configurado corretamente. Clique em Maven no lado
direito da tela. Em seguida, dentro da
pasta do ciclo de vida, clique duas vezes em Testar. Opa, recebemos um erro do Maven. Para resolver esse erro, vamos clicar na caixa de diálogo
de configuração. Vamos mudar o caminho inicial do Maven
para o pacote Maven 3. Clique em Aplicar então. Ok. Antes de clicar em testar novamente, verificarei se a
estrutura do meu projeto foi configurada corretamente. Então, vou clicar em Arquivo. Em seguida, a estrutura do projeto
garante que o SDK do projeto tenha a versão Java que você escolheu, o inicializador
Spring. Se não for o caso, clique em Adicionar SDK
e baixe o SDK, escolha a
versão correta do Java e, em uma de suas implementações,
clique em baixar. No meu caso, não vou fazer isso porque já tenho
a versão correta. Então, vou clicar em Cancelar. Certifique-se de que o nível da linguagem do
projeto também
esteja definido para a versão
correta do Java. Agora, vamos fazer o teste novamente. Espere até que o teste passe. Ótimo. O console indica
que o teste foi aprovado. Estamos prontos para começar a
trabalhar em nossa carteira.
8. 6 Configurar o compartilhamento de habilidade da GUI 2: Neste vídeo, começaremos a construir a primeira
janela da nossa carteira. Para fazer isso, primeiro adicionaremos algumas dependências
ao nosso projeto. Abra o arquivo xml de palma
na raiz do projeto. O arquivo xml palm dot contém todas as dependências externas
do projeto. Vamos adicionar algumas dependências do Java
FX. Java FX é uma estrutura responsável pelos recursos da interface gráfica
do usuário. É muito conhecido
na comunidade Java. A versão é 16. A próxima
dependência é JavaFX, FXML. A versão também é 16. Também adicionaremos um plugin. É chamado de plugin Java
FX Maven. versão é 0.0, 0.6. Para carregar essas dependências
em seu projeto, clique nesse ícone. O projeto carregou
todas as dependências. Agora vamos criar o código necessário para inicializar
nosso aplicativo. Esse processo requer
alguma coordenação entre as formas em que
os efeitos Spring Boot
e Java são iniciados. Para fazer isso, primeiro criaremos uma nova classe Java chamada aplicação
GUI. Essa classe deve estender a classe do aplicativo
a partir dos efeitos Java. E devemos implementar
o método start da mesma classe. Adicionaremos uma
propriedade privada com o tipo de contexto de
aplicativo configurável. Usaremos a seguir. Adicionaremos o método init aqui, que é executado antes
do método start, durante a
inicialização do aplicativo. O código que acabei de digitar
é responsável por inicializar nossas dependências
injetadas no aplicativo Spring
Boot . Agora vamos para a classe de aplicação BYOD
W. Vamos modificar o método principal. O método principal dessa classe é o primeiro método chamado quando
executamos nosso aplicativo. Quando o código que acabei
de digitar for executado, ele chamará primeiro
o método init
da classe
do aplicativo GUI e não o método start
da mesma classe. Vamos voltar para a classe de aplicação
GUI. Vamos continuar implementando
o método start. Agora, chamaremos o método de
publicação do evento na propriedade context, passando um novo objeto de evento
iniciado pela GUI, que será criado em
seguida como argumento. Vamos criar uma aula de eventos
bem iniciada. Vamos criá-lo em uma
nova pasta de eventos. Devido à forma como
criamos essa classe, o ID já
sabia qual classe
tínhamos que estender e, ao
criar automaticamente , o código
padronizado precisará ser muito útil, não é? Agora continuaremos
implementando nosso construtor. Chamaremos o
superconstrutor passando um
objeto de aplicação GUI como argumento. E atribuiremos o estágio
primário do argumento ao estágio. A propriedade privada também
criará um ouvinte para
essa classe de evento dentro de um pacote
chamado ouvintes. Adicionaremos a
anotação do componente a essa classe. Você verá muito essa anotação
ao longo do curso. É do Spring
Boot e seu objetivo é disponibilizar um objeto
de uma classe para injeção, e
outros objetos
do projeto também
implementarão a
interface de ouvinte do
aplicativo para essa classe, passando o
evento gooey started como um parâmetro de tipo. Isso é necessário para que o
Spring Boot interprete essa classe como um ouvinte de eventos
para um evento iniciado de forma pegajosa. Agora implementaremos o
método necessário da interface. Também precisará de um construtor. Esse construtor pegará
um objeto de recurso com uma anotação de valor apontando para um arquivo chamado ponto
da janela principal FXML, que será adicionado posteriormente
ao projeto. O construtor também usará um argumento de contexto do aplicativo. Em seguida, inicializaremos propriedades
privadas
com o
mesmo nome dos argumentos do construtor. Fará com que ambas as propriedades sejam finais. Tudo bem, agora que temos nossas dependências
injetadas nessa classe, vamos implementar o código do método de evento
do aplicativo. Esse código será
responsável por mostrar a janela principal da nossa carteira
quando iniciarmos o programa. Então, primeiro instanciaremos
um objeto carregador FXML. Em seguida, obteremos o objeto
de palco do evento iniciado pela GUI. Para fazer isso,
adicionaremos o método gets stage à classe de evento gooey
started. Esse método retornará
o objeto de palco. Adicionaremos um título
à carteira usando o método set title
do objeto de palco. Pode ser qualquer string que você quiser. Vou defini-la como carteira BYOD W. Esse texto será exibido
na barra superior da janela do
programa. Também chamará o
método set scene, passando um novo objeto de cena como seu parâmetro instanciado com um objeto retornado
por um novo método que criará chamado
initialize FXML. Esse método começará a declarar uma variável do tipo
parent chamada root. Em seguida, dentro de um bloco try catch usaremos o método set
location
da variável do carregador FXML passando a localização do URL de
nossa propriedade FXML. Definiremos a
fábrica de controladores do carregador
FXML como uma referência
do método good bean da propriedade context. Isso é necessário para
que a estrutura JavaFX
reconheça as classes do controlador anotadas com a anotação do componente. Também definiremos
a variável raiz como resultado da chamada do método de carregamento
do carregador FXML,
capturaremos uma IOException e a
lançaremos em uma exceção de
tempo de execução. Nós retornaremos a variável raiz. Finalmente, no método
sem aplicação chamará o
método show do estágio, que fará com que
a janela apareça na tela. Agora, criaremos o arquivo FXML, mas nos referimos à anotação de
valor
da propriedade FXML do construtor do
ouvinte. E o arquivo FXML é um
tipo de arquivo usado para codificar elementos de GUI de
um aplicativo JavaFX. Como um arquivo HTML,
codifica páginas da Web, arquivos
FXML e código. As janelas de efeitos
Java criarão esse arquivo dentro do novo caminho FXML
que será criado. Esse diretório estará localizado
dentro do caminho dos recursos. Vamos chamá-la de janela principal de
sublinhado dot FXML. Vamos excluir o clichê
gerado automaticamente. Vamos adicionar uma tag de painel de borda. Vamos adicionar alguns atributos a ele. Adicionará um ID Fx que
permitirá fazer referência à tag
do painel de borda dentro de
sua classe controladora, que será criada posteriormente. Vamos adicionar alguns atributos
para definir o tamanho da janela. Por fim, adicionaremos
alguns atributos de metal para definir o esquema do arquivo. É isso mesmo. Vamos executar o aplicativo
para ver se tudo correu bem. Dentro da guia Maven, vamos clicar em plug-ins, Spring Boot e Spring Boot run. Ótimo. A primeira janela da nossa carteira apareceu na tela. Bom trabalho.
9. 7 Criar nossa primeira carteira parte 1 skillshare 2: Neste vídeo,
começaremos a criar um teste para o primeiro
recurso da nossa carteira. O primeiro recurso
da nossa carteira
será a opção de
criar uma carteira. Mais especificamente, criaremos um menu com um botão
que, quando clicado, fará com que uma caixa de diálogo
apareça na tela. Essa caixa de diálogo
conterá inicialmente um TextField onde o usuário definirá
o nome da carteira e um botão Criar
que, quando clicado, gerará uma semente mnemônica
aleatória. Aprenderá o que é
a semente mnemônica. No próximo vídeo, criaremos todos os recursos
de nossa carteira usando o desenvolvimento orientado por testes
ou a abordagem TDD. Essa abordagem consiste em primeiro criar um teste de
integração, que é um teste que descreve o que queremos alcançar
com esse recurso. Em seguida, implementaremos o recurso e executaremos o teste
até que ele seja aprovado. Durante a implementação,
podemos encontrar situações em que precisamos criar novas classes ou métodos para nos ajudar a
atingir nossos objetivos. Se for esse o caso,
criaremos testes unitários para essas classes que eram métodos
e os implementaremos usando o TDD. Ao final de cada ciclo de TDD, refatoraremos nosso
código, se necessário. Vamos ver como isso
funciona na prática. Mas primeiro, vamos adicionar algumas
dependências ao nosso projeto. Adicionaremos algumas dependências relacionadas à estrutura do Spark. O framework Spark é um framework
de testes em groovy, uma linguagem de programação
compatível com Java. Ele contém recursos que
facilitam a construção de testes, também
usará uma versão do
test FX compatível com Spock. Test fx é uma estrutura
que fornece recursos para testar aplicativos
JavaFX. Agora, vamos adicionar
groovy versão 3.0, 0.6 ao nosso arquivo POM. E vamos adicionar Spock
Spring a ele. A versão será
2.0, groovy 3.0. Seu escopo será testado. A próxima dependência que
será adicionada é o Spark Core. A versão será a
mesma de Spock Spring. O escopo será testado. A próxima dependência
será testar o FX Spock. Sua versão será 4.0, 0.16 alpha também
adicionará um plugin G Maven. Ok, esqueci de colocar o escopo certo e
testar a dependência de FX. Também adicionaremos algumas metas
no plugin GI Maven. Será necessário que o
groovy funcione corretamente. Agora, faremos uma alteração no arquivo de
propriedades
dos pontos do aplicativo. Spring, por padrão,
cria um servidor web, mas não precisaremos de um
em nosso aplicativo. Portanto, devemos definir essa
propriedade como nenhuma. Portanto, a primavera não criará um servidor
web quando for inicializada. Agora vamos criar nosso primeiro teste. Mas primeiro, vamos excluir esse arquivo. O teste do
aplicativo BYOD W, que foi gerado automaticamente
pelo inicializador spring, criará um pacote
nessa pasta chamado gooey que conterá todo o nosso usuário
gráfico testes de interface. Dentro desse pacote,
vamos criar o teste. Mas primeiro, no arquivo xml de
palma, clique no botão carregar alterações do
Maven. Agora, o IDE nos
permitirá criar classes incríveis. Então, vamos criar um chamado teste de
criação de carteira. Adicionaremos a essa classe uma anotação de teste do Spring Boot que estenderá essa classe com
a classe de especificação do aplicativo. Isso é necessário para que
tanto o Spring Boot quanto o
test fx considerem essa
classe como uma classe de teste. Todo teste de integração deve conter essa anotação
e extensão. Devemos implementar
o método
de início a partir da especificação do aplicativo. Também implementaremos os métodos
de unidade e parada. Dentro do método init, adicionará esse código que é necessário
para a inicialização do teste. Dentro do
método de parada incluirá um código necessário para
interromper o teste. Dentro do método stark, devemos incluir o
código necessário para mostrar a primeira tela
do nosso aplicativo. Esse código será
semelhante ao código presente na classe de ouvinte
iniciada pela GUI. Portanto, instanciaremos
um carregador FXML passando a URL FXML
como argumento e, em seguida, criaremos a propriedade
privada FXML com a mesma
anotação de valor presente na classe de
ouvinte iniciada pela GUI. Groovy transforma cada método com getter definido em
uma propriedade de objeto Podemos usar esse URL aqui. Em vez de get URL,
definirá a propriedade de
fábrica do controlador como a referência do
método get bean do contexto. Vamos adicionar o
campo de contexto à classe. Acima. Ele colocará a anotação automática
com fio. Essa anotação é necessária
para que o Spring Boot injete o objeto de
contexto do aplicativo de seu
contêiner de injeção de dependência nessa variável. Em seguida, criaremos
a variável raiz usando o método load
do carregador FXML. Em seguida, definiremos o título do palco, a cena e chamaremos
o método de show de palco ,
assim como o código dentro do ouvinte
pegajoso iniciado. Ok, estamos prontos para trabalhar
no código do nosso primeiro teste. O nome do teste
será deve criar carteira. O teste conterá
os requisitos do recurso
que queremos implementar, usará a palavra-chave ao descrever as ações que o usuário do
teste realizará. Então, vamos implementá-lo. O usuário clicará em um
botão com o texto conhecido. Em seguida, você clicará em um
botão com a carteira de texto. Em seguida, em um campo de texto
com um nome de ID FX. Quando queremos nos
referir a um ID de câmbio, colocamos o nome do ID
após um sinal de libra como este. Em seguida, o usuário escreverá
as palavras carteira MyText. Em seguida, ele clicará em um botão
com o texto de criação. Em seguida, o teste
examinará o conteúdo de um campo da área de texto com um ID de
ética de semente mnemônica. Ele atribuirá o conteúdo
desse campo à variável de semente
mnemônica. Por fim, usaremos a palavra-chave para definir o que esperamos que
aconteça depois que o usuário fizer todas as ações dentro
do bloco de vento. Esperamos que a variável de semente
mnemônica contenha um valor não nulo. Para fazer isso, basta colocar a variável de semente mnemônica
dentro do bloco then. Se a semente mnemônica for definida, o bloco será avaliado como
verdadeiro e o teste será aprovado. Caso contrário, será avaliado como falso e o teste não será aprovado. Vamos fazer esse teste
para ver o que acontece. Primeiro, clicaremos em Construir
e depois em reconstruir o projeto para garantir que o IDE carregue todas as alterações que
fizemos no código. Em seguida, clicaremos em
Testar na guia Configuração do Maven. *****. O IDE
reclamou do Maven novamente, vamos corrigir isso rapidamente. Agora. Vamos fazer o teste novamente. O teste falhou conforme o esperado. Você notou que
uma janela apareceu rapidamente na tela
durante o teste? Mostra nossa janela
aberta, pelo menos. Vamos conferir os resultados dos
nossos testes no console. Diz que a
nova consulta não retorna nenhum nó. O teste abriu nosso aplicativo e,
em seguida, tentou encontrar um
elemento com o texto conhecido, pois não o encontrou,
ele falhou rapidamente e
fechou o aplicativo. No próximo vídeo, aprenderemos o que é uma semente
mnemônica. Em seguida, no vídeo
seguinte, criaremos nossa primeira
carteira e faremos com que esse teste seja aprovado. Te vejo.
10. Sementes de mnemônica: Neste vídeo, aprenderemos
mais sobre sementes mnemônicas. Então, qual é a semente mnemônica? Uma semente mnemônica é uma
frase contendo 121-51-8201 ou 24 palavras. É usado para derivar todas as carteiras, chaves
privadas e endereços. As regras de geração mnemônica de
sementes que usaremos estão descritas na Proposta de Melhoria
do Bitcoin 39 ou BIP 39. Muitas carteiras usaram
as regras do BIP 39 para gerar sementes mnemônicas. As sementes mnemônicas são combinadas
com a string mnemonic mais uma senha opcional para produzir uma semente raiz representada
aqui em formato hexadecimal. A senha opcional
geralmente é chamada
de frase secreta, mas usaremos a palavra
senha para simplificar. Em seguida, usando outros algoritmos, o root seed
gera chaves privadas, chaves
públicas e endereços, aprenderá os detalhes
dessas operações
em um vídeo posterior. Agora, vamos nos concentrar em como as sementes
mnemônicas são geradas. Para gerar uma semente
mnemônica, primeiro, precisamos gerar uma
sequência aleatória de bits chamada entropia de comprimento
igual a 128 bits. Se quisermos uma semente mnemônica
de 12 palavras, 160 bits, se quisermos uma com 15 palavras, 192 bits, se quisermos
uma com 18 palavras, 224 bits se quisermos uma
com 21 palavras ou 256 bits, se quisermos uma com 24 palavras, em seguida, calculamos a soma de verificação. Para fazer isso, calculamos
o comprimento da entropia dividido por 32 e obtemos
o tamanho da soma de verificação. Em seguida, obtemos os primeiros bits do tamanho
da
soma de verificação do hash SHA-256 da entropia. O resultado é a soma de verificação. A soma de verificação é usada para verificar se uma determinada semente mnemônica é válida. Anexamos a soma de verificação ao
final da entropia inicial. O resultado é
dividido em grupos de 11 bits. Cada grupo de 11 bits é
convertido em um número 0-2047. Esses números são usados como
índices em uma lista de palavras. As palavras correspondentes
formam a semente mnemônica.
11. 9 Criar nossa primeira carteira parte 2 skillshare 2: Neste vídeo,
continuaremos implementando o recurso
de criação de carteira do nosso aplicativo. O primeiro passo é adicionar um botão com o
novo texto escrito nele. Vamos fazer isso. Abra o arquivo FXML da janela
principal. De agora em diante, usaremos a ferramenta IDE Scene Builder para criar as janelas
do nosso projeto. Scene Builder nos
permite criar a interface gráfica do usuário de nosso aplicativo de
forma interativa e fácil. Clique no botão Scene
Builder na parte inferior da tela. No meu caso, essa
janela apareceu. Mas se você não tiver o
Java FX ou o Scene Builder instalados, um botão para
baixá-los aparecerá na
parte superior da tela. Depois de baixá-los
e instalá-los, essa janela será exibida. Agora, adicionaremos uma
barra de menu superior à janela principal. Para fazer isso,
clicaremos nos controles e
arrastaremos e soltaremos o componente da barra de
menu na parte superior do menu do painel de
borda abaixo. Agora teremos uma barra de menu
com três itens de menu. Vamos excluir as
edições e as de ajuda. Vamos mudar o
menu de arquivos denominado dois novos. Ótimo. Agora temos
nosso novo botão. Vamos conferir nosso teste para
ver o que fazer a seguir. A próxima ação que nosso usuário
fará é clicar no botão
da carteira.
Vamos criá-lo. Volte para a janela principal. Adicionaremos um item de menu
dentro do novo menu. Nesse caso, já
temos um item de menu. Então, vamos mudar seu
rótulo para carteira. Quando o usuário clica
no botão da carteira, uma nova janela de diálogo deve aparecer. Vamos implementá-lo no
Scene Builder. Clique no item do menu da carteira. Adicionaremos uma ação
a esse botão. Clique em Código, digite open
create wallet dialog. Se clicarmos no
botão Texto na parte inferior
da tela e
verificarmos o arquivo FXML. Perceberemos que o IDE
adicionou o
atributo on action na tag do item de menu com o valor que acabamos de digitar. Agora, para criar uma ação para esse botão, será
necessário criar um controlador. Mas primeiro, vamos fazer uma
refatoração em nosso código. Criaremos um novo pacote
dentro do pacote BYOD W. Vamos chamar isso de gooey,
transferirá os pacotes de eventos e ouvintes para ele, adicionará todas as
classes relacionadas à gráfica do usuário do aplicativo interface gráfica do usuário do aplicativo a este pacote. De volta à janela principal, adicionaremos um atributo de
controlador FX à
tag do painel de borda e o configuraremos para que o novo controlador que
criaremos o crie dentro de um
novo pacote de controladores. Dentro da embalagem pegajosa. Seu nome será controlador de
janela principal. Cada arquivo FXML pode ter um controlador que é usado
para definir as ações que acontecem em resposta às interações
do usuário com a janela codificada por esse FXML. Em nosso caso, o
controlador da janela principal conterá um código que definirá ações em resposta aos eventos
na janela principal. Voltar para a
janela principal, coloque o arquivo FXML. Quando clicamos no atributo Abrir caixa de diálogo de criação de
carteira
e pressionamos Alt e enter, o IDE
mostrará a opção de criar um método dentro do controlador da janela
principal. Clique nessa opção. O IDE gerou automaticamente
o método no controlador da janela principal. Vamos excluir o argumento do evento de
ação porque não precisaremos dele. Nesse método,
incluirá o código responsável por abrir a caixa de diálogo de
criação da carteira. Quando clicamos no item do menu da
carteira, primeiro
instanciaremos
um objeto
de diálogo do tipo botão. Em seguida, definiremos as
caixas de diálogo em seu proprietário na janela do
painel de borda para indicar que a
caixa de diálogo pertence
ao painel
de borda da janela principal. Voltar para a
janela principal, coloque o arquivo FXML. Podemos clicar no atributo de
ID de ética da tag do painel de
borda, pressionar Alt mais Enter e criar a propriedade do painel de borda dentro do controlador da
janela principal. O IDE gerou automaticamente
a propriedade. Vamos defini-lo como privado e
incluir a anotação FXML acima dele para indicar que ele
se refere a um componente FXML. Em seguida, definiremos o
título do diálogo para criar uma nova carteira. Agora, dentro de um bloco try
catch,
instanciará um objeto
carregador FXML. Passando esses argumentos. Em seguida, criaremos a propriedade de diálogo de criação de
carteira e a propriedade de contexto. Em seguida, criaremos um construtor para inicializar as duas propriedades. Ambas as propriedades serão injetadas
automaticamente
pelo contêiner de
injeção de dependência do Spring e adicionará uma anotação de valor ao argumento
do
construtor de diálogo create wallet passando pelo caminho de um FXML.
arquivo que será criado a seguir. Em seguida, definiremos o conteúdo do do diálogo como resultado
da chamada do carregamento do método
do carregador FXML.
Em seguida, capturaremos uma IOException e lançaremos como uma exceção de tempo de execução. Por fim, chamaremos
o método de exibição de diálogos e aguardaremos para
abrir o diálogo. Não se esqueça de
adicionar a
anotação do componente a essa classe. Agora, vamos executar nosso aplicativo para ver o que temos até agora. Na guia Maven, dentro de
plugins e Spring Boot, clique em Spring Boot run. Temos nossa barra de menu superior com o botão Novo e
o botão da carteira. Quando clicamos
no botão da carteira, o aplicativo
gera uma exceção. Isso porque ele
não encontrou o arquivo FXML de ponto da caixa de diálogo de criação de
carteira. Vamos criá-lo.
Depois de criá-lo, clique em Scene Builder. Vamos excluir esse painel de ancoragem. Arraste a dor do diálogo
e solte-a aqui. Bom. Vamos ajustar o tamanho dela. Clique em Layout. Em seguida, no campo pref
height, digite 500, no
campo pref width, digite 50. Em seguida, defina o tamanho
de preparação de uso nos campos largura mínima
e altura mínima. Agora vamos adicionar um
texto de cabeçalho à janela. No campo de texto do cabeçalho, digite. Dê um nome à sua carteira
e clique em Criar. Vamos adicionar um pouco de
preenchimento ao redor. Bom. Agora vamos adicionar um painel de grade. Arraste e solte
esse componente no painel de diálogo abaixo. Dentro da primeira célula do painel
da grade, adicionará
um rótulo como este. E esse rótulo
conterá o nome da carteira de texto. Também adicionaremos um
campo de texto ao painel da grade. Vamos mudar suas coordenadas, definir o índice da coluna como um. Agora vamos adicionar um botão
ao painel da grade. Altere o índice da linha para um
e o índice da coluna para um. Vamos mudar seu texto para criar. Vamos voltar ao nosso teste
para verificar o que mais ele exige. Ele tentará clicar em um componente com um nome de identificação
ética. Então, vamos adicionar um
nome de ID Fx ao campo de texto. Depois disso, ele tentará escrever minha carteira de texto
no campo de texto. Em seguida, ele
clicará em um componente com o texto Criar nele, criar com uma letra maiúscula
C. Ao clicar nele, o teste
pesquisará o conteúdo de
uma área de texto com uma
ideia FX de semente mnemônica. Então, vamos criar essa área de texto. Arraste-o para o painel da grade abaixo. Em seguida, altere o índice da linha para
dois e a extensão da coluna para dois, de forma que o campo de semente
mnemônico ocupe o espaço
de duas colunas. Bom. Também adicionaremos um rótulo para
o campo de sementes mnemônicas. Mas primeiro, vamos adicionar outra
linha ao painel da grade. Bom. Vamos aumentar o índice de linha do
campo de sementes mnemônico para três. Em seguida, arrastaremos um rótulo
para o painel da grade. Ajuste o índice da linha para dois, altere o texto
para semente mnemônica. Agora vamos adicionar um ID Fx de velocidade
mnemônica à área de texto. Agora, vamos executar nosso aplicativo
e ver o que acontece. Primeiro, reconstrua o projeto e
clique em Spring Boot run. Ótimo. Mas quando clicamos em
Criar, nada acontece. Também devemos lidar com o
encerramento do nosso diálogo. Por enquanto, clique em parar. O posicionamento desses
campos está me incomodando um pouco. Vamos consertar isso. Clique no botão Texto. Incluímos o painel de
grade dentro
da tag de cabeçalho
da janela de diálogo. O local correto
para incluí-lo é
na tag de conteúdo.
Vamos mudar isso. Vamos verificar sua aparência
agora no Scene Builder. Ótimo, agora parece muito melhor. No próximo vídeo, continuaremos implementando
o recurso de criação de carteira. vejo.
12. 10 Criar nossa primeira carteira parte 3 skillshare 2: Neste vídeo, continuaremos implementando o
recurso de criação de carteira e, finalmente, faremos nosso primeiro teste de GUI. Para fazer isso, vamos adicionar uma
dependência ao projeto. Adicionaremos Bitcoin, Java e uma biblioteca de código aberto criada
exclusivamente para este curso. Essa biblioteca contém muitos utilitários relacionados ao
Bitcoin, como métodos para gerar sementes mnemônicas
aleatórias, criar transações
e muito mais. Para o funcionamento correto
desta biblioteca, devemos adicionar uma
meta de plug-in que
copiará o arquivo (
lista de palavras) dot (TXT) do Bitcoin Java para
o projeto durante a fase de compilação dos
aplicativos. processo de construção. O Wordless dot TXT contém todas as palavras válidas para geração de sementes
mnemônicas. Agora abra o ponto de diálogo de criação de
carteira FXML. Mude para a exibição de texto. Adicionaremos um controlador a esse FXML para adicionar uma
ação ao botão Criar. Então, vamos adicionar o atributo do
controlador FX à tag de problemas do diálogo. O nome do controlador será criado como controlador de
diálogo da carteira e o adicionaremos ao pacote de
controladores. Como acontece com todo controlador, adicionará a
anotação do componente a ele. Vamos criar a
propriedade de semente mnemônica neste controlador. No FXML, adicionaremos uma
ação ao botão Criar. Vamos adicioná-lo aqui. Vamos nomear a ação como
criar uma semente mnemônica. E nós o criaremos no controlador
correspondente. Assim, quando o usuário clicar
no botão Criar, esse método será chamado e a área de texto mostrará
uma semente mnemônica aleatória. Portanto, definiremos os textos de
sementes mnemônicas como o resultado
do método de criação que o serviço
de
sementes mnemônicas criará a seguir. Vamos injetar o serviço de
sementes mnemônicas nessa classe. Agora, vamos criar a classe de serviço de
semente mnemônica dentro do novo pacote chamado api dot services dentro do pacote
BYOD W. Basicamente, todas as
classes de negócios não relacionadas
à interface gráfica do usuário serão colocadas dentro do pacote da API. Vamos adicionar o método de criação
ao serviço de sementes mnemônicas. Adicione a
anotação de serviço a essa classe. finalidade é idêntica
à anotação do componente, mas é mais adequada
às classes de serviço. Agora, vamos inicializar a propriedade do serviço de semente
mnemônica no construtor create
wallet. Agora, vamos implementar esse método porque estamos usando o TDD para
criar nosso aplicativo. Primeiro, criaremos um
teste unitário para essa classe. Vamos criar um pacote de API
dentro da pasta de teste. Dentro dela, crie uma classe bacana chamada teste mnemônico
de serviço de sementes. Como teste unitário, essa
classe só precisa
estender a classe de especificação de Spock. Agora, criaremos um teste chamado deve retornar uma semente
mnemônica aleatória. E esperamos que o serviço de sementes
mnemônicas retorne um valor não nulo. Vamos instanciar o serviço de sementes
mnemônicas aqui. Vamos fazer esse teste para
verificar o que acontece. Falhou conforme o esperado. Vamos implementar esse método. Para fazer isso, usaremos o método generate
random
da classe mnemônica de geradores de sementes do Bitcoin Java. Devemos passar o número
de bits das
entropias que queremos que
a semente
mnemônica tenha como argumento para
esse método, que usaremos para 56. Lembre-se de que uma entropia de 256 bits gera uma semente
mnemônica de 24 palavras. Por fim, chamaremos o método
get sentenced
no retorno desse método
e retornaremos o resultado. Como acontece com todo trabalho, uma exceção
verificada, também
precisamos adicionar
a frase lança FileNotFoundException à assinatura do método de
criação. Precisamos fazer o mesmo com o método de criação de
sementes mnemônicas
no controlador de
diálogo de criação de carteira. Vamos fazer esse teste novamente. Ótimo, o teste foi aprovado. Agora vamos verificar o que acontece
quando executamos nosso aplicativo. Opa, e ocorreu um erro. Oh, é sobrescrito por um W
maiúsculo nesta tag. Essa etiqueta de ID de grupo também está errada. Na verdade, é apenas o ensino do hífen do
Bitcoin. Vamos executar nosso aplicativo novamente. Ótimo.
Geramos com sucesso uma semente mnemônica, mas eu quero que seu texto seja
embrulhado. Vamos consertar isso. Vamos para a caixa de diálogo de criação de
carteira dot FXML. No Scene Builder, clique
na área de texto e clique na caixa de seleção
The Wrap Text. Vamos executar o projeto novamente. Ok, muito melhor. Agora, vamos fazer todos os nossos testes. Ótimo. Todos eles passaram.
13. 11 Criar nossa primeira carteira parte 4 skillshare 2: Neste vídeo,
desenvolveremos ainda mais nosso recurso de
criação de carteira de aplicativos. Adicionará um botão OK e
um botão de cancelamento à caixa de diálogo de
criação de carteira. Quando o usuário clicar
no botão OK, sua carteira será criada e o nome da carteira aparecerá
na parte superior da tela. Quando ele clica
no botão Cancelar, a caixa de diálogo simplesmente fecha. Também adicionaremos uma restrição
ao botão OK para que
ele seja desativado por
padrão e ativado somente quando o nome e os campos de
sementes mnemônicos forem preenchidos. Por fim, adicionaremos um campo de senha
opcional para que o usuário só possa acessar sua carteira
e fazer transações com ela depois de fornecer a senha
correta. Vamos adicionar esses novos recursos primeiro em nosso teste de criação de carteira. Primeiro, adicionaremos um clique
na ação do botão OK. Então, esperamos que o título do
palco seja igual ao nome
do nosso aplicativo,
traçado com o nome da nossa carteira, que é minha carteira de teste. Agora vamos criar
a propriedade do palco. Vamos inicializá-lo
no método start. Agora, vamos criar outro
teste para verificar o que acontece quando o usuário
tenta clicar no botão Cancelar. Para isso,
criaremos um teste com o nome deve cancelar a criação da
carteira. Portanto, esperamos que, quando o usuário clicar em uma nova carteira e cancelar, nenhuma exceção seja lançada. Vamos fazer esses testes
para ver o que acontece. Os testes
falharam conforme o esperado. Vamos implementar esses recursos. Vá para o arquivo FXML
de pontos da caixa de diálogo de criação de carteira. Clique no
painel de diálogo no lado esquerdo. Em seguida, adicione um botão OK e
esse campo de tipos de botão. Clique em mais e, em seguida,
adicione um botão de cancelamento. Agora, adicionaremos o campo de
senha. Mas primeiro, vamos adicionar outra
linha no painel da grade. Agora vamos mover o nome, o rótulo e o campo
para a primeira linha. Em seguida, adicionaremos um rótulo senha
e um campo de senha
na próxima linha. Vamos também adicionar uma ideia
de senha Fx ao campo de
senha. Agora, vamos mudar o
texto do cabeçalho do diálogo para o seguinte. Já que estamos nisso, vamos tornar o
campo de semente mnemônico não editável. Essa é uma medida de segurança
porque não queremos que o usuário altere sua semente
mnemônica acidentalmente. Mude para a exibição de texto. Adicionaremos algumas alterações
nesses botões, etiquetas no botão OK, adicionaremos uma ideia Fx de ok. O botão Cancelar apagará seu conteúdo e adicionará
uma ideia de cancelamento do Fx. Também adicionaremos o
valor de cancelado próximo aos dados do
botão Atributo. Também adicionaremos a
string de cancelamento ao atributo text. Isso é necessário porque, quando
usamos o botão de cancelamento padrão, texto
é traduzido
para o idioma do computador, e não queremos isso. Agora, vamos fazer algumas alterações no controlador
de criação de
diálogo. Adicionará um método chamado
initialize a ele. Mas primeiro, vamos
voltar ao FXML e adicionar um ID Fx da dor de diálogo
à tag de dor do diálogo. Agora, vamos adicionar as propriedades com um ID FX ao controlador. Fará isso com a senha de
propriedades denominada dialog pain,
OK e Cancel. Agora, de volta ao método
inicializado. Esse método
será executado após a inicialização
do diálogo. Incluirá um código para definir as ações
de cada botão. Primeiro, definiremos a
ação do botão Cancelar. Quando um usuário clica nele, o diálogo se oculta. Então, chamaremos o Método do Botão de
Pesquisa do diálogo, passando o botão de cancelamento
como argumento. Em seguida, adicionaremos um manipulador de
eventos a ele, passando o argumento da ação e um retorno de chamada que chamará o método hide da janela de dores de
diálogo. Faremos o mesmo
com o botão OK. Mas, em vez disso, chamaremos o método create wallet no retorno de chamada. Vamos incluir o mesmo código para ocultar a janela
durante o método de criação de
carteira por enquanto e executar o aplicativo para
ver o que acontece. Quando clicamos no
botão Cancelar, a caixa de diálogo se esconde. O mesmo acontece quando
clicamos no botão OK. Bom. Mas quando clicamos no X ao
lado do diálogo, nada acontece. Vamos corrigir isso. Vá para o controlador
da janela principal. Será necessário incluir o código a
seguir para fechar a janela de diálogo quando
clicarmos no botão X. Agora, vamos executar o
aplicativo e tentar novamente. Bom, isso resolveu tudo. Vamos também mudar
o
método de exibição e espera usado no diálogo para simplesmente mostrar que isso
simplifica um pouco as coisas. Agora, execute o aplicativo novamente. Tudo
continua funcionando conforme o esperado. Mas há outro
problema com o diálogo. Permite a
criação de carteiras sem nome e
sem semente mnemônica. Queremos que cada carteira tenha
um nome e uma semente mnemônica. Portanto, precisamos desativar o botão
OK se um
não for preenchido. Vamos corrigir isso. Acesse o controlador de
diálogo de criação de carteira. Agora, criaremos uma propriedade
privada do tipo vinculação booleana chamada
todas as entradas necessárias estão cheias. Definiremos essa propriedade
no método inicializado
com o código a seguir. Aqui, usaremos uma classe
Java anônima que estende a vinculação booleana. Em seguida, inicializaremos a
classe com o método bind, passando o nome
e as propriedades mnemônicas do
texto inicial como argumentos. Em seguida, no método de valor computacional incluirá um código que
retornará verdadeiro somente se o nome e campos de semente
mnemônica não
estiverem vazios. Agora, criaremos um
método getter para essa propriedade. Por fim, chamaremos o
método de propriedade desativado no botão OK. Em seguida, chamaremos bind no
resultado e passaremos o método get all required inputs are all required inputs are
full chamando
o método nele. Vamos fazer uma pequena correção
nesse método primeiro, ele deve retornar uma associação
booleana. E vamos remover isso, ir atrás dele. Bom. Agora vamos executar nosso
aplicativo novamente. Ok, o botão OK
está desativado por padrão. Se digitarmos algo no campo
do nome da carteira,
ele permanecerá desativado. Mas quando clicamos no
botão Criar, ele é ativado. Ótimo. Vamos fazer nossos testes novamente. Isso deve ter
falhado no teste de criação da carteira porque ainda não
implementamos o código para alterar
o título do aplicativo. Vamos fazer isso no próximo vídeo.
14. 12 Criar nossa primeira carteira parte 5 skillshare 2: Neste vídeo, implementaremos
um recurso que fará com que o aplicativo
carregue a carteira e
mostre seu nome no título do
aplicativo. Depois que o usuário
cria, a carteira. Criará um código que será útil posteriormente, quando
quisermos mostrar recursos de
outras carteiras,
como endereços, na tela. Depois de implementarmos esse recurso, esse teste será aprovado porque o título do estágio será igual
ao espaço da carteira BYOD W, espaço no
painel e nome da carteira. Então, vamos implementá-lo. Primeiro. Vamos até o controlador de criação de
carteira. Em seguida, neste método, criará uma carteira usando
um novo serviço chamado criar serviço de carteira e
um método chamado criar. Passaremos o nome, a
senha e a
semente mnemônica da carteira para o método. Agora vamos criar
a classe de carteira. Vamos adicionar um novo pacote dentro do
BYOD W, chamá-lo de domínios. Dentro dele, adicionará um novo registro
Java chamado wallet. Por enquanto, vamos apenas adicionar um
atributo de string chamado
nome a esse registro. Um registro Java é um
recurso recente da linguagem. Cada atributo de registro tem um getter
e um construtor integrados, então não precisamos adicioná-los. Agora, importe o registro da carteira para o controlador de
diálogo de criação de carteira. Agora, injetaremos o
serviço de criação de carteira nessa classe. E criaremos
essa classe dentro
do pacote de serviços da API. Adicionará a
anotação do componente a essa classe. Vamos injetar esse serviço no construtor
dessa classe. Agora, criaremos
o método de criação dentro do serviço de criação de
carteira. Por enquanto, retornaremos apenas uma nova carteira passando o
nome como parâmetro para o controlador de
diálogo Criar carteira. Agora que criamos,
a carteira publicará um evento que usará a carteira criada
como parâmetro. Esse evento será
ouvido por uma classe para que, quando o usuário
criar uma carteira, o ouvinte atualize
a carteira atual carregada
pelo aplicativo. Vamos injetar o
contexto do aplicativo nessa classe. Agora, vamos criar o evento de carteira
criado dentro do pacote de eventos. Em seguida, chamará o
superconstrutor passando pelo controlador de
diálogo de criação de carteira. E definiremos um
novo campo de carteira, atribuindo o argumento do
construtor da carteira a ele também incluirá um
getter para esse campo. Agora, vamos criar um ouvinte para esse evento chamado
created wallet listener. E vamos criá-lo dentro
do pacote de ouvintes. Ele implementará a classe de ouvinte do
aplicativo com o
evento de carteira criado como parâmetro. Em seguida, implementará o
método no evento do aplicativo. Ele chamará um método
de um novo serviço
chamado serviço de atualização de
carteira atual. Esse método chamado atualização usa a
carteira de eventos como um parâmetro. Vamos injetar esse
novo serviço
nessa classe e
criar o serviço. Vamos adicioná-lo a um
novo pacote de serviços. Dentro da embalagem pegajosa. Em seguida, criará o método de
atualização nele. Também adicionaremos uma
anotação de serviço a ela. Por enquanto, o método de atualização
definirá apenas o nome
da carteira atual com o nome da carteira
recém-criada. Agora, vamos criar um novo pacote
dentro do BYOD W
chamado observáveis. Dentro deste pacote, criará
a classe de carteira atual. Voltar ao serviço de
carteira Update Current
instanciará a
carteira atual em seu construtor. Na classe de carteira atual incluirá a anotação do
componente. Essa classe representará a carteira atual carregada
pelo aplicativo. Cada alteração feita pelo
aplicativo nessa instância de classe aparecerá na interface
gráfica do usuário do aplicativo. Nós o incluímos em um
pacote chamado observable, porque todas as propriedades
dessa classe não serão observáveis. E observável é
um tipo de objeto no qual cada
mudança de estado pode ser ouvida executada por outros objetos. A primeira propriedade observável adicionaremos a ela é o nome. Ele terá o tipo de propriedade de
string simples. Esse tipo implementa a interface
observável e aciona um evento de alteração
quando o valor da string muda. Vamos instanciá-lo aqui. E criaremos um
getter para esse campo. A ideia Intellij identificou que é observável e
criou dois getters. Uma para a propriedade
chamada propriedade do nome e a outra para o valor da
propriedade chamada getName também
criarão um configurador para esse campo para definir o valor da propriedade do
nome. Vamos tornar esse campo definitivo. Também farei um teste para essa classe de
serviço de criação de carteira. Deveríamos ter criado o teste antes de
implementar esse método, já que estamos usando o TDD. Mas considerando que incrementaremos funcionalidade
desse método
quando perdoada. Vamos criar o teste. Agora. Primeiro, criaremos uma propriedade para o serviço de criação de
carteira e instanciaremos dentro
do método de configuração que é executado antes de cada teste. Em seguida, criaremos um teste
chamado should create wallet. Dado que temos um nome, uma senha e uma semente mnemônica. Quando chamamos o
método create
a partir do serviço create wallet
com esses parâmetros. Então, esperaremos que
o nome
da carteira seja igual à variável de
nome. Vamos fazer o teste. O teste foi aprovado. Agora, vamos recapitular
o que fizemos até agora. Quando o usuário clica
no botão OK, o método criar carteira
do controlador de
diálogo de criação de carteira será chamado e
a carteira será criada pelo serviço de carteira. Para fazer isso, ele usa
o método create, usando o nome, a senha e a semente mnemônica que
o usuário escolheu. Por enquanto, esse método
retorna apenas uma nova carteira
com seu nome. Em seguida, passamos a carteira
criada para um novo evento de carteira criada
e publicamos esse evento. Quando isso acontecer,
ele acionará o
método de ouvinte de carteira criado no evento do aplicativo. Ele receberá o evento da carteira
criada como parâmetro. Devemos adicionar a
anotação do componente a essa classe e injetar o serviço de atualização
atual da carteira em seu construtor. Portanto, o método de
evento do aplicativo chamará o método de
atualização do serviço de atualização da carteira atual, passando a carteira do
evento como seu parâmetro. Finalmente, o método de atualização. Definiremos o nome
da carteira atual com o nome da carteira
recém-criada. Agora, vamos voltar ao controlador da janela
principal. Aqui, criará um
método inicializado que será executado antes que a janela principal do
aplicativo apareça. Dentro dela, adicionará um ouvinte à propriedade
atual da carteira. Vamos injetar a
carteira atual nessa classe primeiro. Dentro do
método ad listener, passará um retorno de chamada que usará três parâmetros e um valor observável e antigo, e um novo valor no corpo
do retorno obterá o estágio do Windows e atribua-o à variável de estágio. Devemos lançar seu tipo para o palco. Em seguida, definiremos seu título
como BYOD W wallet space, dash space, new value. A nova variável de valor contém o novo valor do nome
da carteira atual. Sempre que o nome da
carteira atual mudar, essa alteração será ouvida
por esse retorno de chamada e o título do palco também
mudará para a frase que
acabamos de dizer. Vamos executar o aplicativo
para verificar se isso funciona. Criaremos uma nova carteira
com o teste de nome, depois uma semente mnemônica e clicaremos em “
Ok, ótimo, funcionou”. A mudança do título da janela
para BYU OWL é um teste de traço. Vamos criar outra carteira com um nome diferente para
ver o que acontece. Como esperado. Ele foi alterado para corresponder à carteira
recém-criada. Agora, vamos fazer todos os nossos testes. Ótimo. Todos os testes foram aprovados. Bom trabalho.
15. 13 Criar nossa primeira carteira parte 6 skillshare 2: Neste vídeo, começaremos a implementar um recurso
que nos permitirá criar endereços que serão usados posteriormente para receber Bitcoins. A primeira coisa que faremos é
criar a guia Receber. Essa guia conterá os endereços derivados
de nossa carteira. Então vá para o arquivo FXML da
janela principal. No Scene Builder
incluirá uma caixa V no centro
do painel de borda. Dentro da caixa V
incluirá um painel de abas. Excluirá a segunda guia que foi criada automaticamente. Altere o texto
das guias restantes para receber. Dentro do menu de
configuração do VBox definirá a altura pref para 300. Dentro da guia Receber
incluirá um painel de grade. Por alguma razão, não
podemos incluir um painel de grade em uma guia
usando o Scene Builder. Não tem problema. Faremos isso
usando o editor de texto. Em vez disso. Incluiremos um rótulo. Seu texto será igual
ao endereço de recebimento. Dentro, ele adicionará algumas
tags para definir suas margens. Agora, incluiremos um campo de texto. Não será editável. Ele terá 350, conforme
sua largura preferida. E seu índice de coluna
será igual a um, incluirá as mesmas tags de margem do painel de
grade que usamos anteriormente. O Construtor de cenas
não está mais funcionando devido ao painel de grade que
incluímos na guia. Não tem problema. Veremos a
aparência do aplicativo ao executá-lo. Ótimo, nossa carteira
agora está pronta para receber um endereço nesse novo
campo que acabamos de criar. Dentro do teste de criação de
carteira,
incluirá um código para verificar
se um endereço foi criado e inserido
no campo de endereço de recebimento
após a criação da carteira. Então, depois que o teste
clicar no botão OK, ele clicará
na guia Receber. E o teste pesquisará
o conteúdo
do campo de endereço de recebimento e armazenará na variável de
endereço. Em seguida, o teste afirmará que, se o endereço não for conhecido, vamos fazer o teste
para ver o que acontece. O teste falhou conforme o esperado. Agora, vamos fazer uma
refatoração e
o arquivo FXML da janela principal. Vemos agora que nosso arquivo
FXML principal está ficando maior É melhor criar
um novo arquivo FXML somente para a guia de recebimento, qual a janela principal se
referirá posteriormente. Então, vamos criá-lo. Vamos chamá-la de guia Receber ponto FXML copiará todo o conteúdo da guia para
a guia Receber ponto FXML. A única alteração que
faremos é na tag da guia. Vamos mudá-lo para
f x cólon root. Em seguida, usaremos a classe tab
como atributo de tipo. Também precisamos incluir o
atributo Meta XML e S colon FX. Agora vamos importar as outras tags. De volta à janela principal, o ponto FXML excluirá a tag da guia
e todo o seu conteúdo. Incluirá a tag
Receive tab controller, que será criada agora. Vamos criá-lo dentro
do pacote de controladores. E vamos importá-lo dentro
do ponto FXML da janela principal. Voltar à
guia Receber, o controlador adicionará a
anotação do componente a essa classe. Criaremos um construtor
passando um recurso com
uma anotação de valor apontando
para a guia Receber. O arquivo FXML também
passará o contexto do
aplicativo. Aqui, configuraremos uma nova instância do carregador
FXML com parâmetros semelhantes aos que
usamos para os
outros controladores. Em seguida, configuraremos seu
controlador para isso. Também definiremos seu
caminho para isso. Em seguida, chamaremos o método de
carregamento nele. Ok, precisamos fazer
mais uma coisa para que funcione. Dentro da classe gooey
started listener, adicione o código a seguir aqui. Esse código é necessário para informar ao Java FX como criar componentes
personalizados, como o controlador da
guia Receber, quando ele vê dentro dos arquivos FXML. Esse código fará com que o Java FX use o contexto para
obter o método bean para criar um componente
ao ver uma tag controladora da guia Receive. Portanto, sempre que o Java FX precisar criar uma tag controladora da
guia Receive, ele usará a classe do
controlador da guia Receive para criá-la. Para outras tags, ele usará
o construtor Java FX padrão. É isso mesmo. Agora, o Java FX sabe como criar nossa
nova tag FXML personalizada. Vamos executar nosso aplicativo
para verificar se tudo está indo bem. ***** e ocorreu um erro. Está dizendo que
o controlador raiz não é uma instância de guia. Eu sei como consertar isso. Devemos fazer com que o controlador da guia
Receber estenda a classe TAP. Agora, vamos ver se funciona. Ok, está funcionando
exatamente como antes. Portanto, quando criamos uma nova carteira, esperamos que o campo do
endereço
de recebimento seja preenchido com o
novo endereço Bitcoin. Nos próximos vídeos, entenderemos o
processo de derivação de um endereço Bitcoin e implementaremos esse recurso
em nossa carteira. Veja, sim.
16. Endereços Bitcoin e carteiras HD: Neste vídeo, aprenderemos sobre carteiras
HD e endereços
Bitcoin. Então, o que é um endereço Bitcoin? Um endereço bitcoin é uma palavra
que codifica uma chave pública, o hash de uma
chave pública ou um hash de script. Ele é usado para receber
bitcoins em uma transação. Para receber Bitcoins por meio de
uma transação de Bitcoin, você mostra seu endereço
para outra pessoa que essa pessoa possa enviar
bitcoins para o seu endereço. Existem vários tipos
de endereços Bitcoin e as regras para
gerá-los estão em muitos VIPs, como VIP, VIP 3d2 e BIP 44. Agora vamos falar sobre carteiras HD. As carteiras Hd representam carteiras
determinísticas hierárquicas. Eles são hierárquicos
porque são compostos de vários níveis de chaves e determinísticos
porque uma única semente
sempre gerará os mesmos
endereços e chaves privadas. E a carteira HD é um tipo
de carteira em que, a partir de uma única semente, os blocos de derivação são usados para derivar chaves privadas, chaves
públicas e endereços. As especificações das carteiras Hd
foram originalmente definidas no BI P32 com outros BIPs estendendo
essa especificação. Agora vamos recapitular um slide da
nossa última apresentação de ppt. Nesta apresentação, aprendemos como gerar uma semente mnemônica. E mencionamos
que combinando uma semente mnemônica com uma frase secreta
opcional, poderíamos gerar
uma semente raiz usando o algoritmo P vk df two. A partir dessa raiz,
poderíamos gerar chaves privadas, chaves
públicas e endereços. Nesta apresentação,
aprofundaremos os detalhes
dessa última parte sobre como chaves e
endereços privados e
públicos são gerados
a partir de uma semente raiz. Então, começando com uma semente raiz, que tem 512 bits de tamanho, aplicando o algoritmo de
hash HMAC SHA-512 a ela, obtemos a chave mestra, que também tem 512 bits
da chave mestra. Ao aplicar a função CKD, que significa derivação de chave
secundária, podemos obter diferentes chaves
estendidas
usando índices diferentes como parâmetros. Se n for o índice
dessa função, então n pode variar de 0 a 2 à
potência de 32 menos um. Cada chave estendida pode gerar mais chaves estendidas usando a função CKD e, portanto, ser a mãe de muitas chaves
secundárias. Esse esquema de derivação permite
a formação de uma árvore de chaves com um
número indefinido de gerações. Vamos ver mais detalhes
sobre as funções do CKD. Há dois tipos
de chaves estendidas. Elas podem ser chaves
privadas estendidas
ou chaves públicas estendidas. E a chave privada estendida cuja versão serializada
começa com x PRV, ou outra letra mais PRV é gerada usando a função privada
CKD. Se o índice
passado para essa função for igual ou maior que
dois elevado a 31, então é uma derivação endurecida. E disse que a chave privada
estendida gerada é uma criança endurecida. As chaves reforçadas têm recursos de segurança
adicionais que explicaremos em resumo é possível gerar uma chave pública estendida
usando a função pública CKD. Chaves públicas atendidas,
quando serializadas, começam com x pub ou outra letra mais pub. Também é possível
gerar uma chave
pública estendida a partir de outra chave pública estendida
usando a função pública CKD Duas derivações não são possíveis. Gerar uma chave privada
estendida a partir de uma chave pública estendida e uma chave pública
estendida reforçada a partir de uma chave pública estendida. Então, como passamos de chaves
estendidas para endereços? Começando com uma chave privada
estendida, extraímos uma
chave privada dela. Uma chave privada faz parte de
uma chave privada estendida. Portanto, essa extração é
uma operação simples. Então, por meio de uma operação chamada
multiplicação de curva elíptica, geramos uma
chave pública a partir de uma chave privada. Finalmente, ao fazer o hash e
codificar a chave pública, obtemos um endereço Bitcoin. Existem diferentes tipos
de hash e codificação de chaves
públicas para produzir
diferentes tipos de endereços. Aprenderemos mais sobre essas operações nos
próximos vídeos. Também usamos chaves privadas para produzir
assinaturas de transações transferir Bitcoins
para outros endereços. As assinaturas de transações são produzidas usando o algoritmo de
assinatura digital Elliptic Curve ou ECDSA. Você também pode gerar endereços com uma chave pública
estendida. Você faz isso
extraindo a chave pública dela. Em seguida, um endereço bitcoin
é gerado
a partir da chave pública
por meio de hash e codificação, conforme explicado anteriormente. Lembre-se de que uma chave
pública não pode ser convertida em uma chave privada. Portanto, ele não pode ser usado para assinar transações e
transferir Bitcoins. Agora, vamos entender o
conceito de caminhos de derivação, começando com a chave mestra, que tem a profundidade de zero
em uma árvore de chaves estendidas. Ao derivar uma chave
estendida passando zero como argumento
para uma função CKD, obtemos uma
chave estendida com uma profundidade de um. Repetindo o processo com a chave estendida
recém-gerada, obtemos uma
chave estendida com uma profundidade de dois. Em seguida, podemos repetir o processo, passando um como
índice e obtendo uma chave estendida com
uma profundidade de três. Dessa última chave estendida, podemos extrair uma
chave pública e um endereço. Diz-se que esse endereço tem um caminho de derivação de
zero barra zero barra um porque, nesse caso,
o índice é usado para derivar a chave estendida que
gerou esse endereço. Aplicando o mesmo raciocínio. Neste outro exemplo, obtemos um endereço
com um
caminho de derivação de uma barra
zero barra dois. Este outro exemplo
mostra que você pode usar outros números como índices para funções CKD em qualquer chave
estendida em uma árvore de chaves, permitindo a geração de um número quase infinito de caminhos e endereços de derivação. Este outro exemplo
mostra a geração de um filho endurecido usando uma
única aspa após o índice Podemos representar
índices que geram filhos
endurecidos em
um caminho de derivação. Zero seguido por uma única aspa representa o primeiro índice
endurecido, que é dois elevado
a 3011, seguido por uma única aspa é o segundo
índice de endurecimento e assim por diante. Essa notação é usada para
facilitar a descrição de um caminho de derivação para que possamos usar números pequenos
para descrevê-lo. É importante acrescentar isso. Para gastar Bitcoins
de um endereço, é
necessário produzir
uma chave privada com o mesmo caminho de derivação
usado para derivar esse endereço. Assim, você pode usar as funções
públicas do CKD para produzir
chaves e endereços públicos estendidos. Mas, para gastar fundos
com esses endereços, você deve usar as funções
privadas do CKD para produzir
chaves privadas e chaves privadas estendidas. Outra característica das carteiras
HD e de seus caminhos de derivação é sua relação com
a função de morte. Cada nível em uma árvore de teclas
recebe uma função. Bi P32 define a profundidade, um representa a profundidade das contas duas cadeias diferentes, e a profundidade,
três endereços diferentes. O Bip 44 veio com diferentes definições
que são mais usadas hoje em dia na
maioria das carteiras HD. De acordo com uma profundidade de 44, uma tecla estendida
endurecida
representa propósitos diferentes. Chaves de profundidade para endurecer
diferentes tipos de moedas, três
chaves reforçadas de
profundidade, contas diferentes. profundidade para define se os
endereços
descendentes devem ser usados para alteração
não são booleanos e a morte cinco representa endereços
diferentes. Para entender melhor como
isso funciona na prática, vamos ver alguns exemplos de caminhos de derivação e
suas funções. E abordado com um
caminho de derivação de 84 aspas
barra barra zero barra zero barra zero tem o propósito de
encontrar um BIP A14. Vip 84 define que
os endereços com uma finalidade de 84 devem ser endereços P2 WP k h, que significa pagar para testemunhar endereços hash de chave
pública. Falaremos sobre
diferentes tipos de endereços detalhadamente
nos próximos vídeos. Mas, em resumo, P2, WP k, h, também conhecido como segue, os endereços
nativos são
o tipo de
endereço mais comum nas carteiras modernas mais
atualizadas. Esse endereço também tem um tipo de
moeda com cotação zero, o que significa que é
um endereço Bitcoin. Ele também tem uma conta zero, o que significa que faz parte
da conta do primeiro usuário. Mudou. O índice está definido como zero, o que significa que não é
um endereço de alteração. Finalmente, seu
índice de endereço é zero, o que significa que é o primeiro
usuário a receber endereço. O próximo exemplo tem um caminho de derivação semelhante
ao exemplo anterior, exceto que seu índice de
endereço é um. Portanto, é o segundo endereço de recebimento
nativo Bitcoin segue da primeira conta do usuário, aplicando o mesmo raciocínio. O terceiro exemplo é o primeiro endereço de mudança
nativo Bitcoin segue da primeira conta do usuário. O índice um em profundidade quatro indica que é
um endereço de mudança. O último exemplo é
semelhante ao primeiro,
exceto que seu propósito
é 49 sem aspas. Vip 49 define que os endereços
com essa finalidade devem ser P2 WP k-th aninhados
em endereços SSH P2. Se isso parecer
complicado, não se preocupe, aprenderemos detalhes sobre
isso nos próximos vídeos. Agora, vamos fazer uma visão geral
dos recursos do HD Wallet. Com carteiras HD,
podemos gerar facilmente um número quase infinito de endereços a partir de uma única semente. Isso é ótimo, pois podemos evitar reutilização de
endereços e a
perda de privacidade. As carteiras HD também permitem
uma estrutura de várias contas,
na qual a chave privada estendida dos pais tem acesso aos principais fundos de seus
filhos, mas os filhos podem
transferir os fundos dos pais. Esse esquema pode ser útil casos como proprietários de empresas que têm acesso às chaves infantis dos
departamentos da empresa. Outro recurso útil
que as carteiras HD permitem é a criação
de carteiras somente para relógios cujos endereços podem
ser gerados e seus fundos auditados usando
apenas chaves públicas estendidas, mas onde nenhum fundo pode. ser movido , pois nenhuma transação
pode ser assinada. Outro recurso do HD Wallet
é a possibilidade de gerar outros endereços
de
criptomoedas a partir da mesma semente mnemônica. Uma lista de diferentes índices de tipos de
moedas é descrita no slip 44, um
sistema de proposta semelhante ao BIP da Satoshi labs, a empresa
responsável pela treliça ou carteira. Outro recurso das carteiras HD é
que seus endereços e chaves
privadas podem
ser reconstruídos com suas sementes e caminhos
de derivação. Isso permite que você importe uma semente mnemônica e uma
senha em uma carteira compatível para recuperar todos os seus endereços
e chaves privadas. A compartimentação de segurança é outro recurso interessante
das carteiras HD. Se uma
chave privada estendida vazar por acidente, isso afetaria apenas
os fundos bloqueados nos endereços descendentes
da chave vazada. Os fundos trancados nas chaves dos pais ou
irmãos estariam seguros. Finalmente, as carteiras HD facilitam a geração e a organização de
diferentes tipos de endereços Bitcoin. Agora vamos ver por que
chaves reforçadas são necessárias. Durante o desenvolvimento do HD Wallet, descobriu-se que se uma chave pública estendida e uma chave privada secundária
não Hodgkin do próximo nível vazassem, isso
equivaleria a vazar chave privada estendida aparente. Isso pode levar à
perda de fundos para cada endereço descendente da chave pública
estendida que vazou. Portanto, a derivação do perdão
foi criada para evitar que essa exploração aconteça
em uma conta e em profundidades mais baixas. Por fim, vamos discutir
como implementaremos o
esquema de derivação de endereços em nossa carteira. Usaremos o
caminho de derivação 84 aspas
barra barra zero barra zero para gerar nosso primeiro endereço de
recebimento. Depois de receber Bitcoins,
o próximo endereço de recebimento será alterado aumentando
o índice de endereços em um. Portanto, os próximos
endereços de recebimento terão índices
de
endereço de 123 e assim por diante. Isso nos impede de usar o mesmo endereço para receber
Bitcoins mais de uma vez. Usaremos o
caminho de derivação 84 aspas barra, barra, barra, barra, uma barra zero para gerar nosso primeiro endereço de
alteração. Depois de enviar Bitcoins
e receber uma alteração, o
endereço da próxima alteração é alterado
aumentando o índice de
endereços em um. Da mesma forma que faremos
para receber endereços. Você pode perguntar por que evitar a reutilização de
endereços é importante por dois motivos principais. Primeiro, ao fazer isso, aumentamos nossa privacidade. Ao fazer isso, se um terceiro descobrir que um
endereço pertence a nós, essas informações não serão
replicadas em outros endereços
que usamos. O outro motivo é a segurança. Se, por algum motivo,
a chave privada um endereço vazar, isso
afetará somente esse endereço. O provérbio que diz: não coloque todos os ovos na mesma
cesta se aplica aqui. Dito isso,
implementaremos o esquema de derivação
gerando primeiro a chave
pública estendida com um caminho igual a 84 aspas, barra zero, barra zero, barra zero,
para receber endereços. E a chave pública estendida com um caminho igual a 84 aspas barra barra zero barra
um para alterar endereços. Em seguida, obteremos
chaves públicas e endereços
estendidos para seus filhos . Ao fazer isso,
gerará todos os endereços de que precisamos sem expor nenhuma chave
privada à memória. Portanto, nossa principal
política de segurança é evitar a exposição de sementes e chaves privadas à memória, tanto quanto possível. Nossas chaves privadas serão derivadas somente ao assinar
transações usando os mesmos
blocos de derivação usados para produzir os endereços dos quais essas transações estão
gastando Bitcoins.
17. 15 Criar nossa primeira carteira parte 7 skillshare 2: Neste vídeo,
criaremos as chaves públicas estendidas que carteira precisará para
criar endereços. Como vimos no vídeo mais recente, nossas carteiras inicialmente
precisarão de chaves estendidas, que serão a chave estendida para endereços de recebimento de segmentos e a chave estendida para endereços
de mudança seguinte. Primeiro, vamos corrigir alguns
problemas com nossos testes de GUI. Se você tentar executar o teste de
criação de carteira, agora você verá
que ele funcionará. Isso se deve em parte a uma instanciação prematura de nossa nova classe de
controlador da guia Receber. Para corrigir isso, crie
um novo pacote chamado Config dentro do pacote de teste
BYOD W. Em seguida, crie uma nova
classe chamada test lazy, que contém uma
configuração IP. Essa classe implementará o Bean Factory. O pós-processador implementará esse
método necessário com esse código. Esse código fará com que todas as classes durante os testes sejam
inicializadas lentamente. Há outro código que devemos
adicionar em nosso
teste
de criação de carteira para que ele funcione. Adicionaremos ao
carregador FXML no método start,
a mesma
fábrica de construtores que definimos em nossa classe de
ouvinte iniciada pela GUI. Agora vamos executar nossos testes de GUI. Ótimo. Agora os testes estão funcionando. Vemos que somente eles
deveriam cancelar os testes aprovados e nos outros
ainda temos que fazer com que sejam aprovados. Agora, vamos continuar adicionando as
chaves públicas estendidas à nossa carteira. A primeira coisa que
faremos é ajustar nosso teste
de serviço de criação de carteira passar por uma
semente mnemônica válida para essa variável. Você pode obtê-lo na página
Projeto e Recursos. Em seguida, verificaremos se a carteira criada tem chaves públicas
estendidas. Afirmará se tem duas chaves públicas
estendidas, já que cada carteira terá uma chave pública
estendida para receber endereços e uma chave
pública estendida para alterar endereços. Agora, adicionaremos uma lista de chaves públicas
estendidas
ao registro da carteira. Vamos criar nossa classe
estendida de chaves de pub. Ele terá uma chave e um tipo. Vamos adicioná-los a um construtor. Ambas as propriedades
terão um getter. Agora, criaremos uma classe de
configuração de endereço. Primeiro, vamos criar
um novo pacote de configuração
dentro do pacote da API. Em seguida, criaremos a classe
de configuração de endereço nela. Adicione a
anotação de configuração a ela. Essa anotação é necessária para que o Spring Boot inicialize todos os objetos definidos
nessa classe durante a inicialização do
aplicativo. Agora, criaremos uma
classe de domínio chamada configuração de endereço. Na verdade, será um recorde. Ele terá um tipo de endereço
e o caminho de derivação. Em seguida, crie uma enumeração chamada tipo de
endereço
no mesmo pacote. Ele terá dois tipos, segmentar e seguir com alteração de
sublinhado. Agora, de volta à classe de
configuração de endereço. Criaremos um feixe para o endereço do
nosso segmento. No Spring Boot, um bean
é apenas um objeto que pode ser injetado em
outras classes de projeto. Instanciará esse bean
com esses parâmetros. E adicione a
anotação Bean a esse método. Passar a string do segmento como seu parâmetro duplicará esse método e o modificará para ser nossa configuração de endereço de alteração Altere o
parâmetro de anotação do Bean para seguir a alteração. O nome do método será
segue change config. O tipo de endereço
será definido como mudaria. E o caminho de derivação
terá um índice de mudança de um. Agora, usaremos essas
configurações em nosso serviço de criação de carteira. Então, vamos injetar uma lista de configurações de endereço nessa classe. Ao fazer isso, o Spring
Boot
identifica automaticamente que há dois beans com o tipo de configuração de
endereço e injetará
ambos nessa lista. Agora, no método create criará uma variável de
semente mnemônica. Primeiro, alteraremos o
parâmetro do método de semente
mnemônica para a
sequência de sementes mnemônicas e, em seguida, instanciaremos um objeto de semente mnemônica passando a string de semente mnemônica
como seu parâmetro. Em seguida, criaremos uma chave mestra, que é um tipo de chave privada
estendida. Para fazer isso, chamaremos o método de semente mnemônica
para a chave mestra e passaremos a senha e essa
constante como seus parâmetros. Mas primeiro, precisamos atualizar nossa versão Bitcoin Java para 0,3,
0,0 no arquivo POM. Vamos fazer isso. Agora. Clique em Carregar as alterações do Maven de
volta para o método de criação. Agora, ele nos permite importar
a constante principal do prefixo de rede passará seu
prefixo privado como parâmetro. Agora vamos adicionar esse código e,
em seguida, explicarei
o que ele faz a seguir. Esse código começa a converter a
lista de configuração de endereços em um fluxo. Em Java oito ou superior, os
fluxos são usados para aplicar operações
funcionais a
uma coleção de dados. Nesse caso, cada configuração de
endereço
da lista está sendo passada
para essa função lambda, que usará a chave
pub estendida que o serviço de chave pub
criará ao lado de retornar um objeto de chave pub
estendida. Cada
chave de pub estendida devolvida será coletada em uma lista que será armazenada
na variável de chaves de pub estendidas e, em seguida, passará a
lista de chaves de pub
estendidas para a carteira devolvida. Agora, vamos injetar o
serviço estendido de chaves de pub nessa classe. Teremos que criá-lo. Agora podemos adicioná-lo
ao construtor. Agora criará
seu método de criação. Ele retornará uma chave de pub
estendida. Seguindo o TDD. É hora de criar um
teste para esse método. Vamos fazer isso. Irá criá-lo dentro
do pacote da API de teste. Ele deve estender a classe de
especificação. Vamos instanciar o serviço estendido de chaves de
pub aqui. Também precisamos adicionar esse trecho de código ao método de configuração. E criaremos um teste chamado should create extended key. Quando recebe uma semente mnemônica e uma chave mestra
derivada dela. Quando chamamos o método
create
do serviço estendido de pub key. Então, esperamos que a
chave de pub estendida
criada seja igual à chave de pub estendida
esperada. Ok, então como vamos criar
essas variáveis em cinza? Vamos passá-los usando a cláusula
where como esta. Você pode perguntar: onde
consegui esses valores? Eu os comprei no site de treonina EN Coleman io slash pip. Este site é muito
útil para gerar muitos tipos de
chaves e endereços estendidos. Vou copiar e colar
essa semente mnemônica no campo BIP 39 do site para
demonstrar como ela funciona. Imediatamente após
colarmos a semente mnemônica, a ferramenta calculou a chave mestra da semente
raiz e as chaves
estendidas para mostrar o BIP AT derivado
para chaves estendidas, clique nesta guia. Vemos que a chave de pub
esperada e o teste são iguais a esse
valor no site. Ao aplicar a função CKD a essa chave pública estendida com números
diferentes, pois
os índices
obterão posteriormente chaves
públicas estendidas, cujas chaves públicas
extraídas
serão usadas para gerar recebendo endereços
usando o mesmo site que criei para mais casos de teste. Vou colá-los aqui e
ajustar a formatação. Os dois últimos
casos de teste gerarão chaves de pub
estendidas que serão usadas para gerar endereços de
alteração. Você pode copiá-los dos recursos deste
vídeo ou criar seus próprios casos de teste usando
o site de Ian Coleman. Usando a cláusula where, o mesmo teste será executado para cada parametrização
que criamos. Vamos fazer o teste. O teste falhou conforme o esperado. Agora vamos implementar o método. Primeiro. Criaremos um mapa aqui
que não abordará tipos de prefixos de chaves de
pub estendidas. Ambos os tipos de endereço serão mapeados para o mesmo prefixo do
segmento de rede principal. Ao fazer isso,
facilitamos a extensão dessa funcionalidade se precisarmos adicionar mais
tipos de endereçamento posteriormente. Agora, no método create retornará uma nova chave pub
estendida. passagem desses parâmetros
passará o retorno do
método CKD da chave mestra, que seguirá um caminho
de derivação. Falso, pois não é uma chave privada estendida e o prefixo
do tipo de endereço. Em seguida, serializaremos o resultado. E o segundo argumento estendido da chave
pub será o
tipo de endereço e a forma da string. Por fim, não nos esqueçamos de adicionar a
anotação do serviço aqui. Agora, vamos executar o teste estendido do serviço
pub key novamente. Ótimo, todos eles passaram. Agora vamos executar nossos testes do serviço de criação de
carteira. Mas primeiro, vamos fazer algumas
mudanças nesse teste. Devemos adicionar o provedor
de segurança, necessário para
que as
funções de criptografia Bitcoin Java funcionem. Também precisamos definir os argumentos corretos
para o serviço. Vamos criar as configurações de endereço e o serviço estendido de chave
pub. Agora vamos executá-lo. Ótimo, os testes foram aprovados. Isso significa que nossa carteira
foi criada com uma lista de chaves
públicas estendidas de tamanho dois. Opa, o
índice de mudança aqui é um. Isso não afetará esse
teste, pois estamos apenas afirmando que a carteira
precisará estender as chaves do pub. Mas vamos mudá-lo para um
por uma questão de correção.
18. 16 Criar nossa primeira carteira parte 8 skillshare 2: Neste vídeo,
criaremos um vestido para cada chave de pub estendida
que a Wallet fabrica. Para fazer isso, cada chave de pub
estendida
será passada para o método de vestidos
gerado, que será criado agora. Esse método definirá uma lista de endereços para o registro
estendido da chave pub. Vamos criar esse centro. Essa lista de endereços
será criada por um novo serviço
gerador sequencial de endereços que será criado. Ele usará um
método de geração que usará a chave pub estendida e
o tipo de chave pub estendida. O serviço
gerador sequencial de endereços terá esse nome porque gerará vestidos com
um índice crescente de
derivação de endereços. Vamos injetar o gerador
sequencial de endereços nessa classe e criá-lo. Agora, vamos criar
seu método de geração que retornará uma
lista de endereços. Vamos criar o registro de endereço. Esse registro terá
um campo de endereço e um campo de índice. Vamos ajustar o método de definição de
endereços a
partir da tecla pub estendida. Ele pegará uma lista de
endereços e definirá o campo estendido de
endereços das chaves de pub. Vamos criar um teste para a classe
geradora sequencial de endereços. Por enquanto, seu método
retornará nulo. A classe de teste estenderá
a classe de especificação. Criaremos um teste chamado
deve gerar 20 endereços, usaremos o
gerador sequencial de endereços no bloco de vento. Então, vamos adicioná-lo como um
campo a essa classe. Quando o método generate é
chamado com esses parâmetros, essa é uma
chave pública estendida no tipo de segmento. Então, esperamos que
a devolução dessa lista de
vestidos tenha um tamanho de 20. Você pode copiar a chave pública
estendida
desse teste dos recursos desta
lição. Vamos instanciar o gerador sequencial de
endereços no método de configuração
e executar o teste. Falhou conforme o esperado. Agora, vamos implementar que o serviço declarará uma chave de pub
estendida. Em seguida, dentro de um bloco try
catch, serializará o parâmetro da chave
recebida. O
método serializado ANS transforma a chave pub estendida no objeto de chave pub estendida
do Bitcoin. Java então envolverá a IOException em
uma exceção de tempo de execução
no bloco de captura. Agora, usaremos o método
de alcance da
classe de fluxo de pulmões para passar de zero a uma variável de número inicial de endereços
gerados
que será definida posteriormente. Vamos injetar essa
variável nessa classe. No construtor, definirá uma anotação qualificadora
para essa variável, que terá o mesmo nome de
variável como parâmetro, mudará seu tipo para hint, mapeará cada índice e chamará o método de geração de
endereço. Portanto, para cada índice, chamaremos o método generate
address, passando o retorno do método Get de fábrica
do gerador de endereços, a chave pub estendida e o
índice como seus parâmetros. Por fim, converteremos
o resultado em uma lista. Vamos criar o método de geração
endereçada. Será necessário um
gerador de endereços, uma chave de pub
estendida e um índice. O gerador de endereços
será passado de uma fábrica de
geradores de endereços, que será injetado
nessa classe e criado agora. Vamos mudar o
parâmetro de tipo para o tipo de endereço. Agora vamos criar o método Get de fábrica do
gerador de endereços . Ele retornará uma interface de
gerador de endereços que
agora retornará ao método
generate address a
partir do gerador
sequencial de endereços. Primeiro, derivaremos uma chave
secundária estendida
da chave pub estendida
usando o método CKD. Esse método aplicará a função de
derivação de chave secundária que aprendemos há dois vídeos. Será necessário um índice que
definirá o índice de
derivação da criança. Agora retornará um
novo registro de endereço. Ele obterá o resultado
do método de geração
do gerador de endereços. Esse método pegará
a chave secundária estendida e derivará um endereço dela. O segundo parâmetro de endereço
será o índice. Agora, adicionaremos o método
generate à interface do
gerador de endereços. Agora implementaremos
o método get fábrica
do
gerador de endereços. Ele retornará o resultado
do GetMethod de um mapa gerador de
endereços. Essa variável será
um campo nessa classe e será inicializada
nesse construtor de classe. Será um mapa de cadeias de caracteres como chaves e
geradores de endereço como valores. No construtor, passará um
serviço gerador de endereços de segmento, que será criado. Em seguida, mapearemos cada tipo de endereço para o gerador de
endereços do segmento. No mapa do gerador de endereços. O
gerador de endereços do segmento
implementará a interface do
gerador de endereços. Vamos criar o método de
interface necessário. Antes de implementá-lo,
vamos criar seu teste. Isso estenderá a classe de
especificação. Instanciará o gerador de
endereços do segmento aqui. No método de configuração, adicionaremos o provedor de segurança,
assim como nossos outros
testes que precisam dele. Em seguida, criaremos o que deve gerar um teste de endereço de segmento. No bloco fornecido,
criará uma chave pub estendida usando a
classe de chave pub estendida no método serializado. O método serializado
usará uma string de chave pub estendida, que passará
no bloco where. Em seguida, criaremos uma creche
estendida chamando o método CKD na variável pub key
estendida. Para este método, passará um parâmetro de índice que
passará pelo bloco da web. Quando o método de geração do
gerador de endereço de segmento é chamado com a chave secundária
estendida. Então, esperamos que
o endereço de devolução seja igual ao endereço
esperado. Agora, vamos usar o bloco
where para inicializar as variáveis em cinza Vamos usar dados de teste que eles
retiraram do
site da E and Coleman para isso. Você pode copiar esses parâmetros dos recursos desta lição. Vamos fazer o teste. Falhou conforme o esperado. No próximo vídeo, aprenderemos mais sobre como
assinar quais endereços. Em seguida, no vídeo
seguinte,
implementaremos o gerador de endereços de segmentos e o gerador de
endereços sequenciais
e sequenciais faremos com que seus testes sejam aprovados.
19. Entendendo os endereços do Segwit e introdução aos ambientes de rede do Bitcoin: Nesta apresentação,
aprenderemos mais sobre os endereços do
segmento Bitcoin, que será o tipo de endereço
padrão que nossa carteira fornecerá. Então, o que é uma
sequência de Bitcoin, qual endereço? Os endereços de segmento
também são conhecidos como endereços
nativos segue para 32 endereços, endereços versão zero do
segmento
ou endereços P2 WP k-th, onde P2 WP k h significa pagar
para testemunhar o hash da chave pública. Cada um desses termos é usado
para se referir à mesma coisa. Era o
tipo de
endereço Bitcoin mais atualizado até novembro de 2021. Depois de novembro de 2021, quando a atualização taproot foi ativada
na rede Bitcoin, um novo tipo de endereço Bitcoin
chamado endereço taproot,
também conhecido como endereço segue versão um
, tornou-se disponível. Por enquanto, vamos nos concentrar no endereço
do segmento, cuja maioria dos endereços
segmentados de suporte de carteiras modernas se tornou disponível em 2017 na rede Bitcoin após a atualização de
testemunhas segregadas. Opcionalmente, essa atualização permitiu transações
menores,
já que a parte
dessas transações mais recentes,
chamada de testemunha, é enviada separadamente e não está
incluída no blockchain. As regras para gerar endereços de
segmentos estão
descritas no VIP
one-seventh three e também são
implementadas em métodos da biblioteca
Bitcoin Java. Os endereços dos segmentos permitem que os remetentes de
Bitcoin paguem as taxas mais baratas
por transações comuns. A razão para isso é porque as transações que enviam
bitcoins para endereços de segmentos são efetivamente menores
em comparação com transações enviadas para
outros tipos de endereços. Mas aprenderemos
mais detalhes sobre transações de
Bitcoin
em vídeos futuros. Como
os endereços de segmentos são bem suportados pela maioria das carteiras modernas
e porque nos
permitem enviar transações
mais baratas, nós os definiremos como o tipo de
endereço padrão de nossa carteira. Agora, vamos recapitular
um slide
da apresentação anterior
sobre teclas estendidas. Nesse vídeo, aprendemos que poderíamos
obter uma chave pública a
partir de uma chave privada estendida
ou de uma chave pública estendida. Então, ao fazer o hash e
codificar a chave pública, poderíamos obter um endereço. Agora, vamos ver
mais detalhes sobre esse processo de hash e
codificação. Começando com uma chave pública obtida conforme explicado
anteriormente, aplicando as funções de
hash criptográficas SHA-256 e 160 à direita à chave pública, obtemos um hash de chave pública
com um tamanho de 20 bytes. O SHA-256, combinado
com o
160 do lado direito , é chamado de algoritmo
hash 160. Finalmente, o hash da chave pública, combinado com um prefixo
e uma versão numérica, gera um endereço de segmento
por meio da codificação Beck 32. codificação Back 32 é reversível pelo processo chamado decodificação
Beck 32. Ao criar transações,
devemos decodificar 32 endereços em hashes de chave
pública antes de incluí-los
nas saídas da transação. É por isso que esse
tipo de endereço também é chamado de pay to witness. O
hash de chave pública revisitará esse tópico com mais
detalhes ao falar sobre transações para endereços de
segmentos. Quando o Beck 32 codifica hashes de chave
pública, a versão é definida como zero quando o prefixo é definido como
BC unnamed net. Falando sobre a rede principal, vamos rapidamente ter uma visão geral dos ambientes de rede
Bitcoin. Cada um desses ambientes
é uma rede separada com blockchains e
propósitos
diferentes, mas com regras semelhantes. A rede Bitcoin pode ser chamada de rede principal do
Bitcoin. É onde os
bitcoins têm valor. O blockchain é imutável e a dificuldade de mineração
é a maior. O ambiente da rede de teste é semelhante à rede principal, mas tem uma menor dificuldade de mineração e onde os bitcoins não têm valor, ele é usado para fazer testes
em um ambiente em que os nós interagem enquanto mantendo
um blockchain compartilhado. Test Net teve versões
diferentes desde que foi criado com
diferentes blockchains. Finalmente, o ambiente de
teste de registro é uma
rede individual que pode ser executada por qualquer usuário do node Bitcoin com um blockchain não
compartilhado com outros. Os blocos podem ser
gerados instantaneamente, sem esforço e
livremente pelo usuário. Ele é usado para fazer testes mais rápidos
e automatizados em um ambiente controlado. Os endereços em cada rede têm prefixos
diferentes e são válidos somente em seus
ambientes. Para
endereços de segmentos, esses C são o prefixo usado para
vestidos vermelhos na rede principal. Tb é usado para endereços
na rede de teste. E BCRP é o prefixo usado para vestidos vermelhos
no teste de registro. Como dito anteriormente, a versão zero é usada para endereços de
segmentos. A versão um é usada
para endereços de raiz principal.
20. 18 Criar nossa primeira carteira parte 9 skillshare 2: Neste vídeo, faremos
todos os testes que criamos para isso,
implementaremos primeiro o método gerador de
endereços de segmentos. Para gerar um endereço de
segmento, você
converterá uma
chave estendida em uma chave pública. Vamos mudar o
nome desse parâmetro para chave estendida. Em seguida, a chave pública será convertida em um endereço de segmento usando esse método, pois seu
parâmetro passará um prefixo. Vamos passar essa
constante por enquanto, que tornará o
endereço válido
no ambiente principal da rede Bitcoin. Vamos também adicionar a
anotação de serviço a essa classe. Agora, vamos executar o teste do gerador
de endereços de segmentos. Falhou porque
precisamos aumentar a
versão
do Bitcoin Java para 0,4, 0.0, que contém o método CKD
correto para essa operação
funcione. Vamos fazer isso. Clique em Carregar alterações do Maven. Vamos fazer o teste novamente. Ótimo, todos os testes foram aprovados. Agora vamos ajustar o teste do gerador
sequencial de endereços. Temos dois novos parâmetros
de construtor que precisamos passar
para o serviço. Primeiro, vamos instanciar a fábrica do gerador de
endereços. Passar um novo conjunto seria um gerador de
endereços. Em seguida, passaremos 20 como
o número inicial de endereços
gerados. Agora vamos fazer esse teste novamente. Ok, esquecemos de adicionar
o provedor de segurança no método de configuração.
Vamos consertar isso. Execute-o novamente. Ok,
o teste foi aprovado. Alguns serviços não têm
a anotação do serviço. Vamos consertar isso. Ok, agora
vamos adicionar um novo Bean, que será o número
inicial de endereços
gerados
para cada chave estendida, definirá arbitrariamente como 20. Agora vamos executar nosso aplicativo
para ver como ele está funcionando. Recebemos um erro no
console indicando que nosso aplicativo não tem
o provedor de segurança. Vamos adicioná-lo
ao método principal
na classe de aplicativo BYOD W. Vamos executar nosso aplicativo novamente. Ok, o erro não ocorreu, mas o campo do endereço de recebimento ainda não tem um endereço. Vamos mudar isso. Primeiro. Vamos executar todos os nossos testes para verificar quais outros testes
precisam ser corrigidos. Os testes do serviço de criação de carteira estão interrompidos. Vamos consertá-los. Primeiro, temos que
incluir um objeto gerador
sequencial de endereço válido como seu terceiro parâmetro. Vamos
instanciá-lo passando 20 como o primeiro parâmetro e uma
fábrica de geradores de endereços como o segundo. Em seguida, instanciaremos
a fábrica exatamente como no teste anterior. Agora garantirá que o serviço de
criação de carteira esteja criando uma carteira com
duas chaves de pub estendidas, cada uma com 20 endereços. Afirmará que o primeiro campo
estendido de endereços de chaves de pub tem um tamanho de 20. Vamos criar um getter
para esse campo. Afirmará o mesmo para a
segunda chave de pub estendida. Agora vamos fazer esse teste. Ótimo, já passou. Agora vamos fazer com que o teste de
criação de carteira seja aprovado. Lembre-se de que esperamos que o
endereço de recebimento TextField contenha um endereço depois de
criar uma carteira. Então, vamos para o controlador da guia de
recepção. Adicionará um método
chamado initialize, que será executado após
o aplicativo inicializar esse controlador. Em seguida, injetaremos a
carteira atual nessa classe. Na
classe de carteira atual, incluirá um novo campo de
propriedade de string simples chamado endereço de recebimento, que será inicializado
aqui criará setters
e getters para ela. Agora, vamos para
a guia Receber. O Fxml adicionará um
ID Fx ao TextField. Esse ID de ética será
chamado de endereço de recebimento e também o adicionaremos ao controlador da guia de
recebimento. Agora, no método inicializado vinculará a propriedade de
endereço de recebimento da
carteira atual a um
ouvinte que usará esses três parâmetros
em uma função Lambda. No corpo do Lambda, definirá o
campo de endereço de recebimento com o novo valor, que será um endereço. Agora, na atualização, o serviço de carteira
atual definirá o endereço de
recebimento da carteira atual como
o primeiro endereço da primeira chave pub
estendida da carteira. Agora, quando o
endereço de recebimento for alterado dessa forma, ele acionará esse
ouvinte que
definimos aqui no controlador da
guia Receber. E espero que ele adicione o endereço ao campo de endereço de
recebimento. Agora, vamos executar
esses testes para ver se eles funcionam. Grupos. Falhou. Vamos descobrir o porquê. Ok, o erro aconteceu porque esse método deve ser
inicializado, não inicializado. Vamos corrigir isso e executar
o aplicativo. Ótimo. A carteira fez o que
esperávamos e preencheu o campo de endereço de recebimento
depois de criarmos uma carteira. Agora, se apresentarmos esse
endereço para alguém, eles poderão enviar bitcoins para ele. Agora, vamos executar todos os testes
de aplicativos. Ótimo, todos eles passaram.
21. 19 Criar nossa primeira carteira parte 10 skillshare 2: Neste vídeo, faremos
uma refatoração rápida no gerador de endereços do
segmento. Em vez de codificar o prefixo do segmento de rede
principal como parâmetro para o endereço do
segmento a partir do método de chave pública
compactada criará um serviço
que
nos permitirá criar endereços para os ambientes de teste net e reg
test. Chamaremos esse prefixo de
endereço de serviço de fábrica. Ele terá um método get
em que passaremos um tipo de endereço e
retornaremos um prefixo de endereço. Esse valor retornado
será usado como um parâmetro para o endereço do segmento do método de chave pública
compactada. Agora vamos injetar esse serviço nessa classe e criá-lo. Agora vamos criar o método
It's GET. Para implementar esse método,
será necessário um mapa auxiliar, que mapeará
os tipos de endereço para outro mapa, mapeando os três
ambientes com seus prefixos de
endereço correspondentes. Vamos construí-lo e
ficará claro o que eu quis dizer. Agora, vamos mudar o nome desse
parâmetro para o tipo de endereço. No GetMethod retornará um prefixo de endereço usando o tipo de endereço
como a primeira chave. E uma variável chamada ambiente
Bitcoin como a segunda chave do
mapa que acabamos de criar. A
variável de ambiente Bitcoin será definida posteriormente em nosso arquivo de propriedades do
aplicativo e a
injetaremos nessa classe. Agora. No construtor, adicionaremos
uma anotação de valor antes da variável para injetar seu
valor no arquivo de propriedades. Agora, vamos digitar corretamente o campo
do mapa do tipo de endereço. Agora vamos adicionar a configuração do
ambiente Bitcoin ao arquivo de propriedades do
ponto do aplicativo. Vamos configurá-lo para um teste de registro. Agora vamos corrigir alguns arquivos de teste para lidar com as mudanças que
fizemos até agora. Começando com o teste do gerador de
endereço de segmento, excluirá essa
parte e instanciará o gerador de endereços de segmento
no método de configuração, passando a
fábrica de prefixos de endereço como seu parâmetro. Agora vamos instanciar a fábrica de prefixos de
endereço, passando a
constante de rede principal como parâmetro. Agora vamos fazer esse teste. Ótimo, continua funcionando. Agora vamos corrigir o teste do serviço de criação de
carteira. Faremos o mesmo
que no último teste. Basta injetar o prefixo de
endereço factory no gerador de
endereços do segmento. Vamos fazer o teste. Ótimo, já passou. Agora vamos corrigir o teste do gerador
sequencial de endereços. Faremos o mesmo de antes. Agora, vamos fazer o teste. Ótimo, já passou das duas. Agora vamos fazer todos os nossos testes. Alguns testes falharam porque
o prefixo de endereço factory tem uma anotação.
Vamos consertar isso. Execute os testes novamente. Ótimo. Todos os testes foram aprovados. Agora vamos fazer esse
pequeno refator de adicionar importações estáticas
para essas constantes. Agora, vamos executar o aplicativo para ver o que
fizemos até agora. Lembre-se de que agora esperamos
que nossa carteira gere endereços compatíveis com o teste de registro, já que nossa
propriedade de ambiente Bitcoin está configurada para teste de registro. Ok, como esperado, nossa carteira gerou endereços
começando com BCR t, já que é o prefixo de endereços de segmentos no ambiente
de teste de registro. Agora vamos mudar a propriedade do
ambiente Bitcoin duas redes principais, e executar
o aplicativo novamente. Agora temos endereços que
começam com BC, que é o
prefixo de endereço do segmento para a rede principal. Finalmente, vamos mudar a propriedade do ambiente
Bitcoin para testar a rede e tentar o mesmo. Ok, agora podemos gerar
endereços começando com TB, que é o prefixo para testar endereços compatíveis com a
rede. Ótimo, agora temos uma maneira
fácil de mudar o ambiente de rede
compatível com nossa carteira.
22. 20 Preparar o nó para receber bitcoins skillshare 2: Agora temos uma carteira Bitcoin capaz de gerar endereços compatíveis com
diferentes ambientes de
rede Bitcoin ,
que são reg, test, test net e main net. Já é possível usar esses endereços para
receber Bitcoins. Para fazer isso, basta
mostrá-los a outros proprietários de
bitcoins, que podem usar suas carteiras
para enviar Bitcoins para você, ou provavelmente Satoshi, que são frações de Bitcoin. Mas, por enquanto, nossa carteira está habilitada para detectar
esses pagamentos. Portanto, nada acontecerá na interface de usuário de
nossas carteiras após uma transação em um
de nossos endereços. De agora em diante, pretendemos
mudar isso. Começaremos a criar um recurso que nos permitirá ouvir as transações que chegam ao
nosso núcleo do Bitcoin. Em seguida, filtraremos as
transações com saídas que correspondam aos nossos endereços de carteira
atuais. Por fim, modificaremos
nossa carteira para mostrar informações sobre a quantidade
de Bitcoin que nossa carteira contém. Agora, vamos garantir que nosso node Bitcoin esteja
corretamente configurado e preparado para enviar e receber informações de
transações
para nossa carteira. Para fazer isso, abra o arquivo
bitcoin.com. A localização desse arquivo
dependerá do sistema operacional que você está usando. Como estou usando o Windows 10, meu arquivo bitcoin.com está localizado
no caminho na tela. Abra o arquivo e
verifique se ele está assim. Vamos analisar o significado de
cada uma dessas configurações. O primeiro parâmetro,
reg test, é definido como
um para fazer nosso node funcionar
nos ambientes de teste de registro. Uma vez que usaremos o ambiente
de teste de registro para nos ajudar a desenvolver
nosso aplicativo. O segundo parâmetro, os dados
, são definidos na pasta em que você deseja que o nó registre as informações do
blockchain e da
carteira. Eu defino os meus dados de Bitcoin com
barra invertida de dois pontos, mas você pode escolher
qualquer caminho que preferir. O parâmetro do servidor
é definido como um para permitir que nosso nó receba
chamadas de API de nosso aplicativo. Os parâmetros de usuário RPC e senha RPC podem ser
definidos como você quiser. Por enquanto, vou escolher
BYUI W para ambos. Mas ao usar nosso
aplicativo de verdade, é altamente recomendável escolher valores
mais seguros para
esses parâmetros. O índice TX está definido como um. Isso é necessário para permitir que
nosso node recupere qualquer informação
de transação do blockchain. O parâmetro da taxa de fallback
pode ser definido como 0,00 001. Esse valor será usado
para taxas de transação que não
puderam ser calculadas
adequadamente pelo nó. Por fim, definiremos a
propriedade z MQ pub Ratti x com esse valor. Essa propriedade define
o endereço TCP para onde as informações da transação que vão as informações da transação que
chegam ao nó. nosso aplicativo, ouviremos
o mesmo endereço TCP e capturaremos novas transações enviadas para um de nossos
endereços Bitcoin dessa forma. Agora, vamos executar nosso nó
Bitcoin com essas configurações
usando o terminal, vá para a pasta em que seu aplicativo Bitcoin
está instalado. Isso depende de
onde você o
instalou e de qual sistema operacional você está usando. Como estou usando o Windows 10, já abri meu terminal e fui até essa
pasta na tela. Agora, execute o
nó Bitcoin digitando dot slash Bitcoin D
e pressionando Enter. Agora, seu nó principal do Bitcoin está funcionando com
as configurações. Dissemos anteriormente agora
estamos prontos para
as próximas aulas.
23. 21 cliente de nó parte 1 skillshare 2: Neste vídeo, criaremos um cliente HTTP que fará algumas chamadas para nosso nó principal do
Bitcoin. Esse cliente será
necessário posteriormente, quando
o usarmos para enviar e
receber transações. Primeiro, importaremos uma
dependência no arquivo POM. Essa dependência é a web inicial do
Spring Boot
, necessária para a implementação do cliente
HTTP, excluirá uma
dependência transitiva dessa biblioteca adicionando
uma tag de exclusão. dependência excluída será o Tomcat inicial do Spring Boot. Faremos isso para evitar a inicialização de um servidor web em nosso aplicativo. Agora, clique no botão carregar
Maven Changes. Agora vamos criar uma
classe de configuração para o cliente node. Crie uma classe
chamada
configuração do cliente Node dentro
do
pacote api dot config em uma
anotação de configuração para ele. Agora, criaremos algumas
propriedades privadas nessa classe, todas precedidas por uma anotação de
valor. No primeiro, teremos
essa anotação de valor. E será chamado
de node RPC URI. O próximo terá
essa anotação de valor. E será que o nome de usuário RPC do
nó terá outra propriedade com a seguinte anotação de valor com o nome igual
node RPC password. Todas essas propriedades serão injetadas a partir de valores
adicionados posteriormente no aplicativo.
O
arquivo de propriedades de pontos também criará um feixe com a classe
de modelo restante. Será necessário um Template
Builder em repouso como parâmetro. Usaremos esse construtor para retornar um objeto
de modelo de prisão com um URI raiz igual à propriedade
note RPC URI. Ele terá uma
autenticação básica com as propriedades do nome de usuário RPC
da nota e da
senha RPC da nota. Em seguida, ligaremos para
Build e retornaremos. Agora vamos atribuir as propriedades que serão
injetadas nessa classe. Vamos para o arquivo de propriedades de
pontos do aplicativo. Vamos atribuir à propriedade
node dot RPC dot dot URI ao
seguinte endereço. Esse URI com a porta
18443 é o
URI padrão da API Bitcoin
Core Node RPC para o ambiente de teste de registro. Como propriedade de nome de usuário node
dot RPC dot, você precisa escolher o
mesmo valor que escolheu para a
configuração do usuário RPC em seu arquivo
bitcoin.com como a propriedade de senha node
dot RPC dot, escolha o mesmo valor
que você definiu para a configuração da senha RPC
em seu bitcoin.com. Agora, dentro do pacote de serviços api
dot, crie o pacote node, incited, crie o pacote
cliente. Agora vamos criar a classe de
cliente node dentro dela. Vamos adicionar a
anotação do serviço a ela. Agora, vamos injetar o bean do
modelo restante nessa classe. Adicionaremos o
método a seguir para fazer solicitações à API Bitcoin RPC. Quanto aos parâmetros, será
usado um método de string, uma referência de tipo parametrizada do tipo node client response, que criará em seguida uma URL de string e zero
ou mais objetos. Agora vamos criar a resposta flexível do
nó dentro do nó de pontos do
domínio do pacote. Voltar ao node
client, o método
instanciará um novo objeto de solicitação
do cliente node. Ele usará os argumentos do método e dos
parâmetros em
seu construtor. Vamos criar essa nova classe dentro dos domínios,
esse pacote de nós. Vamos criar seu construtor. Agora, vamos encapsular a solicitação
dentro de um objeto de entidade HTTP. Em seguida, retornaremos o
resultado dessa chamada de método, que finalmente
fará uma solicitação de postagem ao Bitcoin Core Node, ajustará a classe de resposta do
cliente do nó transformará em uma gravar e adicionar uma propriedade de resultado a ela
fará um ajuste semelhante
à solicitação do cliente do nó, transformará em um registro e adicionará
esses campos a ela. Esquecemos de
colocar um T aqui. Agora, veremos como fazer uma chamada importante para a API
Bitcoin Core Node. Acesse este site
na tela. É uma referência à chamada RPC core
do
Bitcoin Create Wallet . Vemos na última linha
que essa chamada usa uma chave de método com a carteira de
criação de valor em seu corpo. Cada chamada à API Bitcoin tem esse formato com a
chave do método contendo o
nome do método. As chamadas de API do Bitcoin também têm uma chave de parâmetros contendo
vários tipos de dados. Nesse caso, seu valor é uma matriz com
apenas um elemento. O nome da carteira, chamada de
criação de carteira cria uma carteira dentro do
Bitcoin Core e a carrega. Muitas chamadas de API que
usaremos posteriormente são necessárias. Mas nosso núcleo do Bitcoin
tem uma carteira carregada. De volta ao cliente node. Agora podemos entender por que o método make request
cria um objeto de solicitação que usa um argumento de string
chamado method e um
argumento de tipo variável chamado params. Agora vamos criar uma classe chamada node create
wallet client. Vamos adicionar uma
anotação de serviço a ela. Injetará o
cliente node nele. Agora, criaremos um
método chamado create, que usará um parâmetro de
string. Agora, faça uma chamada para o método
de criação de carteira da API Bitcoin Core. Nós os chamaremos de
método make request do
cliente node desta forma, seguindo a referência do site Bitcoin
Core. Agora vamos testar esse
método para isso. Vamos executar nosso Bitcoin Core
Node no terminal. Em vez de usar nossa forma tradicional de
TDD de fazer as coisas, testaremos esse
método de forma diferente. De volta ao node, o cliente create
wallet criará um método precedido por uma anotação
pós-construção. A
anotação de construção Post é útil para executar código quando um
aplicativo Spring está sendo iniciado. Também é útil para testes
rápidos e aplicativos
Spring, quase como criar um método
estático principal em uma classe Java, mas com todos os benefícios
dos beans gerenciados
pelo aplicativo. Dentro desse método, chamará o método create
passando qualquer nome de carteira. Vamos executar o aplicativo. Ok, ao observar os
registros do Bitcoin Core Node no terminal, vemos que nosso node
criou e carregou uma carteira com o nome que
dissemos na chamada do método. Com isso, sabemos
que nosso método está funcionando e podemos remover esse método de
pós-construção. Agora, vamos acessar o site do
Bitcoin Core novamente e pesquisar o método DIR da carteira
listada. Esse método
não usa parâmetros e retorna todas as
carteiras de nós criadas até o momento. Ele retorna uma estrutura JSON
com um campo de carteiras. Esse campo contém
uma matriz de objetos, cada um representando uma carteira existente
com um campo de nome. Vamos criar um cliente
para esse método. Vamos chamá-la de lista de nós
enquanto for cliente. Novamente, vamos injetar o
cliente node nessa classe. Em seguida, criaremos
o método list all, que retornará uma
lista de nomes de carteiras. Dentro desse método, eles os
chamarão de make
request method
do node client passando list wallet DIR como
o nome do método. Uma nova
referência de tipo parametrizada e um URL vazio. Não passaremos nenhum parâmetro
adicional. O objeto retornado
será um registro node wallets, que será criado agora, nós o criaremos dentro do pacote
domains dot node. Esse registro
terá somente um campo. Será uma lista de carteiras node. Seu nome será carteiras. Vamos criar o
registro da carteira node no mesmo pacote. único campo
será um nome de string. Lembre-se de que estamos modelando
esses objetos com
base nessa referência
do site Bitcoin Core. Mas o campo de carteiras
no registro de carteiras de nós
corresponde ao nome desse campo na
resposta JSON da chamada de API. O mesmo acontece com o campo de nome do registro da carteira
node. O campo carteiras
da resposta
terá uma lista de objetos
com o campo de nome. Cada um desses objetos será armazenado como registros do NerdWallet
no aplicativo, de volta à lista
de nós enquanto ele for cliente. Da lista, todos os métodos
retornarão uma lista de nomes de carteiras. Para fazer isso, obteremos as
carteiras das carteiras node. Em seguida, chamaremos stream e,
em seguida, mapearemos passando uma referência ao campo do nome da carteira do node. Em seguida, converteremos o resultado
em uma lista e o retornaremos. Agora, vamos testar o método list all usando um método
anotado com a
construção Post para
imprimir cada elemento retornado pela chamada do método list
all. Vemos nessa linha no
console que o aplicativo registra o nome
da carteira node que criamos. Ótimo. Agora implementaremos
outro cliente para chamar o método da API Node
chamado list wallets. A diferença
entre esse método e a carteira de lista DIR é que as carteiras da lista retornarão somente as
carteiras atualmente carregadas pelo nó. Ele também retorna uma lista de nomes de carteiras sem
envolvê-los em objetos. Agora vamos criar o método
de carregamento da lista. Ele retornará uma lista
de nomes de carteiras. Para fazer isso, basta
retornar essa chamada de método. Agora vamos testá-lo da mesma
forma que testamos a lista. Eu vou ligar. Vemos no console, mas nosso aplicativo registra duas vezes o
nome da carteira que criamos. A primeira foi devido à chamada do método
list all, e a segunda foi devido à chamada
do método carregada na lista. Agora, para ver a diferença
entre as duas chamadas de método, vamos fazer o seguinte. Encerre o aplicativo Bitcoin
Core Node pressionando Control
plus C no terminal. Agora, inicie o Bitcoin
Core Note novamente. Agora vamos fazer o mesmo teste. Mas primeiro, adicione
essas linhas antes das chamadas do método para
diferenciar cada método. No console,
vemos que somente a chamada do método list all retornou
a carteira criada. Isso demonstra que, depois de
iniciarmos o aplicativo Bitcoin Core
Node, precisamos carregar a
carteira que usaremos, possamos fazer outras chamadas de API que precisem carregar uma carteira de node. Mas veremos como isso funciona na prática nos próximos vídeos.
24. 22 cliente de nó parte 2 skillshare 2: Neste vídeo,
continuaremos implementando mais
métodos que nos
permitirão interagir com nosso node Bitcoin a partir de
nosso aplicativo. O primeiro é um método
que carregará uma carteira node. Ao executar seu node, você precisa carregar uma
carteira para poder chamar muitos outros métodos de node. Então, vamos criar o cliente de carteira node
load. Como sempre, em uma
anotação de serviço. Agora, injetaremos o cliente
node nele. Em seguida, criaremos
o método de carregamento, que terá o
nome da carteira como parâmetro. Em seguida, simplesmente
os chamaremos de
método make request do
cliente node, assim. Agora, vamos testar esse método
usando uma construção de post. Primeiro, vamos remover esse método de
pós-construção que
criamos anteriormente. Agora chamaremos o método de carregamento passando o nome
da carteira que criamos. Antes de executá-lo, vamos executar nosso node Bitcoin
no terminal. Ok, nos registros do terminal, vemos que nosso node carregou
corretamente nossa carteira. Agora, criaremos um serviço
útil para carregar uma carteira node se ela já
existir e não estiver carregada. Se uma carteira com esse nome
já existir e já estiver carregada pelo
node, o método não fará nada
e nós retornaremos. Por fim, se uma carteira com
esse nome não existir, o método a
criará e o nó será carregado
automaticamente, pois carrega uma carteira
após sua criação. Então, no pacote services
dot node, vamos criar um
nome de classe node load ou criar um serviço de carteira. Vamos injetar os seguintes
clientes nele. O cliente de carteira de criação do node, o cliente da carteira de carregamento e a lista de nós
enquanto cliente. Agora vamos criar um método
chamado load ou create wallet. Ele usará um nome
como parâmetro. Dentro dele, chamará o método
list all
da lista de nós, o cliente de
carteiras
armazenará o resultado em uma
variável chamada all wallets. Em seguida, chamaremos o método
de carregamento da
lista do mesmo cliente. E armazenaremos o resultado na variável
de carteiras carregadas. Agora, adicionaremos uma instrução if verificando a
seguinte condição. Se essa condição for
avaliada como verdadeira, significa que a
carteira com esse nome já existe e foi
carregada pelo nó. Se for esse o caso, não
precisamos fazer
nada e podemos retornar. Agora, adicionaremos a
seguinte declaração if. Se essa afirmação retornar verdadeira, significa que uma carteira com
esse nome já existe, mas não foi carregada pelo node. Se for esse o caso, chamaremos o método de carregamento
do cliente node load wallet passando o nome da carteira e retornaremos. Por fim, se a execução
do código for considerada falsa das declarações IF
anteriores, isso significa que uma carteira com
esse nome não existe. Nesse caso, simplesmente
criamos a carteira, chamando o método create
do cliente node create wallet e passando
o nome da carteira. Ok, o método está concluído. Vamos usá-lo nos próximos vídeos. Agora vamos criar
outro cliente útil. Ele se chamará Node
get new address client. Como o próprio nome sugere, ele será usado para gerar um novo endereço a partir de nossa carteira de node
carregada. Então, vamos injetar o cliente
node nele. Agora, criaremos um método
chamado obter novo endereço. Ele retornará o
endereço em uma string. E ele usará o
nome da carteira como parâmetro. Em seguida, retornaremos para
fazer a
chamada do método de solicitação do cliente node
com esses parâmetros. Observe que definimos
o parâmetro URL para a string Wallet e corte
o nome da carteira. É assim que dizemos ao
nosso node que
queremos um endereço
dessa carteira específica. Vamos testar esse método. Para isso, criaremos o
seguinte método
anotado de construção Post que chamará o método get new address,
passando o nome de uma carteira que carregamos
anteriormente como parâmetro. Se chamarmos esse método sem
carregar essa carteira primeiro, ele não funcionará e o nó
retornará um erro. Armazenaremos o resultado
da chamada do método
na variável de endereço
e o imprimiremos. Vamos testá-lo. O registro do console mostra
que ele gerou e imprimiu um endereço de teste
de registro do segmento Bitcoin. Ótimo. Anote o endereço
gerado. Vamos usá-lo para testar o
método que será implementado a seguir. Agora, criaremos um método
que será usado para controlar
alguns blocos que produzem
Bitcoins em um endereço. Esse método funciona apenas
no ambiente de teste de registro e será útil para
nós em alguns testes que precisam de um número inicial
de moedas para jogar. Vamos criar uma classe chamada no degenerate para abordar o cliente. Como de costume, injetaremos
o cliente node nele. Em seguida, criaremos um método
chamado generate to address. Ele tomará como parâmetros
um nome de carteira, vários blocos
e um endereço. Em seguida, vamos chamá-los de método
make request
do cliente node com os
seguintes parâmetros. Novamente, passaremos
a string Wallet cortar a variável de nome. Em seguida, passaremos o parâmetro
blocks, que indica o número de blocos que você deseja gerar. Por fim, passaremos
a variável de endereço, que é o endereço que
receberá os Bitcoins gerados. Agora, vamos testar esse método. Primeiro. Vamos remover o método anotado
de construção da postagem anterior . Agora, faremos com que esse método
de
pós-construção chame o método generate
to address, passando o nome de
uma carteira carregada. Novamente, se você passar
o nome de uma carteira que não existe
ou não está carregada, o método funcionará. Criaremos 1.000
blocos e passaremos o endereço
gerado anteriormente. Vamos executá-lo. Se inspecionarmos nossos registros de
nós, veremos que ele mostra algumas linhas indicando que nosso
método chamado funcionou. O último cliente criado para este vídeo será chamado de cliente
Node get balanced. Ele será usado para verificar
o saldo de nossas carteiras. Vamos injetar o cliente
node nele. Em seguida, criaremos
o método get, que retornará o número de bitcoins que nossa carteira contém. Será usado o
nome da carteira como argumento. Em seguida, retornaremos
essa chamada de método. Como os métodos anteriores. Esse método fará com que a
Carteira reduza o nome
da carteira como parâmetro de URL para definir o retorno do
saldo dessa carteira específica. Vamos testar esse método
usando uma construção de post. Chamará o método get passando o nome de uma carteira
carregada anteriormente. Novamente, esse método não funcionará. Se a carteira anterior não
for
carregada pelo nó, armazenaremos o resultado
da chamada em uma variável e a
imprimiremos . Vamos testá-lo. Ótimo. A partir dos registros, vemos que agora temos milhares de Bitcoins. Obviamente, esses
bitcoins são
válidos apenas em nosso ambiente de
teste de registro. Nos próximos vídeos, vamos usá-los para testes.
25. 23 cliente de nó parte 3 skillshare 2: Neste vídeo, criaremos um cliente que nos
permitirá enviar Bitcoin da nossa carteira node para qualquer outro vestido vermelho que quisermos. Em seguida, usaremos todos os clientes que
criamos até agora para criar um teste para receber bitcoins um endereço de nossa carteira de
aplicativos. Então, depois de remover
qualquer método de
construção de post
anterior das aulas anteriores, vamos criar uma classe chamada
nodes enviada para endereçar o cliente. Agora vamos injetar o cliente
node nele. Em seguida, criaremos um
método chamado enviar para endereço como parâmetros ou nome e
endereço da
carteira e um valor. Em seguida, vamos chamá-los de método
make request
do cliente node passando
os seguintes parâmetros. Novamente, passaremos a barra Wallet para cortar
a variável do nome da carteira. Será a carteira de onde
os bitcoins serão enviados. Também será necessário
um endereço para onde os bitcoins serão
enviados e um valor, que é o valor
transferido em Bitcoins. Vamos testar esse método. Primeiro, certifique-se de que
seu node esteja em execução. No meu caso, vou
ter que começar. Agora, vamos garantir que nossa carteira node seja financiada
com Bitcoins para que possamos enviar bitcoins a partir dela, chamaremos o
método get balanced para verificar isso. Mas desta vez vamos ligar
do terminal. Cada método de API que podemos chamar de nosso aplicativo pode ser chamado do
terminal usando o aplicativo Bitcoin CLI. Abra outra janela do terminal e vá para a mesma pasta em que
seu nó está instalado. Em seguida, digite o
comando a seguir para carregar uma
carteira criada anteriormente e pressione Enter. No meu caso, depois de carregar a carteira, tenho que digitar o nome da carteira de
teste, que é o nome da carteira criei entre aspas duplas. Ok, agora que nossa
carteira está carregada, podemos inserir outros
comandos que a exijam. Então, vamos inserir esse comando
para verificar o saldo da nossa carteira. Bem, é equilibrado, é zero. Parece que toda
vez que reiniciamos a nota e o ambiente de
teste de registro, nossos fundos desaparecem. Não tem problema. Vamos financiar nossa carteira Node. Agora usando a interface de
linha de comando. Para fazer isso, primeiro obtemos um novo endereço do
nosso nó enquanto ele está assim. Em seguida, chamamos o comando generate to address
para gerar 1.000 blocos e direcionamos
as recompensas do bloco para o endereço que
acabamos de gerar. Agora, vamos chamar o comando Get
balanced novamente. Ótimo. Vemos que nossa carteira agora contém milhares
de Bitcoins. Novamente. Agora, de volta ao node,
envie para o endereço do cliente. Vamos criar um método de
pós-construção para testar o método send
to address. Chamará o método de envio
para endereço, passando o nome da carteira carregada. O segundo parâmetro pode
ser qualquer endereço de teste de registro. Usaremos o Bitcoin CLI
para gerar um novo endereço. Em seguida, vamos passá-lo como
o segundo parâmetro para o método de envio para endereço. Em seguida, escolheremos
um como valor. Vamos executá-lo. Ok, se chamarmos o
método Get balanced do Bitcoin CLI, veremos que nosso
balanceamento quase não mudou. Há uma pequena
diferença entre o saldo atual e
o saldo anterior. Essa diferença se deve
à taxa de transação, pois
transferimos um Bitcoin para um endereço da
mesma carteira node, se chamarmos o método de receber por endereço da CLI. Passando o endereço,
enviamos um Bitcoin para o número zero como segundo parâmetro,
o que indica que
queremos o saldo, incluindo
transações não confirmadas, obtemos o valor um, que é o valor que
transferimos para esse endereço. Ok, terminamos nossa
CLI jogando por enquanto. Vamos remover o método de
construção Post. Agora, dentro do BYOD,
um pacote pegajoso criará o teste de
recebimento de Bitcoin. Esse teste precisará de
muitas coisas em comum com o teste de
criação de carteira. Então, vamos fazer com que ele estenda uma classe abstrata que
criaremos chamada teste de GUI. Essa classe terá todos os métodos comuns a qualquer teste de GUI de que precisarmos. Então, vamos criá-lo. No teste de criação de carteira, o teste
cortará todas as propriedades e métodos, exceto o último, e os
transferirá para
a classe de teste de GUI. Em seguida, adicionaremos a anotação de teste do Spring
Boot a ela e ela estenderá a classe de especificação do
aplicativo. Removeremos a
mesma anotação
do teste de criação de carteira e faremos com que ela estenda a classe de teste de
GUI. Vamos remover todas as importações não utilizadas. Agora,
protegerá todas as
propriedades privadas no teste de GUI e incluirá essa chamada de
provedor de adição de pontos de segurança em
seu método de início. Finalmente, vamos tornar
essa aula abstrata. Agora, vamos testar o teste de
criação de carteira para ver se tudo continua funcionando
como antes da ocorrência
de um erro. Minha intuição diz que
é um bug da ideia do IntelliJ. Para resolver isso, vamos chamá-los método de ciclo de vida limpo
maven. Vamos também reconstruir o projeto e executar todos os testes do aplicativo. Todos os testes foram aprovados. Portanto, foi apenas um bug do IDE. Agora, vamos continuar construindo nosso teste de recebimento de
Bitcoin para injetar os
seguintes grãos nele. O nó envia para o cliente de endereço, o nó carrega ou
cria o serviço de carteira. O nó fica equilibrado, cliente. E o node obtém um
novo cliente de endereço. *****. Parece que
esquecemos de adicionar a palavra cliente e o
node obter um novo endereço. Vamos renomeá-lo. Agora, vamos criar um método de configuração que será executado antes que
essa classe seja testada. Dentro, ele chamará o método load ou create wallet a
partir do node load ou create wallet service, pois seu parâmetro
passará pela string, testará a carteira e a
armazenará na constante. Em seguida, chamaremos o método
create balance, se necessário, que será criado em seguida. Neste método, primeiro
verificaremos o saldo
da carteira de teste usando o cliente
node get balanced. Se o saldo for
inferior a 100 Bitcoin, obteremos um novo endereço
da carteira de teste. Usando o node generate
para endereçar o cliente, que esquecemos de
injetar nessa classe, e faremos isso agora. Vamos gerar 1.000 blocos, financiando
assim nossa carteira. E vamos tornar esse
método privado. Com esse método
executado antes dos testes, garantimos que sempre teremos Bitcoins que podemos
usar em nossos testes. Agora, criaremos um teste
chamado deve receber Bitcoin. Quando o bloco
for semelhante ao bloco de vento
no teste de
criação de carteira, chamaremos os seguintes
métodos para criar uma nova carteira. Clicaremos na guia Receber. Em seguida, pesquisaremos o valor na entrada do endereço de recebimento, que neste momento
conterá o primeiro
endereço da nossa carteira. E nós o armazenaremos
na variável de endereço. Agora, chamaremos o
método de
envio para endereço a partir do nó
enviado para o cliente de endereço. Como seus parâmetros
passarão pelo nome da carteira de teste, pelo endereço que geramos
com nossa carteira de aplicativos e pelo valor um. Depois de receber
Bitcoins, esperamos que nossa carteira de aplicativos
detecte a transação, mas esse processo
não será imediato. Levará alguns segundos
para que isso aconteça. Por esse motivo,
usaremos um método chamado wait-for do test fx. Como seus parâmetros passarão de dez, que será o
valor do tempo limite para o peso. O tempo limite nesse contexto é o tempo máximo que o
aplicativo
aguardará antes de lançar
uma exceção de tempo limite. O segundo parâmetro indica a unidade de tempo do parâmetro
anterior. Então, vamos escolher os segundos. O último parâmetro
será um método de retorno de chamada. Dentro, ele procurará um componente de GUI com
um ID de endereços. Tabela, consultará se ela tem um TableView e armazenará seu resultado em uma variável
do mesmo tipo. Em seguida, retornaremos a comparação entre o tamanho do
item do TableView e um. Esse TableView com uma tabela
de ID de endereços
será um componente que armazenará
uma tabela contendo linhas, cada uma com um
endereço financiado de nossa carteira. O método de retorno de chamada será executado em um loop e só será interrompido se a comparação retornar verdadeira ou se o tempo limite for atingido. Em resumo, esse peso para a chamada de
método
fará o seguinte. Ele verificará se há uma tabela com uma linha preenchida
na tela. Isso acontecerá quando nossa carteira detectar que um de
seus endereços recebeu uma transação e preencheu uma linha da tabela com
essas informações. Esperará 10 s para
que isso aconteça ou menos. Se a tabela for preenchida
com uma linha antes, copiaremos a linha de pesquisa da
visualização da tabela e a colaremos aqui. Em seguida, o bloco verificará novamente se o
tamanho do item TableView é igual a um. Vamos armazenar esse
valor de tempo limite em uma constante. Agora, vamos fazer o teste. Como esperado. O teste falhou porque não encontrou a tabela de endereços. No próximo vídeo, começaremos a implementar
esse recurso em nossa carteira.
26. 24 Receber bitcoin parte 1 skillshare 2: Neste vídeo,
criaremos uma tabela mostrando informações
sobre nossos endereços. Essa tabela conterá
cada endereço financiado, seu valor em Bitcoin
e o número mínimo de confirmações que
as transações com esses endereços têm. A ideia é preencher
essa tabela logo após nossas carteiras detectarem transações
enviadas para nossos endereços. Então, na janela principal, pontilhe FXML, se clicarmos na guia
Scene Builder, veremos que ela está
mostrando uma mensagem para baixar o Java FX, mesmo que o tenhamos baixado antes. Isso está acontecendo porque esse recurso do IDE não lida bem com componentes
externos, como o controlador da
guia Receber. Então, para poder usar
o Scene Builder,
criaremos um novo arquivo FXML
chamado playground. Neste arquivo, colaremos todo o conteúdo do ponto FXML da janela
principal. Mas, em vez de usar componentes
externos como o controlador da
guia Receber, os
embutirá no arquivo. Portanto, dentro do pacote resources
dot FXML, crie o arquivo playground
dot FXML. Exclua todo o seu conteúdo. Em seguida, copie todo o conteúdo
da janela principal com o ponto FXML
e cole-o lá. Agora, substituiremos o
conteúdo do controlador da
guia Receber pelo conteúdo da guia Receber ponto FXML. E modificaremos a tag
raiz FX com a tag tag. E vamos excluir
seu atributo de tipo. Vamos importar a tag insets. Agora, quando clicamos
no Scene Builder, podemos usá-lo normalmente. Agora, vamos adicionar um novo
painel de guias ao componente VBox. Agora, vamos excluir uma
das guias criadas. Vamos renomear os dois endereços restantes da
guia. Vamos dar a ele uma guia de
identificação FX de endereços. Agora, dentro da guia Conteúdo, adicionaremos um componente de
exibição de tabela. Infelizmente, por motivos de
erros, o Scene Builder
não nos permite adicionar uma visualização de tabela a uma guia. Não tem problema. Vamos adicioná-lo
usando o editor de texto. Vamos também adicionar uma ideia
de tabela de endereços do Fx aqui. Vamos voltar para
o Scene Builder. Começou a funcionar novamente. Agora temos uma tabela vazia
dentro da guia de endereços. Agora vamos adicionar três
colunas à tabela. Vamos renomear a primeira
coluna para dois endereços, a segunda para balancear e a terceira para duas confirmações. Em seguida, clicaremos
na tabela e alteraremos essa configuração para
redimensionamento restrito. Agora, todas as colunas têm
o mesmo tamanho e ocupam toda
a área da tabela. Agora vamos clicar em cada coluna da
tabela e desmarcar. São caixas de seleção editáveis e
classificáveis. Agora, para cada coluna da tabela definirá sua largura máxima para 100. Esse é apenas um truque necessário
para que possamos ajustar seu tamanho. Agora, vamos ajustar o tamanho deles
usando o mouse desta forma. A coluna de endereços
deve ser maior, pois os endereços ocuparão
um espaço maior, as colunas de
saldo e confirmação podem ter o mesmo tamanho. De volta ao editor de texto. Vamos mudar o
atributo pref height do painel de
abas para 355. Voltando ao Scene Builder, podemos ver que ele parece melhor. Vamos também alterar a mensagem do
espaço reservado, que mostra quando
a tabela está vazia. Para fazer isso, basta adicionar uma tag de etiqueta vazia dentro
dessa tag de espaço reservado. Agora que nosso componente de tabela
está pronto no playground, vamos criar um FXML para ele. Vamos chamá-la de tabela de endereços. Vamos excluir todo o
código padronizado. E vamos copiar todo
o conteúdo entre a tag TableView
e colá-lo lá. Agora, em vez de usar
a tag de visualização em tabela, vamos usar a tag raiz FX faz referência
às plantas de visualização da tabela e ao atributo type. Vamos importar as tags restantes. E vamos adicionar esses atributos XML
e S aqui. Agora, de volta ao playground FXML. A guia de endereços não tem
um ID FX. Vamos acrescentar a isso. Essa ideia já foi usada
no componente VBox por engano. Então, vamos removê-lo de lá. Agora, vamos copiar essas quatro linhas e colá-las
na janela principal. Agora, vamos adicionar as
tags de fechamento e as tags que copiamos. Agora, excluiremos
a tag de exibição da tabela e adicionaremos uma
tag de conteúdo em seu lugar. Dentro dela, adicionará uma tag controladora
de tabela de endereços. Agora vamos criar
esse controlador. Vamos adicionar uma
anotação de componente a ela. Ele deve estender a classe
de exibição de tabela com a classe de endereço
como seu parâmetro de tipo. Agora, volte para a janela principal. Vamos importar o controlador
criado recentemente. No controlador da
tabela de endereços, vamos criar um construtor. Ele usará um parâmetro FXML
com uma anotação de valor. A anotação do valor fará referência à tabela de
endereços FXML. O segundo
parâmetro do construtor
será um objeto de
contexto do aplicativo. No corpo do construtor,
criará um novo objeto carregador FXML, inicializando-o com
esses parâmetros. Em seguida, definiremos seu
controlador FXML para isso. E estabeleceremos seu caminho para isso. Em seguida, chamaremos de carga sobre ele. E adicionaremos uma
declaração throws ao construtor. Precisamos fazer mais uma
coisa para que funcione. Dentro dessa instrução if
no ouvinte iniciado pela GUI adicione o código a seguir. Isso é necessário para que o Java FX
crie a tag do
controlador de endereços corretamente. Agora, vamos executar nosso aplicativo
para ver como ele está funcionando. Ótimo, tudo bem, a
mesa de vestidos está bonita. Nos próximos vídeos, faremos com que funcione
para nossas carteiras.
27. 25 Receber bitcoin parte 2 skillshare 2: Neste vídeo,
faremos com que nossas carteiras comecem a interagir com
nossos nós de Bitcoin para que possamos receber
informações sobre transações enviadas
para nossos endereços. Lembre-se de que, quando
criamos uma carteira, geramos os primeiros
20 endereços para ela. Mas nosso
node Bitcoin
ainda não sabe quais são os endereços
gerados. Are Bitcoin Node deve
conhecer nossos endereços para
enviar ativamente informações sobre suas transações
para nosso aplicativo. Portanto, precisamos importar nossos endereços de carteira
para nosso node. Para isso, criaremos um novo cliente node que
será responsável por isso. Portanto, dentro do pacote node dot
client,
criará uma classe chamada node
multi import address client. Como outros clientes, ele terá uma anotação de serviço e injetaremos o serviço de
cliente node nela. Antes de criarmos seu método, vamos verificar a documentação
do site Bitcoin Core Sua API usará o multimétodo
de importação da API do nó Bitcoin. Vemos aqui que ele usa uma matriz de objetos
como parâmetro. Cada objeto pode ter
várias chaves diferentes, mas usaremos apenas
três delas. A chave pub do script, que pode assumir como valor
e objeto um endereço que o nó
importará, um timestamp, que é a data em que o
endereço foi gerado. Esse parâmetro é importante para determinar até que ponto no passado
o nó
pesquisará transações com esse endereço
no blockchain também
definirá o parâmetro watch only como verdadeiro
já que nosso node usará nossos endereços
apenas para monitorar transações
no blockchain, mas não poderá assinar transações com
esses endereços. Somente nossa
carteira de aplicativos
poderá assinar
transações de saída, mas esse é um tópico
para vídeos futuros. De volta ao IDE, vamos criar um método
chamado endereços de importação. Serão utilizados como parâmetros
um nome de carteira, uma lista de endereços e uma data de criação da carteira. Agora, criaremos um
objeto params que modelará o multiparâmetro de importação que
vimos na documentação do Bitcoin
Core. Esse objeto será uma lista
de um novo objeto que
criaremos chamado node multi
reimport dress params. Vamos criá-lo agora. Será um registro e criaremos no pacote
domains dot node. Ele terá um novo
nó reimportado várias vezes, respire ele script pub
key object criará. Ele também terá um campo de registro de data e hora
longo
e um campo exclusivo para observação booleana. Vamos criar essa
classe como um registro. Ele terá somente
um campo de endereço. De volta ao cliente de endereços de
importação múltipla do node. Como o método de importação de
endereços recebe uma lista de endereços, devemos usar o
código a seguir para convertê-lo em uma lista de endereços
reimportados com vários nós por ohms. Em seguida, usaremos o método
make request do cliente node dessa forma. Agora, vamos testar esse código
usando um método de pós-construção. Importaremos endereços para
a carteira node com o
nome da carteira de teste. E usaremos a data atual
como a data de criação da carteira. Como os endereços. Usarei esses três endereços de teste de
registro, que você pode encontrar
nesta classe como recursos. Antes de executar esse código, vamos executar nosso Bitcoin
Core Node e carregar a carteira com o
mesmo nome que usaremos. Para carregá-lo, usaremos
o Bitcoin CLI, assim como fizemos nos vídeos
anteriores. Ok, ao examinar
os registros dos nós do Bitcoin, parece que funcionou. A última linha do registro mostra que a nova verificação
foi concluída. A nova verificação acontece por padrão depois que importamos
endereços para o nó. O
reescaneamento busca transações
no blockchain para os endereços importados
recentemente. Nesse processo, o nó pesquisa
transações e blocos criados até 2 horas
antes da data que
passamos como parâmetro de
timestamp. Vamos remover o método de
construção Post. Agora, dentro do pacote gooey
dot listeners, vamos criar uma classe chamada created wallet
important listener. Ele terá uma anotação de
componente e implementará a classe de ouvinte do
aplicativo com um parâmetro do evento de carteira
criado. Vamos implementar seu método. Assim como o ouvinte de
carteira criado, esse método de classe será chamado após a criação de uma carteira. Vamos injetar a carga do node ou criar um serviço de carteira nele. Agora, no método de
evento sem aplicativo chamará o método load ou create wallet
a partir do serviço injetado passando o nome da
carteira de eventos como parâmetro. Vamos também injetar o cliente de endereços de
importação múltipla de nós nele. Vamos finalizar os dois
serviços injetados. Agora chamaremos o
método de
importação de endereços do último serviço
injetado. Mas primeiro, vamos
criar uma variável para a carteira de eventos e usá-la nesse método. Agora, na chamada de
endereços de importação, vamos passar o nome da carteira. O método wallet get addresses, que criará a
carteira criada na propriedade, que também criaremos
no registro da carteira. Vamos criar a propriedade de data
createdAt, vamos criá-la usando o recurso IDE de
alteração de assinatura. Vamos usar um
valor padrão de nova data. Ao fazer isso, o IDE
adicionará automaticamente esse terceiro parâmetro em cada instanciação de uma carteira
encontrada no projeto. Vamos clicar em Refactor
e importar a classe de data. Se acessarmos o serviço de criação de
carteira, veremos que ele
adicionou uma nova data como o terceiro parâmetro
na instanciação da carteira. Isso fará com que a carteira tenha a data atual como
data de criação. O
controlador de diálogo de criação de carteira usará a carteira criada na chamada do método de evento
público. Isso acionará a chamada do método de evento no
aplicativo. Agora vamos criar o método
get addresses no registro da carteira. Ele retornará uma lista de endereços obtendo
os endereços de suas chaves de
pub estendidas, assim. Ao chamar o
método flatMap no fluxo de
chaves de pub estendidas e retornar a chave de pub estendida, o fluxo de
endereços dessa chamada obterá um fluxo de todos os objetos
de endereço da carteira. Em seguida, chamaremos o método
map para converter o fluxo de objetos de endereço em um fluxo de cadeias de
endereço. Por fim, chamaremos o método de duas
listas no resultado e retornaremos uma lista de todos os
endereços da carteira em formato de string. Ok, agora, depois de
criar nossa carteira, esperamos que nossos
aplicativos sejam carregados criemos uma carteira com o
mesmo nome em nosso node. Depois disso, nosso
aplicativo importará todos os endereços gerados
para nosso nó. Vamos executar nosso
aplicativo para testá-lo. Vamos criar uma nova carteira. Eu cliquei no botão OK, mas parece que
nada aconteceu. Vamos verificar os registros dos nós. Ok, depois de algum tempo, diz
que a nova digitalização foi concluída e a carteira
terminou sua criação. No próximo vídeo, tornaremos esse processo assíncrono
executando as chamadas para o
nó em outro thread. Ao fazer isso, o pegajoso não ficará preso e a
criação da carteira será mais fácil. Cia.
28. 26 Receber bitcoin parte 3 skillshare 2: No último vídeo, fizemos com que
nosso node Bitcoin criasse e carregasse nossa carteira de aplicativos
e endereços importantes. Mas esse processo estava
demorando alguns segundos e bloqueando a interface
gráfica do usuário. Neste vídeo, corrigiremos isso
fazendo com que a comunicação
com o node seja executada em outro thread de forma assíncrona
dentro do pacote BYU OWL. Vamos criar um novo
pacote chamado Config. Dentro desse pacote, vamos criar uma classe
chamada configuração assíncrona. Essa classe conterá
todas as configurações relacionadas à
execução assíncrona do código no projeto. Vamos adicionar uma
anotação de configuração a ela. E uma
anotação assíncrona ativada para. Essa anotação é importante para habilitar
recursos assíncronos no projeto. Agora, vamos criar um método anotado com a anotação
Bean. Ele retornará um ExecutorService. Vamos chamá-lo de serviço de
executor padrão. Ele retornará um novo executor
de thread
único da classe executors. Esse bean fornecerá um thread sempre que quisermos
executar código nele. Será um único encadeamento, o que significa que, se duas
ou mais seções de código tentarem ser executadas nesse
thread simultaneamente, teremos que
esperar que a outra termine de ser executada. Optamos por usar um único fio porque isso facilita o
controle
dos processos em nosso
aplicativo e nos permite evitar
as condições de corrida com mais facilidade. Agora, vamos fazer uma pequena refatoração de código dentro do pacote de serviços
de pontos pegajosos. Vamos criar uma classe
chamada
serviço de carteira de importação e adicionar a anotação do
serviço a ela. Vamos criar um método
chamado de importação de carteira. Transferirá o código
do ouvinte de
importação de carteira criado para o serviço de importação de carteira. Vamos também injetar os
serviços necessários nessa classe. E vamos adicionar a carteira como um parâmetro ao método de
importação da carteira. Na carteira criada,
importe o ouvinte. Vamos remover todo esse código. Vamos injetar o serviço de importação de
carteira nele. Agora, no método de
evento sem aplicativo, vamos chamar o método de
importação da carteira
do serviço injetado passando a carteira de eventos
como parâmetro. O
método de importação da carteira contém o código que queremos
executar de forma assíncrona. Para torná-lo assíncrono, basta anotar esse método com a anotação
assíncrona, passando o nome do bean
do serviço executor que
criamos. Também devemos retornar um
valor desse método, o que nos permitirá gerenciar essa chamada
assíncrona a partir da cor do método. O valor retornado
será um futuro. Um parâmetro do tipo void retornará um novo objeto de resultado
assíncrono passando null para seu construtor. Agora, vamos testar a
criação de uma carteira. Mas primeiro, vamos executar
nosso node Bitcoin. Se ainda não estiver em execução. Vemos que nossa carteira
foi criada imediatamente, mas quando verificamos os registros dos nós, ela ainda está carregando e
importando os endereços da carteira. Ótimo. O nó
concluiu a nova digitalização. Portanto, nossos
processos de carregamento e importação de carteiras são assíncronos. Agora vamos fazer alguns ajustes finos. Vamos até o ouvinte de importação de
carteira criado. No método de
evento sem aplicativo registrará o retorno do método de importação da carteira e armazenará na variável de resultado. Faremos dessa variável um campo
privado dessa classe. Agora, adicionaremos a
seguinte declaração if. Antes de ligar para importar carteira. Se a
variável resultante não for nula, chamaremos o método
cancel nela, passando true como argumento. Isso é necessário porque,
se tentarmos criar outra carteira quando uma ainda não tiver
concluído a importação, precisaremos cancelar
o processo
de importação da primeira carteira criada. Vamos fazer outro ajuste fino na classe
do aplicativo GUI para
substituir o método stop. Dentro dele, adicionará
o seguinte código. Esse código garantirá que o
tópico criado pelo nosso
ExecutorService padrão seja fechado depois que fecharmos nosso aplicativo. Agora, há outro problema
com nosso aplicativo. Quando criamos uma carteira sem
nosso nó Bitcoin em execução, as chamadas para criar ou carregar uma carteira e os
endereços importantes falharão. Vamos ver como isso funciona
na prática fechando nosso node Bitcoin e
executando nosso aplicativo. Depois de criar uma carteira, parece que nosso aplicativo
está funcionando normalmente, mas isso porque
as exceções e outros tópicos não estão
sendo relatados. Nossa carteira não poderia
ter se comunicado com nosso nó enquanto
nosso nó estava desligado. Quando ele tentou fazer isso, uma exceção foi lançada
pelo thread e um thread
terminou de ser executado. Vamos consertar isso. O que
queremos que nosso aplicativo faça ao criar uma carteira é tentar se comunicar
indefinidamente com nossa nota. Se, por algum motivo, não conseguir
fazer isso após a primeira tentativa, faça-o, usaremos uma
anotação do Spring Boot chamada retrial. Essa anotação faz com que o método
anotado seja executado novamente, se gerar uma exceção. Para usá-lo, precisamos adicionar as seguintes dependências
ao nosso arquivo POM. A primeira é a nova tentativa na primavera, a segunda são os aspectos da primavera. Agora, no método de importação de carteira, vamos adicionar a anotação de nova tentativa também
passará alguns
parâmetros para ela. A primeira será a expressão de
exceção, que será definida como
na porta de login, o serviço de carteira dot deve tentar abrir
e fechar novamente o parêntese. Isso fará com que o aplicativo seja
chamado de método de
repetição antes de cada nova tentativa e só tente novamente se essa
chamada de método retornar verdadeira. Também adicionaremos o parâmetro de tentativas
máximas, definindo-o como a constante inteira do
valor máximo. Essa configuração
fará com que esse método seja repetido indefinidamente. Por fim, vamos adicionar o parâmetro de
recuo, configurando-o como a anotação de
recuo, passando o
parâmetro de atraso de 1.000. Isso fará com que o aplicativo
espere 1.000 milissegundos ou 1 s antes de executar
o método em cada tentativa. Agora, vamos criar esse
método de repetição. Seu tipo de retorno
será um booleano. O método retornará a
negação do resultado de uma chamada de método
interrompida do thread atual. Essa chamada retornará true se o thread atual não for
interrompido ou falsa, caso contrário. Portanto, se o
aplicativo for fechado ou se outra carteira for criada
entre cada nova tentativa, esse tópico
será interrompido e o método de importação da carteira
não será mais repetido. Mais uma coisa para que
a anotação de nova tentativa funcione, precisamos adicionar a anotação de nova
tentativa ativada
na classe de configuração assíncrona. Vamos fazer isso. Agora. Vamos executar nosso aplicativo com nosso nó fechado
e fazer alguns testes. Vamos criar uma nova carteira. Agora, vamos começar nosso nodo. registros do node, vemos que a carteira
criada foi carregada e a nova
verificação foi concluída. Agora. Agora vamos criar outra carteira. Vemos nos registros do
node que ele também foi criado,
carregado e importado
com sucesso . Ótimo.
29. 27 Receber bitcoin parte 4 skillshare 2: Neste vídeo, continuaremos a integrar nossa carteira
com nosso node. A próxima etapa da integração é ouvir
as mensagens que o nó envia quando recebe uma transação em um endereço
importado. Para isso, criaremos uma
classe chamada node task, que terá um método que será executado em um loop infinito em outro thread após
o início do aplicativo. Esse método
escutará continuamente as transações que são recebidas pelo node em qualquer um dos endereços atualmente
carregados de nossos aplicativos. Quando encontrar um, fará com
que nosso aplicativo o
trate adequadamente. Então, vamos criar um
novo pacote chamado node no pacote BYOD W. Dentro dela, criará uma classe chamada gooey
started node listener. Vamos adicionar uma
anotação de componente a ela. Essa classe será um ouvinte
acionado pelo evento gooey started publicado quando
o aplicativo for iniciado. Portanto, ele implementará o ouvinte do aplicativo com esse evento como seu parâmetro
de tipo. Vamos implementar seu método. Vamos adicionar o novo node que o serviço de
tarefas
criará como um
campo privado nesta classe. Vamos criar o novo serviço. Agora, vamos injetá-lo no ouvinte do node iniciado pela
GUI. No método de
evento não relacionado ao aplicativo,
chamará o método de execução da
tarefa do nó. Vamos criar esse método
na tarefa do node. Vamos adicionar a
anotação do serviço a essa classe. Agora, adicionaremos uma
dependência que a tarefa do node
precisará no arquivo POM. Será a biblioteca do herói MQ. Vamos clicar no botão carregar alterações do
Maven. Essa biblioteca
gerencia a comunicação entre o aplicativo
e o zero MQ. Zero MQ é um agente de mensagens que recebe mensagens
do node Bitcoin. Essas mensagens serão enviadas para um URL local e coletadas por nosso aplicativo por meio de zero
MQ de volta à tarefa do node. Vamos adicionar a
anotação assíncrona ao método run. Vamos passar o
serviço executor de notas como seu parâmetro. Isso fará com que
esse método seja executado forma assíncrona em outro
thread gerenciado
pelo serviço executor do node que vamos
criar na classe de
configuração assíncrona, vamos criar o serviço
executor do node. Como o serviço de
execução padrão, ele será gerenciado por um novo executor de thread
único. Agora, vamos injetar
o objeto
de soquete de zero MQ nessa classe. Esse campo será chamado de
assinantes, pois
tratará de uma assinatura
do agente de mensagens zero MQ. No método de execução, vamos definir o
tempo limite
de recebimento do assinante para 1.000. Isso adicionará um segundo de
atraso cada vez nosso aplicativo consultar zero e Q para pesquisar mensagens. Vamos chamar esse método de
subscrição de assinantes, passando os bytes da string
rod TX como parâmetro. Isso fará com que nosso aplicativo ouça
apenas mensagens relacionadas a transações de roubo de
Bitcoin que são enviadas para zero. Mq também chamará o método de conexão dos
assinantes, passando a variável
z MQ URL para ele. Vamos injetar essa
variável nessa classe. Adicionaremos uma anotação de valor
ao argumento do construtor, passando essa string
como parâmetro. Portanto, o valor dessa variável será injetado
nessa classe por meio uma propriedade do aplicativo chamada z e o URL de q ponto será definido agora, o valor dessa
variável deve corresponder ao mesmo valor que Eu configurei
em nosso arquivo bitcoin.com. Então, vamos copiar o valor
definido para a configuração do z MQ pub rock TX bitcoin.com
e colá-lo aqui. Agora, voltando ao
node, o método de execução de tarefas criará nosso loop contínuo. Vamos criar um loop inteiro. Ele será executado enquanto o
thread atual não for interrompido. Dentro do loop,
chamaremos os assinantes de destruírem o método STR e armazenaremos o resultado na variável
topic. A destruição do
método STR consulta zero MQ para qualquer mensagem e retorna
uma string se encontrar uma. No nosso caso, essa string conterá o
nome do tópico, que será igual a ra
TX para transações brutas. Em seguida, adicionaremos um loop if
verificando a variável do tópico. Se seu conteúdo for
diferente do Ratti x
, chamaremos para
continuar fazendo o loop funcionar novamente
desde o início. Caso contrário, chamaremos
o método wreck
V dos assinantes e armazenaremos o conteúdo
na variável content. A destruição do método é
semelhante ao rec VNTR, mas retorna uma matriz de bytes
em vez de uma string. Nesse ponto, essa matriz de
bytes conterá a transação bruta ou o
nó enviado para zero MQ. Agora, converteremos
a matriz de bytes
no objeto de
transação Bitcoin Java. Para fazer isso, usaremos
o código a seguir. Devemos adicionar uma instrução throws IOException à assinatura
desse método. Na GUI, iniciei o
node listener. Também precisamos
agrupar a chamada de execução em um bloco try-catch como este. De volta ao método de execução. Agora, usaremos um
serviço de aplicativos de editores de
eventos para publicar um evento. Vamos injetar esse
serviço nessa classe. Primeiro. Passaremos um novo evento de transação recebida para o método de
publicação do evento. Para a transação recebida instanciação do
evento
passará isso e o objeto da transação antes criar a nova classe de evento, vamos adicionar uma peça que falta
para que esse método funcione. Vamos criar uma nova classe
chamada configuração de nós. Vamos movê-lo para um novo pacote
de configuração node dot. Vamos adicionar uma
anotação de configuração a ela. Nesta classe,
adicionaremos alguns beans para o objeto
Socket injetado nas tarefas do node funcione. O primeiro bean será
o ser do contexto Z. O segundo feixe
será o soquete zero MQ. Ele será chamado de assinante. E adotará em seu método
o contexto Z criado acima. Ele retornará os
contextos Z para criar uma chamada de método de
soquete passando a
subconstante do tipo de soquete como seu parâmetro. Agora, de volta ao node, a tarefa criará o evento da transação
recebida, criará no pacote
de eventos node dot. Passaremos a tarefa do node para o superconstrutor e
injetaremos a transação em
um campo de transação privada. Também vamos criar um
método getter para a transação. Agora, vamos criar um pacote de ouvintes
no pacote node. Dentro dela. Vamos criar uma transação recebida pelo
ouvinte para esse evento. Vamos adicionar uma
anotação de componente a ela. Esse ouvinte
será responsável por filtrar
as transações recebidas
identificando se elas
têm endereços pertencentes a uma carteira atualmente
carregada. Ele implementará um ouvinte de
aplicativo com o
evento da transação recebida como seu parâmetro de tipo. Vamos implementar seu método. Nesse método, vamos pegar a transação do evento e armazená-la na variável de
transação. Agora, a primeira coisa que
faremos é identificar os endereços de saída
da transação recebida. Para fazer isso, criará
a variável de endereços, que será uma lista de cadeias de caracteres. Em seguida, atribuiremos o resultado
da seguinte expressão a ela. Mapeará as saídas da transação passando por um método de
análise do analisador de endereços. Agora, vamos injetar e criar
o serviço de análise de endereços. Vamos criá-lo no pacote de serviços
node dot. Vamos adicionar a
anotação do serviço a ela. Agora, vamos criar
o método de análise. Ele retornará uma string e tomará uma saída de transação
como seu parâmetro. Esse método será responsável por extrair o endereço da saída de uma transação para a transação
recebida.
O ouvinte converterá o
resultado em uma lista. Em seguida, para fins de teste imprimirá todos os endereços
analisados. Agora vamos implementar
o método de análise. A primeira coisa que
faremos é obter a chave pub
do script de transação e atribuí-la a essa variável. Não se preocupe,
explicaremos o que é uma
chave de script pub e outros detalhes da
transação. No próximo vídeo,
retornaremos o resultado da
seguinte instrução switch. Se o tipo da chave pub do
script for igual à constante P2 WP k,
h, que é o tipo de nossos endereços de carteira
atuais. Em seguida, retornaremos a chave pub do
script P2, chamada do método de endereço
WP k h. Passando a chamada do método Get do prefixo de endereço
factory como o parâmetro que passa
a constante de Segway para ela. A declaração de caso padrão
será uma string vazia. Vamos injetar o prefixo de endereço
factory nessa classe. Agora, vamos fazer alguns testes. Meu node Bitcoin
já está em execução. Certifique-se de que o seu também seja. Vamos para a aula de teste de recebimento de
Bitcoin e executá-la. O teste falhou porque ainda não
modificamos nosso teste de GUI para considerar o controlador da tabela de endereços. Lembre-se de que nosso ouvinte iniciado pela
GUI lida com o problema de
usar essa condição if. Poderíamos usar a mesma
condição if em nosso fixo, mas vamos fazer isso de uma forma mais organizada. Vamos ao evento iniciado pela
GUI. Vamos mudar o tipo de
aplicativo GUI para objeto. Simplesmente publicaremos o evento gooey started em
nossa classe de teste de GUI, da mesma forma que fizemos aqui
na classe de aplicativos de GUI. Na classe de teste de GUI, vamos remover todo esse código. Agora, vamos copiar essa linha
do aplicativo GUI
e colá-la aqui. Vamos remover todas
essas importações não utilizadas e esse campo privado não utilizado. Agora, vamos fazer o teste de recebimento de
Bitcoin novamente. Nosso teste falhou,
mas vemos aqui
nos registros de teste que são dois endereços
impressos pelo aplicativo. Isso aconteceu porque
imprimimos os endereços
da transação que nosso teste fez um dos endereços de nossa carteira. Um desses endereços é nosso, o outro é um
endereço de mudança do remetente. Ótimo. Vemos que o que
fizemos até agora funcionou. Vamos fazer uma refatoração
na classe de teste de GUI. Vamos remover essas
importações não utilizadas. Na classe de aplicação GUI. Vamos incluir essa
linha de código que fará com que nosso thread de
serviço de executor de notas pare de executado depois que fecharmos
nosso aplicativo. No próximo vídeo,
aprenderemos mais sobre as transações de
Bitcoin para
nos preparar para o que vem a seguir.
30. Transações de Bitcoin: Entradas, Saídas, scripts e o conjunto UTXO: Nesta apresentação,
aprenderemos alguns conceitos sobre transações de
Bitcoin. Será útil entender melhor
a implementação
do recebimento de Bitcoins em nossa carteira de
aplicativos. Vamos recapitular o que
aprendemos até agora sobre transações de
Bitcoin
e gradualmente adicionar complexidade à nossa
compreensão delas. Portanto, uma transação de Bitcoin
é comumente usada para transferir Bitcoins da
pessoa a para a pessoa B. Uma transação de Bitcoin
pode ser
composta por muitas entradas e muitas saídas. Uma entrada de transação indica o proprietário anterior do Bitcoin ou o remetente
da transação. saída de uma transação indica
o destinatário das moedas ou o proprietário das moedas após a publicação da transação. Nesta imagem, temos uma transação simples com
uma entrada e duas saídas. Diz que um Bitcoin
foi transferido de John, que assinou a entrada
dessa transação. A saída zero indica que 0,9 Bitcoins foram enviados para casar. Vou colocar que um indica que 0,099 Bitcoins foram enviados de
volta para John como a mudança. Os valores de Bitcoin não podem
ser divididos em entradas. Como John queria enviar
0,9 Bitcoins para se casar, ele
só tinha um Bitcoin. Ele precisava criar uma
saída de mudança para si mesmo. Mas seu valor é de
0,099 Bitcoins, não 0,1 Bitcoins, como
você poderia esperar. A diferença, que
é de 0,001 Bitcoins, é a
taxa de transação necessária para que
a transação seja
incluída no blockchain. Então, a partir dessa imagem, tiramos três lições. A soma dos bitcoins
nas entradas não pode ser menor que a soma dos
Bitcoins e das saídas. O valor do Bitcoin nas entradas é fixo, embora possa ser escolhido à vontade e nas saídas, desde
que atenda à regra anterior. Finalmente, a taxa de transação é a diferença
entre a soma dos valores de Bitcoin nas entradas e a soma dos
valores e saídas do Bitcoin. Aumentando a complexidade. Também aprendemos sobre os
campos que fazem parte de uma entrada e de
uma saída de transação. E a entrada sempre se refere a uma saída de uma transação
anterior. Ele faz isso usando o ID da transação anterior e o índice de saída da transação
anterior. Seria redundante que
a entrada tivesse
um campo de valor. Esses dois campos são
suficientes para identificar qualquer saída de transação
no blockchain. Uh, a entrada da transação também deve conter uma
assinatura válida produzida usando a mesma
chave privada usada para derivar o endereço da saída
à qual a entrada se refere. Observe que a
entrada de uma transação não tem um campo indicando
o valor do Bitcoin. Isso porque o valor é automaticamente igual ao valor
de saída ao qual se refere. A
saída da transação tem dois campos. Um é o endereço
usado para receber bitcoins. E o endereço é uma sequência
codificada e, por si só, não revela
o dono das moedas. É por isso que consideramos
o Bitcoin pseudônimo. O outro campo é
a quantidade que indica o valor do Bitcoin
bloqueado pelo endereço. Agora, vamos aumentar a
complexidade mais uma vez explicando exatamente o que exatamente as entradas
e saídas da
transação contêm. A entrada da transação tem
os seguintes campos. O ID da transação anterior, que é uma sequência
hexadecimal exclusiva, é obtido por meio do hashing da
transação serializada anterior. O índice
de saída da transação anterior é um número inteiro. Como uma transação
pode ter muitas saídas, uma saída específica
pode ser
identificada de forma inequívoca pelo
ID da transação e pelo índice de saída. O ScriptSig ou o campo de testemunhas. A assinatura de entrada é adicionada
ao campo ScriptSig em transações que
não sejam do Segway. Nas transações do Segway, a assinatura é adicionada
ao campo de testemunha, que não conta para
o tamanho da transação. A saída da transação
tem os seguintes campos. A chave do script pub. chave Script pub contém
o endereço decodificado e o campo de quantidade
que determina a quantidade de Bitcoin
bloqueada pelo endereço. Agora, vamos ver como criar uma transação de Bitcoin
por meio de um exemplo. Nosso objetivo neste
exemplo é enviar 1,5 bitcoins para esse endereço. Antes de começar, temos
uma transação confirmada, o que significa que ela já está
armazenada no blockchain. Ele tem uma saída
com dois bitcoins, que posso
gastar, pois tenho uma chave privada que foi usada
para criar seu endereço e que pode ser usada para assinar uma entrada de transação em uma nova
transação. Então, vamos criar uma
nova transação, adicionaremos uma entrada a ela. A entrada será referida
à nossa transação por meio do campo de ID
da transação anterior. O índice
de produção da transação anterior é zero, pois é o
índice de saída de nossa produção. O campo ScriptSig é
composto por uma assinatura produzida usando a mesma chave privada usada para produzir o endereço
de nossa saída. E uma chave pública, que é a mesma chave pública derivada usando nossa chave privada. A transação
terá duas saídas. As saídas zero conterão um
campo de chave de script pub composto, entre outras coisas, pela
chave pública com hash do endereço. Queremos enviar nossos bitcoins para. Esse hash é obtido por Beck
32 decodificando o endereço. Back 32 é o algoritmo usado para codificar o
hash de uma chave pública, produzindo em um segundo qual endereço? Base 58 é outro algoritmo usado para fazer o mesmo para endereços que
não sejam segmentados. Como estamos enviando bitcoins
para um endereço de segmento, devemos usar o Beck 32. O campo de quantidade dessa
saída será igual a 1,5, que é a
quantidade de Bitcoin que queremos enviar, precisará de uma segunda
saída para a alteração. Sua chave de script pub
conterá uma chave pública com hash obtida pela
decodificação de Beck 32 e um endereço
que pertence a nós, derivado de uma
chave privada sobre a qual temos controle. quantidade
será de 0,49 Bitcoins, o que somado a 1,5 da saída
zero é igual a 1,99. Portanto, temos uma diferença de 0,01 entre a soma dos
valores de Bitcoin em entradas e saídas. Essa diferença será a taxa de
transação necessária para a transação seja incluída no blockchain por um menor. Falamos sobre o ScriptSig
e o script pub key, mas ainda não explicamos o que
essas coisas realmente são. O Bitcoin tem uma
linguagem de contrato inteligente chamada script. Um contrato inteligente é uma
forma sofisticada de se referir a um programa escrito em uma transação e executado pela rede Bitcoin. Os campos de chave scriptSig e
script pub são criados com código de
linguagem de script. Essa linguagem é
interpretada combinando o ScriptSig de uma entrada
e a chave script pub de uma saída e verificando
se o ScriptSig satisfaz as condições
codificadas pela chave pub do script. Você pode considerar esse mecanismo como um mecanismo de chave e bloqueio, que o ScriptSig
é a chave para desbloquear
a chave pub do script,
que é a fechadura. Se um ScriptSig for válido para
desbloquear uma chave pub de script, você
poderá gastar os fundos
de saída bloqueados por ela. Um ScriptSig tem esse nome
porque geralmente contém uma assinatura que satisfaz uma condição específica da chave de
pub do script. Da mesma forma, a chave script pub
tem esse nome porque continha uma chave pública nas
primeiras transações de Bitcoin. Mas, em teoria, qualquer código de script
arbitrário pode ser incluído em ambos os campos. A restrição exclusiva para que um programa de
script seja válido é que ele retorne verdadeiro
ao final de sua execução. Há muitos tipos
de programas de script, também conhecidos como tipos de script. Um deles é o hash de
pagamento para chave pública usado em transações simples não
sequitur. Vamos ver como isso é
executado neste exemplo, todos os scripts de Bitcoin são
executados da mesma forma, o que muda entre eles
ou o código que está sendo executado? Então, começando com nossa transação
confirmada do slide anterior , mostramos
aqui apenas
sua saída zero com o
conteúdo da chave script pub na caixa cinza. Em transações de
hash de pagamento para chave pública, o
campo script pub key é
composto por opcodes e pelo hash de chave
pública. E opcode é uma instrução de
linguagem de script. Eles são identificados pelas
letras OP no início. sublinhado ascendente é igual, por exemplo, compara dois elementos e
retorna verdadeiro se eles forem iguais. Cada script de chave pub e scripts de hash de pagamento para chave pública têm essa sequência de código que
difere apenas em seus hashes de chave
pub. Agora temos nossa nova transação, que é a mesma
do slide anterior. Desta vez, mostramos
apenas sua entrada aqui. Seu conteúdo do ScriptSig
está na caixa cinza. Em scripts de hash de pagamento para
chaves públicas. O ScriptSig tem
apenas uma assinatura seguida por uma chave pública. Agora vamos ver como os dois campos
são combinados e executados. Primeiro, o conteúdo ScriptSig
da entrada é concatenado com o conteúdo da chave script pub
da saída referenciada
pela entrada nesta ordem. Em seguida, cada elemento
do script combinado é colocado em uma
pilha de execução da esquerda para a direita. Se o elemento for um opcode, ele poderá atuar em outros
elementos na pilha, processando-os e adicionando
outros elementos à pilha. Então, vamos ver como esse
script é executado. A assinatura é o primeiro
elemento da esquerda para a direita. Portanto, ele é
colocado primeiro na pilha. O próximo elemento
é a chave pública, que também é
inserida na pilha. O próximo elemento é o opcode
up sublinhado. Up, underscore up codifica
uma instrução para duplicar o último elemento adicionado
à pilha e adicionar a
cópia à pilha. O próximo elemento é o opcode op
underscore hash 160. Ele remove o último elemento
adicionado à pilha, aplica a função hash 160 a ele e adiciona o
resultado do hash de volta à pilha. Então, acabamos com o hash da chave pública no
topo da pilha de execução. O próximo elemento a ser adicionado
à pilha é o hash da chave
pública. Em seguida, temos o sublinhado op
equal verify opcode. Esse opcode remove dois elementos do topo da pilha de
execução e os
compara se eles forem iguais ao que o script
continua sendo executado. Caso contrário, a execução falha e a transação
é invalidada. Essa etapa é
importante porque valida que a
chave pública do ScriptSig é igual à chave
pública usada para gerar o endereço da
saída da qual ele está gastando. O último elemento
do script é o opcode op underscore
check sig. Ele remove dois elementos
do topo
da pilha de execução
e valida se o primeiro elemento é
uma assinatura válida para o segundo elemento
dessa transação específica, se for uma assinatura válida, um booleano verdadeiro é
adicionado à pilha. Se for inválido do que um booleano, false será adicionado à pilha. Finalmente, depois que todos
os elementos do script forem adicionados à pilha de
execução, a entrada da transação
seria considerada válida se o último elemento
adicionado fosse verdadeiro. Caso contrário, a
entrada da transação é inválida. Esse processo deve ser repetido para cada entrada de transação. Para que uma transação
seja considerada válida, todas as suas entradas devem ser válidas. Há muitos tipos de script. O script de pagamento para chave pública foi o primeiro
script de Bitcoin criado, mas hoje está obsoleto
e raramente é usado. As primeiras transações de Bitcoin
contêm o tipo de script. Em vez de usar o
hash da chave pública, é a chave pub do script, use
a chave pública diretamente. O script de hash de pagamento para
chave pública foi exemplificado
no último slide. Foi o tipo de
script mais usado desde o
aumento da relevância das
transações de Segway nos últimos anos. Hoje, ainda é comumente usado, então é bom saber sobre isso. O script de hash de
chave pública pay to witness é o tipo de script mais
usado atualmente em transações de Bitcoin. A razão para isso é que é vantajoso usá-lo, pois as transações com ele são menores e, portanto, têm uma taxa de
transação menor. Esse tipo de script tem uma chave de pub de script
menor e o conteúdo do ScriptSig é
movido para o campo de testemunha, o
que não contribui
para o tamanho da transação. Por esses motivos,
implementaremos primeiro
esse tipo de script em
nossas carteiras O hash de pagamento para script
é outro script usado principalmente para transações
com várias assinaturas. As transações com várias assinaturas exigem mais de uma assinatura para gastar uma saída. O hash do
script de pagamento para testemunhar é a versão testemunha do
script de hash de pagamento para testemunhar. Sua assinatura é movida
para o campo da testemunha. Portanto, tem as mesmas
vantagens que o script de hash de pagamento para testemunhar uma
chave pública tem. O hash de pagamento para testemunhar uma
chave pública envolto em um script de
hash pago por script também é conhecido como segmento aninhado
ou segmento de rap. Também é comumente usado e
sua principal função é
tornar carteiras antigas que não sejam compatíveis com o segmento
nativo,
compatíveis com transações da
Segway. Aprenderemos mais
sobre o tipo de script mais adiante no curso. Finalmente, outro tipo de script é o script root pay to tap. É o tipo de script
criado mais recentemente, adicionando mais recursos e privacidade às transações de Bitcoin. Agora, vamos ver um
resumo de como criar entradas e saídas de
transações do ponto de vista de uma carteira, começando com uma
semente mnemônica e uma frase secreta. Por meio de um
algoritmo criptográfico, combinamos os dois e
obtemos uma semente raiz. Então, por meio de uma série
de transformações foram produzidas chaves mestras e chaves
estendidas. Obtemos muitas chaves privadas. Aqui, mostramos apenas uma
dessas chaves privadas. As mesmas transformações
também podem produzir chaves públicas. Uma chave pública também pode ser produzida a partir de uma chave privada
específica, que mostramos aqui
em nosso exemplo. A partir de uma chave pública, obtemos um endereço usando a função hash 160 e codificando o
resultado por meio da
codificação Beck 3.2 no caso de endereços de
segmentos ou codificação de base 58 no caso
de endereços não segmentados. Para receber Bitcoins, você
mostra seu endereço para
alguém para que alguém
possa enviar bitcoins para ela. Quando um remetente coloca
seu endereço em sua carteira e envia uma quantia em
Bitcoin para ela, sua carteira
decodifica o endereço volta para um hash de chave pública. Em seguida, ele criará uma
transação com uma saída contendo uma chave pub de script
equivalente a esse endereço. O tipo de chave pub do script
dependerá do tipo do endereço. Nesse caso, a
carteira identificou que o tipo de endereço
é compatível com um script de hash de pagamento para chave pública. Depois de receber Bitcoins
nesse endereço, o destinatário pode gastá-los
por meio de uma nova transação. O conteúdo dos novos
campos de entrada da transação
dependerá do
tipo de chave de pub do script que será gasto. Nesse caso, a
carteira criará uma transação com
uma entrada contendo um ScriptSig com uma assinatura gerada usando a mesma chave
privada que originou a
chave pública originada o endereço que recebeu
Bitcoins anteriormente. detalhes sobre a assinatura de uma transação Veremos detalhes sobre a assinatura de uma transação em um vídeo futuro. A chave pública citada
anteriormente será adicionada após a assinatura
no campo ScriptSig. Finalmente, a entrada também fará referência à saída da
transação não gasta usando o ID da transação anterior e os campos do índice
de saída da transação anterior , conforme explicado anteriormente. Agora vamos aprender o importante
conceito do conjunto UTXO. Lembre-se de que UTXO significa saída de transação
não gasta. Bitcoin tem a
importante característica de não permitir gastos duplos. Em outras palavras,
você só pode gastar Bitcoins com saídas de
transações não gastas. O conjunto UTXO é o conjunto de
todos os UTXOs atualmente existentes. Esse conjunto é armazenado por nós em um banco de dados separado, o que permite uma
recuperação rápida por carteiras. O conjunto UTXO está sendo
constantemente atualizado com cada nova transação adicionando e removendo saídas de
e para o conjunto. Utxos são saídas que ainda não
foram referenciadas
em nenhuma entrada. Portanto, o conjunto UTXO contém todas as moedas
disponíveis para serem gastas. O número de bitcoins
em um endereço é igual à soma
de todos os Bitcoins de
todos os UTXOs cujas chaves de script pub referenciavam o endereço decodificado. Portanto, o Bitcoin
Core Node fornece um método de API chamado
list unspent que retorna todos os
UTXOs que fazem referência aos endereços que você
passou como parâmetros para ele. Ao usar o método de lista
não gasta, você pode calcular facilmente o saldo de um
endereço e as informações da
transação descoberta , como o
ID e o índice da transação UTXO, bem
como seu chave de pub do script. Assim, você pode criar entradas de
transação para gastar seus Bitcoins a
partir do UTXO. Depois de gastar o UTXO, ele é removido do conjunto UTXO. Agora vamos ver um diagrama explicando como nosso
aplicativo detectará as transações
recebidas
e
nos informará sobre os
bitcoins que receberão. Esse será o último slide
desta apresentação, que introduziu
muitas informações complexas. Não se preocupe se você não
absorveu tudo no início. Ao longo do curso,
reutilizaremos as informações aprendidas para
nos aprofundarmos nelas, para que tenhamos muitas oportunidades de compreendê-las melhor. Agora, de volta ao diagrama. Aqui temos retângulos
representando o aplicativo, o
nó Bitcoin e a rede Bitcoin. As transações são criadas e transmitidas por nós
da rede Bitcoin. Essas transações,
quando confirmadas, já
estão armazenadas
no blockchain. Quando não confirmados, eles
permanecem no templo, um banco de dados contendo todas as transações
não confirmadas. Cada nó tem uma cópia
das transações mentais que eventualmente
são detectadas por nossos nós
, que já
importaram nossas
carteiras e endereços de aplicativos. Por meio de zero notificações de MQ, as transações são
enviadas para nosso aplicativo. Quando nosso aplicativo
carrega uma carteira, ele filtra todas as
transações recebidas que não contêm
nenhum de seus endereços. Em seguida, ele enviará uma lista de chamadas
não gastas para o nó, passando como parâmetros
todos os endereços
das transações recebidas que permaneceram após a filtragem. O nó retornará todos os UTXOs relacionados a esses endereços. Nossa carteira então
analisará esses UTXOs para calcular o saldo de Bitcoin
para cada um de seus endereços. Em seguida, mostraremos as informações
obtidas na tabela de endereços.
31. 29 Receber parte do bitcoin 5 skillshare 2: Neste vídeo, implementaremos a lista de clientes não gastos
que nos permitirá coletar informações sobre UTXOs após
recebermos transações. Então, dentro do pacote do cliente node
dot, vamos criar a
lista de nós de clientes não gastos. Vamos adicionar uma
anotação de serviço a ela. Vamos também injetar o cliente
node nele. Agora vamos criar o método
de lista não gasto. Ele retornará uma lista de UTXOs, que é um registro que criaremos. Ele tomará como parâmetros uma lista de endereços
e um nome de carteira. Vamos criar o registro UTXO
no pacote BYOD w dot domains. O UTXO conterá
os seguintes campos. O TX ID, que é um
acrônimo para ID da transação. O campo vout, que
representa o índice de saída, o endereço, o rótulo, que não usaremos no momento. A chave do script pub. O valor que representa
o valor do Bitcoin, as conformações que
conterão o número de conformações que a transação
UTXOs tem. O número de conformações de uma transação é o
número de blocos que foram adicionados ao blockchain
depois que a transação foi inserida em um bloco e esse bloco foi adicionado
ao blockchain. Esse número inclui o bloco que
contém essa transação. Portanto, se uma transação
tiver duas confirmações, isso significa que ela já foi
incluída em um bloco. Esse bloco foi adicionado
ao blockchain e outro bloco foi
adicionado depois disso. Vamos adicionar mais dois campos. Esses campos não
serão usados por enquanto, mas podem ser úteis
em outros tipos de transações que
veremos mais adiante no curso. Eles são o roteiro de resgate
e o roteiro da testemunha. Agora, de volta à
lista de nós, o cliente não gasto chamará o método de
solicitação do cliente node e
armazenará o resultado na
variável de matriz utxOS e
passará os seguintes
parâmetros para o método. Os últimos três parâmetros
farão parte
da lista de poemas da API
Bitcoin node. O primeiro é o número
mínimo de conformações que os UTXOs de
retorno devem ter. O segundo é o máximo. Como queremos que todos
os UTXOs definam zero como o mínimo e o valor
inteiro máximo como o máximo. O terceiro parâmetro é
a lista de endereços. Agora, converteremos
a matriz resultante em uma lista usando esse
código e a retornaremos. Agora, de volta ao ouvinte da transação
recebida. Vamos remover essa linha de código porque era
só para testes. Vamos testar o cliente não gasto da
lista de nós. Vamos obter os UTXOs
para esses endereços. Vamos injetar o cliente
nessa classe primeiro, o método list unspent
passará a variável addresses. O segundo argumento será o nome da carteira do teste de
recebimento do Bitcoin. Vamos copiá-lo e usá-lo
como segundo parâmetro. Agora, vamos adicionar
essa linha para imprimir cada UTXO obtido
na tela. Agora, vamos executar nosso node Bitcoin se ele ainda não estiver em execução. Agora, vamos fazer o teste de recebimento de
Bitcoin e executá-lo. Nos registros de teste, vemos que ele imprimiu um
UTXO com todos os seus dados. Observe que seu
endereço é o
mesmo que o
endereço de recebimento de nossa carteira. Retroceda o vídeo para conferi-lo. O valor é um, que é esperado porque é o mesmo valor de Bitcoin
enviado e, no teste, tem zero
conformações porque nenhum bloco lembra o
nó desde a transação. Agora vamos excluir essas linhas porque elas eram
apenas para teste. Vamos também remover o
cliente injetado dessa classe. Agora, adicionaremos um
filtro a esse stream. Queremos processar
somente transações
da carteira atualmente carregada pelo aplicativo. Esse filtro será
responsável por isso. O filtro verificará se
o endereço não está vazio. Se a carteira atual
contiver esse endereço. Então, vamos injetar a
carteira atual nessa classe. Em seguida, chamaremos os
endereços get como método de strings. Em seguida, verificaremos se ele
contém o endereço. Oh, uma letra S estava faltando aqui. Agora vamos criar o método get
addresses as strings. Ele retornará uma lista de sequências de caracteres. O valor retornado
resultará da chamada dos endereços get como método
strings no campo de
endereços que criaremos. Então, vamos criar esse campo. Ele terá uma nova
classe de endereços como seu tipo. E vamos
inicializá-lo aqui. Vamos criá-lo no pacote
observables. Vamos também criar seus
endereços get como método de strings. Primeiro, adicionaremos um campo
de endereços privados. Será um mapa em que
o tipo de chave será um tipo de endereço e o tipo dos valores
será outro mapa. O segundo mapa será
um HashMap vinculado com strings como chaves e endereço
como o tipo de seus valores. Usaremos essa estrutura de dados
para armazenar os endereços. A razão para usar
essa estrutura de dados é que ela nos permite separar e consultar os endereços da carteira
por tipo de endereço. O segundo mapa é um HashMap
vinculado porque esse tipo de mapa mantém
a ordem de inserção. Finalmente, o segundo
mapa nos permite consultar
a lista de objetos de endereço por suas sequências de cadeias de endereço. Agora, no método get addresses as strings, retornará
o seguinte código. A função flatMap será
usada para obter todos os endereços
no segundo conjunto de chaves do mapa e retornar um fluxo
contendo todos eles. Em seguida, converteremos a string
resultante em uma lista. Ok, agora podemos usar
o método get addresses as strings para obter todos os endereços criados
para a carteira atual. Mas uma coisa está faltando. Também precisamos preencher o campo de endereços
a partir
da classe de endereços. Para fazer isso, adicionaremos o código a
seguir na atualização. serviço de carteira atual
definirá os endereços da
carteira atual, passando as chaves
pub estendidas da carteira como parâmetro. Agora, vamos criar o método atual de endereços do conjunto de
carteiras. Ele chamará o
método set addresses do campo de endereços, passando as
chaves estendidas como parâmetro. Em seguida, criaremos esse método
na classe de endereços. Vamos adicionar o código a
seguir a ele. Usaremos a
função de coleta para obter um mapa das chaves
estendidas do pub. Dentro dela, adicionará uma chamada de método
to map. Seu primeiro argumento criará um tipo de endereço usando o campo
estendido do tipo de chave pub. Esse argumento define a
chave do mapa resultante. O segundo argumento
definirá o valor
do mapa e conterá
o código a seguir. Novamente, ao combinar
as
funções de coleta e mapeamento , ele será definido
como um Hashmap vinculado. As chaves serão as sequências de
strings de endereços de chaves pub
estendidas sequências de
strings e os valores estarão lá objetos de endereço
correspondentes. Finalmente, a parte filtrante
desse fluxo está concluída. No próximo vídeo, usaremos o que construímos
para continuar construindo o
recurso C de recebimento de Bitcoins, sim.
32. 30 Receber bitcoin parte 6 skillshare 2: Neste vídeo,
processaremos os
UTXOs das transações que
chegam à nossa carteira. Portanto, no método de
evento sem aplicativo, no ouvinte da transação
recebida, vamos adicionar a seguinte instrução
if. Se a
lista de endereços não estiver vazia, chamaremos o método de
atualização
no serviço utxOS de atualização que criaremos. Esse método
usará os endereços e
o nome da carteira atual como parâmetros. Vamos injetar esse
serviço nessa classe. Agora, vamos criar esse serviço no pacote de serviços de pontos da GUI. Vamos adicionar a
anotação do serviço a ela. De volta ao ouvinte da transação
recebida. Vamos terminar de injetar
o serviço. Agora, vamos criar
o método de atualização no serviço de atualização UTXos. Adicionaremos uma
anotação assíncrona a esse método e a
executaremos no thread de serviço de execução padrão. A razão para
executar esse método e outro tópico é que ele
chamará o
método de API de nós não gastos da lista, que pode ser lento. Então, vamos executá-lo de forma assíncrona
para evitar o bloqueio da interface do usuário. No método de atualização, chamará o método list unspent
da lista de nós do cliente não gasto. Vamos injetar o cliente
nessa classe. Vamos passar os endereços e o nome da carteira como
parâmetros para a lista. método não gasto armazenará o resultado da
chamada do método na variável utxOS. Agora, injetaremos uma nova atualização, serviço
atual de endereços de carteira, nessa classe. Vamos criá-lo no pacote de serviços de
pontos da GUI. Vamos terminar de injetar
o serviço. Em seguida, chamaremos
o método de atualização passando utxOS como
parâmetro para ele. Vamos criar esse método. Vamos adicionar a
anotação de serviços a ela. Agora, adicionaremos o código a
seguir para criar um mapa
em que as chaves são endereços e os
valores são listas de UTXOs contendo
esses endereços. Para fazer isso, chamaremos o método collect
no fluxo UTXO passaremos a chamada MyMethod
agrupando coletores para ele. Passando o
método de endereço UTXO como seu parâmetro. Armazenaremos o valor
retornado na variável
do grupo UTxOS. Então, para cada grupo par de valores-chave
UTXO definirá o saldo
de endereço correspondente. São confirmações
e o mercado é usado. Vamos implementar o método
de equilíbrio definido. Retornará a soma de todos os valores de
UTXOs usando esse código. Usando o método map to double
no fluxo da lista UTXO, obterá um fluxo com todos os valores
de UTXO da lista UTXO. Para obter sua soma basta chamar o
método de soma no resultado. Agora, vamos injetar a
carteira atual nessa classe. Em seguida, chamaremos
o método balanceado de endereços do
conjunto de carteiras atual , que criará
a passagem do endereço e da
soma como seus parâmetros. Vamos criá-lo. Dentro, ele chamará o método balanceado de
endereços definidos, passando os mesmos
parâmetros para ele. Em seguida, criaremos esse método. Dentro, ele chamará os
endereços de obtenção como método de mapa, que criará.
Vamos criá-lo. Ele retornará um mapa em que
as chaves são endereços, cadeias de caracteres e os valores
são endereçados como objetos. Ao usar o código a seguir,
retornará um mapa contendo
todos os endereços. Ao chamar o método string
nos endereços, os valores
obterão um fluxo contendo todos os mapas do campo privado dos
endereços. Então, com esse
método flatMap, a chamada
converterá o fluxo de mapas
em um fluxo de entradas de mapa. Finalmente, usando o método de
coleta no fluxo resultante e o método de dois mapas
com esses parâmetros obterá o mapa desejado. No resultado de obter
endereços, uma chamada de mapa chamará o método get para obter
um objeto de endereço por sua string de endereço. Em seguida, definiremos o
saldo do endereço para a variável soma. Agora, vamos criar o método
de saldo definido no registro de endereço. Opa, não podemos adicionar
configuradores em um registro, então teremos que converter o registro de
endereço em uma classe. Vamos fazer isso com uma pequena
ajuda do nosso IDE. Vamos remover esses métodos
porque não precisaremos deles. Vamos criar o centro de
equilíbrio agora. E remova a palavra-chave
final aqui. No gerador
sequencial de endereços. Vamos adicionar zero como o terceiro parâmetro na instanciação do
endereço aqui. Vamos também mudar
o nome dos getters, fazendo com que eles comecem com get. Agora, no serviço de atualização de endereços da
carteira atual, vamos criar o método de
confirmação definida. Confirmação. Nesse caso, nos referiremos ao saldo do
endereço e ele será definido como
igual ao número de conformações do UTXO com menos conformações
para esse endereço. Por exemplo, digamos que um endereço tenha um
saldo de dois Bitcoins, com cada Bitcoin vindo de
uma transação diferente. Uma dessas transações
tem duas confirmações, a outra tem apenas uma. Nesse caso,
consideraremos que o saldo dos endereços
tem uma conformação. Para fazer isso,
usaremos o código a seguir. Obteremos um stream contendo todas as confirmações
da lista UTXOs aprovada. Para obter esse fluxo, chamaremos o método map
too long no fluxo da lista UTXO, passando a referência do
método de confirmações UTXO como seu parâmetro. Em seguida, usando o método Min e o
método good is long, retornará o número mínimo
de confirmações
no fluxo e o armazenará
na variável de confirmações. Em seguida, passaremos as
confirmações e as variáveis de endereço para a chamada atual do método de
confirmação de endereço definido pela carteira. Agora vamos criar esse método
na classe de carteira atual. Ele chamará o método de
confirmação de endereço
definido de endereços , passando os mesmos
parâmetros recebidos. Vamos criar esse método
na classe de endereços. Usaremos o método get
addresses como map para obter o endereço e
definir suas conformações. Agora, vamos criar o método
de confirmações definidas na classe de endereço. Vamos usá-lo para definir o campo de
confirmações que criaremos. Vamos criar esse campo e
adicioná-lo ao construtor. Em seguida, vamos adicionar esse parâmetro à classe
do
gerador sequencial endereços
na instanciação do endereço. Finalmente, vamos criar
o
método mark is used no serviço de atualização de endereços de
carteira atuais. Um dos objetivos de
nossa carteira e de muitos outros é evitar a reutilização de endereços
ao receber Bitcoins. Por motivos de privacidade. Para fazer isso, devemos primeiro comercializar vestidos que tiveram
transações com eles conforme usados. O método de marcação como usado
será usado para esse insight. Ele chamará a atual roupa do mercado de
carteiras. Como método usado, criará a
passagem do endereço
como seu parâmetro. Vamos criá-lo. Dentro dele, chamará o método
mark is used da classe de endereços
que passa o endereço para ela. Em seguida, criaremos esse método. Dentro, ele usará
os endereços de obtenção como método
matemático para obter o
endereço e o mercado será usado. Finalmente, vamos criar o método mark is used
na classe de endereço. Aqui, basta definir
se o combustível usado é verdadeiro. Vamos criar esse
campo nesta classe.
33. 31 Receber bitcoin parte 7 skillshare 2: Neste vídeo, finalmente
conectaremos tudo o que fizemos
nas últimas aulas para exibir informações de
nossos endereços
na tela. Portanto, no pacote observables criará a classe da linha de
endereço. Como o nome sugere, essa classe modelará uma
linha na tabela de endereços. Vamos criar os seguintes
campos nessa classe, cada um para uma coluna
na tabela de endereços. O primeiro campo será uma propriedade de
string chamada balance, que será instanciada aqui com uma nova propriedade de string simples. O próximo campo será uma propriedade longa
chamada confirmations e será instanciado com uma nova propriedade longa simples. O último campo será uma propriedade
de string chamada address. Ele será instanciado com uma
nova propriedade de string simples. Agora, com a ajuda do IDE, vamos criar getters
para cada propriedade. Observe que, ao criar getters para campos de propriedades Java FX, o IDE cria dois getters, um para a propriedade e outro para o conteúdo
da propriedade. Agora, vamos criar o seguinte construtor
para essa classe. Ok, agora que
modelamos a linha de endereço, criaremos um código para
preenchê-la ao atualizar nossos endereços. Para fazer isso, vamos acessar o serviço de
atualização de
endereços atuais da carteira. No método de atualização, depois de marcar o
endereço como usado, vamos chamar o método set address row na carteira
atual, passando o endereço
como parâmetro. Em seguida, vamos criar o método
set address row. Para implementar esse
método, adicionará o
campo de linhas de endereço a essa classe. Vamos criar a classe
de linhas de endereço no pacote observables. Vamos instanciar isso aqui. Agora, chamaremos o método set
address row
na propriedade address rows passará um
objeto de endereço para ele. Esse objeto será obtido do campo de endereços usando o método get address que
criaremos passando a string de
endereço para ele. Para criar esse método
, basta selecionar esse trecho de código e extrair um método dele usando o ID. Vamos substituir todas as
ocorrências de código por esse método e tornaremos público o método
gerado. Agora, de volta à classe de carteira
atual. Vamos criar o método set
address row na classe address rows. Para fazer isso,
criaremos uma
variável de linha de endereço chamando o método
na classe da linha de endereço, passando o
objeto de endereço como seu parâmetro. Vamos criar o método de formulário
na classe da linha de endereço. Ele retornará uma nova linha de endereço, instanciando-a com
esses parâmetros. Vamos criar o método de boas
confirmações na classe de endereço. E agora podemos usá-lo aqui. Observe que aqui estamos simplesmente criando um objeto de
linha de endereço
convertendo os valores do campo de
endereço nos valores do campo da linha de endereço. Voltar para a classe de linhas de endereço. Criaremos o campo de endereço do
conjunto de estradas nesta classe. Será um conjunto observável com a linha de endereço como parâmetro
de tipo. Irá instanciá-lo aqui com um novo wrapper de
conjunto observável, passando um novo
conjunto de hash vinculado para seu construtor. Esse objeto
publicará um evento para cada novo endereço inserido
ou removido e
será necessário atualizar
a tabela de endereços medida que a carteira atual
receber novas transações. Agora chamaremos o método de remoção do conjunto de
linhas de endereço, passando a
linha de endereço como seu parâmetro. Em seguida, chamaremos o método
add nele, passando a mesma
linha de endereço como seu parâmetro. Você pode se perguntar por que
estamos removendo e adicionando a mesma
linha de endereço no conjunto. Bem, isso é um pouco complicado. Se não removermos a linha de
endereço primeiro e inserirmos uma linha de endereço que já
esteja no conjunto. O conjunto observável
não publicará um evento indicando que uma
linha de endereço foi adicionada a ele. Há outra coisa que
precisamos fazer para que isso funcione. Quando removemos uma linha
de endereço do conjunto usando
o método remove, esse método usa
o método equals
da linha de endereço para definir qual linha de endereço ele
removerá do conjunto. Consideraremos que as
duas fileiras do I Dress são iguais se tiverem
o mesmo endereço. Portanto, devemos implementar
o método equals na classe
da linha de endereço. Vamos fazer isso. Adicionaremos os métodos de código igual e hash usando
esse recurso do IDE. Certifique-se de que essa
caixa de seleção esteja marcada para gerar métodos
usando getters. Agora, optaremos por usar somente o campo de endereço para
gerar o método equals. E o mesmo campo para gerar o método hashCode e selecionar o campo de endereço aqui para
defini-lo como não nulo. Ok, o IDE
gerou os métodos de código igual
e hash. Agora vamos para a tabela de
endereços. O Fxml adicionará IDs de FX a cada
tag de coluna da tabela. Os endereços. O controlador de tabela precisará desses IDs de FX para vincular e
manipular essas colunas posteriormente. Primeiro, o endereço da coluna, depois o saldo da coluna
e, finalmente, as conformações da
coluna. Agora, vamos até o controlador da tabela de endereços adicionará os seguintes campos, cada um correspondendo
a uma tag com um ID de ética na tabela de
endereços, FXML. Os nomes desses
campos devem ser iguais
aos IDs FX das tags.
Eles estão vinculados a. Primeiro, a tabela de endereços, depois o endereço da coluna, o saldo da coluna
e as confirmações da coluna. Agora, adicionaremos o
método inicializado a essa classe. Lembre-se de que os métodos
inicializados nos controladores
Java FX
são chamados Quando a estrutura está inicializando
esses controladores. Nesse método,
adicionaremos um código que vinculará a tabela de endereços e suas colunas aos nossos observáveis de função de
endereço. Para fazer isso, chamaremos
o método set items
na tabela de endereços, pois seu argumento passará por
uma nova lista filtrada. Isso é necessário
porque queremos mostrar somente endereços com um balanceado maior que zero
na tabela de endereços. Como primeiro parâmetro da
lista filtrada,
passará pelas linhas de endereço
observáveis da carteira atual. Então, vamos injetar a
carteira atual nessa classe. Em seguida, chamaremos o método get observable address
rows nele. Vamos criar esse método. Ele retornará uma lista observável com a linha de endereço como
parâmetro de tipo. Em seguida, retornaremos a boa chamada do
método de linhas de endereço
observáveis no campo
de linhas de endereço. Vamos criar esse método
na classe de linhas de endereço. Dentro dele, retornará o
campo da lista de linhas de endereços que criaremos. Vamos criá-lo. Esse campo será instanciado aqui com um novo wrapper de lista observável passando uma lista vinculada
como seu parâmetro. Agora, temos que fazer com que a lista
observável responda às inserções e remoções de linhas de endereço no conjunto de linhas de
endereço. Faremos isso no construtor da
classe. Primeiro, criaremos uma variável de listener de
mudança definida. Vamos defini-la como essa função
lambda. O parâmetro de alteração
aqui representa uma inserção ou remoção de
uma linha de endereço no conjunto. Se a alteração foi uma remoção
, removeremos
o elemento
removido da lista de linhas de endereço. Se a alteração fosse uma inserção. Em seguida, adicionaremos o elemento adicionado à lista de funções de endereço. Por fim, adicionaremos
esse ouvinte
ao conjunto de linhas de endereço
usando esse método. Agora, de volta ao controlador da
tabela de endereços. O segundo parâmetro
da lista filtrada é usado como condição de filtro
para exibir linhas. Será uma função lambda com um parâmetro de endereço rho. O corpo da função
será esse código que
verificará se o
saldo da linha de endereço é maior que zero. Dessa forma, atingimos
nosso objetivo de
exibir apenas endereços com um
balanceado maior que zero. Agora, para cada campo de coluna, precisamos definir uma fábrica de
valores de célula que será usada para preencher cada célula
da tabela de endereços. Para isso, usaremos
o código a seguir. A fábrica de valor da propriedade será usada para obter cada propriedade
real de endereço e vincular seu valor à célula
correspondente. Ele sabe qual endereço de propriedade
real queremos vincular à coluna ao combinar o nome que
estamos passando como parâmetro com o
nome da propriedade. Há mais uma
coisa que devemos fazer para que nosso
recurso de recebimento de Bitcoin funcione corretamente. Vamos para a classe de carteira
atual no método set addresses, que é chamado quando uma
nova carteira é criada Precisamos incluir esse código
para garantir que o endereço tenha
surgido de um anterior
a carteira criada é limpa. Chamaremos o método
clear de linhas de endereço , que criará. Para fazer isso, vamos
criá-lo. Aqui. Simplesmente chamaremos
o método clear
no conjunto de linhas de endereço e
na lista de linhas de endereço. Agora vamos testar nosso recurso. Certifique-se de que seu nó
principal do Bitcoin esteja funcionando. Vamos fazer o teste de recebimento de
Bitcoin e executá-lo. Ótimo, funcionou. Observe que a primeira linha
da tabela de endereços foi preenchida corretamente com um saldo de
um Bitcoin, conforme o esperado. Bom trabalho. Nos próximos vídeos, adicionaremos mais
casos de teste para garantir que nosso recurso de recebimento de Bitcoin esteja funcionando corretamente em
diferentes cenários.
34. 32 Receber bitcoin parte 8 skillshare 2: Neste vídeo, adicionaremos
mais casos de teste para garantir que nosso
recurso de recebimento de Bitcoin funcione corretamente em
diferentes cenários. No primeiro
cenário adicional, testaremos se o mesmo endereço pode receber Bitcoins de duas transações, um Bitcoin de cada. Verificaremos se o saldo do
endereço foi atualizado para dois bitcoins. Então, vamos copiar o conteúdo desse método e
colá-lo abaixo. Vamos modificar o
nome do teste para receber Bitcoins em duas transações
no mesmo endereço. Agora, vamos selecionar esse código e extrair um método dele
com a ajuda do id. Vamos nomeá-lo, enviar
Bitcoin e peso. Chamaremos esse método duas
vezes, pois queremos enviar transações
para esse endereço. Vamos modificar o método de envio de Bitcoin em peso, incluindo
o código a seguir. Verificaremos se o endereço
na primeira linha da tabela tem um saldo igual ao parâmetro de valor
total esperado. Vamos adicionar esse parâmetro
à assinatura do método. Ele terá um
valor padrão de 1,0. Nessa chamada de método, vamos adicionar 2.0 como
segundo parâmetro, pois esperamos que
o saldo do endereço seja igual a dois. Vamos adicionar dois ao nome
da carteira. Há um problema com
nosso ambiente de teste. No teste de registro,
só é possível minerar 15.000 blocos com recompensas em
blocos. Portanto, nesse método, é demais
minerar 1.000 blocos ao chamar o método generate
to address. Vamos chamá-lo apenas se o
saldo da carteira de teste for inferior a
50 e gerar apenas
150 blocos para cada chamada. Dessa forma, evitamos a necessidade de
redefinir nosso
ambiente de teste de registro com muita frequência. Vamos também substituir esse código pelo método
de enviar Bitcoin
e esperar. Agora, vamos tornar nossos testes um pouco mais resistentes
às condições da corrida. Percebi que,
às vezes, esses testes enviam bitcoins para nossas carteiras
de
aplicativos antes de serem totalmente carregados. Portanto, essas transações não
foram capturadas
pelo aplicativo e os
testes falham por esse motivo. Então, depois de criar uma carteira e antes de enviar
Bitcoins para ela, vamos chamar o método de sono
com esses parâmetros. A chamada do método sleep fará com que o aplicativo
espere 10 s antes de enviar Bitcoins, tempo suficiente para que a nova carteira seja
carregada completamente. Dependendo do seu computador, talvez seja necessário aumentar
a constante de tempo limite. Agora, antes de executar os testes, vou redefinir meu ambiente de
teste de registro. Preciso fazer isso porque
ele já gerou 15.000 blocos e a geração de blocos não está mais produzindo
Bitcoins. Então, vou até a pasta
onde a blockchain está armazenada e removerei a pasta reg
test dentro dela. No seu caso, você pode descobrir em
qual pasta ela está localizada
verificando o valor DIR de dados
em seu arquivo bitcoin.com. Agora, vamos executar nosso node Bitcoin e executar nossos testes de recebimento de
Bitcoin. Ótimo, os testes foram aprovados. Quando recebemos
Bitcoins em nossa carteira, queremos que o próximo
endereço de recebimento seja alterado. Dessa forma, evitamos a
reutilização de endereços. É importante
usar apenas um endereço para receber a
transação, para que terceiros possam rastrear facilmente quantos Bitcoins você tem e com
quais endereços você faz
transações. Para cobrir esse cenário, vamos criar o teste a seguir. Copie o último teste
e cole-o abaixo. Vamos renomeá-lo para
receber Bitcoins em duas transações, dois endereços
diferentes. Vamos mudar o nome da carteira
criada para minha carteira de teste três. Agora, antes da segunda chamada do método de enviar
Bitcoin e esperar, vamos adicionar esse código para consultar
o campo de endereço de recebimento novamente e armazenar seu conteúdo
na próxima variável de endereço. Agora, altere o
primeiro parâmetro
desse método para a
próxima variável de endereço. E esperamos que o valor
total de Bitcoin para esse endereço
seja igual a 1,0. Além disso, esperamos que
o tamanho dos itens da tabela seja igual a 21
linhas para cada endereço. Então, vamos modificar esse
método para aceitar o
tamanho esperado da tabela como parâmetro. Vamos adicionar esse parâmetro a ele com um valor padrão de um. Substituirá esse
valor aqui
para esperar que o número de
linhas da tabela seja igual a ele. E substituiremos o índice de itens em pontos da
tabela pelo tamanho
total esperado menos um para esperar que a última linha
no saldo da tabela seja igual ao valor
total esperado para aquela linha. Finalmente, vamos parametrizar
o terceiro argumento dessa chamada de método para dois. Vamos fazer nossos testes. Como esperado. O terceiro teste falhou porque ainda não
implementamos o recurso de alterar o endereço de recebimento
depois de usá-lo. Vamos fazer isso agora. Então, vamos para o serviço de atualização de
endereços de carteira
atuais. Dentro disso, para cada bloco, vamos chamar o método de atualização do
endereço de recebimento que criaremos. Ele tomará o endereço
como parâmetro. Vamos criá-lo. A primeira coisa que
faremos é chamar o método do tipo get
address na carteira atual. Passar o endereço
como parâmetro
armazenará o resultado
da chamada do método na variável de tipo de endereço. É importante
saber o tipo
de endereço do endereço substituído, pois ele precisa ser substituído por um endereço do mesmo tipo. Então, vamos criar esse método
na classe de carteira atual. Ele simplesmente
chamará o método do tipo
get address type. Criaremos a passagem do
endereço como seu parâmetro. Vamos criá-lo. Agora. Chamaremos o método get address e
retornaremos seu tipo de endereço. Vamos criar o método get
address type na classe de endereço. Dentro dele, retornará o
campo do tipo de endereço que criaremos. Vamos criar esse campo e
adicioná-lo ao construtor. Também vamos corrigir o gerador
sequencial de endereços para adicionar o último argumento
à instanciação do endereço. Adicionaremos esse tipo de endereço como um parâmetro a esse método. E incluiremos o
tipo de endereço nessa chamada de método
chamando o valor do método
na classe do tipo de endereço. Agora, de volta ao serviço
Atualizar
endereços da carteira atual , calculará o valor do próximo índice de
endereços chamando o
método fine next address index na carteira atual, passando o endereço
digite como parâmetro armazenará o resultado da chamada
do método na próxima variável de índice de
endereço. Vamos criar esse método. Aqui. Chamaremos o próximo
índice de endereço fino no campo de endereços, passando o
tipo de endereço como parâmetro. Vamos criar esse
método na
classe de endereços com o código a seguir, obteremos o último endereço usado para armazená-lo na variável de
endereço. Obterá todos os objetos de
vestuário com o tipo de endereço fornecido
e obterá um stream a partir deles. Em seguida, classificaremos
o fluxo obtido usando o método classificado com
os seguintes parâmetros. Usarei o método de comparação de
pontos do comparador, passando o método address
get indexed como o primeiro parâmetro e o
comparador de ordem inversa como o segundo. Dessa forma, obteremos um fluxo de endereços
ordenado de forma inversa por seus índices. Agora, filtraremos
o fluxo para obter uma string contendo
somente endereços usados. Para fazer isso, vamos
criar um getter para o campo usado
na classe de endereço. Eles usaram getter is called é usado porque é
assim que o IDE nomeia os getters
booleanos de volta à
classe de endereços e
passará o método de endereços usados como o prompt para a chamada do método de
filtro. Agora, chamaremos o
primeiro método fino no resultado. Para obter o primeiro endereço usado e o fluxo ordenado invertido, que é igual ao
último usado para endereçar. E se nenhum endereço usado for encontrado. Nesse caso, usaremos o método
or else para retornar null. Adicionaremos a seguinte declaração
if. Se o endereço obtido for nulo, retornaremos zero
como o próximo índice. Caso contrário, retornaremos o
último índice de endereço mais um. Agora, de volta ao
serviço
Atualizar endereços de carteira atuais , obterá
o próximo endereço ligando para o método get
address ID na carteira atual. Vamos passar o
próximo índice de endereço e o
tipo de endereço como parâmetros. Vamos criar esse método
na carteira atual. Retornarão, eles receberão a chamada do método de identificação de
endereço no campo de endereços, passando os mesmos
argumentos recebidos de seus parâmetros. Vamos criar esse método
na classe de endereços. Receberá todos os
objetos de vestuário com o tipo de endereço
fornecido. Em seguida, vamos convertê-lo em uma lista. Em seguida, obteremos o
endereço por índice. Para fazer isso, precisamos mudar o tipo de índice de endereço
para um objeto longo, não apenas para o tipo primitivo. Em seguida, chamaremos
o valor int, passando-o como o parâmetro
getMethod. Agora, retornaremos
a string
de endereço do endereço obtido. Agora, de volta ao serviço Atualizar endereços de
carteira atuais basta definir
o endereço de
recebimento da carteira atual como o próximo endereço
obtido. Vamos fazer mais uma coisa
antes de testar nosso código. Lembre-se de que o códon, essa classe, será executado
em um novo thread. No Java FX, é
uma boa prática executar código que modifica a interface do usuário
somente no thread principal. Para fazer isso, vamos chamar
o método dot run
later da plataforma passando uma função
Lambda para ela. Vamos mover essas duas
linhas para o corpo da função
lambda, pois elas causam alterações que
afetarão a interface do usuário. Agora, vamos executar nossos testes de recebimento de
Bitcoin novamente. Ótimo. O
campo do endereço de recebimento foi atualizado após recebimento dos fundos e
a aprovação dos testes. No próximo vídeo,
continuaremos aprimorando nossos testes e adicionaremos
mais um cenário de teste. C, sim.
35. 33 Receber Bitcoin parte 9 skillshare 2: Neste vídeo, continuaremos
aprimorando nossos testes e adicionaremos mais
um cenário de teste importante para o recurso de recebimento de
Bitcoin. Uma coisa está faltando
em nossos testes. Ainda não sabemos se
os endereços corretos estão sendo gerados e se estão respeitando a sequência do
índice do caminho de derivação. Para verificar isso, vamos criar
o endereço é um método válido. Em seguida, o bloco do
primeiro teste chamado endereço é um método válido
que passa
o endereço, a semente mnemônica e o índice de endereço
esperado, que neste caso é
zero como seus parâmetros. Vamos criar esse método. Ele retornará um booleano. Vamos definir os nomes corretos dos
parâmetros. Aqui. Criaremos um novo objeto de semente
mnemônica e o armazenaremos na variável de semente
mnemônica. Vamos renomear o parâmetro de semente
mnemônica para a sequência de sementes mnemônica. Agora vamos instanciar
o objeto de semente mnemônico passando a string de semente mnemônica como parâmetro do construtor. Agora, vamos criar a
chave mestra com o código a seguir. Chamará o método de duas chaves
mestras no objeto semente mnemônico, passando uma string vazia como o primeiro parâmetro e o
prefixo privado da rede principal como o segundo. Agora, vamos criar
a string de
chave pub estendida com o código a
seguir. Usaremos o serviço estendido de chaves de
pub. Então, vamos
injetá-lo nessa classe. Em seguida, chamaremos o método
create nele, passando a chave mestra
como seu primeiro parâmetro. O segundo parâmetro será uma concatenação entre parte do caminho de derivação
do endereço do segmento e o parâmetro do índice. Vamos mudar o tipo de parâmetro do
índice para a classe inteira, para que possamos chamar o método
toString nela. O terceiro parâmetro será o tipo de endereço constante de
Segway. Em seguida, chamaremos o método get
key no resultado. Agora, obteremos o objeto de chave pub
estendida
da biblioteca Bitcoin Java usando a chave pub estendida
no método serializado, passando a string da chave
pub estendida conforme seu parâmetro obterá o endereço esperado usando o gerador de endereços de
segmentos. Vamos injetá-lo nesta classe. Em seguida, chamaremos o método
generate nele, passando a
chave pub estendida como seu parâmetro. Por fim, retornaremos o
resultado da comparação se o endereço esperado é igual
ao parâmetro de endereço. Agora vamos adicionar se o endereço
é uma chamada de método válida para verificar os endereços nos
outros métodos dessa classe. Neste método, vamos
adicioná-lo duas vezes. Na segunda vez, verificaremos
se o próximo endereço é igual ao
endereço esperado com o índice um. Vamos fazer nossos testes. Ótimo, os testes foram aprovados. Agora sabemos que os endereços estão sendo gerados corretamente. Agora vamos criar outro teste. O próximo teste
tentará transferir mais transações do que o
número de endereços gerados. Lembre-se de que definimos o número inicial de endereços
gerados como 20. Portanto, devemos verificar
o que acontece quando todos os
endereços gerados inicialmente são usados. Mas fazer um teste com 20 transações
levaria muito tempo. Então, alteraremos o número
inicial de endereços
gerados
no ambiente de teste para três posteriormente para
acelerar as coisas. Então, vamos copiar esse método
e colá-lo abaixo. Mude seu nome
para se receber Bitcoin em sete transações para endereços
diferentes,
com três endereços gerados em nossa carteira e sete transações, neste teste, nossa carteira precisaria para
gerar quatro endereços a mais do que o número inicial
para que esse teste seja aprovado. Vamos mudar o nome da
carteira criada para minha carteira de teste. Por enquanto, criaremos
um arquivo de propriedades para o ambiente de teste para alterar o número inicial de
endereços gerados para nossos testes. Então, vamos criar um
caminho de recursos dentro do pacote de teste. Selecione a
opção Recursos abaixo. Dentro dele, criará um arquivo chamado application
test dot properties. Copiaremos o conteúdo do
arquivo de propriedades do ponto do nosso
aplicativo e o colaremos aqui. Agora, vamos definir o número
inicial de
propriedades de endereços
gerados como três. Agora vamos para a classe de
configuração de endereço. O número inicial de endereços
gerados que
está retornando atualmente. 20 injetará esse valor
nessa classe
a partir do arquivo de propriedades usando
essa anotação de valor e esse campo privado. Agora, neste método, apenas
retornará o campo criado. Agora, para usar propriedades
do aplicativo, teste arquivos de
propriedades de pontos em nossos testes. Vamos para a aula de teste de GUI. Adicione essa anotação a ela. Ok, agora todo arquivo de teste que
estende o teste da GUI
obterá suas propriedades do arquivo de propriedades
do
ponto de teste do aplicativo. Agora, de volta ao nosso último teste. Vamos mudar o nome dessa
variável para o primeiro endereço. O nome dessa variável
para o segundo endereço. Agora vamos copiar essas
linhas e gerar mais
quatro transações para formar mais endereços recém-gerados, modificando seu
código adequadamente. Vamos mudar o tamanho esperado da linha da
tabela para sete. Vamos copiar essas linhas também para validar todos os endereços
gerados no teste. Vamos alterar os
parâmetros dos métodos conforme necessário. Agora, vamos fazer nossos testes. Como esperado. O
último teste falhou após a terceira transação que aconteceu porque a
carteira não conseguiu encontrar o quarto endereço, pois gerou apenas os três
primeiros endereços. No próximo vídeo,
vamos corrigir isso. Antes de terminar o vídeo, vamos adicionar o número inicial de propriedades
de endereços
gerados ao arquivo de propriedades de
pontos do aplicativo. Vamos configurá-lo para 20 para
que a carteira
funcione como antes no ambiente
sem teste.
36. 34 Receber bitcoin parte 10 skillshare 2: Neste vídeo, faremos
nosso último teste criado passar. Para fazer isso, vamos acessar o serviço de
atualização de
endereços atuais da carteira. Nesse método, vamos adicionar
a seguinte instrução if. Depois de calcular o
próximo índice de endereço. Dentro da instrução if, nós os chamaremos de método must
import addresses passando o próximo
índice de endereço e o tipo de endereço. Vamos criar esse método. Só importará endereços se o próximo
índice de endereços for igual
ao número total de endereços
na carteira atual com
um determinado tipo de endereço. Se for esse o caso,
significa que ficamos sem endereços e, portanto, não podemos preencher o
próximo endereço de nossa carteira sem
criar mais endereços. Dentro desse método,
retornará o resultado da verificação de se o próximo índice de
endereço é igual ao da carteira
atual. A chamada do
método de contagem de endereços passará o tipo de
endereço para esse método. E vamos criar esse método. Esse método retornará um int e
retornará os endereços, a chamada do método
get adresses count, passando o
tipo de endereço como seu parâmetro. Vamos criar esse método. Aqui, simplesmente
obteremos todos os endereços com o tipo de endereço fornecido
em uma lista e retornaremos o tamanho da lista ao serviço Atualizar endereços de
carteira atuais. No bloco if, primeiro obterá as chaves de pub
estendidas da carteira atual e as armazenará em uma variável. Vamos criar esse método. Aqui. Devolveremos o campo
estendido de chaves do pub. Vamos criá-lo. Vamos também adicionar um
setter para esse campo. Chamaremos esse conjunto ou, no atualização
do
serviço de carteira atual, atualizar o método de atualização. Passando as carteiras,
estendia as chaves do pub para ela. Agora, de volta ao serviço Atualizar endereços de
carteira atuais. Chamaremos o método de adicionar
endereços no serviço de endereço ADD. Passar as chaves de pub estendidas
obtidas anteriormente como seu primeiro parâmetro e o próximo índice de endereço
como seu segundo parâmetro. Vamos injetar esse
serviço nessa classe. Vamos criar esse serviço e
o pacote de serviços da API. Vamos adicionar a
anotação do serviço a ela. Agora, vamos terminar de injetar
esse serviço nessa classe. E vamos criar esse método
no serviço de endereços de anúncios. Vamos mudar o
nome desse parâmetro para do índice. O que planejamos fazer agora é
gerar endereços para as chaves de pub estendidas que
foram passadas como parâmetros. O número de
endereços gerados será igual
ao número inicial de
endereços gerados no campo injetado. E o primeiro índice de
derivação gerado pelo endereço será determinado pela variável de
índice firme, por exemplo, suponha que o número inicial de endereços
gerados seja igual a 20 e a
variável do índice from seja igual a 20. Nesse caso, esse
método
gerará vestidos com um
índice de derivação de 20 a 39. Para fazer isso, para cada chave de pub
estendida. Chamaremos o método add
addresses, passando a chave e o parâmetro
from index. Vamos remover essa letra S. Agora, vamos criar esse método
privado de adição de endereços. Ele chamará o método add
addresses
na chave pub estendida
como seu parâmetro. Usaremos o gerador
sequencial de endereços. Então, vamos
injetá-lo nessa classe. Chamaremos o método
generate
no gerador
sequencial de endereço, passando a chave
pub estendida, o tipo de chave pub estendida e a variável de índice from
como seus parâmetros. Vamos ver a implementação do
método generate. Irá alterá-lo para
gerar endereços com índices
de derivação usando
o parâmetro from index. Então, vamos adicionar do índice
como seu terceiro parâmetro. Aqui, na
chamada do método range, adicionará a variável
de índice from como
seu primeiro parâmetro. E a soma do parâmetro from
index e do número inicial de
endereços gerados como o segundo. Agora, de volta ao serviço de
endereço ADD. Vamos criar o método de
endereços de anúncios na classe de chave pub estendida. Vamos corrigir esse nome de parâmetro. Aqui. Chamaremos o método address add all passando o parâmetro
addresses para ele. Há um problema
com esse código. O campo de endereços é do tipo
lista, que é imutável. Isso significa que
quando tentamos adicionar itens a ele por meio
do método adicionar tudo, isso gerará um erro. Então, vamos alterá-lo para o tipo ArrayList,
que é mutável. Vamos também torná-lo definitivo
e instanciado aqui. Também vamos alterar o getter de
endereços e o método addresses para
obter e definir uma ArrayList. Também vamos remover
o
método de endereços definidos , pois não
o usaremos mais. Voltar ao serviço de adicionar
endereços. Vamos agrupar o resultado da
chamada do método generate em uma nova ArrayList, já que o método de endereços de anúncios agora aceita somente uma ArrayList. Agora vamos analisar os fatores que
criam o serviço de carteira. Uma vez que fizemos
mudanças que afetaram. Primeiro, vamos remover o
serviço gerador sequencial de endereços dessa classe. Vamos também remover esse método. Vamos remover essa linha de código. Usaremos o serviço de adição de
endereço para adicionar endereços às chaves de pub
estendidas. Então, vamos
injetá-lo nessa classe. E vamos chamar o método add
addresses nele, passando as chaves pub estendidas
e zero como seus parâmetros. Vamos terminar de
injetá-lo nesta classe. Agora, de volta ao serviço Atualizar endereços de
carteira atuais. Chamaremos o
método set addresses na carteira atual, passando as
chaves de pub estendidas como seu parâmetro. Vamos remover a chamada de
método limpa das linhas de
endereço nos métodos de conjunto de
endereços, pois não
queremos remover
nenhuma linha da tabela de endereços depois de definir esses endereços. Em vez disso, vamos criar
um método chamado linhas de endereço
claras,
que fará isso. Em seguida, no método de atualização
do serviço de atualização da
carteira atual, chamaremos esse método para limpar as linhas de endereço somente
após adicionar uma nova carteira. Agora, de volta ao serviço
Atualizar
endereços de carteira atuais ,
obterá todos os endereços
recém-gerados
na carteira atual e
os armazenará nessa variável. Para obter os endereços, chamaremos o método get addresses as strings
na carteira atual. Passando o próximo
índice de endereço como seu primeiro parâmetro. E a soma do
próximo índice de endereços e do campo
do número inicial de endereços gerados
como segundo parâmetro. Vamos injetar esse
campo nessa classe. Vamos adicionar a anotação do
qualificador para usar o bean definido
na classe de
configuração de endereço para injetar o valor
desejado nesse parâmetro. Agora, vamos criar esse método. Vamos mudar esses nomes de
parâmetros para do índice dois. Esse método
retornará os endereços, obterá endereços como uma chamada de
método de cadeias de caracteres passando os mesmos
parâmetros recebidos. Vamos criar esse método
na classe de endereços. Esse método retornará
todos os seus endereços com índices entre os parâmetros
do índice dois, mas sem incluir a escada. Para fazer isso, ele retornará
o código a seguir. Usaremos o
método flatMap para converter todos os endereços em um
fluxo de objetos de endereço. Em seguida, filtraremos
o fluxo para
retornar somente endereços com
índice
maior ou igual à variável de índice
firme e menor que as
duas variáveis de índice. Em seguida, chamaremos um mapa
no resultado para retornar um
fluxo de cadeias de endereço. Por fim,
converteremos o resultado uma lista e o retornaremos. Agora, de volta ao serviço
Atualizar
endereços de carteira atuais , usaremos os clientes de
endereços de importação múltipla de nós para importar os endereços recém-gerados
em nosso nó Bitcoin. Lembre-se de que isso
é
necessário porque é necessário que o
node conheça
nossos endereços para poder enviar transações
relacionadas para
nossa carteira de aplicativos. Então, vamos
injetá-lo nessa classe. Agora, chamaremos o método de
endereços de entrada nele, passando o nome da carteira atual, as cadeias de endereço e uma
nova data como parâmetros. Ótimo, nosso
recurso de rotação de endereços deve funcionar agora, mesmo depois de todos os endereços
gerados inicialmente serem usados. Mas vamos lidar com
outro problema aqui. Estamos definindo o
próximo endereço como o endereço de recebimento
em nossa carteira. Mesmo que seja o
tipo de endereço, é um endereço de alteração. Vamos corrigir isso. Como queremos apenas endereços
com o tipo Segway,
não o tipo de mudança de Segway sendo chamado de
endereços de recebimento em nossa carteira. Então, adicionaremos esta declaração if. Se o tipo de endereço for igual à constante de
endereço principal
, isso o definirá como segue. Agora. Em seguida, definiremos o
próximo endereço como o próximo endereço de recebimento
na carteira atual. Mais uma coisa, vamos remover
essa plataforma. A chamada run later chamará o
método run later , envolvendo apenas o código que realmente mudará a interface do usuário. Então, vamos usá-lo para encapsular apenas a chamada nominal de
endereços do conjunto de carteiras atual. Também vamos usá-lo para encerrar a chamada
do método de endereço de
recebimento do conjunto atual da carteira. Dessa forma, evitamos
bloquear a interface do usuário ao comunicarmos com
nosso nó Bitcoin na chamada do método de importação de
endereços. Agora vamos para o controlador da tabela de
endereços. Percebi que o
TableView às vezes não é atualizado para refletir o estado
real de suas linhas. Para corrigir isso, vamos adicionar
esse código a esse método. Adicionará um ouvinte às linhas
de endereços
observáveis da carteira atual. No corpo deste
lambda, simplesmente
chamará o método de atualização
na tabela de endereços. Dessa forma, para cada atualização
nos endereços de nossa carteira, garantimos que,
na visualização da tabela atualizaremos seu
estado e mostraremos as informações atuais dos endereços de nossa carteira
na tela. Agora, vamos ao
teste do gerador
sequencial de endereço e adicionar zero como o terceiro
parâmetro do método de geração para que esse
teste continue funcionando. Também vamos corrigir o teste do serviço de criação de
carteira. No método de configuração, vamos instanciar o serviço de endereço
ADD, passando o gerador
sequencial de endereços como seu parâmetro. E vamos substituir
o terceiro parâmetro
do serviço de criação de carteira
pelo serviço de endereço ADD. Agora, no último teste de
recebimento de Bitcoin, vamos fazer uma pequena mudança. Depois de enviar Bitcoin
para o terceiro endereço. Vamos adicionar o
tempo limite de passagem da chamada do
método suspenso e os segundos
como argumentos. Vamos também adicionar a
mesma chamada depois enviar Bitcoins para
o sexto endereço. O motivo dessas
chamadas é que, antes enviar Bitcoins para o
quarto e sétimo endereços, precisamos
gerá-las e importá-las para nossos nós antes de aceitar
transações para eles. E o
processo de importação leva algum tempo. Vamos finalmente executar todos os
nossos testes de aplicativos. Ótimo, todos os testes foram aprovados. Finalmente concluímos
o básico sobre
o
recurso de recebimento de Bitcoin em nossa carteira. Agora, começaremos a implementar a observação de novos
blocos que são adicionados
ao blockchain para que possamos
atualizar o número de conformações que são
endereços com C, sim.
37. 35 Receber bloco parte 1 skillshare 2: Neste vídeo,
faremos testes para garantir que, quando um bloco for
minerado no Blockchain, nossa carteira receba transações
atualizadas com conformações crescentes. Então, vamos mover os métodos
auxiliares na classe de teste
Bitcoin de recebimento para o teste de GUI para que possamos usar esses métodos em outras
classes que os estendam. Agora, vamos mover todas
essas propriedades para a classe GUI também
pelo mesmo motivo. Agora, vamos cortar essas duas linhas e colá-las na carteira de
carga e adicionar método
balanceado
na classe de teste de GUI. No método de configuração
na classe de teste recebida, chamaremos esse método. Vamos excluir todas essas
importações não utilizadas nessa classe. Na classe de teste de GUI, vamos proteger esses métodos
e propriedades. Agora, no pacote de teste da GUI, vamos criar a classe de teste do
bloco receptor. Isso estenderá a classe de teste de GUI. Vamos copiar o método de configuração e o
teste de recebimento do Bitcoin e colá-lo aqui. Vamos também copiar
o primeiro teste
no teste de recebimento de Bitcoin
e
colá-lo na classe de teste do
bloco receptor. Ele será usado como um modelo para o próximo teste que criaremos. Vamos mudar o nome da carteira
criada para minha carteira de teste cinco. Vamos mudar o nome
do tubo de ensaio para
receber Bitcoin e adicionar confirmações de
hashtag, confirmações para
receber esse vestido. As conformações da hashtag
serão interpoladas pela
variável de teste de confirmações que criaremos. Agora, após o envio, os Bitcoins chamarão o método mine
blocks, passando a
variável confirmations como seu parâmetro. Vamos criar esse método. Ele usará um int
como parâmetro. Neste método, usaremos
o node generate para direcionar o cliente
aos blocos de mineração. Então, vamos colar
um código nele. Na classe de teste da GUI, copie essa linha de código
e cole-a aqui. Modifique o
nome da variável de endereço para anotar o endereço. Faça o mesmo com
essa outra linha. Altere o
segundo parâmetro do método de geração para blocos. Portanto, ele usará essa variável para definir o número
de blocos que
minerará e alterará esse
parâmetro para o endereço da nota. Agora, vamos copiar esse peso para uma chamada de método e colar aqui. Exclua essas partes do código. Esse método aguardará até que o valor da célula de
confirmação da primeira linha da tabela de endereços seja igual à variável blocks. No bloco Venn, verificará se o valor da célula de
confirmação da primeira linha da tabela é igual à variável de
confirmações. Vamos incluir uma cláusula where. Aqui. Definiremos que a
confirmação é variável para alguns valores de teste. Adicionaremos um espaço reservado para a segunda coluna
na WhereClause, porque aparentemente ela só funciona quando tem
duas ou mais colunas. Vamos definir os
valores das confirmações para 12,3. Agora, vamos executar nosso node Bitcoin e executar nosso novo teste. Ótimo, os testes foram aprovados. Agora, vamos fazer outro teste
para o cenário a seguir. Queremos saber
o que acontece quando um endereço recebe
duas transações. E a segunda transação tem menos conformações
do que a primeira. Nesse caso, esperamos que o número de
conformações do endereço seja igual
ao número de conformações
da transação com menos
conformações nesse endereço. Então, vamos duplicar
o primeiro teste. Vamos mudar seu nome para receber Bitcoin e considerar a transação com
menos conformações como confirmações de endereço. Vamos mudar o nome de
criação da carteira para minha carteira de teste seis. Agora, vamos duplicar
essas linhas de código para enviar bitcoins e
minerar blocos novamente. Na segunda
chamada de blocos de mina, adicione menos um em seu parâmetro para minerar menos blocos após a
segunda transação. No bloco, esperamos
confirmações menos uma como o número de confirmações na
primeira linha da tabela. Vamos excluir essa
linha, pois não
queremos esse caso de teste
porque ela
tentaria evitar zero blocos na segunda
chamada de blocos de minas,
o que falharia. Vamos fazer nossos testes novamente. Ótimo, os testes foram aprovados. Portanto, concluímos que
nossa carteira já está preparada para atualizar o número de conformações de nossos endereços. Isso porque, após
cada bloco de mina, o nó envia uma mensagem
por meio de zero MQ para nosso aplicativo contendo as transações
importadas anteriormente, mas com um
número atualizado de confirmações.
38. 36 Receber transação parte 1 skillshare 2: Neste vídeo, começaremos a criar a tabela de transações. Essa tabela será semelhante
à tabela de endereços, mas em vez de linhas contendo informações sobre endereços, ela conterá
informações sobre cada transação que nossa
carteira envia ou recebe. Então, vamos começar a criar um teste de
GUI para essa tabela. No pacote de GUI, crie uma classe chamada teste de transação de
recebimento. Copie esses métodos
do teste do bloco receptor
e cole-os aqui. Essa classe estenderá
a classe de teste de GUI. Altere o nome do teste para que a transação
deve ser recebida. Vamos formatar esse método. Remova o bloco it's where, altere o nome de criação da carteira para meu teste enquanto estiver com sete anos. Exclua essa linha. Agora, depois de chamar
o método sleep, vamos fazer o teste
clicar em um componente com uma guia de identificação ética das
transações. Agora, vamos adicionar outro parâmetro
opcional ao método de enviar Bitcoin
e esperar. Esse parâmetro será uma string e será chamado de componente de
pesquisa. Seu valor padrão será tabela de endereços de
hashtag. Vamos substituir
esse parâmetro na chamada
do método de pesquisa pela variável do componente de
pesquisa. Agora, no teste, vamos adicionar esses parâmetros
ao método de enviar Bitcoin
e esperar. O quarto parâmetro será a tabela de transações de
hashtag. Dessa forma, após o envio de
uma transação, essa chamada de método
aguardará que a tabela de transações seja preenchida com uma
linha contendo um saldo de 1,0 Bitcoin. Agora, vamos mudar também
o
parâmetro do método de pesquisa para a tabela de
transações com hashtag. No bloco then, vamos
deixar a afirmação
de que o tamanho da linha da tabela é
igual a um por enquanto. Agora, vamos projetar nossa mesa. Vamos para o
playground dot FXML. Vamos copiar todo esse
conteúdo entre a tag tab e colá-lo abaixo. Agora, altere sua propriedade de texto para transações e sua
ID de ética para a guia de transações. Altere também a ID de ética da etiqueta de
visualização para a tabela de transações. Agora vamos mudar o campo
de texto da primeira coluna
para ID da transação. A tabela também terá uma coluna balanceada e uma coluna de
confirmações. Portanto, manteremos essas
tags como estão. Vamos duplicar a última tag, alterar seu texto até o momento. Essa coluna conterá a data de criação
dessas transações. Agora vamos clicar
no Scene Builder para ver a aparência de nossa nova
guia e tabela. Ok, está lindo. Agora, vamos criar um novo
FXML para esse componente. Vamos chamá-la de tabela de
sublinhados de transações. Vamos excluir o
código padronizado. Vamos copiar esse conteúdo
do ponto FXML do playground
e colá-lo aqui. Vamos importar essas tags. Altere essa tag para
fx colon route. Exclua esse conteúdo como seu tipo. Vamos definir o caminho do componente de
visualização da tabela e definir esse URL como o campo XML NS como a tabela de transações do
conjunto de propriedades do ID de ética. Agora exclua essas tags, que não precisávamos copiar. Agora, vamos adicionar esses
IDs de ética a essas tags de coluna. Eles serão úteis
posteriormente, quando criarmos o controlador da
tabela de transações. Agora, na janela principal, pontilhe FXML, vamos duplicar o conteúdo
entre essas tags. Vamos mudar o texto da guia para transações e a guia FX
ID para transações. Agora, altere essa tag para controlador de tabela de
transações. Vamos criar esse controlador
no pacote de controladores de pontos GUI. Vamos importar para a janela
principal o ponto FXML. Agora, vamos adicionar a
anotação do componente ao controlador da
tabela de transações. Isso estenderá a classe de visualização de
tabela parametrizada com a
classe de linha de transação que criaremos. Vamos criar a classe real da
transação no pacote observables. Agora, vamos até o controlador da
guia Receber, copiar seu construtor
e colá-lo aqui, fazendo as
modificações apropriadas nele. Vamos alterar sua
anotação de valor para apontar para
o ponto FXML da tabela de
sublinhado de transações. Vamos também injetar a
carteira atual nessa classe. Será útil mais tarde. Agora, precisamos incluir o
controlador da tabela de transações na lista de componentes personalizados
no ouvinte iniciado pela GUI, poderíamos simplesmente adicionar
outra cláusula or na instrução if na
inicialização
Método FXML. Mas vamos refatorar essa classe
fazendo o seguinte. Vamos criar um conjunto estático
privado de objetos de classe chamados componentes
personalizados aqui. Vamos instanciá-lo aqui
com a classe de método set. Vamos incluir essas
classes de controladores no conjunto. Agora, na instrução if, apenas
verificaremos se o conjunto de componentes personalizados
contém o tipo fornecido. Agora vamos fazer o teste de
recebimento da transação. Agora, vamos executar as metas do Maven de ciclo de vida limpo e compilado. Às vezes, isso é
necessário para incluir novos arquivos FXML no projeto
compilado. Agora, vamos executar nosso node principal do
Bitcoin se ele ainda não estiver em execução. Finalmente, vamos fazer o teste. O teste falhou
porque não encontrou uma linha contendo as informações da
transação na tabela de transações continuará implementando esse recurso no próximo vídeo. vejo.
39. 37 Receber transação parte 2 skillshare 2: Neste vídeo, concluiremos
a implementação da tabela de transações
e faremos com que esse teste seja aprovado. Então, vamos para o serviço UTXO de
atualização. Se você se lembrar, esse método de
atualização é chamado depois que recebemos uma
transação do nosso nó A classe de tarefa do nó monitora nosso nó em busca de mensagens de
transação. Em seguida, nosso aplicativo
publica um evento de transação recebida que é ouvido pelo nosso ouvinte de
transações. O ouvinte da transação
analisa e
filtra a mensagem e chama o método de atualização do serviço
UTXO de atualização. Então, depois de recuperar UTXOs e atualizar os endereços atuais da
carteira, vamos atualizar as transações atuais da
carteira usando esse serviço. Vamos injetá-lo nesta classe. Vamos criá-lo no pacote de serviços
GUI dot. Vamos adicionar a
anotação do serviço a ela. Agora, vamos terminar de
injetá-lo nesta classe. Agora, vamos chamar o
método de atualização nesse serviço, passando a variável utxOS
como seu parâmetro. Vamos criar esse método. Esse método será
executado de forma assíncrona. Então, vamos adicionar a
anotação assíncrona usando o
serviço executor padrão como parâmetro. Vamos fazer o mesmo com
o método de atualização
no serviço de atualização de
endereços da carteira atual. Agora, vamos implementar
o método de atualização e o serviço de
transação atual do Wallet de atualização converterá a lista
de UTXOs em uma lista de
linhas de transação e armazenará o resultado nas
linhas de transação. A variável que usa o código a seguir filtrará o fluxo de UTXOs
mantendo no fluxo somente os UTXOs com endereços
na carteira atual. Então, vamos injetar a
carteira atual nessa classe. Agora, no corpo do lambda
obterá todos os endereços como strings e verificará se ele
contém o endereço UTXO. Agora, chamaremos o método map
no fluxo resultante, passando a linha
de transação do método como seu parâmetro. Vamos criar esse método. Será um
método estático e
retornará um objeto de linha de transação. Semelhante à classe da linha de
endereço. A classe da linha da transação
representará uma linha e
a tabela de transações. Então, vamos adicionar as seguintes
propriedades a essa classe. Cada propriedade representará uma coluna na tabela
de transações. Vamos excluir a palavra-chave
final de cada propriedade porque o IDE permite criar automaticamente configuradores para essas
propriedades, se forem finais. Agora, usando esse recurso de ID, adicione getters e setters
para cada propriedade. Agora podemos adicionar a palavra-chave final
a essas propriedades. Agora, vamos criar um construtor. O construtor usará cada propriedade de classe
como seus parâmetros. E usaremos os configuradores de
propriedades para definir as propriedades no corpo
do construtor. Agora, podemos continuar
implementando o método. Ele retornará uma nova linha de
transação com os seguintes parâmetros. Voltar ao serviço de transação Update Current
Wallet. Agora, converteremos a string
resultante em uma lista. Agora, adicionaremos a
transação obtida rose à carteira atual usando o método de
adicionar linhas de transação. Vamos criar esse método. Ele usará o campo
de linhas de transação. Então, vamos criá-lo agora. Seu tipo será a
transação Rose Class. Vamos criá-lo no pacote
observables. Voltar para a carteira atual. Vamos defini-lo e
instanciá-lo aqui. Vamos também tornar o campo das linhas
de endereço definitivo. No método de
linhas de transação ED, vamos chamar o método adicionar linhas de
transação no campo de linhas de transação. Passando as
linhas de transação fornecidas como seu parâmetro. Vamos criar esse método. Assim como a
classe de linhas de endereço é responsável por gerenciar a lista de
linhas de endereço mostrada na tabela de
endereços. Essa classe fará o mesmo com
as linhas de transação
e a tabela de transações. Portanto, para cada linha de transação, verificaremos se o campo do roteiro da
transação já a contém. Então, vamos criar esse campo. Será um
mapa observável em que a chave é uma string e o valor
é uma linha de transação. Vamos instanciá-lo aqui com
um invólucro de mapa observável, passando um novo
HashMap vinculado como seu construtor. Portanto, se o roteiro da transação
contiver o ID da
linha da transação em suas chaves, definiremos a
rotação da transação para a data da
transação presente
no roteiro da transação da transação
contiver o ID da
linha da transação em suas chaves,
definiremos a
rotação da transação para a data da
transação presente
no roteiro da transação.
isso para preservar a data
de criação da transação. Em seguida, após a instrução if,
removerá a
linha de transação do mapa por sua ID e colocará a
linha de transação fornecida novamente
no roteiro da transação
usando sua ID como chave. Novamente, estamos removendo e adicionando a mesma
linha de transação para forçar o mapa observável a publicar eventos de
alteração que
serão ouvidos posteriormente. Agora, vamos criar o campo de lista observável
que será usado para vincular as alterações no roteiro da
transação ao controlador da tabela. Vamos instanciá-lo aqui usando um wrapper de lista observável instanciado com
uma nova lista vinculada. Agora, vamos criar o método get observable transaction row list. Ele retornará a lista
de funções da transação. Agora vincularemos o roteiro da
transação à lista de funções da transação no construtor,
assim como fizemos
com o conjunto de linhas de endereço e a lista de linhas de endereço
na classe de linhas de endereço. Então, para acelerar as coisas, vamos copiar o construtor de
linhas de endereço e colá-lo aqui. Vamos corrigir seu nome. Agora, em vez de chamar métodos
na lista de funções de endereço, faremos isso na lista de funções da
transação. Em vez de usar um set
change, o ouvinte usará um ouvinte de mudança de mapa parametrizado com uma string
e uma linha de transação. Além disso, em vez de usar o elemento
get removido aqui, usaremos o getValue removido. Aqui. Usaremos o
get value-added. E aqui adicionaremos um ouvinte
ao roteiro da transação. Mais uma coisa para que isso funcione, temos que implementar
o método equals na classe de linha de transação. Isso ocorre porque, na lista de linhas de
transação, usaremos o método para decidir qual linha de transação
remover de si mesma. Então, vamos implementá-lo
usando esse recurso do IDE. Certifique-se de marcar a caixa de seleção
usar getters
nesta janela para usar somente a propriedade ID para definir a
igualdade nessa classe. Além disso, clique na caixa de seleção de ID aqui para que ela não possa ser nula. Ok, o IDE gerou
esses métodos conforme o esperado. Voltar para a classe de
linhas de transação. Vamos criar o método claro, que será chamado quando
uma nova carteira for criada. Dentro, ele chamará
o método claro
no roteiro da transação e
na lista de funções da transação. Na classe de carteira atual, vamos criar o bom método de linhas de
transação observáveis. Isso retornará que eles receberão uma chamada de método de lista de linhas de
transação observável chamada de método de lista de linhas de
transação no campo de linhas de transação. Também vamos criar o método de
transações claras aqui. Isso chamará as linhas de transação método
claro que acabamos de criar. Agora vamos para o serviço de atualização da carteira
atual. Aqui, chamaremos
o método atual de transações
de compensação de carteira . Ao fazer isso, garantimos
que
limparemos as linhas de transação
após criar uma carteira. Agora, vamos para o controlador da tabela de
transações. Vamos adicionar os seguintes campos. Será usado no método
inicializado posteriormente para vincular a tabela e suas colunas
às linhas de transação observáveis. Agora vamos criar o método
inicializado. Aqui, primeiro definiremos itens
da tabela de transações para as linhas de transações
observáveis da carteira atual. Agora, adicionaremos um ouvinte às linhas
de transações
observáveis da carteira atual. Chamaremos o método de
atualização da tabela de
transações no corpo para que cada alteração que ocorra no observável acione um
redesenho da tabela. Além disso, vinculará cada campo da
coluna ao campo da linha da transação usando a fábrica do
valor da célula definida, assim como fizemos no controlador da tabela de
endereços. Como parâmetro de
fábrica do valor da propriedade, precisamos usar os mesmos
nomes de propriedades que usamos na classe real
da transação
para fazer a vinculação corretamente. Vamos duplicar essa linha três vezes e alterar as
colunas que estamos vinculando. Agora vamos para a classe de teste de
transação receptora. Verifique se você está executando o Bitcoin Core Node
e faça o teste. Boops, o teste
falhou. Vamos ver o porquê. Há um problema com o campo de
balanceamento de transações da
coluna no controlador da
tabela de transações. Para corrigir isso, vamos até o ponto FXML da tabela de
sublinhado de transações. O problema é que
nomeamos incorretamente o saldo, confirmações e os IDs de câmbio de data. Todos os três estão faltando a palavra
transação após coluna. Então, vamos corrigi-los e
executar o teste novamente. Ótimo, o teste foi aprovado. No próximo vídeo, adicionaremos mais
testes para garantir que a tabela de transações
esteja funcionando conforme o esperado. C, sim.
40. 38 Receber transação parte 3 skillshare 2: Neste vídeo, adicionaremos
mais testes para verificar se nossa tabela de transações
funciona para outros cenários. Então, vamos para a aula de teste de bloco
receptor. Em cada método, adicionará código para testar se a tabela de transações contém as informações
esperadas sobre as
transações recebidas. Então, vamos renomear a exibição de tabela neste teste para abordar
sua visualização em tabela, para esclarecer seu significado. Agora, chamaremos o método
click on passando como parâmetro,
a string transactions. Agora vamos copiar a linha
com a variável de visualização da
tabela de endereços e colá-la abaixo. Vamos mudar o nome dessa variável para a exibição da tabela de transações. No método de pesquisa, vamos substituir esse parâmetro pela tabela de transações de hashtag. Agora vamos copiar essas duas
linhas, colá-las abaixo e alterá-las para chamar esses métodos na visualização da tabela de
transações. Vamos fazer o mesmo com
o outro método de teste. Mas, nesse caso, esperamos que a tabela de transações contenha duas linhas, uma para cada transação. E para a segunda linha, esperamos que o número
de confirmações seja igual à variável total de
confirmações, que criará o valor
total de confirmações igual ao número
dos blocos meus até agora, esse número será igual a confirmações mais
confirmações menos uma. Como esperamos que
a segunda linha contenha informações sobre
a primeira transação, isso será confirmado
esse número de vezes. Vamos fazer uma pequena correção no método
de blocos de minas. Às vezes, essa linha de código gera uma NullPointerException devido
ao TableView ter uma propriedade de itens
nulos. Para evitar isso, vamos usar o operador seguro nulo antes de cada propriedade na exibição em tabela. Agora, vamos fazer nossos testes. Primeiro, certifique-se de
executar seu node Bitcoin. Vamos fazer os testes. Os dois últimos testes falharam. Isso aconteceu porque as
transações na tabela não estão ordenadas, seu
pedido é aparentemente aleatório. Às vezes, esses testes podem ser aprovados porque podem ser ordenados
corretamente por acaso. Então, vamos corrigir isso. Nosso objetivo é classificar as
transações por data com as transações mais recentes
nas primeiras linhas. Então, vamos para a classe da linha de
transação. No método de formulário.
Vamos mudar a forma como passamos os dados para a instanciação da
linha de transação. Em vez de usar uma nova data, vamos usar o método
instant now. Estamos fazendo isso porque
a aula instantânea é mais precisa e
fácil de classificar por Parson. Agora vamos para o controlador da tabela de
transações. Na tabela de transações,
defina itens (método call). Vamos passar uma nova
lista ordenada como parâmetro. As linhas de
transação observáveis da carteira atual
serão o primeiro parâmetro a
instanciar a lista classificada. O segundo parâmetro será a chamada do método de
comparação do comparador. Esse método
passará um lambda como o primeiro parâmetro ou
uma linha de transação
será o parâmetro no corpo
do lambda. Vamos chamar o método de análise
instantânea, passando a
rotação da transação como parâmetro. O método parse gerará um objeto
de instância a partir da string de data. O segundo parâmetro do
método de comparação
será a chamada do método de
ordem inversa do comparador. Dessa forma, esperamos que a tabela de
transações seja classificada pela data
da transação, com as transações
mais recentes primeiro. Agora vamos fazer nossos testes novamente. Desta vez, apenas
os que falharam. Faremos isso
clicando nesse botão. Ótimo, os testes foram aprovados. Agora vamos adicionar testes de
tabela de transações à classe de teste de recebimento de
Bitcoin. Faremos o mesmo que fizemos
na aula de teste de blocos de recebimento. Para cada método,
refatoraremos o nome da visualização da tabela, faremos com que o teste clique na guia de transações e
faremos afirmações sobre o conteúdo esperado na tabela de transações. Vamos fazer isso. Ok, agora, vamos
fazer esses testes. Ótimo, os testes foram aprovados. Agora, usaremos nossa carteira
no ambiente de teste da rede
pela primeira vez. O ambiente da rede de teste é
semelhante ao da rede principal, mas suas moedas não valem nada. É muito mais fácil se preocupar e
o tempo de bloqueio é menor. Isso exige que executemos e
afundemos nosso nó Bitcoin
nesse ambiente. Falamos sobre como fazer isso
no guia de configuração do curso. Então, vamos modificar nosso bitcoin.com para executar nosso node no ambiente de
teste da rede. Basta alterar essa chave de
reg test para test net. Vamos parar de executar nosso
node no teste de registro. E vamos rodar nossa nota novamente para começar a afundar nossa
nota na rede de teste. Minha nota está quase acabando, então vou levar alguns
minutos para ser atualizada. Mas, dependendo da
última vez que você o executou
, pode levar mais tempo para
sincronizarmos
, pois o
download dos blocos mais recentes levará algum tempo. De qualquer forma, enquanto está afundando, vamos modificar nossos projetos
para que possamos executar nosso aplicativo na rede de
teste com sucesso. No caminho dos recursos, vamos criar o
aplicativo de arquivo test
net dot properties. Esse arquivo conterá
as propriedades usadas em nosso projeto quando executarmos o aplicativo no ambiente
de rede de teste. Vamos copiar o conteúdo
do
arquivo de propriedades de pontos do aplicativo e colá-lo aqui. Agora, mude o
ambiente Bitcoin para testar a rede. E a porta URI sem
pontos RPC 218332. Essa é a
porta padrão do nosso node quando ele é executado no ambiente
de rede de teste. Agora, vamos fazer uma
pequena melhoria. Em nossa carteira, seria bom poder copiar
o ID
da transação mostrado na tabela de
transações
simplesmente clicando com o botão direito do mouse sobre
elas e clicando em Copiar. Vamos implementar esse recurso. Para fazer isso, vamos até
a tabela de
sublinhado de transações dot FXML. Agora vamos adicionar o código a
seguir aqui. Primeiro, vamos adicionar essas tags de menu de
contexto dentro dela. Vamos adicionar a tag de itens. Em seguida, a tag dos itens do menu. Nessa propriedade de texto de tags, adicione a cópia da string e ID da transação do café com
hashtag
como está na propriedade de ação. Isso faz com que o
aplicativo chame o método de cópia da ID da transação no controlador da
tabela de transações. Depois de clicarmos no item Copiar
menu no menu de contexto. O menu de contexto é
um menu que aparece
depois que clicamos com o botão direito do mouse em
algo na tela. Agora, vamos para o controlador da tabela de
transações. Vamos criar o método de cópia do ID da
transação aqui. Primeiro, obteremos a linha
da transação que foi clicada com o botão direito do mouse
usando esse código. Agora vamos simplesmente chamar
o método de cópia. Criaremos
a passagem do
ID da linha da transação como seu parâmetro. Para criar esse método,
criará primeiro um pacote utils dentro
do pacote BYOD W. Dentro dela, vamos criar
uma classe chamada Copy. Agora, vamos criar o método de
cópia aqui. Como um método estático. Instanciará um objeto de conteúdo
da área de transferência, armazenando-o na variável
de conteúdo. Em seguida, chamaremos o método put
string nele, passando o
texto da variável como seu parâmetro. Vamos adicionar essa variável como parâmetro
do método de cópia. Por fim, chamaremos o método get
system clipboard e definiremos seu conteúdo como
o conteúdo variável no controlador
da
tabela de transações. Vamos importar esse
método. Mais uma coisa. Ao executar o nó Bitcoin no ambiente de rede de teste, nosso nó pode receber diferentes
tipos de transações que a
biblioteca Bitcoin Java
ainda não consegue analisar e gerar erros
ao tentar fazer isso. . Embora a não análise
dessas transações afete nossas carteiras, o erro foi bem gerado. Para evitar isso,
na classe de tarefa node, envolva o método de transação do fluxo de bytes em um bloco
try-catch. No bloco de captura, vamos usar um registrador para nos
avisar sobre o erro. No único método, a chamada
passará uma frase indicando o erro e um par de chaves no final. Esses colchetes serão
interpolados pelo
segundo argumento,
que será a variável de conteúdo
codificada hexadecimal interpolados pelo
segundo argumento,
que será a . O terceiro parâmetro
será o objeto de exceção. Assim, podemos acessar
todo o rastreamento
da pilha do erro nos registros. Após o registro, o erro
irá diretamente para
a próxima iteração
do loop while usando
a palavra-chave continue. Vamos criar o campo do registrador. Será uma propriedade estática. Vamos instanciá-lo aqui
usando a fábrica de registradores. Vamos corrigir a importação da
classe logger. Na verdade, temos que
importá-lo
do pacote 4D dot SELF for J. Agora vamos executar nosso aplicativo no ambiente de rede de teste. Primeiro, vamos verificar se nosso nó está vinculado ao ambiente da
rede de teste. Ok, já está afundando porque seu progresso
é igual a 1,00. Agora vamos para a classe de aplicação BYOD
W. Clique com o botão direito do mouse nesse
símbolo e clique em modificar configurações de execução. Agora, clique em modificar opções e verifique se as opções da VM
de anúncios estão selecionadas. Agora, defina-o para menos d perfis de pontos de mola, ponto
ativo é igual à rede de teste. Clique em OK e clique
no botão Executar. Agora vamos criar uma carteira. Observe que o
endereço de recebimento começa com TB, indicando que é
um endereço de rede de teste. Agora, vamos copiar esse endereço. Usarei uma torneira de rede de teste
para obter Bitcoins líquidos de teste. Uma torneira de Bitcoin é um site ou API que oferece
Bitcoins gratuitamente. Eles foram muito populares
nos primeiros anos do Bitcoin, quando um Bitcoin era muito barato. Atualmente, existem maneiras rápidas de
obter moedas líquidas de teste. Vamos acessar o
site na tela. É uma torneira de rede de teste. Vamos colar o
endereço copiado nesse campo. Escolha um valor e clique nesse botão
para nos enviar Bitcoin. Vamos esperar um pouco. Ok, o alerta diz que ele envia alguns Satoshi
para nossa carteira. Vamos verificar se o
recebemos. Ótimo. Nossa carteira identificou nossa transação e
nossa transação e endereço já
têm uma conformação. Mas há uma coisa estranha. A balança é formatada
em notação científica. Vamos corrigir isso mais tarde. Por enquanto, vamos copiar
nosso ID
de transação clicando com o botão direito do mouse nele
e clicando em Copiar. Verificaremos a transação em um explorador de
blockchain de terceiros. Um explorador de blockchain
é um site que mostra informações sobre endereços,
blocos e transações de
Bitcoin de
uma forma agradável e organizada. Se você está preocupado com sua privacidade, pesquisar seus
vestidos vermelhos e transações no não é
aconselhável
pesquisar seus
vestidos vermelhos e transações no
explorador de blockchain de
terceiros , pois permite que eles vinculem você aos dados de
sua carteira. Mas como o estamos usando
apenas para fins
de teste, tudo bem. Com isso dito, vamos acessar
o site na tela, que é um explorador de blockchain do Bitcoin test
net, colar o ID da
transação copiada
no campo de pesquisa e
clicar no botão Pesquisar. Aqui, obteremos algumas informações sobre
nossa transação. Observe que ele já
tem duas confirmações, mas nossa carteira indica que ele tem apenas uma conformação. Acontece que, no ambiente de
teste da rede, nosso node Bitcoin só envia
notificações de transação por meio zero MQ quando as
transações são enviadas e quando
recebem uma confirmação. Depois disso, não importa quantas
confirmações sejam recebidas, o nó não notifica
nosso aplicativo sobre isso. Precisamos fazer com que nosso aplicativo
comece a ouvir as notificações de
bloqueio para que
possamos resolver esse problema. Começaremos a fazer isso
no próximo vídeo. vejo.
41. 39 Receber bloco parte 2 skillshare 2: Neste vídeo,
faremos com que nosso aplicativo comece a ouvir
mensagens de bloqueio do nó Bitcoin. Dessa forma, poderemos
atualizar nossas
confirmações de transações corretamente
no ambiente de rede de teste. Também modificará a formatação do endereço e
dos saldos de transações, pois agora eles não estão sendo exibidos bem nas tabelas. Então, vamos para o arquivo
bitcoin.com. Vamos mudar essa
chave para o teste de registro. Para começar a ouvir
mensagens de bloqueio, vamos adicionar a propriedade de bloco de
hash pub Z MQ aqui. Seu valor será o mesmo
URL na propriedade acima. Então, vamos colá-lo aqui. Essa configuração fará com que os nós enviem o bloco de hash para nosso aplicativo após detectar um novo bloco, estendendo
o blockchain. Depois disso, o
código será criado enviará uma solicitação de lista
não gasta para o nó contendo todos os endereços
atuais da carteira. Em resposta, receberemos
uma lista de UTXOs atualizados que serão analisados
e usados para atualizar nossos vestidos vermelhos e tabelas de
transações. Vamos salvar o arquivo bitcoin.com. Agora, vamos para a classe
de tarefas node. Vamos duplicar essa linha. Vamos mudar a
string para um bloco de hash. Dessa forma, começaremos a receber mensagens de bloqueio de
hash
do node. Agora, nesta instrução if, vamos adicionar o código a seguir. Se o tópico for igual a nulo ou se a lista com
esses tópicos
não contiver o tópico recebido. Em seguida, passaremos para a próxima
iteração do loop while. Agora, vamos adicionar uma instrução
switch aqui. Caso a variável do tópico
seja igual a ra t x. Em seguida, executamos
o código para analisar e processar a transação
recebida. Vamos mover a linha
que publica evento
da transação recebida para esse local. Dessa forma, podemos remover essa instrução redundante
continue caso a variável tópico
seja igual ao bloco de hash. Em seguida, usaremos o editor do evento do
aplicativo para publicar um novo
bloco de eventos recebidos. Vamos criar esse evento no pacote de eventos
da BYU w dot no
doubt. Agora vamos criar um
ouvinte para esse evento
no pacote BYOD w dot, dot
listeners. Vamos adicionar uma
anotação de componente a ela. Vamos fazer com que ele implemente a interface do
ouvinte do aplicativo, passando o
evento do bloco recebido como seu parâmetro de tipo. Vamos implementar seu método. Primeiro. Obteremos todos os endereços de
carteira atuais usando esse método e os armazenaremos
na variável de endereços. Vamos injetar a
carteira atual nessa classe. Em seguida, usar uma instrução if
verificará se a
variável de endereços está vazia. Caso contrário, usaremos
o serviço de atualização UTXos para atualizar nossos endereços
e transações. Vamos injetá-lo nesta classe. Vamos chamar o método de
atualização nele, passando o endereço é variável e o
nome da carteira atual como parâmetros. Agora vamos para a
transação recebida, o ouvinte otimizará nosso código. Lembre-se de que depois de receber
uma confirmação
no ambiente de rede de teste e todas as confirmações no
ambiente de teste de registro, o nó envia uma mensagem de
transação para nosso aplicativo
por meio de zero MQ. Como, a partir de agora, nosso ouvinte de blocos
recebidos
atualizará todos os
endereços atuais da carteira quando
receber confirmações, não
faz sentido atualizar
a tabela de endereços e
transações no a transação recebeu a classe de
ouvinte após
recebermos mais
mensagens de transação repetidas. Portanto, modificaremos
essa classe para
processar transações somente se a carteira atual
não as contiver. Então, vamos adicionar essa declaração if. Se os IDs de
transação atuais da carteira contiverem o ID
da transação recebida
, simplesmente retornaremos. Vamos criar esse método. Ele retornará uma lista de cadeias de caracteres e retornará as linhas
da transação, método
get transaction IDs. Vamos criar esse método. Aqui. Retornaremos o código a seguir de um fluxo da lista de funções da
transação. Chamaremos o
método de mapa passando uma referência ao método getID da linha de
transação. Em seguida, converteremos o
resultado em uma lista e o
devolveremos ao ouvinte da transação
recebida. Precisamos agrupar esse código em
um bloco de tentativa de captura porque o método de ID da transação gera uma exceção verificada
no bloco de captura usará um registrador para
imprimir uma mensagem de aviso. Vamos injetar o registrador
nessa classe, assim como fizemos
na classe de tarefa node. Vamos também adicionar uma
declaração de retorno ao bloco de captura. Agora, vamos corrigir o problema de
formatação balanceada da linha de endereço. Em vez de usar o método de duas cadeias de caracteres de
classe dupla, usaremos o
formato Bitcoin ou o
método de formato passando o
saldo do endereço como parâmetro. Vamos criar essa classe
no pacote utils. Agora, vamos criar
o método de formatação. Aqui, instanciaremos
um novo objeto de
símbolos de formato decimal passando a rota local para
seu construtor. Em seguida, definiremos o ponto como separador decimal e a vírgula como separador
de agrupamento. Em seguida, instanciaremos um novo objeto de formato decimal , pois seu parâmetro construtor
passará esse padrão. E a variável dos símbolos. Em seguida, definiremos o formato
ou o agrupamento usado como falso. Em seguida, definiremos seus dígitos
fracionários mínimos para oito. E é o máximo de dígitos
fracionários 282. Por fim, chamaremos o
método de formato no formatador, passando o número recebido como parâmetro e
o retornaremos. uso desse método formatará
qualquer número de passagens para ele com dígitos decimais e
sem separadores de agrupamento. Esse tipo de formatação
é útil, pois um bitcoin pode ter no
máximo oito dígitos fracionários. Essa formatação também facilita
a visualização de quantos Satoshi um balanceado contém. Agora vamos para a classe da linha de
transação. Vamos usar o
formatador Bitcoin aqui para formatar o saldo UTXO
no método de quadro. Agora, vamos ajustar nossos testes para cobrir essa nova formatação de
balança. Vamos para a classe de teste de GUI no método send Bitcoin
in weight, vamos alterar o segundo tipo de
parâmetro para o dobro e ajustar seu valor
padrão de acordo. Vamos também adicionar esse parâmetro de valor
opcional com um valor padrão de 1,0. Agora, vamos substituir
esse parâmetro pela variável de quantidade. E aqui vamos agrupar a variável de
valor total esperado no formato
ou método de formato Bitcoin. Agora, vamos fazer o teste de
recebimento de Bitcoin. Vamos modificar isso e o Bitcoin
e aguardar a chamada do método para enviar 0,00 001 Bitcoin. Assim, podemos testar a
nova formatação quando nossa carteira recebe frações de
Bitcoin. Agora, vamos verificar cada uso
desse método e modificar sua parametrização
do parâmetro de quantidade total esperada para passar um duplo
em vez de uma string. Agora, vamos adicionar essas verificações
nulas
às propriedades de exibição de tabela
nesse método para evitar exceções de ponteiro
nulo. Agora, vamos executar nosso node
e executar todos os testes do projeto. Ótimo, os testes foram aprovados. Agora, vamos executar nosso aplicativo no ambiente de rede de teste. Para fazer isso, vamos ajustar
nosso arquivo bitcoin.com. Agora, vamos reiniciar nosso node. Depois de alguns minutos, minha
nota está totalmente vazia. Agora, vamos executar nosso
aplicativo
no ambiente de rede de teste usando nossa configuração de
execução modificada anteriormente. Vamos criar uma nova carteira. Agora, vamos copiar nosso
endereço e usar uma torneira de rede de teste para
receber o de Satoshi, assim como fizemos em
um vídeo anterior. Ok, nossas carteiras identificaram
com sucesso a transação e ela está
balanceada, exatamente como esperávamos. Agora, vamos comer um sanduíche e deixar nossa carteira
aberta por um tempo. Depois de alguns minutos
serem resolvidos transação já obteve
quatro confirmações. Ótimo.
42. 40 Total de saldo parte 1 skillshare 2: Neste vídeo, começaremos a
desenvolver o recurso de
saldo total. Basicamente, será um texto acima da guia de transações e
endereços indicando que o saldo da carteira
atualmente carregada mostrará o saldo confirmado, o saldo não confirmado
e o saldo total. O saldo confirmado mostrará a soma de
todos os UTXOs confirmados. O saldo não confirmado é a soma de todos os UTXOs
não confirmados. O saldo total
será a soma dos saldos não
confirmados e confirmados. Então, vamos ao playground dot FXML para esboçar algo. Após o primeiro
fechamento do painel da guia. Vamos adicionar essa etiqueta de etiqueta. Agora, vamos adicionar essa tag de margem
de pontos VBox. Dentro dela. Adicione essa tag de inserções. Adicionaremos algumas
propriedades de margem aqui. Vamos definir a
margem inferior para 10,0, a margem esquerda para 10,0 e a margem superior para zero. Agora, para fins de teste, vamos definir a propriedade de texto desse rótulo como um teste. Vamos ver como fica
no Scene Builder. Ok, vemos que os textos balanceados
estarão localizados aqui. Vamos remover essa propriedade de texto. Vamos criar um novo arquivo FXML chamado saldo total do sublinhado. Vamos remover esse clichê. Agora, vamos copiar todo
o conteúdo e a etiqueta que acabamos de
criar no playground. E cole aqui. Vamos também copiar essas duas linhas de
importação e colá-las no ponto balanceado total do
sublinhado FXML. Agora vamos substituir as
tags de rótulo pela tag raiz de dois pontos FX. Ele terá um ID FX de saldo total e um
tipo de rótulo de ponto Java FX, ponto de controle de pontos. Vamos também incluir essa propriedade
XML e S. Agora, na janela principal, vamos adicionar a etiqueta do controlador de
saldo total após o primeiro painel de
fechamento da guia. Agora vamos criar esse controlador no pacote de controladores. E vamos importá-lo aqui de
volta para o controlador. Vamos fazer com que ele estenda a classe do rótulo e adicione a anotação do
componente a ela. Agora, vamos copiar esse construtor e colá-lo aqui,
modificando-o adequadamente. O valor do recurso FXML será a localização do ponto balanceado total do
sublinhado FXML. Vamos também injetar a
carteira atual nessa classe. Agora, no ouvinte iniciado pela GUI, vamos adicionar a classe do controlador de
equilíbrio total ao conjunto de componentes personalizados. No controlador de saldo total. Vamos adicionar o método
inicializado. Usaremos o método
setText herdado para definir o
texto do rótulo dinamicamente. Vamos configurá-lo para testar para fins
de teste por enquanto. Agora, vamos criar o teste de equilíbrio
total no pacote de GUI. Isso estenderá a classe de teste de GUI. Vamos copiar esses dois métodos e colá-los
no novo teste. Vamos renomear esse método. Dois devem calcular o saldo total. Agora, vamos fazer alguns
ajustes no corpo. O nome da carteira criada
será minha validação de teste. Vamos remover essa linha,
pois não precisaremos dela. Vamos também remover essas linhas. Com esse código,
obterá o texto presente na etiqueta
do saldo total e armazenará na variável de texto do
rótulo. Em seguida, o bloco verificará se a variável de texto do rótulo é
igual à seguinte frase. Depois de receber a transação, esperamos que o
conteúdo do rótulo mostre que nossos
saldos totais e não confirmados são de um Bitcoin. Esperamos que o
saldo confirmado seja zero, pois nossa transação
não será incluída em um bloco e mente
durante o teste. Antes de executar nosso node, vamos garantir que nosso ambiente
Bitcoin dot conf esteja configurado para teste de registro. Agora, vamos executar nosso node. E vamos fazer esse teste. Ele falhou conforme o
esperado porque o rótulo do saldo total contém o teste de sequência de caracteres em vez
do que queríamos. No próximo vídeo, implementaremos esse recurso
e faremos com que esse teste seja aprovado. vejo.
43. 41 balanço total parte 2 skillshare 2: Neste vídeo, concluiremos implementação do recurso de
saldo total. Então, vamos para o serviço de
atualização UTXos. No método de atualização, adicionará uma nova chamada de método para
atualizar o saldo da carteira. Para isso, chamaremos
o método de atualização na atualização do
saldo da carteira atual que o serviço criará. Vamos injetar esse
serviço nessa classe. Vamos criar essa classe
no pacote de serviços de pontos da GUI. E vamos terminar de
injetá-lo aqui. Agora, vamos criar
seu método de atualização. Aqui, primeiro calcularemos saldo não confirmado e o armazenaremos na variável de
saldo não confirmado. Para isso, precisaremos injetar a carteira
atual nessa classe. Em seguida, obteremos suas linhas
de transação observáveis
e as converteremos em um fluxo. Em seguida, usaremos o
método de filtro no resultado para excluir as linhas da transação com confirmações
diferentes de zero. Em seguida, usaremos o método de
mapa para converter o fluxo obtido
em um fluxo de saldos de linha de transações. Usaremos o método parse
double para converter cada
string balanceada em uma dupla. Agora usaremos o método
reduzido, passando o método de
soma dupla para ele, para alguns dos
saldos obtidos no fluxo. Finalmente, usaremos o
método or else passando 0.0 para ele. Portanto, caso o fluxo
obtido esteja vazio, a
variável balanceada não confirmada será definida como zero. Agora, vamos duplicar
esse bloco de código. Vamos modificá-lo para calcular o saldo confirmado e
armazená-lo na variável
balanceada confirmada. Só precisamos mudar
o sinal de igual e o método de filtro para
esse sinal maior que. Com essa simples modificação, obteremos a soma
dos saldos de todas as transações com
pelo menos uma conformação. Por fim, chamaremos o método de
saldos definidos na
carteira atual, passando o
saldo não confirmado e o saldo confirmado
como parâmetros. Como esse código
modificará a interface do usuário, vamos agrupá-lo em uma chamada de método posteriormente
executada pela plataforma. E vamos criar o método
de saldos definidos na classe de carteira atual. Para fazer isso, vamos adicionar o campo de
saldos a essa classe. Seu tipo será a classe de
saldos que criaremos. Vamos criá-lo no pacote
observables. E vamos instanciá-lo aqui. Aqui, chamaremos esse método de
saldos definidos no campo saldos, passando os saldos não confirmados e
não confirmados
como seus parâmetros. Vamos criar esse método. Primeiro. Vamos adicionar alguns
campos privados a essa classe. Adicionaremos o campo
balanceado não confirmado da propriedade do tipo string. Vamos instanciá-lo aqui com uma nova propriedade de
string simples. Vamos duplicar essa
linha duas vezes. Vamos alterar esses nomes de
campo para confirmar o saldo e o saldo total. Agora, no
método set balances, chamará o método set nas propriedades
injetadas para definir seus valores. Usaremos o
formato ou método de formato Bitcoin para
formatar os saldos no formato desejado. Para o saldo total
passará a soma dos saldos não
confirmados e confirmados. Agora, vamos criar getters
para esses campos. Vamos também criar
o método claro. Esse método definirá o saldo de cada
propriedade como zero. Chamaremos esse método
depois de criarmos uma carteira para apagar os valores da carteira carregada
anteriormente. Agora, na carteira atual, vamos criar o método de bons
saldos. Isso retornará o campo de saldos. E vamos criar o método de balanços
claros. Isso chamará o método claro de
saldos. No serviço de atualização da
carteira atual, que é chamado após a criação de
uma carteira, vamos chamar o método de compensação de
saldos da carteira atual aqui. Agora, vamos para o controlador de saldo
total. Vamos remover essa linha. Obteremos a propriedade
balanceada não confirmada dos saldos atuais da
carteira. Chamaremos o método do
ouvinte de anúncios nele. Passaremos um lambda
como parâmetro, onde no corpo chamaremos o método de atualização
do texto. Vamos criar esse método. Chamaremos o
método setText nele e passaremos uma chamada de método em
formato de string como seu parâmetro. O primeiro parâmetro
do método de formato
será essa frase. Cada sinal de porcentagem seguido
pela letra S será interpolado pelos
seguintes parâmetros dessa chamada de método. Os próximos parâmetros serão o saldo
total atual da carteira. O saldo
confirmado da carteira atual. E, finalmente, o saldo atual não confirmado da
carteira. Agora, no método inicializado, vamos duplicar essa
linha duas vezes. Adicionaremos o mesmo ouvinte à propriedade
balanceada confirmada
e à propriedade de saldo total. Então, vamos modificar essas
linhas adequadamente. Vamos refatorar essa string, incluindo-a em uma
constante nessa classe. Vamos chamá-lo de
texto equilibrado e torná-lo privado. Agora, vamos fazer uma
pequena modificação no serviço de atualização UTXos. Observe que já temos uma anotação
assíncrona no método de atualização. Portanto, adicionar a mesma anotação
no método é chamado
de é redundante. Portanto, vamos removê-los. Primeiro no serviço de atualização de endereços da
carteira atual. Em seguida, na atualização do serviço de transação atual da
Wallet. Outra coisa que
notei é que
precisamos agrupar a chamada do
método das linhas de
transação de anúncios e uma plataforma para aprender mais tarde, uma vez que ela
modifica elementos na interface do usuário. Agora vamos ao teste de equilíbrio
total. Vamos garantir que nosso node
Bitcoin esteja funcionando. E vamos dirigir nossos
grupos de teste . O teste falhou.
Vamos ver o porquê. Acontece que esqueci de adicionar
a anotação de serviços ao serviço de atualização
do saldo da
carteira atual. Vamos consertar isso. E vamos fazer nosso teste novamente. Ótimo, o teste foi aprovado. No próximo vídeo, adicionaremos testes mais balanceados em nossos outros testes para garantir
que estejam funcionando conforme o esperado.
44. 42 Total saldo parte 3 skillshare 2: Neste vídeo,
implementaremos mais testes para garantir que o recurso de balança
esteja funcionando corretamente. Então, vamos copiar essa linha e
o teste de equilíbrio total. Primeiro, adicionaremos algumas afirmações de
teste sobre o saldo e o teste do bloco
receptor. Então, vamos colar a linha aqui. Vamos também copiar essa linha e
colá-la no bloco seguinte deste teste. Neste teste, esperamos que o saldo total
seja igual a um Bitcoin. Então, vamos ajustar essa
frase adequadamente. Também esperamos que todo o
saldo seja confirmado. Vamos fazer o mesmo
com esse outro teste. Nesse caso, esperamos
que o saldo total seja igual a dois
bitcoins, também confirmados. Agora vamos verificar se nosso node
está em execução e executar o teste. Os testes foram aprovados. Agora, vamos adicionar algumas afirmações de
equilíbrio à classe de teste de
Bitcoin recebedor. Nestes testes, espera-se
apenas saldos não confirmados. Vamos fazer esses testes. Ótimo, os testes foram aprovados.
45. 43 Enviar parte do bitcoin 1 skillshare 2: Ok, até agora, com nossa carteira, podemos receber Bitcoins
usando endereços gerados. Também podemos inspecionar o
saldo recebido por cada endereço e verificar as informações sobre
nossas transações. Agora, começaremos a implementar
a capacidade de gastar esses bitcoins enviando transações para outros
endereços que quisermos. Então, vamos começar a
criar um teste chamado send Bitcoin test
no pacote de teste da GUI. Isso estenderá a classe de teste de GUI. Adicionaremos o mesmo método de configuração. Adicionamos dois outros testes, chamando a carteira de carga
e adicionando o método balanceado. Vamos criar um teste chamado
should send Bitcoin. Agora no bloco de vento, criará uma nova
carteira e enviará um Bitcoin para seu
primeiro endereço. O código a seguir será muito semelhante ao código
dos outros testes. Depois de enviar um Bitcoin
para o endereço da nossa carteira, clicaremos na guia Enviar. Em seguida, clicaremos
no campo de valor para definir
quanto queremos enviar. Vamos enviar 0,5 Bitcoin, que é metade do nosso
saldo neste momento. Agora, clicaremos no campo
de endereço para enviar. Neste teste enviará
bitcoins para outro endereço. Então, vamos usar o cliente Node get new address para
obter um novo endereço de nó. Em seguida, escreveremos o endereço
obtido na entrada clicada. Agora, clicaremos
no botão Enviar. Depois disso, esperamos que um modal seja aberto com
informações sobre a transação
e um botão OK para confirmar e enviar
a transação. Então, vamos chamar o
método click on passando ok,
como seu parâmetro. Agora, clicaremos
na guia de transações. E com o código a seguir, verificaremos se a
tabela de transações tem duas linhas, uma para a
transação recebida e outra para a transação que
acabamos de enviar. Agora, vamos ao
playground dot FXML para criar nossa guia Enviar. Vamos duplicar o código
da guia Receber. E vamos mudar
seu texto para enviar. Vamos excluir essas linhas para começar com uma
nova guia na qual trabalhar. Agora, vamos para
o Scene Builder. Vamos clicar na guia Enviar. Vamos clicar no
corpo da guia para
selecionar o componente do painel de grade dentro dela. Vamos definir sua
altura pref para 130 e sua largura pref para 600. Agora, vamos adicionar um controle de rótulo
ao painel de grade dentro
da guia Enviar. Vamos definir dez em suas margens superior, direita e esquerda. Vamos mudar seu nome
para abordar esse fim. Agora, vamos adicionar um
campo de texto a esse painel de grade. Vamos mudar o índice da coluna do
painel de grade para um. Não está nos permitindo fazer isso. Primeiro, precisamos adicionar uma
coluna ao painel da grade. Vamos clicar com o botão direito aqui e adicionar duas linhas e uma coluna
ao painel da grade. Agora podemos alterar o índice da coluna
TextField para um. Vamos definir dez em suas margens superior, direita e esquerda. Vamos mudar sua largura
pref para 350. Vamos também mudar essa largura pref de
Collins para 600. Vamos adicionar outro rótulo
ao painel da grade. Vamos mudar o índice da
linha para um e definir dez para as margens superior, direita e esquerda. Vamos também alterar seu
texto para o valor a ser enviado. Vamos adicionar outro
campo de texto ao painel da grade. E vamos definir o índice da linha como um e o índice da coluna como um. Vamos definir sua altura pref para 26. E sua largura preferida é 100. Vamos definir dez em suas margens superior, direita e esquerda. Agora vamos colocar o último campo de
texto inserido em uma caixa H. Então, vamos adicionar uma caixa H
ao painel da grade. E seus
índices de linha e coluna são iguais a um. Vamos mover esse
campo de texto para a caixa H. Também vamos definir dez para
as margens superior,
direita e esquerda de oito dólares . Agora vamos adicionar uma
etiqueta à caixa H. Vamos também definir essas margens para dez e alterar seu texto para BTC. Na verdade, vamos colocar essas
margens de volta a zero. Em vez disso, colocaremos cinco nesses
recheios. Agora, vamos adicionar um
botão OK ao painel da grade. E vamos definir seu índice de
linha como dois. Também vamos definir essas
margens para dez. E vamos configurar seu texto para enviar. Agora, vamos copiar todo o
conteúdo da guia Enviar que criamos
no playground dot FXML. Vamos criar a guia send
underscore dot FXML no pacote FXML. E vamos colar o
conteúdo copiado nesse arquivo. Vamos mudar a tag tab para
a tag ética com cólon raiz. Vamos definir seu tipo
para efeitos Java, pontos vistos, controle de pontos, guia de pontos. Agora vamos importar todas
as tags restantes. Opa, definimos erroneamente
a propriedade de tipo como rótulo. Vamos consertar isso. Agora, vamos definir o ID
FX dessas tags. Primeiro, vamos definir esse ID de
fax para enviar a guia. Esse ID fx para endereço, para enviar esse ID fx
para o valor a ser enviado, esse ID de fax para enviar. Agora vamos para a janela principal de
sublinhado dot FXML. Vamos duplicar essa linha e mudar essa tag
para enviar o controlador de abas. Vamos criar esse controlador
no pacote de controladores. E vamos importá-lo aqui. Isso estenderá a classe de tabulação e adicionará a
anotação do componente a ela. Vamos copiar o construtor da
guia Receber e colá-lo aqui,
ajustando-o adequadamente. Vamos injetar a
carteira atual nessa classe. Agora, vamos adicionar a classe do controlador da
guia Enviar
ao conjunto de componentes personalizados
no ouvinte iniciado pela GUI. E vamos alterar o valor
desse parâmetro para enviar o ponto FXML da guia de
sublinhado. Agora vamos garantir que nosso node
Bitcoin esteja funcionando. E vamos fazer nosso teste de
envio de Bitcoin. Como esperado, o
teste falhou. Nos próximos vídeos, continuaremos
implementando esse recurso. C, sim.
46. 44 transações Bitcoin parte 2 skillshare 2: Neste vídeo, aprenderemos mais sobre transações de Bitcoin. Mais especificamente,
aprenderemos mais sobre o tamanho e as taxas
da transação. Esse conhecimento será necessário posteriormente, quando começarmos a criar transações para
transferir Bitcoins de nossas carteiras para
outros endereços. Na apresentação anterior, aprendemos que a taxa de
transação é igual à
soma de Bitcoin em entradas menos a soma de Bitcoins e saídas
de uma transação. Lembre-se de que a taxa de
transação é o preço que você
paga para que um menor escolha sua transação do mental incluído em um
bloco e a extraia. Quanto maior a taxa de transação, mais rápido
a transação
será incluída em um bloco. Com uma pequena taxa de transação, sua transação permanecerá
na mente por mais tempo. Portanto, é importante escolher
a taxa certa para garantir que sua transação
seja confirmada em um prazo razoável,
sem pagar demais. A taxa de transação
varia muito com o tempo. Seu valor segue a
lógica da oferta e da demanda. Quanto maior o número de
transações enviadas, maior tende a ser
a taxa de transação. E quanto maior o
número de mineradores, menor tende a ser
a taxa de transação. Este gráfico mostra a taxa
média de transação em dólares nos
últimos dois anos. Observe que, nesse período, a taxa de transação
variou de alguns dólares a mais de
$60 por transação. Então, como calculamos
a taxa de transação? Considerando que os blocos de
transação têm espaço
limitado, mas demanda
ilimitada, faz sentido que as taxas sejam calculadas pelo tamanho da transação. Existem diferentes
maneiras de obter a taxa de
transação recomendada. Por exemplo, você pode usar sites como Bitcoin
Fees, earned.com. Aqui podemos ver quantas
transações têm por taxa nas últimas 24 horas. Na coluna
da direita, vemos uma estimativa de quanto
tempo seria necessário para confirmar uma transação com essas
taxas em blocos e minutos. Se você rolar para baixo, ele fornecerá uma taxa de taxa recomendada para usar. Isso quase garante que sua transação será
confirmada no próximo bloco. Men pull dot space é outro site que, junto
com gráficos interessantes, mostrando a taxa média
de taxa de cada bloco, também mostra a
taxa de taxa recomendada para usar em transações de baixa, média e alta
prioridade. Quanto maior a prioridade, mais rápida se espera que a transação
seja confirmada. Também podemos usar nosso método de taxa inteligente de
estimativa RPC do
Bitcoin Core Note . De acordo com sua documentação, ele toma como parâmetro
uma meta de confirmação, que é o número de
blocos que esperamos
transacionar com
a taxa de
devolução necessários para serem confirmados. Também é necessário um parâmetro
opcional para definir o modo de estimativa, que pode ser indefinido,
econômico ou conservador. A taxa é
retornada em Bitcoin por quilo de byte virtual ou byte de KV. Esses exemplos mostram
que as
taxas recomendadas podem variar muito
entre as diferentes ferramentas. Para simplificar, em
nossa carteira usaremos as estimativas de chamadas RPC do Bitcoin Core para
smartphones, pois não
exigirá que consultemos ferramentas
externas com uma taxa de taxa. Portanto, podemos calcular a
taxa de transação multiplicando o
tamanho da transação em v bytes
pela taxa em
Satoshi is privy bite. Mas espere, o que é
um byte virtual? Para calcular as taxas de
transação, há dois
conceitos importantes a serem entendidos primeiro tamanho
virtual e byte virtual. Tamanho virtual, ou tamanho V, é o tamanho da transação em bits
virtuais ou v bytes. São conceitos
inventados para dar conta do tamanho menor das transações da
Segway. O tamanho V é calculado de
forma compatível com versões anteriores, para que predefina quais
tamanhos de transação são iguais e
predefina quais tamanhos de transação V. Para transações de Segway,
o tamanho V é igual ao tamanho
da parte não testemunha de uma transação mais o tamanho da
testemunha dividido por quatro. A testemunha é um campo presente apenas nas transações da Segway. Ele contém os campos que nas transações
pré-segmentadas estavam localizados no
campo ScriptSig de cada entrada. Essa forma diferente
de calcular os tamanhos das
transações resulta em tamanhos de transação V
menores para Segway em
comparação com transações legadas. Por exemplo, para transações com
uma entrada e uma saída, as transações do
Segway têm
110 v bytes de tamanho, enquanto as transações
legadas têm 192 v bytes de tamanho. Para transações com uma
entrada e duas saídas, as transações do
Segway têm
141 v bytes de tamanho, enquanto as transações
legadas têm 226 v bytes. Finalmente, para transações
com duas entradas em saídas, as transações do
Segway têm
209 v bytes de tamanho, enquanto as transações legadas
têm 374 bytes de tamanho. Então, digamos que queremos
calcular a taxa para uma transação seguinte
com uma entrada e duas saídas com
uma taxa de taxa de 19. Satoshi é um byte privado. Para fazer isso,
multiplicaríamos o tamanho v da transação, que é de 141 v bytes, pela taxa de taxa, que é de
19 Satoshi por v bytes. Isso daria 2.679 Satoshi em taxas por
essa transação. Então, em resumo, para
construir uma transação, precisaríamos criar
os seguintes itens. Para uma saída, precisaríamos de um endereço e uma quantia
para enviar para esse endereço. Se houver necessidade de uma mudança
e a maioria das transações sim
, precisaríamos
criar uma segunda saída contendo um
endereço de alteração e um valor. Também precisaríamos de um número
variável de entradas cuja soma do valor do Bitcoin
deveria ser maior do que a quantia a ser enviada mais
a taxa de transação. Lembre-se de que uma entrada
se referirá a uma saída não gasta de uma transação anterior enviada
para um de seus endereços. Uma alteração será necessária se
a soma dos valores de entrada for maior que o valor a ser
enviado mais a taxa de transação. Se, por sorte ou por design, a soma dos valores de entrada for igual ao valor a ser enviado mais a taxa de transação a transação não
terá um resultado alterado. E o remetente se
beneficiará de pagar menos na taxa de
transação por uma transação
com apenas uma saída. Novamente, para calcular
a taxa de transação será necessária a taxa em
Satoshi por v bytes. Obteremos esse valor
usando a API gRPC estimada do
smartphone
do Bitcoin Core e converteremos o resultado em por V de
Satoshi também
precisaremos do tamanho da
transação em v bytes. No próximo vídeo, implementaremos as
estimativas de notas, taxa inteligente, cliente e serviço para
calcular o tamanho da transação. Posteriormente, combinaremos os dois para
calcular as taxas de transação. Veja, sim.
47. 45 Enviar bitcoin parte 2 skillshare 2: Neste vídeo, criaremos uma
calculadora do tamanho da transação e criaremos o cliente node para
o método RPC do nó Bitcoin de
alimentação inteligente estimada . No pacote de serviços api dot, vamos criar a classe de calculadora
do tamanho da transação. Essa classe será
responsável por calcular tamanhos das
transações de acordo com seus tipos e números
de entradas e saídas. Esses tamanhos serão
usados posteriormente para calcular o valor da taxa que devemos
incluir em nossas transações. Vamos adicionar uma
anotação de serviços a ela. Primeiro, definiremos algumas
constantes nessa classe. Essas constantes conterão
os tamanhos de cada parte
de uma transação. Como estamos trabalhando apenas com transações de
Segway no momento, essas constantes se referirão apenas a partes das transações da Segway. Então, vamos começar a definir o tamanho da sobrecarga da
transação. A sobrecarga é a
parte da transação cujo tamanho não muda com o número de entradas ou saídas. A primeira constante
será chamada de inversão, que faz parte da sobrecarga. Ele codifica qual versão
a transação tem. Ele tem quatro bytes de tamanho. Em seguida, temos a contagem de entradas, que, como o nome sugere, especifica o número de
entradas na transação. Ele tem um
número variável de bytes, mas para até 252 entradas, seu tamanho é de um byte. Em seguida, temos o campo
de contagem de saída, que tem o mesmo tamanho e
regras da contagem de entrada. Como o próprio nome sugere, ele especifica o número de
saídas na transação. Em seguida, temos o campo de tempo do lote
N, que tem quatro bytes. Às vezes, esse campo é
usado para codificar o tempo após o qual a
transação pode ser gasta. Depois, temos o
marcador e a bandeira do Segway, que estão presentes apenas
para transações do Segway. Ele tem dois bytes de tamanho. Agora vamos definir os tamanhos dos campos
de entrada, começando com o ponto de saída, que tem 36 bytes de tamanho. O ponto é a combinação do ID
da transação anterior e do índice de saída. Ele indica o UTXO
usado para essa entrada. Em seguida, temos o campo de comprimento do
ScriptSig, que temos até 252
bytes, tem um byte. Ele indica o
tamanho do ScriptSig para a entrada. Em seguida, temos o campo
ScriptSig. Para transações de Segway. Seu tamanho é zero. Lembre-se de que, para entradas de
segmento, o conteúdo do ScriptSig é
movido para o campo de testemunha. Agora vamos adicionar o campo de sequência
final. Ele tem quatro bytes de tamanho
e é usado para definir se a transação
é substituível
caso o remetente
queira alterar sua taxa. Em seguida, vamos adicionar o campo de contagem de
testemunhas de até 250 aos itens de testemunhas. Ele tem um byte de tamanho. Em seguida, temos o campo de itens de
testemunha, que tem um tamanho de
107 bytes para entradas P2, WP, k, h. Esse campo é
composto pela assinatura, que pode ter 71 ou
72 bytes de tamanho, e a chave pública, que tem 33 bytes
de tamanho, 72 bytes, é escolhida como o tamanho
das assinaturas, já que preferimos superestimar um pouco o tamanho da transação. Portanto, o F0 calculado tem a garantia de ser suficiente
para a transação. Os dois
bytes restantes que
codificam o tamanho da assinatura
e da chave pública. Explique o valor
constante de 107 do item da testemunha. Agora vamos definir as constantes
com os tamanhos de saída. O valor n é a quantidade de bitcoin enviada
nessa saída. Ele tem oito bytes de tamanho. Em seguida, temos o comprimento da chave pub do
script, que tem um byte de tamanho para até 252 bytes no comprimento da chave do
script pub. Em seguida, temos a chave
script pub, que tem 22 bytes de tamanho
por um segundo, quais endereços? Agora, antes de continuar
implementando o cálculo
do tamanho da transação, vamos criar o teste da calculadora
do tamanho da transação no pacote de teste da API. Isso estenderá a classe de
especificação. Vamos adicionar um campo de
calculadora de tamanho de transação nessa classe. E vamos usar um
método de configuração para instanciá-lo. Agora, vamos criar
um nome de teste para calcular o
tamanho da transação para
saídas e entradas de transação P2, WP k, h. No bloco único, chamaremos
o método de cálculo no serviço de
calculadora do tamanho
da transação e armazenaremos o retorno na
variável de resultado. Como parâmetros passarão
as entradas e saídas, que definiremos
no bloco where. No bloco, verificaremos se o resultado é igual à variável de tamanho
esperada. No bloco where, adicionará
os seguintes casos de teste. Para as entradas e
saídas, as variáveis
definirão listas com um
número variável de endereços. Como, por enquanto, não nos
importamos com o tipo de endereço, simplesmente
adicionaremos uma letra
representando cada endereço. Os valores de tamanho
esperados aqui foram previamente calculados para cada combinação de
entradas e saídas e validados usando
o Bitcoin Core CLI. Agora, vamos criar o método de
cálculo na classe
da
calculadora do tamanho da transação. Ele retornará um número inteiro grande
e receberá como parâmetros uma lista de endereços de entrada e uma
lista de endereços de saída. Agora, vamos primeiro calcular
o tamanho da sobrecarga. É igual à soma
dessas constantes. Lembre-se de que o
valor que queremos calcular aqui é o tamanho V. Portanto, os elementos das transações do
Segway, como o Segway, o
marcador e a bandeira, devem ser divididos por quatro. Dessa forma, vamos dividir
essa constante por quatro. Agora, vamos calcular
o tamanho da entrada. Será a soma
dessas constantes. Agora, vamos calcular o
tamanho de todas as entradas
multiplicando a variável de entrada pelo número de endereços de
entrada. Agora, vamos calcular
o tamanho da testemunha
adicionando a contagem de testemunhas e as constantes dos itens da
testemunha. A seguir, quais elementos? Vamos dividir a soma deles por quatro. O
tamanho total da testemunha é igual
à variável da testemunha multiplicada pelo tamanho dos endereços de entrada. Agora, vamos calcular
o tamanho da saída. Será igual à
soma dessas constantes. A variável de todas as saídas
será igual
ao tamanho da saída vezes
o número de saídas. Finalmente, o resultado
do tamanho da transação será igual
ao BigDecimal, alguns dos valores calculados
anteriormente. Também vamos definir a
escala do resultado para zero com o
modo de arredondamento pela metade. Isso fará com que o resultado tenha zero casas decimais arredondadas
para o número inteiro mais próximo. Se o
valor decimal do resultado for cinco, ele será arredondado para
o número inteiro acima. Agora, retornamos o resultado
convertido em um número inteiro grande. Agora, vamos executar o teste da calculadora
do tamanho da transação. Ótimo, o teste foi aprovado. Agora vamos criar o cliente
node estimate smart Fee no pacote node
dot client. Vamos injetar o cliente
node nele. E vamos criar o método de
estimativa inteligente de taxas. Ele retornará um novo nó que o objeto
FI criará e usará um número inteiro
como parâmetro. Agora, vamos voltar a fazer a chamada do método de
solicitação
no cliente node. O nome do método será a taxa inteligente
estimada. Seu segundo parâmetro será um novo objeto de referência de
tipo parametrizado. A terceira será
uma string vazia e seu último parâmetro,
a variável blocks. Agora vamos criar
o registro node V no pacote domains dot node. Seus campos serão
uma taxa dupla e uma lista de erros. Agora, no pacote de
serviços api dot, vamos criar uma interface
chamada serviço de taxa estimada. Vamos adicionar o
método de estimativa a ele. Ele retornará um grande decimal. Agora, vamos criar uma
implementação dessa interface. Os nomes anotam a taxa
de serviço estimada no mesmo pacote. Vamos implementar seu método. Essa classe será
usada posteriormente para estimar a taxa usando
o cliente inteligente de taxas de
estimativas do node. Se quisermos alterar o método de estimativa de
taxas ou adicionar mais opções
para fazer isso posteriormente, basta criar outra
implementação da interface do
serviço de taxa estimada. Primeiro, chamaremos o método de estimativa do
smartphone
a partir do cliente criado anteriormente e armazenado na variável
node V. Vamos injetar esse cliente nessa classe e passar para esse método para que tentemos
obter uma taxa que
fará com que nossa transação seja
confirmada no próximo bloco. Se, por algum motivo,
a taxa
devolvida for igual a nula, retornaremos
a taxa de substituição. Vamos injetar essa
variável nessa classe. Irá injetá-lo a partir
dos arquivos de propriedades. Então, vamos adicionar essa
anotação de valor antes dela. Após a
declaração if, retornará o grande valor decimal
da taxa da taxa. Agora, vamos adicionar a propriedade da taxa de
fallback rate do bitcoin dot a todos os arquivos
de propriedades do projeto. Vamos fazer com que seja igual a 0,002.
48. Seleção de moedas e poeira: Nesta apresentação,
continuaremos explicando conceitos
importantes para entender
as transações de Bitcoin e
continuar criando nosso recurso de transação
pecaminosa. Então, vamos falar sobre seleção de
moedas. seleção de moedas é o
processo de selecionar UTXOs para criar uma transação. A regra geral para
essa seleção é que a soma dos
valores de Bitcoin em UTXos deve ser maior que a
quantidade de areia mais a taxa de transação mais
a alteração, se necessário. Existem muitos métodos diferentes de seleção de
moedas. Cada um tem vantagens
e desvantagens. O algoritmo que escolheremos para nossa carteira é chamado de sorteio aleatório
único. É provavelmente o algoritmo de seleção de
moedas mais simples e bom o suficiente
para nossos propósitos. Esse algoritmo foi
apresentado pela primeira vez em uma tese de
mestrado intitulada e avaliação de
estratégias de seleção de moedas de Mark Earhart. Eu recomendo a leitura desta
tese se você quiser
saber mais sobre estratégias
de seleção de moedas. Esse método de seleção de moedas
foi adicionado ao Bitcoin Core em setembro de 2021 como uma estratégia alternativa de seleção de
moedas. Consiste em embaralhar
os gastos ou UTXOs e, em
seguida, selecionar os UTXOs um por um até que a soma dos valores de UTXOs
selecionados seja maior ou igual
ao valor a ser enviado mais a taxa de transação mais
a mude, se necessário. Se o valor da alteração for
menor que o limite de poeira, a saída
da alteração será removida
da transação e seu valor será adicionado à taxa da transação. Mas espere um momento, o que é poeira? Uma produção de poeira é uma produção cuja quantidade de Bitcoin é menor do que o
custo de gastá-la. O exemplo a seguir mostra como as saídas de
poeira
não são econômicas de gastar. Digamos que você tenha um
UTXO contendo 50 Satoshi e queira enviar esses 50 Satoshi para um amigo. Ao criar a transação, você descobre que
a taxa de transação necessária para enviá-la é
igual a 100 Satoshi. Portanto, não faz sentido
gastar o UTXO com 50 Satoshi, pois você
pagará mais em taxas do que
o valor enviado. Além disso, seu amigo também não
se beneficiará de receber um UTXO com 50 Satoshi pois ele teria o mesmo problema de você gastá-lo. Este exemplo mostra
que é prejudicial para a rede Bitcoin
criar saídas de poeira, já que ninguém na
rede se beneficia disso. Portanto, a maioria dos nós de
Bitcoin não relaciona transações
contendo poeira. Isso ajuda a proteger a
rede contra ataques de poeira. ataque de poeira é o processo
de enviar
poeira maliciosamente aos endereços da carteira para
rastrear suas transações. Esse ataque é mostrado
neste exemplo. Suponha que a
agência governamental envie poeira para o endereço X que
pertence à pessoa. Por quê? Quando a carteira eletrônica
cria ingenuamente uma transação, ela inclui a saída de poeira
e outras cinco como entradas. Agora, a agência governamental sabe por que cinco endereços anteriores e todas as
transações anteriores. Além disso, o governo agora
sabe o endereço da mudança dessa transação e contrata outras transações com ela. Mas quais são os critérios para
considerar uma saída como poeira? O limite de poeira é usado para isso. Cada saída cuja quantidade de
Bitcoin é menor que o limite de poeira
é considerada poeira. O Bitcoin Core usa a
seguinte fórmula para calcular o limite de poeira. O limite de poeira em Satoshi
de uma saída de transação é igual ao tamanho da saída da
transação mais o tamanho de entrada necessário para gastá-la
em v bytes multiplicado
pela folha da indústria
em Satoshi por KV bytes divididos por 1.000. O resultado representa o
custo de saída da transação que o valor de saída de
Bitcoin de
uma transação deve ser igual ou superior para
não ser considerado pó. A taxa de retransmissão de poeira é uma propriedade
de configuração do nó Bitcoin. É a taxa de transação usada ao calcular o limite de poeira. A
taxa padrão de retransmissão de poeira é definida para 3.000 Satoshi por KV bytes ou
três Satoshi por bit de V. Isso faz com que o limite de
poeira padrão para saídas seguidas seja igual a 294. De Satoshi. O limite de poeira padrão para
não segue quais
saídas são iguais a 546 de Satoshi. Para obter mais detalhes sobre como
calcular o limite de poeira, este link do código
Bitcoin Core tem um comentário explicando como o limite de
poeira é calculado. Agora vamos resumir as etapas gerais
do algoritmo
de
sorteio aleatório único. O primeiro passo é agrupar
todos os UTXOs da carteira em uma lista. Em seguida, para cada UTXO disponível na
lista embaralhada, adicione esse UTXO a uma lista
de UTXOs selecionados. Calcule a meta ajustada, que é igual à
quantidade de areia mais a taxa de transação mais
a alteração, se necessário. Se o valor total de Bitcoin
na lista UTXOs selecionada for maior ou igual
à meta ajustada. Pare. Finalmente, use os UTXOs selecionados como entradas da transação
desejada. Alguns pontos de atenção
sobre esse algoritmo, metas
ajustadas
com e sem a saída de alteração, devem
ser calculados para melhor precisão, pois as taxas de
transação diferem entre as transações.
com saídas de 1,2, se a alteração gerada estiver entre zero e o limite de poeira, interrompemos a iteração, pois não
incluiremos uma alteração na transação e, portanto,
não precisaremos de mais UTXOs. Isso é necessário
para não gerar uma saída de poeira para a
mudança por acidente. A desvantagem do algoritmo de
sorteio aleatório único aparece em alguns casos patológicos, por exemplo, quando você tem um
único UTXO grande e muitos UTXOs pequenos. Uma transação com muitas
entradas e uma alta taxa de transação pode ser criada em vez de usar o grande UTXO para evitar a
necessidade de muitas entradas. Quando for esse o caso, uma abordagem diferente é recomendada para construir
uma transação. Por exemplo, escolha manualmente os UTXOs que farão parte de algumas transações
específicas. No próximo vídeo, implementaremos uma calculadora de
poeira e o
algoritmo de sorteio aleatório único, C, sim.
49. 47 Enviar parte do bitcoin 3 skillshare 2: Neste vídeo,
começaremos a implementar uma calculadora de poeira e o algoritmo de sorteio aleatório
único. Mas primeiro, vamos refatorar
o registro UTXO. Já que faremos
muitos cálculos
com o campo de valor UTXO. E os cálculos são melhor
feitos com números decimais grandes em vez de duplos para alterar a quantidade, tipo dois decimais grandes. Agora, temos que refatorar todos os usos do
campo de quantidade no projeto. Então, vamos fazer isso. Vamos mudar o
formato ou parâmetro de formato do Bitcoin para BigDecimal e ajustar esse
parâmetro de acordo. Vamos fazer o mesmo
com todos os métodos que o IDE sinalizou como
erros no projeto. Aqui, adicionaremos números decimais grandes
usando o método add. E vamos passar o grande valor
decimal zero em vez do primitivo zero
para essas chamadas de método. Agora, temos que
mudar o tipo
desse campo balanceado
e todos os seus usos. Vamos refatorar esse
método para fazer a soma usando grandes valores
decimais. Também vamos ajustar esse
código para fazer a mesma coisa, mas com grandes valores decimais. Ok, a refatoração está feita. Agora no pacote de
serviços api dot. Vamos criar a classe de
calculadora de poeira. Vamos adicionar a
anotação do serviço a ela. Vamos criar esse método de
poeira nele. Como o próprio nome sugere, ele retornará verdadeiro se uma quantidade for
considerada falsa, caso contrário, retornará
um booleano e tomará um grande número inteiro como parâmetro representando a
quantidade em De Satoshi. Esse método avaliará
se o valor em Satoshi de uma produção é menor do que o
custo de gastá-la. O custo do gasto é igual
ao tamanho V da saída
mais o tamanho v da entrada
necessária para gastá-la, que armazenará
nessa constante vezes os pés do relé de poeira em Satoshi por quilo (v
bytes). dividido por 1.000. Como trabalharemos apenas com saídas
sigmóides por enquanto, nos preocuparemos apenas com o limite de
poeira para saídas seguidas. Então, vamos criar essa constante
que será igual a 98. Esse valor é retirado
diretamente
do arquivo dot cpp da
política Bitcoin Core mencionado na
última apresentação. Vamos também injetar a taxa de
relé de poeira nessa classe. Ele estará pronto
e seu valor será injetado
do arquivo de propriedades. Vamos adicionar a seguinte anotação de
valor antes dela. Agora vamos adicionar esse valor
a todos os arquivos de propriedades. Vamos defini-lo para 3.000, o mesmo valor padrão usado
no Bitcoin Core Node. Agora, no pacote de
serviços api dot, vamos criar a interface do
seletor de moedas. Criará essa interface para permitir
mais flexibilidade. Se quisermos criar mais implementações de seletores de
moedas posteriormente. Vamos adicionar o
método de seleção a ele. Ele retornará uma lista
dos UTXOs selecionados. E precisaremos de parâmetros, uma lista de UTXOs, um número inteiro grande para
o valor a ser enviado, um decimal grande para a taxa, endereço a ser enviado e um endereço de alteração. Agora, no mesmo pacote, vamos criar o seletor de moedas de sorteio
aleatório único, que implementará
essa interface. Vamos implementar seu método e adicionar uma
anotação de serviço a ele. Vamos injetar a calculadora
do tamanho da transação nessa classe. E vamos injetar a calculadora de
poeira nela. Antes de continuar
implementando o método de seleção, vamos criar a classe de teste de sorteio aleatório
único de
um seletor de moedas. Na classe de teste da API. Isso estenderá a classe de
especificação. Vamos injetar o único sorteio
aleatório nessa classe. E vamos usar o
método de configuração para instanciá-lo. Vamos passar pela calculadora
do tamanho da transação e pela calculadora de poeira com uma taxa de retransmissão de poeira de
3.000 como parâmetros. Agora, vamos criar um teste. O Tidal deve selecionar n entradas esperadas, moedas para transação com saídas
esperadas e saídas. Agora vamos criar uma
classe utilitária que nos ajudará a testar e implementar o seletor de moedas de sorteio
aleatório único. Vamos chamá-lo de Satoshi e
criado no pacote utils. Agora, vamos criar os
dois métodos de Satoshi. Ele usará um grande decimal como parâmetro e
retornará um número inteiro grande. Esse método
converterá uma quantia em Bitcoin na mesma
quantia em Satoshi. Para fazer isso, simplesmente retornamos
o valor em Bitcoin multiplicado por 100 milhões e convertemos o resultado
em um número inteiro grande. Vamos também criar um método
para fazer a operação inversa, que é converter
Satoshi em Bitcoin. Para isso, retornaremos apenas
o valor embrulhado em um novo grande decimal
dividido por 100 milhões. No método de divisão
passará oito como segundo parâmetro para fazer com que o resultado tenha oito
casas decimais. Também passaremos
o modo de arredondamento desnecessário como
terceiro parâmetro. Agora, vamos criar um método
para converter uma taxa em Bitcoins por KV de bicicleta em
Satoshi por V byte. Ele será chamado de BTC por KB
em vez de Satoshi por byte. Ele retornará um número inteiro grande e tomará como parâmetro
um grande decimal. Primeiro, multiplicaremos a
taxa por 100 milhões. Em seguida, dividiremos o resultado por 1024 com duas casas decimais
e um modo de arredondamento de piso. Em seguida, vamos converter o resultado um número inteiro grande e
armazená-lo na variável correta. Se o resultado for menor que um, então o tornaremos igual a um. Finalmente, retornamos
a taxa convertida. No próximo vídeo, terminaremos de testar
e implementar o seletor de moedas de
sorteio aleatório único C. Sim.
50. 48 Enviar parte bitcoin 4 Skillshare 2: Neste vídeo, concluiremos implementação do algoritmo de sorteio
aleatório único. No teste do
seletor de moedas de sorteio aleatório único em um determinado bloco, primeiro
criaremos UTXOs usando esse método e armazenaremos o
resultado na variável UTxOS. Esses serão os UTXOs
disponíveis que
passarão como o primeiro parâmetro
para o método testado. Então, vamos criar esse método. Ele usará uma lista de
números inteiros grandes como parâmetro, que definirá a
quantidade de cada UTXO. Portanto, para cada elemento na lista, chamaremos o método
create UTXO para criar um único UTXO. Vamos criar esse método. Vamos instanciar um UTXO
com esses parâmetros. Você pode copiar esses valores
dos recursos desta lição. Agora, vamos criar um UTXO
adicional e adicioná-lo à lista de
UTXOs usando esse código. O motivo para adicionar um UTXO extra à lista é que
queremos permitir o método
select o adicione erroneamente à lista UTXOs selecionada. Se for esse o caso,
saberemos que o método testado não está
funcionando conforme o esperado. Vamos definir esses
dois endereços. Um será o endereço a ser enviado e o outro será
o endereço da mudança. Você pode copiá-los da página
Projeto e Recursos. Vamos definir a
taxa para 0,002. No bloco de vento, chamaremos o método de seleção de
sorteio aleatório único com esses parâmetros. No bloco then, verificaremos se o tamanho do UTXOs selecionado é
igual ao número esperado de entradas variável
no bloco where. Vamos adicionar esses casos de teste. Você pode encontrá-los na página
Projeto e Recursos. Esses casos de teste cobriram
transações com 12,3 entradas e
1,2 saídas. os valores de entrada para
transações com Espera-se
que os valores de entrada para
transações com
uma saída não gerem alterações ou
gerem mudanças com poeira, cujo valor é
adicionado à taxa. os valores de entrada para
transações com Espera-se que os valores de entrada para
transações com
duas saídas
gerem alterações incorretas, que retornam ao remetente
por meio de uma segunda saída. Vamos fazer o teste. Falhou conforme o esperado. Agora, vamos implementar o método de seleção de
sorteio aleatório único. Primeiro, filtraremos todos os UTXOs
recebidos para criar uma lista somente com UTXOs que tenham uma ou
mais conformações. Então, vamos criar esse
método. Para fazer isso. Chamaremos o
método de filtro no stream UTXOs, retornando uma lista com
apenas UTXOs confirmados. Agora, vamos criar
essa variável para armazenar a taxa de taxa em
Satoshi por V byte. Para isso, usaremos
o método BTC por KB para Satoshi por bicicleta
da classe Satoshi. Agora, vamos armazenar os
UTXOs embaralhados nessa variável, atribuindo o retorno
dessa chamada de método a ela. Vamos criar esse método. Primeiro, vamos instanciar
uma nova ArrayList contendo o conteúdo da lista
UTXOs. Em seguida, chamaremos o método de
coleta aleatória, passando a nova lista
como parâmetro. Em seguida, retornaremos a lista de moedas
embaralhadas. Agora vamos instanciar
uma ArrayList que armazenará os UTXOs
selecionados. E vamos criar essa variável para armazenar o saldo total
de entrada. Agora, para cada UTXO
da lista de moedas embaralhadas, adicionaremos o UTXO à lista de
UTXOs selecionada. E adicionaremos sua quantidade em Satoshi à variável
balanceada de entrada total. Se o saldo total de entrada for menor que o valor ascendente, continuaremos a execução a
partir da próxima iteração do loop. Após a instrução if, quando o
saldo total de entrada exceder o valor a ser enviado,
instanciará uma ArrayList com
os endereços de saída e adicionará o endereço
a ser enviado a essa lista. E criaremos uma lista
com os endereços
das entradas selecionadas usando
esse mapeamento de fluxo. Agora, vamos calcular
a taxa total em Satoshi e armazenada
nessa variável. Para isso, vamos chamar
o método da taxa total, passando a taxa em
Satoshi por V, morda os endereços de entrada e os endereços de saída
como seus parâmetros. Vamos criar esse método. Dentro, ele retornará a
calculadora do tamanho da transação, calcula chamada do
método, passando
os endereços de entrada e os endereços de saída
como seus parâmetros. Em seguida, multiplicaremos
o resultado pela taxa de taxa em
Satoshi por mordida em V. Agora, criaremos a variável alvo
ajustada, que será igual
à soma do valor
a ser enviado
e da taxa total. Agora vamos adicionar o
endereço de alteração à lista de
endereços de saída. Calcularemos a taxa
total com alterações, chamando o método da taxa total e
passando esses parâmetros. E calcularemos a meta
ajustada com a mudança, que será igual
à soma da quantidade de areia e da
taxa total com a alteração. Agora, se o resultado
do
método de transação
preenchido com balanceamento de entrada com esses parâmetros for verdadeiro, sairemos do loop
usando a palavra-chave break. Vamos criar esse método. Ele retornará o resultado
da seguinte declaração. Se o saldo total de entrada
for igual ou maior que a meta ajustada e a poeira
gerada de mudanças
, isso significa que
os
UTXOs selecionados são suficientes para realizar
essa transação. Outra condição para que os
UTXOs selecionados cumpram a transação é que a
soma dos valores seja igual ou maior do que a
meta ajustada com a alteração. Vamos criar a mudança no método de
poeira retornará
a calculadora de
poeira é chamada de método de poeira passando a grande
diferença inteira entre o saldo total de entrada e o alvo ajustado
como seu parâmetro. Por fim, simplesmente
retornaremos os UTXOs selecionados
desse método. Agora, vamos fazer o teste do seletor de moedas de sorteio
aleatório único teste do seletor de moedas de sorteio
aleatório e executar esse teste. Grau. Os testes foram aprovados.
51. Como as transações do Segwit são construídas e Validated: Nesta apresentação, veremos mais detalhes sobre como
criar uma transação. Então, digamos que já
usamos o seletor de moedas para selecionar alguns UTXOs para gastar
como entradas em uma transação. Em nossa carteira, também
temos a capacidade de derivar as chaves privadas necessárias
para gastar esses UTXOs. Essas chaves privadas serão necessárias para assinar a
transação posteriormente. Já escolhemos um
endereço para enviar alguns Bitcoins. E temos o endereço de alteração o
qual a alteração
será enviada. Depois de definir essas coisas, é hora de construir
nossa transação. Vamos ver os campos que fazem parte de uma transação de Bitcoin. Primeiro, o campo da versão. É usado para definir as regras que a transação segue. Atualmente, a
primeira versão, que
usaremos , é para transações comuns. A versão dois é para transações que
seguem o BIP 68, que implementa
regras para validar uma transação somente
após um certo tempo. O campo de vida útil é usado
para uma finalidade semelhante. Seu valor pode representar
um certo tempo para adicionar uma transação a um bloco ou
zero para ignorar essa regra, então temos o sinalizador e o marcador seg
would. Está presente apenas nas transações da
Segway. Se seu valor for 0001, isso marca essa transação como tendo dito quais entradas, cada transação tem uma ou
mais entradas de transação. Cada entrada de transação tem um ID de
transação que define uma transação anterior
da qual a entrada atual está
gastando Bitcoins. O índice de saída indica qual saída da transação
anterior. A entrada atual é
gastar Bitcoins de. Juntos, o ID da transação e o índice de saída são
chamados de ponto de saída. Você pode ver o ponto de saída
como uma coordenada para
identificar a qual UTXO
e entrada se referem. Em seguida, para cada entrada, temos o campo ScriptSig. Em entradas de segmento. Esse campo está vazio e seu conteúdo é movido
para o campo da testemunha. Em transações não segmentadas, seu conteúdo é necessário para desbloquear
os gastos do UTXO. A entrada está se referindo a. O campo da sequência n define quando a entrada é
válida para gastar. Quando esse
valor de campo é igual
ao valor hexadecimal máximo para seu tamanho, esse campo é ignorado. Uma transação também tem
uma ou mais saídas. Cada saída contém
uma chave de script pub, que tem um código de script
definindo as regras para gastar essa saída em
uma transação futura. Cada saída também contém
um campo de quantidade que define o número de Satoshi
bloqueados nessa saída. Finalmente, as transações também
contêm um campo de testemunha. Para transações que não sejam da Segway, esse campo está vazio. Para transações de Segway, a testemunha contém
todo o conteúdo que, em
transações não sequitur está no ScriptSig
de cada entrada. Agora, vamos falar
sobre como criar entradas de
transação e o campo de testemunho
para entradas de segmentos. Para cada UTXO selecionado, precisamos criar uma entrada de
transação. O campo ID da transação
da entrada da transação será igual ao ID da transação UTXO. O campo do índice de saída será igual ao índice de saída UTXO, também conhecido como Vout na documentação
da
API Bitcoin Core RPC. O ScriptSig ficará vazio e a sequência final será igual
a esse valor hexadecimal, que é o valor máximo
permitido para esse campo. Também precisamos criar uma
testemunha para cada entrada, o campo da testemunha
conterá uma assinatura obtida usando a chave privada usada
para derivar o endereço UTXO. E uma chave pública que
foi derivada usando a
chave privada anterior e que também pode gerar o mesmo
endereço UTXO mencionado. Veremos mais detalhes sobre o processo de assinatura em
uma apresentação futura. Observe que as
assinaturas fictícias e os bupkis, cujos valores podem ser
vários zeros, podem ser usados como espaços reservados para criar e assinar transações. Esse truque facilita o cálculo
do tamanho da
transação antes de
assinar as transações. Agora vamos falar sobre como
criar uma sequência de resultados. Primeiro. Por outro lado, é
possível criar
uma transação com diferentes tipos de
entradas e saídas, por exemplo, na mesma transação, você pode ter entradas e saídas segmentadas e não
segmentadas. De volta ao assunto principal. Geralmente, queremos criar uma saída para o
endereço para o qual queremos enviar bitcoins e uma saída para o endereço de
alteração. Se a transação
precisar de uma alteração. Cada saída de transação tem
um campo de chave de script pub. Cada segmento script pub key, também conhecido como pay to
witness pub key hash ou P2, WP k H tem uma
versão testemunha de zero. A versão de testemunha
é para scripts de raiz principal. Novas versões podem ser adicionadas para scripts
futuros, se necessário. O segundo item da chave
pub do script para saídas
sigmóides é
um hash de chave pública
, obtido por Beck 32 decodificando o endereço
dessa saída. A saída da transação também
tem um campo de valor no Satoshi representando
o valor enviado para esse endereço de saída. Agora, vamos finalizar esta
apresentação falando sobre a
execução e validação do script do segmento. Quando um nó recebe
uma transação, ele começa a validá-la. Para cada entrada em uma transação, o nó combina
a testemunha de uma entrada com a chave de script
pub do UTXO referenciada pelo
outpoint, e a entrada net executa o
script combinado e o valida . Vamos ver como isso é feito. Aqui está a chave pub do script de um UTXO e o
campo de testemunha que deseja gastar esse UTXO gerando o
seguinte script combinado. Você pode estar
se perguntando de onde
vieram os opcodes do
script combinado. Acontece que, quando
um nó identifica a versão zero na chave pub do script do
segmento, ele aciona uma regra especial que gera parte do código
combinado abaixo. Em seguida, o script combinado é executado da mesma forma que
os scripts não sequiturs. A partir do script combinado, a assinatura e as chaves públicas são adicionadas a uma pilha de execução. Em seguida, o opcode OPT up duplica a chave pub
na pilha de execução. Up hash 160 hashes, a última chave de pub
adicionada à pilha. Em seguida, a partir do script combinado, o hash da chave pub é
adicionado à pilha. opcode Up equal verify remove os dois últimos elementos
da pilha de execução
e os compara. Se forem iguais, o script
continua sendo executado. Finalmente, o object
sig opcode verifica se a assinatura é válida para a chave pub restante
na pilha. Se for válido, ele retornará
verdadeiro para a pilha de execução. Depois que todos os elementos do script forem adicionados à pilha de
execução, a entrada da transação
seria considerada válida se o último elemento
adicionado fosse verdadeiro. Esse processo deve ser repetido para cada entrada de transação. Para que uma transação
seja considerada válida, todas as suas entradas devem ser válidas. Apenas como um lembrete visual, vamos analisar de
onde
vieram cada elemento na chave do pub
do script e da testemunha chave do pub
do script e da testemunha durante a
construção da transação. O hash da chave pub presente
na chave pub do script
veio da década de 30 para decodificar
o endereço do UTXO que está sendo gasto. A assinatura na
testemunha veio com a aplicação do algoritmo ECDSA, que precisa de uma chave privada válida. A chave pública e
a testemunha vieram
da chave pública derivada
da chave privada mencionada. A mesma chave pública
foi usada no passado para gerar o endereço
do UTXO gasto
aplicando sequencialmente o algoritmo hash 160 e a codificação
reversa 32.
52. 50 Enviar parte do bitcoin 5 skillshare 2: Neste vídeo, criaremos um serviço de criação de transações. No início, esse serviço
lidará apenas com
entradas e saídas do segmento, mas mais tarde no curso,
vamos melhorá-lo. Então, no pacote de
serviços api dot, vamos criar o serviço de
criadores de transações. Vamos adicionar a
anotação do serviço a ela. Vamos também injetar a calculadora de
poeira nela. Agora, no pacote de teste da API, vamos criar a classe de teste do serviço de
criadores de transações. Isso estenderá a classe de
especificação. Vamos injetar o serviço de
criadores de transações nele e
instanciá-lo no método de configuração. Será necessário instanciá-lo
com uma nova calculadora de poeira que ultrapassa 3.000 como parâmetro de taxa de relé de
poeira. Antes de fazer esse teste, vamos fazer o teste do seletor de moedas de
sorteio aleatório único para fazer uma pequena refatoração. Vamos recortar esses dois métodos
dessa classe e colá-los na nova
classe utils que criaremos no pacote de teste BYOD W. Vamos tornar esses
dois métodos estáticos. Agora, vamos consertar a
única moeda aleatória de drogas. Selecione seu teste para usar esses
métodos dessa classe. Agora, vamos fazer o teste do serviço de
criadores de transações. Vamos criar um teste
chamado should create transaction com
hashtag n entradas,
entradas e hashtag esperadas
n saídas, saídas. No corpo dado. Vamos primeiro
criar essa variável utxOS e atribuir a
chamada do método utils dot create utxOS retornada a ela, passando a
variável de valores de entrada como seu parâmetro. Agora, vamos criar esse
endereço para enviar a variável. Seu conteúdo será igual
à variável com o mesmo nome no teste
do seletor de moedas de sorteio
aleatório único . Vamos também criar a variável de
alteração de endereço, que será igual
à variável com
o mesmo nome no único sorteio
aleatório de uma moeda,
selecione seu teste. Vamos criar a variável de
taxa de taxa, que será igual a 0.000 a. Vamos também definir a variável de taxa total
esperada, que será igual à variável de tamanho
esperada multiplicada pela taxa de taxa em V de
Satoshi. Agora, vamos criar a quantidade total de entrada
variável. Seu valor será igual ao
resultado dessa expressão, que retornará a soma de
cada valor de UTXO no de Satoshi. O valor da
variável de envio será igual a 100 milhões de Satoshi. Também vamos calcular a quantidade de alteração
esperada. Será igual ao valor
da entrada menos a quantidade de areia menos
a taxa total esperada. No bloco único, chamaremos criador
da transação. O método create passará os seguintes
parâmetros para esse método. O resultado será armazenado
na variável de transação. No bloco then, verificaremos se o tamanho v da transação é igual à variável de
tamanho esperada. Mas primeiro, vamos atualizar a versão
Bitcoin Java para 0,4, 0,2 para disponibilizar o método get v
size. Agora, verificaremos
se o número de saídas da transação é igual
à variável esperada e de
saídas. Também verificaremos se o primeiro valor de saída é igual ao valor
a ser enviado pela variável. Agora, se o número esperado de saídas for maior que um, verificaremos se o
valor da alteração é igual
ao segundo valor de saída
na transação. No bloco where. Vamos adicionar
os seguintes casos de teste. Você pode copiá-los da página
Projeto e Recursos. Esses casos de teste abrangem cenários
com e sem
saídas de alteração e com quantidades de entrada que geram
alterações ou não. Eles também cobriram transações
com 12,3 entradas. Agora vamos criar o método de criação do
serviço de criadores de transações. Vamos renomear esses parâmetros. Antes de implementar esse método, vamos criar a classe fee
no pacote utils. Aqui, criaremos um
método para calcular a
taxa total de transações no Satoshi,
vamos chamá-la de taxa total
calculada. Ele receberá uma transação na taxa em Bitcoin por KV. O bit criará o seguinte código dentro de
um bloco try catch. Primeiro, converteremos a
taxa de Bitcoins por KV de bicicleta em Satoshi
em byte privado. Em seguida, retornaremos o resultado
multiplicando o tamanho
v da transação pela taxa de taxa em Satoshi. A mordida por
V capturará uma IOException que
pode ser lançada
pelo bom método de tamanho V e rápido em uma nova exceção
de tempo de execução. De volta ao serviço de
criadores de transações. Neste método, primeiro construirá as entradas da transação
usando esse método, passando
os UTXOs recebidos como seu parâmetro. Vamos criar esse método. Retornaremos o resultado da seguinte transformação do
fluxo UTXO caso contrário, o fluxo em uma nova entrada de transação passará o
ID UTXO recebido como seu primeiro parâmetro. O grande valor inteiro
do UTXO prometido como seu
segundo parâmetro. Esses dois parâmetros definem o ponto de saída de entrada da transação. Em seguida, passaremos um novo script instanciado com uma lista vazia. Esse parâmetro é a entrada de
transação ScriptSig, que está vazia para entradas de
segmentos. Em seguida, passaremos um grande número inteiro instanciado com
esses parâmetros, que define a
entrada em sequência. Esse valor é o
valor máximo permitido para esse campo, fazendo com que os nós o ignorem. Agora, para cada
transação, a entrada
no stream usará o
método de pico para definir a testemunha instanciará a testemunha
com uma lista contendo constantes para uma
assinatura fictícia e uma chave de pub fictícia. Agora vamos criar
essas constantes. A assinatura fictícia
será igual
à sequência hexadecimal
zero repetida 144 vezes, cujo tamanho em bytes
é igual a 72. A chave de pub fictícia será igual
à string hexadecimal zero repetida 66
vezes, cujo tamanho em bytes é igual a 33, definirá esses valores fictícios porque
eles serão necessários
para fazer o cálculo do tamanho da transação
v, que fará com que,
no método de criação, o processo de assinatura seja feito separadamente, posteriormente, quando
os valores reais forem substituídos pelos valores fictícios. Por fim,
converteremos o stream em um ArrayList e o retornaremos. Agora, criaremos a saída da
transação para o endereço a ser enviado usando
o método PUT de compilação, passando o endereço a ser enviado e o valor a ser enviado
como parâmetros. Vamos criar esse método. Primeiro, analisaremos
o prefixo do endereço usando o
método parse prefix, que criará. Esse método
verificará se o endereço começa com um dos prefixos de segmento
válidos e retornará
o prefixo do endereço ou uma string vazia se um
prefixo válido não for encontrado. Agora, criaremos um objeto de script usando a classe de script P2, método de script
WP k h. Como seu parâmetro
passará o resultado da chamada do método back 30 para
decodificar, passando o prefixo e o
endereço para este último. O retorno do método back
30 to decodificar é uma matriz de objetos em que o segundo elemento
é o hash da chave pub, que passará para o método de script
P2 WP k h. Esse método retornará o equivalente à chave pub do
script, em que o primeiro
parâmetro é zero e o segundo parâmetro
é o hash da chave pub, conforme explicamos na
última apresentação. Por fim, retornaremos uma
nova saída de transação instanciada com o valor
e o script criado. Agora, criaremos uma ArrayList para armazenar as saídas da
transação, instanciaremos, adicionando a ela o endereço para enviar a saída que
acabamos de criar. Em seguida, criaremos
a transação que passará como parâmetro, o número inteiro grande, que é a versão da
transação. As entradas da transação,
as saídas da transação. O grande número inteiro zero é o tempo de bloqueio que
será ignorado. E o booleano é verdadeiro para definir essa transação como
uma transação seguinte. Esse parâmetro fará com que a transação tenha o marcador e a bandeira do
Segway. Agora, vamos calcular a taxa
total da transação usando o método
F0 total calculado que
criamos anteriormente
na classe FI. Vamos considerar a transação e a taxa da taxa como seus parâmetros. Também vamos calcular
a zona de entrada para
mapear o fluxo UTXO em
um fluxo de valores de UTXOs. Em seguida, usaremos o
método reduzido para somá-las. Por fim,
converteremos o resultado ptose ou zero se
os UTXOs não existirem. Em seguida, calcularemos a
alteração que será igual
à soma de entrada menos a quantidade de areia menos a taxa total. Em seguida, adicionaremos a
seguinte declaração if. O uso da calculadora de poeira verificará se a
alteração é poeira. Se for, retornaremos
a transação como está. Caso contrário,
adicionaremos outra saída à transação usando
o método build output,
passando
o endereço de alteração
e o número inteiro grande, pois seus parâmetros passarão um para o valor de saída,
apenas como um valor de espaço reservado, pois teremos que recalcular
a taxa de transação para a transação que agora tem duas saídas, o que
exige uma taxa mais alta. Então, vamos recalcular
a taxa total usando o método F0 total
calculado. Novamente, vamos
recalcular a alteração que será igual à
soma de entrada menos o valor a ser enviado menos a
nova taxa total calculada. Agora, vamos remover a última saída
de transação
adicionada das
saídas da transação ArrayList. Vamos verificar novamente se a nova alteração
calculada é poeira. Se for, ele retornará a transação sem alterações. Caso contrário,
adicionaremos uma nova saída à transação usando
o método build output. Desta vez, passaremos o valor
real da alteração da transação com duas
saídas para esse método. Por fim, devolveremos
a transação. Agora vamos fazer o teste do serviço de
criadores de transações e executar esse teste. Ótimo, os testes
foram aprovados desde que alteramos anteriormente teste
do seletor de
moedas de sorteio aleatório único. Vamos também executá-lo novamente para garantir que não tenhamos
quebrado nada. Eles são ótimos. Está funcionando normalmente.
53. 51 Enviar bitcoin parte 6 skillshare 2: Neste vídeo,
começaremos a criar a janela que aparecerá quando clicarmos
no botão Enviar. Essa janela conterá informações sobre
a transação. Estamos enviando um campo de
senha e um botão OK para confirmar
a transmissão da transação. Então, no pacote FXML, vamos criar o arquivo FXML da caixa de diálogo de
sublinhado da transação de envio de sublinhado. Vamos apagar o
clichê gerado. Agora, vamos criar uma etiqueta
problemática no diálogo. Agora, vamos mudar a visualização
para o Scene Builder. Vamos definir a altura de
preferência do diálogo para 300. E sua largura preferida é 650. E vamos fazer com que a
altura mínima seja
a largura mínima para usar o tamanho da prensa. Agora, vamos adicionar um painel de grade
ao conteúdo da caixa de diálogo. Vamos adicionar mais quatro
linhas a esse painel de grade. Agora vamos adicionar um rótulo
à primeira linha. Vamos mudar seu texto para enviar o ponto de interrogação
da transação. Vamos aumentar o
tamanho da fonte para 16 pixels. Para as próximas linhas, a
ideia aqui é adicionar rótulos e dados para a transação de
envio. Vamos adicionar um rótulo
à segunda linha e alterar seu texto para o
valor para enviar dois pontos. Na segunda coluna
da mesma linha. Vamos adicionar outro rótulo. Desta vez, o texto
ficará vazio e adicionaremos um ID Fx para que possamos alterar seu conteúdo
dinamicamente posteriormente. Vamos adicionar outro rótulo
na terceira linha, desta vez com as
taxas totais do texto na célula à direita. Vamos adicionar uma etiqueta vazia com outra ID FX. Na linha abaixo. Vamos adicionar outro par de
rótulos para o campo total. Na próxima fila. Vamos adicionar
esses rótulos para a taxa de taxa. Agora, vamos fazer o mesmo com
o endereço a ser enviado. Na última fila. Vamos adicionar um rótulo para a senha da carteira. Na cela à esquerda. Vamos adicionar um campo de senha. Ele terá um ID FX ou senha
da carteira. Os rótulos repentinos não dois pontos no final.
Vamos consertá-los. Agora. Vamos acessar a configuração do problema do
diálogo e adicionar um botão OK aqui. Vamos também adicionar um botão de cancelamento. O texto do botão Cancelar está
no meu idioma nativo. Se esse também for o seu caso, você pode alterá-lo
fazendo o seguinte. Vamos para a visualização do editor. Primeiro, vamos adicionar uma ideia Fx
de ok ao botão OK. E vamos adicionar uma ideia Fx de cancelar à tag do botão de cancelamento. Agora, vamos remover essa propriedade. Vamos definir a
propriedade de dados do botão com esse valor e definir seu
texto para cancelar. Agora, no Scene Builder, podemos ver que a
mudança entrou em vigor. Agora, vamos para
a guia Enviar FXML. No botão Enviar, vamos
definir a propriedade de ação hashtag send
para que, ao
clicarmos nesse botão, o método de envio do controlador da
guia Enviar seja chamado. Então, vamos criar esse método. Antes de
implementá-lo, vamos criar um registro DTL de transação
no pacote de domínios. Ttl significa objeto de
transferência de dados e é um
padrão de design comum a ser usado para objetos cujo objetivo principal
é transferir dados entre classes
e métodos. Dessa forma, o
DTO da transação será usado para transferir
dados de transações entre nossos serviços. Vamos adicionar os seguintes
campos a ele. Neste ponto, você pode estar se
perguntando qual é a diferença entre a taxa real total
e o total calculado v? Chegaremos a isso em breve. Agora, vamos para o controlador da guia
Enviar. Vamos adicionar os seguintes
campos a ele. Esses campos serão vinculados
às tags correspondentes
no arquivo FXML da guia Enviar. Agora vamos implementar
o método de envio. Primeiro. Converteremos o valor para enviar texto em um grande valor decimal. Agora, criaremos um objeto DTO de
transação usando o
serviço de criação de transação que criará. Vamos injetar esse
serviço nessa classe. Vamos criá-lo no pacote de serviços de
pontos da GUI. Agora, vamos terminar de
injetá-lo nesta classe. Aqui, chamaremos o método
create nele, passando o endereço para enviar o
texto e a variável de quantidade. Vamos criar esse método. Agora, usaremos esse método
para abrir a janela de diálogo, passando o
DTO da transação como seu parâmetro. Vamos criá-lo. Depois
de abrir a janela de diálogo, chamaremos o método clear no endereço a ser enviado
e a quantidade a ser
enviada para apagar o
conteúdo dessas entradas. Agora, vamos para o serviço de criação de
transações. Vamos adicionar a
anotação do serviço a ela. Implementaremos
o método de criação. Agora, a ideia aqui é usar muitos dos
serviços que criamos
nos vídeos anteriores para
criar uma transação e alguns dados adicionais para
o DTO da transação. Para isso, a primeira
coisa que faremos é usar o serviço de taxa estimada para obter a taxa e armazená-la
na variável de taxa de taxa. Então, vamos injetar esse
serviço nessa classe. E vamos chamar isso de método de
estimativa. Agora, obteremos os endereços da carteira atualmente
carregada usando o objeto de carteira atual. Então, vamos
injetá-lo nessa classe. Em seguida, chamaremos
os endereços get como método de strings nele. Em seguida, receberemos todos os UTXOs da
nossa carteira. Para isso, usaremos o cliente
não gasto da lista de nós. Então, vamos
injetá-lo nessa classe. Chamaremos a lista de método
não gasto nela, passando os endereços e o nome da carteira atual
como parâmetros. Agora, usaremos o
seletor de moedas para selecionar os UTXOs que serão usados
como entradas em nossa transação. Então, vamos injetar o
seletor de moedas nessa classe. Agora, chamaremos
o método
de seleção , passando os UTXOs, o valor convertido em
Satoshi, a taxa da taxa, o endereço
a ser enviado e o endereço de
alteração da carteira atual, ligando para o o método atual de obtenção
de endereço de alteração da carteira,
que será criado. Então, vamos criar esse método. Ele simplesmente retornará a propriedade
de alteração de endereço. Vamos criar essa
propriedade como uma string. Vamos movê-lo para aqui. Vamos também criar um setter
para ele. Nós o usaremos mais tarde. Agora, vamos usar o
serviço de criadores de
transações para criar uma transação. Então, vamos injetar esse
serviço nessa classe. Vamos chamar o método
create nele, passando os seguintes
parâmetros para ele. Agora que temos nossa
transação, criaremos dados
adicionais para incluir
na transação DTL. Próximo. Primeiro, vamos usar o método
de taxa real total da classe FI para obter que a taxa real total seja aprovada na transação e nos
UTXOs selecionados como seus parâmetros. Vamos criar esse método. A diferença entre
o total de pés calculados e a taxa real total
é que, para a última, usamos a diferença entre os
valores de entradas e saídas para calculá-la. Já para o
primeiro, estimamos usando o
tamanho da transação e a taxa da taxa. Em teoria, espera-se que
os dois valores sejam os mesmos, mas vamos usar como padrão o total de
pés reais quando possível, para garantir que estamos mostrando ao usuário a transação real taxa e para permitir que o usuário identifique
possíveis erros de três valores. Então, aqui vamos calcular
os valores de entrada, alguns em Bitcoin usando a seguinte
transformação de fluxo. Mapearemos o fluxo de UTXOs
selecionado para produzir um fluxo
de valores de UTXOs. Em seguida, use o método reduzido para somar todos os valores no fluxo. E use o método or else para retornar zero se a
string estiver vazia. Agora, vamos calcular a
saída entre alguns em Satoshi. Faremos a
mesma transformação que
fizemos para as entradas, mas com as
saídas da transação desta vez. Agora, retornaremos a
entrada que parte em BTC é convertida em Satoshi
menos a saída, parte. Voltar ao serviço Criar
transação. Agora, vamos criar a variável total
calculada F0 e atribuir a ela o resultado da chamada total calculada do método
F0. Desta vez, passaremos a transação e a
taxa da taxa como parâmetros. Agora, vamos calcular
o total gasto,
que, como o nome sugere, é o valor total em Satoshi que o remetente
gastou nessa transação. Para isso, vamos usar o método total gasto
passando pela transação, a taxa real total e o
endereço como parâmetros. Vamos criar esse método. Com esta declaração if. Vamos verificar se o endereço a ser
enviado pertence à nossa carteira. Caso contrário, retornaremos a taxa real total mais o valor da
saída da primeira transação. Se nossa carteira o contiver, isso significa
que estamos transferindo
bitcoins para nós mesmos
e, portanto, estamos gastando
apenas a taxa de transação. Por fim, retornaremos um
novo objeto DTO de transação instanciado com
esses parâmetros continuaremos a implementar o recurso de janela de diálogo
no próximo vídeo. vejo.
54. 52 Enviar bitcoin parte 7 skillshare 2: Neste vídeo, concluiremos implementação da janela de diálogo da
transação. Então, vamos para o controlador da guia
Enviar. No método de diálogo aberto, vamos instanciar um novo objeto de
diálogo como esse. Em seguida, vamos chamar o método
proprietário da unidade nele, passando o objeto da janela como
seu parâmetro, assim. Vamos definir o
título da caixa de diálogo para enviar a transação. Agora, com o código a seguir, definiremos que
quando clicarmos
no botão Fechar
da janela de diálogo, a janela de diálogo será fechada. Em seguida, criaremos um objeto carregador
FXML dentro de um bloco try catch. Para instanciá-lo,
será necessário injetar o
recurso de diálogo FXML nessa classe. Vamos fazer isso. Vamos adicionar uma anotação de valor a
esse campo indicando o caminho da caixa de diálogo de
transação sin FXML. Aqui, chamaremos o método
get URL nele. Em seguida, usaremos null
nesses parâmetros. E a referência do
método get beam de contexto aqui. Primeiro, vamos criar o objeto de
contexto do campo
nessa classe e atribuí-lo aqui. Agora, definiremos o conteúdo
do problema do diálogo como o resultado da chamada do método de carregamento do
carregador FXML. Agora, com o código a seguir, obterá o controlador
de
diálogo de transação syn do carregador FXML. Vamos criar esse controlador
na classe controllers. Por fim, passaremos o objeto DTO da
transação para o controlador de
diálogo de transação sin usando o método de
transação set. Vamos criar esse método. Aqui, capturaremos
uma IOException que o carregador FXML pode lançar e agrupá-la em uma nova exceção de
tempo de execução. Em seguida, mostraremos o
diálogo usando esse método. Agora, antes de implementar o segundo controlador de
diálogo de transações, vamos ao serviço de atualização da carteira
atual. Quando atualizamos a carteira
atual, precisamos definir seu endereço de alteração, que será usado quando
enviarmos uma transação. Então, vamos fazer isso. Faremos isso obtendo a segunda
chave pública estendida da carteira criada. Lembre-se de que essa chave
estendida foi derivada para gerar endereços de
alteração. Em seguida, obteremos seu
primeiro endereço e definiremos como o endereço de alteração da
carteira atual. Agora, vamos para o segundo controlador de
diálogo de transação. Vamos definir a
anotação do componente para ela. Agora, vamos para a segunda caixa de diálogo de
transação FXML. Vamos definir o problema do
diálogo FX ID. E vamos definir a propriedade do
controlador FX para o caminho do
controlador criado recentemente aqui. Agora, definiremos cada tag com
um ID de ética neste arquivo, esses campos no segundo controlador de diálogo de
transação usando esse recurso interessante do IDE. Agora vamos definir que cada
campo aqui é privado. Vamos adicionar a anotação FXML
acima de todas elas. Antes de implementar o método
Set Transaction, vamos criar o domínio do diálogo da
transação no pacote de domínios. Precisarei desse disco em breve. Ele modelará os campos que serão exibidos na caixa de diálogo da transação. Então, vamos criar esses campos. Vamos também criar
isso a partir do método. Isso criará um novo diálogo
de
transação a partir de um DTO de transação. Usaremos o formato ou método de
formato Bitcoin para
analisar corretamente o valor e enviar
a taxa real total,
e o total gasto também
ultrapassará a taxa da
taxa e o endereço da transação. DTO para a instanciação do
diálogo da transação. Voltar ao segundo controlador de
diálogo de transação. No método de transação definido, vamos definir o
campo D TO da transação como o DTO da
transação recebida. Vamos criar esse
campo nesta classe. Agora, vamos criar o objeto de diálogo da
transação usando o método
from passando o DTO da
transação como seu parâmetro. Em seguida, definiremos o
valor a ser enviado para o
diálogo da transação. O valor a ser enviado definirá o texto do campo de taxas
totais para o
diálogo da transação, taxa total. O texto total do campo da caixa de diálogo
da transação totaliza o texto
do campo da taxa de taxa na caixa de diálogo da transação. Taxa de taxa concatenada com
a string BTC slash KV. Mordida. Vamos definir o endereço
para enviar os textos de campo para o
endereço da caixa de diálogo da transação a ser enviada. Agora vamos criar o
método inicializado nessa classe. Aqui, o botão de
cancelamento será vinculado a uma ação que
fechará a janela de diálogo. Para fazer isso, vamos chamar o método do botão de
pesquisa
na caixa de diálogo passando
o campo de cancelamento para ele. Em seguida, chamaremos
esse método para adicionar um manipulador de eventos
ao botão de cancelamento. O manipulador receberá um evento de ação e um
evento como seus parâmetros. E o corpo do manipulador usará essa instrução para fechar
a janela de diálogo. Agora, vamos fazer o teste de
envio de Bitcoin. Algo está faltando
neste teste. Depois de chamar o método de enviar
Bitcoin e esperar, precisamos instruir o
node a minerar um bloco para que nosso UTXO seja confirmado e possa ser usado para
criar uma transação. Para lidar com isso, vamos chamar o
método generate to address no node generate para endereçar o cliente passando esses parâmetros para ele. E vamos mover essa linha
de código para aqui. Agora, vamos executar nosso node. E vamos fazer esse teste. Como esperado, o
teste falhou, mas a caixa de
diálogo da transação foi aberta e preenchida com os dados
da transação. Agora, vamos melhorar esse teste. Verificará se os valores na diálogo
da transação estão corretos. Mas primeiro, vamos tornar
esse teste mais resiliente. Depois de clicar
no botão enviar adicionaremos um código para
garantir que esperemos que a caixa de
diálogo da transação apareça antes de agir
na janela de diálogo. Então, vamos criar o peso
para o método de diálogo. Aqui, chamaremos o método de
peso por método. Passar esses parâmetros para
esperar segundos no corpo do
lambda causará problemas no diálogo e
retornará somente depois
que ele não for nulo. Agora, vamos obter o
valor de cada rótulo
na caixa de diálogo da transação e armazená-lo nas
seguintes variáveis. Vamos adicionar o tipo de
linha da transação aqui. E vamos mudar
o nome da exibição da tabela para tabela de transações. No bloco then, vamos adicionar
as seguintes afirmações para verificar se os rótulos na diálogo
da transação estão corretos. Agora, no bloco where, vamos adicionar um
caso de teste para preencher as variáveis que acabamos de
referenciar no bloco then. Está faltando um sinal de igual e
igual aqui. Vamos consertar isso. Vamos
adicionar outro caso de teste. Agora, vamos remover essas linhas. Adaptará o código para
criar transações anteriores acordo com a variável de número
UTxOS anterior. Portanto, para cada UTXO definido
nessa variável,
procurará o endereço de recebimento. Em seguida, chamaremos o método de enviar Bitcoin e esperar
com esses parâmetros. Agora, vamos substituir
o parâmetro
na chamada de método correta pela variável quantidade
a ser enviada. Agora, precisamos garantir
que a taxa seja igual a 0,002 para que o teste funcione. Para fazer isso, injetaremos o serviço de taxa
de estimativa de nessa classe e adicionaremos a anotação
simulada de Bean a ela. Em seguida, no método de configuração, vamos adicionar o código a seguir. Isso garantirá que, quando o método de estimativa
do serviço for chamado, ele retorne o valor da
taxa que desejamos. Esse perímetro do método de pesquisa
não tem a letra S no final. São taxas totais. Agora, vamos fazer o teste. Ocorreu uma falha, mas
pelo motivo errado, observe que o valor
para enviar a etiqueta está vazio. Isso porque há
outro rótulo com o mesmo ID FX no controlador da guia
Enviar. Também há um
campo de endereço para enviar com o mesmo ID FX. Vamos usar o
segundo controlador de
diálogo de transação para corrigir isso. Vamos renomear esse campo para o
valor a ser enviado ao diálogo. E vamos renomear
o endereço para enviar campo para endereço
para enviar o diálogo. Vamos até a caixa de diálogo de envio de
transações FXML para alterar os rótulos FX IDs. Ok, não precisamos, porque o IDE fez
esse trabalho para nós. Voltar ao teste de envio de Bitcoin. Vamos atualizar esses parâmetros para procurar os rótulos
corretos. Agora, vamos fazer nosso teste. Ok, os testes falharam, mas apenas porque a tabela de
transações não contém o
número esperado de transações. Isso significa que os rótulos da caixa de
diálogo da transação estão corretos. Ótimo.
55. Como as assinaturas de transação funcionam: Nesta apresentação, mostraremos como as assinaturas de transações funcionam. Primeiro, vamos analisar os campos
de uma entrada de transação. As entradas da transação têm um
campo de ID de transação cujo conteúdo indica de qual
transação o UTXO gasto
nessa entrada veio. O
campo do índice de saída indica qual UTXO da transação anterior
a entrada está gastando. Juntos, os dois campos
formam um ponto de saída que
indica inequivocamente qual UTXO a entrada está gastando. O campo ScriptSig está vazio para entradas de transação
segue e contém scripts de desbloqueio para entradas de transação não
seguidas. Esses scripts de desbloqueio
são uma assinatura e uma chave pública para transações
comuns. Finalmente, a entrada da transação contém o campo de sequência final. O campo da sequência final define quando a entrada é
válida para gastar. Esse campo é ignorado quando
seu valor é igual
ao valor hexadecimal máximo para seu tamanho. Para entradas de transação seguintes, o conteúdo que para transações que
não são do Segway está no ScriptSig é
movido para o campo de testemunha. A assinatura nesse campo
é uma assinatura ECDSA obtida usando a chave
privada usada para derivar o
endereço do UTXO. A contribuição é gastar. O outro campo na
testemunha é a chave pública, que é
derivada da chave privada à acabamos de nos referir. Mas espere, o que é
uma assinatura ECDSA? Ecdsa significa algoritmo de assinatura digital de curva
elíptica. É um
algoritmo de assinatura que combina uma chave privada e uma mensagem
para produzir uma assinatura. E a assinatura ECDSA
tem uma propriedade que permite verificar
se é válida, ou seja, verificar se uma determinada assinatura foi produzida por uma
determinada chave privada e uma mensagem usando a chave pública
derivado dessa chave privada, da mensagem e da assinatura. Dessa forma, podemos verificar
se uma assinatura é válida sem revelar
a chave privada usada para gerá-la. Você pode usar o ECDSA para
assinar qualquer mensagem que desejar. No caso de uma assinatura de
transação, a mensagem que está sendo assinada é uma versão modificada da transação
serializada. Então, vamos ver como
as transações de Bitcoin são assinadas. Para assinar uma transação, você precisa assinar cada entrada de
transação separadamente. Para cada entrada de transação comece com uma transação
insana, que é uma transação em
que suas entradas têm script vazio,
CIGS e testemunhas. Você cria um hash de assinatura, que é o hash de
uma versão modificada da transação serializada. Para fazer isso, você usa um algoritmo de hash de
assinatura, que explicaremos
no próximo slide. O hash da assinatura
será a mensagem a ser assinada com uma chave privada válida para essa entrada
e o hash da assinatura usará o ECDSA para
gerar a assinatura. Lembre-se de que a chave
privada válida para uma entrada é a mesma chave privada
usada para gerar o endereço do UTXO
que a entrada está gastando. Se a entrada for uma entrada de segmento, adicione a assinatura
e a chave pública derivada da referida chave
privada à testemunha. Caso contrário, adicione esses elementos ao campo ScriptSig de entrada. Quando os nós recebem
uma transação, eles verificam se as
assinaturas da transação são válidas. Para fazer isso, eles usam o algoritmo
de verificação de assinatura citado no slide anterior. Eles fazem isso durante
a execução do script , conforme explicado na
última apresentação. Agora, vamos ver como o hash da
assinatura é gerado. Existem diferentes algoritmos de
hash de assinatura para entradas de
transação segue, não segmentar e tap root. No entanto, os três
algoritmos modificam a transação de alguma
forma e produzem um hash, que é a mensagem
que será assinada. Vamos ver o algoritmo de
hash de assinatura para entradas de um segmento. Para criar um hash de assinatura para
uma determinada entrada de transação, comece com uma string vazia, depois adicione a
versão da transação à string concatene todos os pontos
de saída das entradas da transação. o hash dos resultados usando o algoritmo hash 256, acrescente o hash
resultante à string e,
em seguida, concatene todas as
entradas e sequências. o hash 256 do resultado e acrescente o hash
à string. Agora adicione o ponto de saída
da entrada que está sendo
assinada à string. Adicione a chave de script pub dos UTXOs gastos pela entrada que
está sendo assinada na string. Adicione o valor dos UTXOs gastos pela entrada que está sendo
assinada à string. Adicione a sequência final
da entrada que está sendo
assinada à string concatene todas as saídas
da transação. hash 256, o resultado, acrescenta o
hash resultante à string adiciona o
tempo de bloqueio da transação à string. Adicione o tipo de hash,
que é sig hash all para transações comuns,
à string. Existem outros tipos de hash, mas eles raramente são usados. Eles
definem as entradas e saídas. A entrada que está sendo assinada pode
ser incluída em uma transação. Assine o hash. Tudo significa que a assinatura
produzida é válida somente em uma transação com
todas as entradas e saídas da transação em
questão. Finalmente, o hash 256,
a string obtida. O resultado é o hash
da assinatura da entrada que está sendo assinada. Um hash de assinatura
deve ser obtido para cada
entrada de transação que está sendo assinada. O processo é
replicado pelos nós quando eles verificam as assinaturas da
transação.
56. Como nossa carteira e nosso nó lidam com transações enviadas: Esta apresentação
explicará o que acontece quando enviamos uma transação
para um nó de Bitcoin. Em seguida, veremos como
nossa carteira atualmente lida com o recebimento de
transações e como planejamos alterá-la
para calcular corretamente endereços
das transações e os saldos
totais da carteira após o
envio de uma transação. Então, vamos ver como um node Bitcoin lida com as transações
enviadas pela nossa carteira. Nossa carteira enviará
transações para nosso node por meio do método RPC de notas chamado
enviar transação bruta. Nosso aplicativo enviará a transação de assinatura em formato
hexadecimal para nosso nó. Depois de receber a transação, o nó a valida. Se a validação for aprovada, o nó
transmitirá a transação para outros nós
na rede Bitcoin. Os outros nós
fazem o mesmo até que todos os nós da rede
reconheçam a transação. A transação permanece
na mente por um tempo, esperando que um menor
a inclua em um bloco e extraia
o bloco com ela. Eventualmente, um menor transmite o bloqueio mental com
a transação para outros nós na rede. À medida que os nós recebem o
bloqueio mental com a transação, a transação é
excluída do mental e
considerada confirmada. Cada bloco adicionado
após o bloco com a transação adiciona uma
confirmação à transação. É recomendável
aguardar seis conformações para que uma transação seja
considerada irreversível. Agora, vamos ver um modelo
ingênuo de como nossa carteira pode lidar com transações de
envio. Depois que nossa carteira enviar uma
transação para nosso node, o nó será
devolvido por meio de zero MQ, a mesma transação
para nosso aplicativo. Nosso
serviço de tarefas de node detectará a transação e a enviará para nosso ouvinte de transações
recebidas. Como a maioria das transações
terá um resultado alterado, o
ouvinte da transação recebida geralmente
verificará se o
endereço da alteração é da nossa carteira. E usaremos o serviço de
atualização UTXos para atualizar nossos endereços de carteira, transações e saldos, mas contando apenas
com a transação recebida pelo ouvinte,
como está atualmente para atualizar nossa a carteira
levantará alguns problemas. Primeiro, o
cálculo do saldo
do serviço UTXos de atualização
não considera os saldos de entrada. Portanto, teremos que modificar a
forma como nossa carteira calcula um vestido e os
saldos de transações para
descontar os valores
de entrada dos valores de alteração. Mas teremos que lidar com um problema maior
com esse modelo. E quanto às transações
sem alterações? Nesse caso, o
ouvinte da
transação recebida não considerará que
a transação do recibo é nossa, pois verifica apenas os endereços de saída e a saída do perfume não
será da nossa carteira. Portanto, nosso aplicativo não
seria atualizado. É equilibrado para esses casos, adotará a seguinte
estratégia para superar esses problemas ao atualizar nossa carteira após o
envio das transações. Depois de enviar a
transação para o nosso node, publicará um evento
da transação enviada que será capturado por um ouvinte enviado pela
transação. Em seguida, o ouvinte de
envio de transações usará o serviço de atualização UTXos
para atualizar
a carteira com a transação para eliminar o problema de não atualizar
as transações sem alterações, tanto a transação o ouvinte recebido e o ouvinte de bloqueio de
recebimento usarão um
cliente de transações da lista de nós para pesquisar todas as transações relacionadas
à nossa carteira no nó, esse cliente enviará
uma lista de transações RPC ligue para o nosso node, que retornará todas as
transações relevantes para o cliente. Em seguida, usando as transações de
devolução, o
serviço de atualização
UTXos atualizará todas as transações em nossa carteira e seus saldos corretamente.
57. 55 Enviar parte 8 skillshare 2: Neste vídeo,
criaremos algumas classes e serviços que nos permitirão
assinar e enviar transações. Então, primeiro, vamos criar uma
classe chamada serviço de
signatário de transações no pacote de serviços api
dot. Vamos adicionar a
anotação do serviço aqui. Agora vamos criar o método de
sinal aqui. Será necessário um
objeto de transação na semente mnemônica, uma senha e uma lista de
DTLs UTXO que uma classe criará. Então, vamos criá-lo
no pacote de domínios. Agora, usaremos o método
stream range para percorrer cada UTXO DTO. Para cada UTXO DTO, chamaremos o método de sinal
passando o parâmetro a, que é o índice
da entrada a ser assinada, o UTXO DTO, que será obtido usando
o parâmetro i, a transação,
a semente mnemônica e a senha da carteira. Vamos criar esse método. Vamos mudar o nome desse
parâmetro para string de semente
mnemônica para
assinar uma entrada de transação. Primeiro, precisamos derivar
a chave privada válida para desbloquear o UTXO que a
entrada está gastando. Se você quiser se lembrar de como isso é feito com mais detalhes, assista novamente à
apresentação de carteiras HD e endereços de Bitcoin. Então, primeiro, vamos instanciar
um objeto de semente mnemônico aqui, passando a
cadeia de sementes mnemônica e a instanciação. Agora, derivaremos uma chave mestra usando o método mnemônico
de semente para
chave mestra , pois seus parâmetros
passarão a senha. E esse prefixo. Para nosso caso de uso,
não há problema em passar o
prefixo privado da rede principal, mesmo se o
usarmos em outro
ambiente, pois isso afeta apenas a serialização da
chave mestra, não o processo de derivação. No processo de derivação
da chave mestra, esse método
de chave mestra primeiro
deriva a semente raiz, que é mencionada
na apresentação
mencionada anteriormente. Agora, derivaremos a chave privada
estendida usando o método CKD da chave mestra, pois seu primeiro parâmetro passará
pelo caminho de derivação UTXO DTO. Primeiro, vamos criar esse
campo no UTXO DTO. E vamos aproveitar a
oportunidade para adicionar o campo de valor
que será necessário em seguida. O próximo parâmetro será verdadeiro, o que indica que queremos
derivar uma chave privada estendida,
uma chave pública estendida. O último parâmetro será
o prefixo privado da rede principal. Novamente, não há problema em usar
o prefixo de rede principal aqui. Observe que a forma como derivamos a
chave privada estendida aqui é semelhante à como derivamos a chave pública
estendida e o serviço de chave
pública estendida. Usamos o mesmo
caminho de derivação que usamos para criar a
chave pública estendida para derivar o endereço UTXO de nossa carteira. Agora, obteremos a chave
privada desejada simplesmente extraindo-a da chave privada
estendida por meio do método de duas chaves
privadas. Esse método está disponível
na próxima versão do Bitcoin Java. Então, vamos ao
arquivo POM para atualizá-lo. Agora, dentro de um bloco try catch, podemos finalmente usar
o método de assinatura
da classe de signatários da transação ECDSA do Bitcoin Java. Esse método pegará a
transação, a chave privada, o índice de entrada e o valor
UTXO DTO
convertido em Satoshi. E o booleano verdadeiro, que indica que
essa entrada está segmentada. O mesmo método obterá um hash de assinatura com
a chave privada. Usaremos o ECDSA para obter
uma assinatura para essa entrada. Em seguida, ele inserirá a
assinatura e a chave pública derivada da chave privada
anterior na testemunha da transação. O valor UTXO é necessário
para o hash da assinatura, e o último
parâmetro verdadeiro é necessário para a geração correta do
hash da assinatura e para adicionar
corretamente a assinatura
e a chave pública à testemunha em vez
de no ScriptSig, que é o caso de entradas
sem segmentos. Finalmente, capturamos uma
possível IOException que o método sign pode lançar e envolvê-la em uma nova exceção
de tempo de execução. Agora, vamos criar o cliente de transação
bruta node send no pacote do cliente node dot. Esse serviço será
necessário para enviar nossas transações para
nosso node Bitcoin. Vamos adicionar a
anotação do serviço a ela. Vamos injetar o
cliente node nessa classe. E vamos criar
o método de envio. Ele aceitará uma string
hexadecimal de transação como seu parâmetro. Aqui, chamaremos o método de solicitação de make
do cliente node. Vamos usá-lo para
chamar o método RPC do
nó
Bitcoin de envio bruto . Como de costume, vamos passar um novo objeto de referência
de tipo parametrizado. Aqui. O URL está vazio e passaremos o parâmetro hexadecimal da
transação como o último parâmetro. Agora, no pacote de
serviços de pontos de GUI, vamos criar o segundo serviço de
transação. Esse serviço
será responsável por assinar e enviar a transação
criativa. Depois de clicarmos
no botão Enviar na caixa de diálogo da transação, vamos adicionar a
anotação do serviço a essa classe. E vamos criar o método de
assinatura e envio. Ele retornará um
futuro do tipo void. E usará o DTO da
transação e a senha da carteira
como parâmetros. Agora, primeiro, criaremos
uma lista de UTXOs, CTOs, convertendo os UTXOs selecionados do DTO da transação. Chamaremos o mapa do método no fluxo
UTXos selecionado e usaremos o construtor UTXO DTO para criar o UTXO d t vai de
cada objeto UTXO. Então, vamos injetar o
construtor UTXO DTO nessa classe. Vamos criá-lo no pacote de serviços
GUI dot. Agora, vamos criar
esse método de construção. Ele retornará um UTXO DTO ao serviço de
transação central. Aqui retornará o método de lista chamado no fluxo resultante. Vamos refatorar aqui para usar a referência do método
em vez de um lambda. Agora, vamos implementar
esse método. Primeiro. Vamos adicionar a
anotação do serviço a essa classe. Aqui, obteremos o objeto de endereço da
carteira atual correspondente ao endereço UTXO
recebido. Então, vamos injetar a
carteira atual nessa classe primeiro. Agora chamaremos o método get
address nele, passando o endereço UTXO
como parâmetro. Vamos criar esse método. Ele retornará um objeto de endereço. Aqui retornará o
resultado da chamada do método get address
no campo de endereços, passando o
endereço recebido como parâmetro. Por fim, obteremos o índice
atual de endereços da carteira e o armazenaremos na variável de índice de
endereço. Agora, obteremos o
mesmo endereço
da carteira atual e
obteremos seu tipo de endereço, armazenando-o na variável de tipo de
endereço. Agora, obteremos o caminho de
derivação UTXO chamando o método build derivation
path com o tipo de endereço e
o índice Address. Vamos criar esse método. Aqui. Usaremos o objeto address
configs para obter parte do caminho de
derivação. Então, vamos
injetá-lo nessa classe. Na verdade, será uma lista de configurações de endereço. Vamos consertar isso. Agora, a partir
do fluxo de configurações de endereço, usaremos o
método de filtro para selecionar a configuração de endereço válida
para o tipo de endereço. Em seguida, usaremos o
método find first e obteremos
a configuração de endereço que queremos. Finalmente, obteremos o caminho de
derivação configuração do endereço e
o concatenaremos com
a seguinte string. Adicionaremos uma barra e, em
seguida, adicionaremos o índice de endereços. Aqui retornará um novo UTXO DTO passando o
caminho de derivação e o valor de UTXO. Voltar ao serviço de envio de
transações. Aqui, precisaremos do serviço de signatário da
transação. Então, vamos
injetá-lo nessa classe. Agora, chamaremos o
mesmo método, pois seus parâmetros passarão pela
transação DTO, a semente
mnemônica da carteira atual. Então, vamos injetar a
carteira atual nessa classe. Vamos criar esse método
na carteira atual. Ele retornará uma string. Aqui, retornará o campo de sementes
mnemônico. Vamos criar esse campo. E vamos adicionar um setter
para esse campo. O terceiro parâmetro
desse método é a senha da
carteira. O próximo parâmetro
é o UTXO ctOS. Agora, em um bloco try-catch,
usaremos o cliente de transação
bruta de envio node para enviar uma transação assinada
ao nosso node. Então, vamos
injetá-lo nessa classe. Chamaremos o método de
envio nele.
Ao passar a transação, a transação
serializada de DTLS usando o método serializado capturará uma IOException e a envolverá
em uma nova exceção de tempo de execução. Agora vamos usar o
aplicativo Event Publisher. Então, vamos
injetá-lo nessa classe. Vamos usá-lo para publicar um
novo evento de transações enviadas passando por isso e o
DTO da transação como seus parâmetros. Então, vamos criar o evento de transação enviada no pacote de eventos de
pontos da GUI. Vamos alterar o
primeiro parâmetro da assinatura do
construtor para
aceitar um objeto. E vamos passar esse objeto
para o superconstrutor. E vamos definir o campo DTO da
transação o
DTO da transação recebida. Vamos adicionar esse campo
a essa classe. E vamos criar
um getter para isso. Usaremos esse evento mais tarde. Voltar ao método sign and send retornará um novo resultado
assíncrono aqui, passando null como parâmetro. Vamos adicionar a
anotação assíncrona a esse método passando o
serviço executor padrão como seu parâmetro. Lembre-se de que estamos
fazendo isso para executar esse método de forma assíncrona, que é nossa política ao
nos comunicarmos com nosso node. Ok, criamos o campo inicial
mnemônico na classe de carteira atual, mas agora precisamos configurá-lo
depois de criarmos uma nova carteira. Então, vamos até o registro da carteira e adicionar o campo de
semente mnemônico a ele. Agora vamos acessar o serviço de criação de
carteira e adicionar a sequência de caracteres mnemônica aqui como o último parâmetro na instanciação da
carteira. Agora, no serviço de atualização da carteira
atual, vamos definir a semente mnemônica da
carteira atual
para a semente mnemônica da carteira. Agora vamos para o segundo controlador de
diálogo de transação. No método inicializado, vamos chamar o método do
Botão de Pesquisa
na caixa de diálogo passando
o botão OK para ele. Agora, vamos adicionar um
manipulador de eventos a esse botão. O primeiro parâmetro
é um evento de ação, que define o clique no botão
OK como a ação. O segundo parâmetro é um método
Lambda que pega um objeto de evento e chama o método de
transação de assinatura e envio. Então, vamos criar esse método. Aqui. Precisaremos do segundo serviço de
transação. Então, vamos
injetá-lo nessa classe. Agora, chamaremos o método de assinatura
e envio nele, passando o
DTO da transação e o texto da senha da carteira
como parâmetros. Por fim, fecharemos
a janela de diálogo usando o método hide na janela
do painel de diálogo. Vamos executar nosso node. E vamos finalmente
testar o que
fizemos executando o teste de
envio de Bitcoin. Ótimo, os testes foram aprovados. A carteira detectou
nossa transação e a adicionou à tabela de
transações. Mas espere, há
algo estranho. Vou retroceder o vídeo
e pausá-lo na visualização
da tabela de endereços
para verificar alguma coisa. Esta é a
tabela de endereços após nossa carteira enviar nossa transação
no primeiro caso de teste Observe que a carteira detectou
que um de nossos
endereços de alteração na segunda
linha recebeu Bitcoins. Bom. Mas como o endereço
na primeira linha tem seu UTXO na entrada da
transação que acabamos de enviar, seu saldo atual deve ser zero porque sua
saída foi gasta. E como nossa tabela de
endereços
mostra apenas vestidos com
saldos maiores que zero, essa tabela deve mostrar apenas uma linha com o endereço alterado. Agora, vamos verificar a tabela de
transações para o mesmo caso de teste. Opa, o saldo
da transação que
acabamos de enviar está errado. Deve ser igual a -0,5 bitcoin menos a taxa de
transação. O sinal de menos
indicaria que enviamos uma transação
de nossa carteira. O
texto do saldo total também está errado. Deve ser igual a 0,5
menos a taxa de transação. No vídeo a seguir, corrigiremos esses problemas.
58. 56 Enviar parte do bitcoin 9 skillshare 2: Neste vídeo, corrigiremos alguns problemas que tivemos
no último vídeo. Um desses problemas é que
a tabela de endereços mostra saldos
desatualizados para endereços
cuja saída foi gasta. Como o endereço usado após ser usado tem saldo zero, ele não deve aparecer
na tabela de endereços. Então, vamos ajustar esse teste para verificar se a tabela de
endereços tem apenas uma linha e
se essa linha tem um equilíbrio igual à mudança
esperada em Mount. Aqui, obteremos a tabela de
endereços usando o método de pesquisa. E no bloco then verificará se a
tabela de endereços tem uma linha. Vamos também verificar se o saldo da primeira linha é
igual a essa variável, que definiremos
no bloco web. Em seguida, vamos definir
o valor da alteração nas capas pretas de desgaste. Outro problema que vimos
no último vídeo é
que o
saldo da transação está errado
na tabela de transações. Isso está acontecendo porque, quando nosso aplicativo recebe uma
transação do nosso node, ele considera apenas
o saldo da alteração como
saldo da transação para garantir que o teste
detecte esse erro, vamos adicionar a seguinte linha
e, em seguida, o bloco verificará se a primeira linha na tabela de
transações tem um saldo igual a menos
a variável total gasta. O saldo também está errado,
pois é igual à soma de todos os saldos da
transação. Então, vamos fazer com que nosso teste
detecte esse problema. Aqui. Verificaremos se o texto do
saldo total está correto. Primeiro, vamos definir
essa variável. Será igual ao
texto presente na etiqueta do
saldo total
da janela depois de
enviarmos uma transação. Vamos verificar se essa variável é igual ao texto a seguir. E aqui vamos definir a
variável de fundos e atualizada
no end stream lambda. Agora, vamos executar nosso node. E vamos fazer esse teste. Ok, o teste falhou porque a
tabela de endereços tem duas linhas. Vamos corrigir esses problemas. Para fazer isso, vamos criar o ouvinte de
transações enviadas. Mas primeiro, vamos consertar
algo totalmente não relacionado. O
ouvinte do bloco recebido está
no pacote node dot events em vez
do pacote node dot listeners. Vamos consertar isso. Com isso resolvido,
vamos criar um
ouvinte de envio de transações no pacote GUI
dot listeners. Como o próprio nome sugere, esse ouvinte lidará com o evento da transação enviada que o serviço de transação
publicará após o
envio de uma transação. Vamos adicionar a
anotação do componente a ela. Ele implementará o ouvinte do
aplicativo com o tipo de evento das transações
enviadas. Vamos implementar seu método. Aqui liderará a
atualização do serviço utxOS. Então, vamos
injetá-lo nessa classe. Agora, vamos chamar
o método de atualização que passa pela
transação do evento de DTO. Agora vamos criar esse método. Aqui, obteremos
uma lista de
UTXOs da transação DTO
selecionou UTXOs. Usaremos um mapa no fluxo UTXO
selecionado e instanciaremos um novo
UTXO para cada
UTXO recebido , passaremos por todos os campos UTXO
recebidos na instanciação UTXO, exceto o valor que será zero, já que acabamos de gastá-lo. Agora, para atualizar nossos endereços de
carteira, chamaremos o método de atualização do
serviço de atualização de endereços atuais da
carteira, passando os UTXOs para ele. E para atualizar as transações da
carteira, vamos chamar o método de atualização
no serviço de
transação Update Current Wallet e
passará o resultado da chamada
da linha de transação do método para ela com a transação
DTO como seu parâmetro. Por fim, vamos chamar o método de
atualização do serviço
balanceado da carteira atual método de
atualização do serviço
balanceado para atualizar o saldo atual da
carteira. Vamos criar isso a partir do método na classe da linha de transação. Aqui retornará uma
nova linha de transação em um bloco try-catch. Vamos instanciá-lo com o ID da transação DTO
da transação. O total de DTO
da transação formatada gasto foi negado usando
o método de negação. Isso tornará o valor negativo,
já que o estamos gastando. Não terá nenhuma confirmação. E sua data será
a data atual. Por fim, detectaremos uma IOException que
pode ser lançada
pelo método de ID da transação e rapidamente em uma nova exceção
de tempo de execução. Voltar ao serviço Update
UTXos. Agora, vamos criar
o método de atualização que receberá uma linha de
transação na atualização.
O serviço de
transação atual do Wallet usará o método de
execução posterior da plataforma, pois o código a seguir
modifique a interface da carteira. Aqui, passaremos um
lambda que
chamará o método de adição de
linha de transação
na carteira atual e
passará pelo
caminho da transação para esse método. Agora, vamos criar esse método. Vamos mover esse método
para esse local próximo ao método de adicionar linhas de
transação. Aqui, chamaremos o método de adicionar linha de
transação no campo de linhas de transação, passando a
linha da transação como seu parâmetro. Vamos criar esse método na classe
de linhas de transação. Aqui, colocaremos a
transação gravada no roteiro da transação usando o ID da
linha da transação como chave. Ok, com essas modificações, esperamos que pelo menos a tabela de
endereços seja atualizada. Vamos executar novamente o
teste de envio de Bitcoin para verificar isso. Ok, os endereços
apresentados agora estão corretos, mas o teste falhou devido
à tabela de transações. As transações de envio ainda
estão com um saldo desatualizado. Isso aconteceu porque, embora nosso ouvinte de transações
pecaminosas esteja atualizando a
transação corretamente, quando nossa carteira recebe a mesma transação
do nosso node, ela detecta que uma atualização é somente
o endereço de alteração UTXO. Isso não desconta a taxa
e os insumos que gastamos. Precisamos mudar a forma como atualizamos nossas
transações atuais de carteira para corrigir isso. Na atualização do
serviço UTXOs, o método de atualização, que é chamado após
nosso aplicativo receber uma transação, chamará o método de lista de transações RPC
do nó. Esse método retornará todas as transações de
nossa carteira, incluindo aquelas
que enviamos com inteligência suficiente para devolver transações com saldos
negativos se elas forem enviadas
de nossa carteira. Com essas transações em mãos, podemos atualizá-las corretamente
em nosso aplicativo. Então, vamos usar a lista de nós do cliente de transações para obter todas as transações
de nossa carteira e armazená-las na variável de
transações do node. Vamos injetar esse
serviço nessa classe. E vamos criá-lo no pacote
do cliente api
dot services dot no dot. Vamos terminar de
injetá-lo nesta classe. Agora, vamos criar o registro da
transação do nó, que modelará o retorno
do método de transações da lista, criará no domínio
e iniciará o pacote do nó. Aqui, chamaremos o método de
transações da lista, passando o nome da carteira atual. Vamos criar esse método. E vamos adicionar a anotação do
serviço aqui. Vamos injetar o
cliente node nessa classe. Aqui, obteremos uma matriz do tipo node transaction chamando o método node client
make request com os seguintes parâmetros. A string de transação da lista, que é o nome
do método RPC do nó, uma nova referência de
tipo parametrizado. O URL da carteira concatenado
com o nome da carteira. E uma sequência de asterisco,
que indica que queremos todas as transações
dessa carteira. O valor inteiro máximo, que significa que queremos
o número máximo de transações
na resposta zero, o
que indica ao
método que não
queremos pular nenhuma transação. E é verdade, o
que indica que queremos observar apenas as transações
incluídas na resposta. Observe que somente transações
são transações. O node não tem a chave
privada para gastar. Essa opção faz sentido
porque nossa carteira não passa nenhuma
chave privada para nosso node. Finalmente, retornamos
a matriz de transações convertida em uma lista. Agora, vamos criar o nó. Os campos de registro de
transação adicionarão somente os
campos que usarão. Eles são o T XID,
as confirmações, o valor, o endereço, que é o endereço para
o qual o remetente
pretende enviar bitcoins, não o endereço de alteração. E a hora, que é a data e hora da criação da
transação. Voltar ao serviço Update
UTXos. Chamaremos o método
de transações do nó de atualização no serviço de transação Update Current
Wallet. Como parâmetro, passará
as transações do node. Vamos criar esse método. Aqui, obteremos uma lista de linhas de transações
a partir de nenhuma transação. Chamaremos o método de filtro
no fluxo de transações do node. Como parâmetro, passará por
um lambda que pegará uma transação de nó e verificará se a carteira atual contém
o endereço da transação do nó. Em seguida, adicionamos um
operador or e verificamos se a carteira atual contém uma transação
sem o ID da transação. Esse filtro resultará em um
fluxo de transações que contém apenas
transações
endereçadas para envio que são nossas, o
que abrange o recebimento de transações. A condição após
o operador or fazer
o fluxo de transações também inclui transações que nosso aplicativo já possui. Isso significa que
as transações que foram adicionadas
anteriormente
pelo ouvinte de
envio da transação terão seu saldo atualizado
corretamente com saldos
negativos. Agora, não faremos o fluxo
resultante usando a
linha de transação do método. Vamos criar esse método
e movê-lo para aqui. Aqui retornará uma
nova linha de transação instanciada com o ID da transação do
nó. O valor da
transação do nó formatado, as
confirmações da transação do nó e o
tempo da transação do nó convertido em uma string. Agora, convertemos o
fluxo de transações em uma lista. Por fim, usamos o método run
later da plataforma e, usando um lambda, chamamos de Adicionar linhas de
transação
na carteira atual, passando
as linhas de transação para ela. Vamos remover esse método, pois não
precisaremos mais dele. Também vamos remover esse método
na linha de transação
pelo mesmo motivo. Mais uma coisa aqui
no método de linhas de transação de anúncios na classe de linhas de
transação precisamos atualizar o saldo da linha da
transação antes que nossas alterações entrem em vigor. Então, vamos incluir o código a
seguir para fazer isso. Agora, vamos fazer o teste de
envio de Bitcoin. Antes de executá-lo, vamos
incluir uma chamada suspensa após o teste clicar no botão OK na segunda caixa de diálogo de
transação. Com isso, evitamos que o teste falhe devido às condições
de corrida. Agora, vamos fazer nosso teste. Ótimo, os testes foram aprovados. Vamos executar todos os testes de
aplicativos para garantir que não quebramos
nada em nossas carteiras. Vou acelerar o vídeo agora, já que esses testes levarão alguns minutos para serem executados na realidade. Ótimo. Todos os
testes foram aprovados.
59. 57 Enviar parte do bitcoin 10 skillshare 2: Neste vídeo, adicionaremos mais testes para verificar
se nossa carteira funciona conforme o esperado ao enviar transações em
diferentes cenários. Vamos ver se nossa carteira pode enviar duas transações,
uma após a outra. Para fazer isso, vamos duplicar esse teste na classe de teste send
Bitcoin. Vamos mudar seu nome para. Deve enviar Bitcoin às vezes. Vamos corrigir sua formatação. Vamos mudar o nome da carteira
para o meu teste aos dez anos. Agora vamos extrair essa seção
de código para um método. Vamos chamá-lo de enviar Bitcoin. Vamos adicionar o valor a ser enviado
como segundo parâmetro. Depois de criar uma transação, clicará no
botão OK para enviá-la. Em seguida, usaremos essa linha de código para transformar nosso nó em um bloco. Com isso, esperamos que nossa segunda transação
seja confirmada, permitindo usar a
alteração UTXO gerada por essa transação como
entrada na próxima transação. Agora, clicaremos na guia Enviar. E chamaremos o método de
sono com esses parâmetros para aguardar a confirmação de
nossa transação. Depois de enviar a
primeira transação, esperamos que nosso primeiro endereço de
alteração seja exibido na tabela de
endereços. Esperamos que um endereço de
alteração diferente seja usado na segunda
transação porque é importante não
reutilizar endereços ao receber Bitcoins
por motivos de privacidade. Então, compararemos o endereço de
alteração nas duas transações e verificaremos
se elas não são iguais. Para fazer isso, vamos pesquisar a tabela de endereços
com essa linha de código. Vamos alterar o tipo TableView para a linha de endereço para fins de
exatidão. Vamos remover a
declaração aqui e
aproveitar a oportunidade para corrigir o mesmo problema no método de teste
anterior. Armazenará o primeiro
endereço de alteração nessa variável, obtendo-o da tabela de
endereços. Em seguida, chamaremos o método de
envio de Bitcoin novamente para enviar a
segunda transação. Após a segunda transação procurará a tabela de
endereços novamente. Espero que a primeira
linha da tabela contenha
o
segundo endereço de alteração. Então, vamos consultá-lo
novamente e armazenar o endereço da primeira linha e a segunda variável de
endereço de alteração. No bloco then, adicionará
a seguinte afirmação para verificar se o primeiro endereço de
alteração não é igual ao segundo. Aqui, esperamos que o tamanho da tabela de
transações seja igual ao número
UTXOs anterior mais dois. E vamos mudar essa parte
do texto do saldo total. Esperamos que o
saldo confirmado seja igual aos fundos
menos o total gasto. Vamos remover esse caso de teste, teremos apenas um
caso para esse teste. Vamos alterar o
valor para enviar 0,25. Vamos atualizar o total
gasto adequadamente. E vamos alterar os
últimos quatro dígitos do valor da alteração. Esse valor de alteração é a soma
dos valores de alteração
das duas transações. Agora, vamos executar nosso node. Vamos adicionar a
anotação de ignorar ao primeiro teste, pois queremos executar
somente o último teste. E vamos executá-lo. O teste falhou porque o primeiro
endereço de alteração é igual ao endereço
da segunda alteração. Vamos corrigir isso. Vamos até o
serviço de atualização dos endereços da carteira
atual e moveremos essa
linha de código para esse local. Aqui, adicionaremos uma
declaração if para verificar se o endereço que está sendo atualizado
é um endereço alterado. Vamos adicionar essa constante
a essa classe. Será igual ao
tipo de endereço que seg mudaria. No corpo da declaração if, definirá o
endereço de alteração da
carteira atual para o próximo endereço. Vamos também adicionar uma instrução
return a esse corpo da declaração if. Vamos executar o teste novamente. Ótimo, o teste foi aprovado. Agora, começaremos a implementar
alguns tratamentos de erros
em situações em que as coisas não correm bem quando tentamos enviar transações, por exemplo, o que deve acontecer quando usamos a senha errada da carteira quando tentando enviar
uma transação. Quando nossa carteira envia uma transação com a senha
incorreta, isso faz com que a
transação seja construída com
assinaturas inválidas. Quando nosso node a recebe, ele tenta validar
essa transação. Como suas assinaturas estão erradas, ele retornará uma
mensagem de erro e não retransmitirá a transação
para outros nós. Atualmente, nossa carteira não
está lidando com o erro retornado e
falhará silenciosamente. Vamos criar uma solução
para essa situação. Nosso node retorna um erro após receber nossa transação mostrará ao usuário
um alerta de erro dizendo que a carteira não conseguiu
enviar a transação. E y. Primeiro, vamos criar um
teste para esse cenário. Na aula de teste de envio de Bitcoin. Vamos duplicar
o primeiro método. Vamos renomeá-lo para não enviar Bitcoin com a senha
errada. E vamos ajustar sua formatação. Vamos também mudar o
nome da carteira para minha carteira de teste 11. Aqui, clicaremos no campo
da senha. Vamos definir uma variável
para essa senha. Vamos configurá-la como minha senha de teste e escrevê-la no campo de
senha. Depois de receber
Bitcoins, vamos armazenar o saldo formatado na variável fundos
formatados. Como não teremos sucesso
no envio de uma transação, esperamos que o
saldo final de nossa carteira não mude e continue sendo
igual a essa variável. Agora, vamos substituir
essa seção de código por uma chamada do método send Bitcoin. Depois que a caixa de
diálogo da transação aparecer, clicaremos no campo de senha da
carteira. E escreveremos a senha
errada. Depois de clicar
no botão OK, esperamos que uma
mensagem de erro apareça. Vamos definir essa mensagem de erro e armazená-la nessa variável. Em seguida, com esse código, tentará armazenar o nó com essa mensagem na variável
de consulta do nó. O alerta de erro terá um botão OK que
tentará clicar. No bloco then, verificará se os textos da consulta do nó são
iguais à mensagem de erro. Também verificará se o endereço
na tabela de endereços tem um saldo igual à variável de fundos
formatada. Esperamos que o tamanho da
tabela de transações seja igual a um, pois não mostraremos a
transação que falhou na tabela. Também vamos alterar o saldo
esperado da transação aqui para ser igual
aos fundos formatados. Também esperamos que o saldo
total e o
saldo confirmado sejam iguais à variável de fundos formatados. O
saldo esperado não confirmado deve ser igual a zero com
oito casas decimais. Vamos remover o segundo
caso de teste no bloco where. Agora vamos implementar o recurso
de alerta de erro. No segundo serviço
de transação. Vamos adicionar uma instrução catch aqui para detectar um erro interno
do servidor. Esse é o tipo de erro que
o nó retornará se algo der errado quando
tentarmos enviar uma transação para ele. Agora, usaremos o registrador
para registrar esse erro. Então, vamos adicionar o registrador a
essa classe como um campo estático. Irá instanciá-lo usando o método logger factory
get logger, passando essa classe
como seu parâmetro. Em seguida, chamaremos o método de
erro nele, passando o erro get response body como chamada de método
string. Em seguida, retornaremos a chamada do método
de erro do
manipulador de erros do node passando o erro para ele. Vamos injetar o
manipulador de erros do node nessa classe. Vamos criar essa classe no pacote de serviços de pontos da
GUI. Vamos terminar de
injetá-lo nesta classe. Vamos criar esse método nele. Ele retornará um erro de tipo
futuro. Voltando ao local
que o chamará, vemos que o ID
indica um erro de tipo. Para corrigir isso, vamos alterar
o tipo de retorno do sinal e
o método de envio
para o futuro do erro de tipo. Mas primeiro, vamos criar o registro de erro no pacote
domains dot node. Vamos copiar essa linha
e colá-la aqui. Vamos alterá-la para importar essa classe de erro que
acabamos de criar. Se não fizermos isso, o Java usará sua classe
de erro embutida. Agora, vamos mudar esse parâmetro
de tipo para erro. Vamos passar a
linha de importação para essa classe também. Vamos adicionar uma
anotação de serviço a ela. Agora, antes de
continuarmos implementando o recurso, vamos executar o último teste
para verificar o formato da mensagem de erro que o
nó retorna nos registros. Primeiro, vamos adicionar a
anotação de ignorar a esse teste. Então, só executamos o último teste. Aqui, vemos que o nó
retornou à mensagem JSON. A parte importante
diz que o script falhou e 0 p é igual à operação de
verificação. Isso significa que o nó falhou
devido a uma assinatura incorreta ao executar o script combinado para validar a transação. Agora que sabemos o que
o nó retorna ao aplicativo quando
a senha da
carteira está errada, vamos mapear essa resposta para
a resposta de senha incorreta que
queremos que o usuário veja. No manipulador de erros do node. Vamos adicionar um bloco try-catch converter o erro recebido em um objeto de
encapsulamento de erro de nó. Então, vamos criar esse registro no pacote domains dot node. Após a resposta
adjacente ao erro do nó, conforme a especificação, adicionará um campo de erro do
tipo erro de nó aqui. Então, vamos criar o registro
de erro do nó no pacote domains dot node. Ele terá um campo de código
e um campo de mensagem. De volta ao node, o manipulador de erros precisará do mapeador de objetos. Então, vamos
injetá-lo nessa classe. Agora, chamaremos o método
read value no mapeador de objetos pois seus parâmetros
passarão o erro get response body as
string method call. E a classe node error
wrapper. Esse código converterá o erro recebido em um objeto
de encapsulamento de erro de nó. Por fim, retornaremos um
novo objeto de resultado assíncrono instanciado com
um objeto de erro. Para instanciar o objeto de erro, usaremos o erro
do método que passa o erro do wrapper de
erro do node como parâmetro. Vamos criar o método frontal. Ele retornará um objeto de erro. Vamos adicionar o
campo de mensagem a esse registro. O método front retornará um novo objeto de erro instanciado
com uma mensagem de erro. Para criar a mensagem de erro, vamos adicionar o
campo de mensagens de erro nessa classe. Esse campo será
responsável por mapear as mensagens de erro do nó com as mensagens que queremos exibir. Será um mapa de
chaves e valores de cadeias de caracteres. Vamos usar o mapa do
método para criá-lo. A primeira chave será a mensagem de erro
retornada pelo nó, que vimos anteriormente nos registros do
aplicativo. O valor será a
mensagem de erro que queremos exibir. Para isso, usaremos a senha incorreta constante
da classe de mensagens de erro que criaremos. Então, vamos criar essa classe no pacote domains dot node. E vamos adicionar essa
constante a ela com a mensagem
que queremos exibir. Agora, chamaremos o método
Get ou padrão no
campo de mensagens de erro no método do formulário Seu primeiro parâmetro
será a mensagem de erro. Seu segundo parâmetro
será uma mensagem padrão, que definiremos
nessa constante. Portanto, se o nó retornar uma mensagem de erro que ainda não
mapeamos, a mensagem de erro exibida
indicará que ocorreu um erro. De volta ao manipulador de erros do node. Vamos adicionar uma
instrução catch aqui para exceção de processamento
adjacente que o mapeador de objetos pode gerar. Em seguida, o agrupamos em uma
exceção de tempo de execução e o lançamos. Agora vamos para o segundo controlador de
diálogo de transação. Aqui, obteremos o
resultado do método sign and send e o
armazenaremos em uma variável. Apenas certifique-se de importar
a classe de erro correta. Agora, precisaremos do serviço de erro de
alerta. Então, vamos
injetá-lo nessa classe. Esse serviço
será responsável por mostrar um alerta com
uma mensagem de erro. Vamos criá-lo no pacote de serviços de
pontos da GUI. E vamos terminar de
injetá-lo nesta classe. Agora, vamos chamar o método de
manipulação do erro
no erro de alerta ou no
objeto de serviço que passa o resultado para ele. Vamos criar esse método. Primeiro. Vamos adicionar a
anotação do serviço a essa classe. Aqui, declararemos
um objeto de erro. Em seguida, em um
bloco try-catch, definirá a variável de erro para a chamada do método dot get
resultante. Em seguida, capturaremos uma exceção
que o resultado pode gerar e a envolveremos em uma
nova exceção de tempo de execução. Agora, nesta instrução if,
verificaremos se o erro não
é igual a nulo. Caso contrário, chamaremos
o método de erro de alerta, passando a mensagem de erro para ele. Vamos criar esse método. Aqui. Criaremos um novo objeto de alerta
com um erro de tipo de alerta. Em seguida, definiremos o título do
alerta como erro. E definiremos o texto do
cabeçalho do alerta como um erro ou dois. Vamos definir o
texto do conteúdo do alerta para a variável da mensagem. Finalmente, vamos chamar o
método show no objeto de alerta. Agora, vamos executar o teste novamente. Ótimo, o teste foi aprovado.
60. 58 Enviar parte do bitcoin 11 Skillshare 2: Neste vídeo, continuaremos
adicionando mais validações e alertas para notificar o usuário sobre tentativas fracassadas de
transferência. Primeiro, criaremos alguns
casos de teste para esses cenários. Então, vamos duplicar esse
teste para adicionar um teste para o cenário em que o
usuário deseja enviar uma transação com mais
bitcoins do que seus fundos. Vamos renomeá-lo para
não enviar Bitcoin sem
fundos maiores que valor mais v.
Vamos reformatá-lo. E vamos mudar o
nome da carteira para o meu teste aos 12 anos. Vamos excluir essas linhas. Aqui. Definiremos uma variável de
mensagem de erro para o conteúdo que queremos que o
usuário veja em caso de erro A mensagem
será não foi possível enviar transação, não há fundos suficientes. Em seguida, com esse código, tentará armazenar
o elemento UI com essa mensagem na variável
de consulta do nó. E tentaremos clicar no botão OK
na caixa de diálogo
de alerta. No bloco then, verificaremos se o texto da consulta do nó é igual
à mensagem que
definimos anteriormente. Vamos excluir essas variáveis
no bloco where, pois não
precisaremos delas. E vamos criar a variável de valor
anterior aqui com o seguinte valor. Vamos duplicar essa linha para
criar um segundo caso de teste. Esse valor será
um Satoshi menor do que o necessário para
enviar 0,5 bitcoin. Agora, vamos deletar essa linha. Vamos substituir esses valores pela variável de
valor anterior. Agora, criaremos um cenário de teste
semelhante, mas desta vez usando uma
carteira sem fundos. Então, vamos duplicar esse teste. Vamos mudar seu
nome para não enviar Bitcoin sem fundos. Vamos mudar o nome da carteira
para o meu teste aos 13 anos. Vamos remover essas linhas pois não
receberemos nenhum fundo. E vamos deixar
apenas o valor para
enviar a variável e
o bloco where. Agora, vamos implementar o recurso na classe de
serviço de criação de transações. Vamos armazenar a transação
DTO em uma variável aqui. E vamos retornar essa variável. Agora. Antes de retornar, ele chamará o método de validação de
fundos, passando a transação
DTO como seu parâmetro. Vamos criar esse método. Usarei esse método
para validar se a soma dos valores
de entrada da transação é maior do que a
saída da transação entre alguns. Então, vamos criar essa variável
para armazenar a quantidade de entrada. Alguns atribuirão o resultado de chamar a transação de DTO receberão quantidades
de método de entrada para ela. Vamos criar esse método. Aqui. Usaremos um mapa no fluxo
UTXOs selecionado para criar um fluxo de valores de UTXO. Em seguida, usaremos o método
reduzido para somar cada valor obtido. Finalmente, usaremos o método
or else para retornar
a soma ou zero se nenhum
UTXOs estiver disponível. Agora, vamos criar as quantidades
de saída do método get output aqui. Usaremos uma estratégia semelhante a alguns dos valores de produção. Mas em vez de usar
os UTXOs selecionados, usará um mapa no fluxo de saída da
transação. O método de mapa retornará os valores de saída
convertidos em Bitcoin. E usaremos o método reduce e Rails da mesma forma
que usamos no método anterior. Voltar ao método de validação de
fundos. Aqui, criaremos uma variável
de saída para armazenar o resultado da chamada
dos valores de saída get. Um método que acabamos de criar. Agora, adicionaremos uma instrução if para verificar se a soma de entrada é menor que a soma de saída
mais o total calculado F0. Se for, lançaremos uma nova exceção de criação de
transação com a mensagem de
fundos insuficientes. Vamos criar essa constante
na classe de mensagens de erro. Vamos tornar as duas constantes finais. E vamos criar a classe de exceção de
transação no pacote de
exceções de pontos da GUI. Ele estenderá a exceção
de tempo de execução e passará sua mensagem
para o superconstrutor. Vamos aproveitar a oportunidade para adicionar outra validação aqui. E se tentarmos enviar uma transação sem
uma carteira carregada? Para lidar com esse caso, vamos usar essa
instrução if para verificar se a carteira atual
tem algum endereço. Caso contrário, lançaremos uma exceção de criação de transação com uma mensagem de carteira não
carregada. Vamos criar essa constante
para armazenar essa mensagem. Agora, vamos para o controlador da guia
Enviar. Vamos agrupar a criação da
transação DTL em um bloco try-catch. A chamada do método de diálogo aberto
para. Aqui, vamos pegá-lo. Crie uma exceção de transação. Usaremos o erro ou
serviço de alerta e o corpo de captura. Então, vamos
injetá-lo nessa classe. Em seguida, chamaremos o método de erro de
alerta, passando a
mensagem de exceção como seu parâmetro. Vamos tornar esse método público. Vamos fazer o teste de
envio de Bitcoin. Vamos adicionar a
anotação de ignorar ao teste que fizemos
no último vídeo. Vamos executar nosso node. Antes de executar o teste, vamos ajustar alguns detalhes. Vamos adicionar um ponto no
final das mensagens de erro. No método de envio de Bitcoin. Vamos adicionar esse parâmetro. O padrão será verdadeiro e
só chamará o
método de diálogo do wafer se for verdadeiro. Agora, vamos configurá-lo como
false e essas chamadas, porque o diálogo da transação não aparecerá nesses testes. Finalmente, vamos executar os testes. Nota: os testes foram aprovados. Vamos remover todas as
anotações de ignorar dessa classe. Agora, adicionaremos vários testes
novos em uma nova classe chamada enviar
teste adicional de Bitcoin neste pacote. Mas não se preocupe, desta
vez, copiaremos o conteúdo dessa aula
da página Projeto e Recursos. Todos esses testes devem ser aprovados. Espero que não precisemos
mudar nada em
nosso código para isso. Mas eles ajudarão a garantir que nossa carteira
envie as transações corretamente e detecte
possíveis quebras de código que
ocorrerão no futuro. Vamos reformatar todos eles. No primeiro teste,
verificaremos se uma carteira com uma senha envia
transações corretamente. O próximo teste gerará
transações sem a necessidade de alteração e verificará se seus parâmetros estão corretos. Esse teste tentará enviar uma
transação para um endereço de nossa própria carteira e
verificar se a carteira calcula
corretamente seus
valores e saldos. Finalmente, o último teste
terá muitos casos de teste
diferentes com números diferentes de UTXOs e valores
anteriores. Para que esses testes funcionem, vamos mover o peso do método de
diálogo no teste de
envio de Bitcoin para
a classe de teste de GUI. Vamos protegê-lo. Vamos remover essas importações
no teste de envio de Bitcoin. Mais uma coisa no método de
envio de Bitcoin, no teste de envio de Bitcoin, vamos adicionar a
superpalavra-chave aqui para garantir que chamaremos o
peso correto para o método de diálogo, não o parâmetro
com o mesmo nome. Faremos outro
teste nesta aula. Desta vez, verificaremos
o que acontece quando
tentamos enviar uma transação
com uma quantidade de poeira. Então, vamos duplicar esse teste. Vamos mudar seu nome para não
enviar pó de Bitcoin. Vamos corrigir sua formatação. Vamos mudar o nome da carteira
para o meu teste aos 18 anos. Agora, vamos copiar esse código e adicioná-lo ao nosso método
para financiar nossa carteira. Vamos alterar a
mensagem de erro para Não foi possível enviar valor
da transação
para enviar é poeira. Vamos mudar o bloco where, adicionando as seguintes
variáveis a ele. Escolheremos uma quantia para
enviar igual a 293 Satoshi, que sabemos que nosso node não pode aceitar, pois
será considerada poeira. Para o valor anterior,
escolherá 0,1 bitcoin. Como confiaremos em nossa nota para detectar esse tipo de erro, aguardaremos que a caixa de diálogo
da
transação apareça depois de clicarmos
no botão Enviar. E vamos adicionar o clique na chamada
do método do botão OK para confirmar a transação
do diálogo. Agora, vamos para
a classe de erro. Vamos adicionar a seguinte entrada ao mapa de mensagens de erro o erro de mensagem de poeira
recebida do nosso nó para a mensagem presente na
constante de poeira na classe de
mensagens de erro. Vamos criar essa constante. Será igual à mensagem que
acabamos de definir no teste. Vamos adicionar a
anotação de ignorar
aos outros testes dessa
classe e executar nosso novo teste. Ótimo, o teste passou. Vamos excluir todas as anotações de
ignorar que adicionamos anteriormente. Neste momento, eu recomendo executar todos os testes do
aplicativo. Eu fiz isso e todos eles passaram. Não vou mostrar isso neste vídeo porque levaria
vários minutos. Vou deixar isso como um
exercício para o aluno.
61. 59 Segwit aninhado parte 1 skillshare 2: Neste vídeo, começaremos a
refatorar nosso aplicativo
para prepará-lo adicionar suporte para
mais tipos de endereço. Será um refator relativamente
grande, mas veremos mais tarde
que isso nos
permitirá adicionar suporte para
outros tipos de endereço, como o conjunto aninhado
abordaria. A ideia desse reator
é centralizar tudo o que específico de um tipo de endereço
em um objeto de configuração de endereço. Ao fazer isso, poderemos
adicionar mais tipos de endereços às nossas carteiras adicionando novos
objetos de configuração de endereço ao projeto. Depois de fazer essa
refatoração, adicionaremos um novo
tipo de endereço chamado segmento aninhado, cuja importância
explicaremos em alguns vídeos. Então, vamos até o registro
de configuração do endereço para adicionar alguns campos. Adicionaremos o campo
gerador de endereços. Vamos usá-lo para definir
o serviço usado para gerar endereços para
diferentes tipos de endereço. Um mapa com uma chave de
enumeração de ambiente e um valor de string. Usaremos esse campo para registrar os prefixos de endereço
para cada ambiente. Então, vamos criar isso o suficiente. No pacote BYU w dot
domains. Ele terá as constantes de
teste net, test net e reg test. Vamos adicionar o campo de prefixo
ki estendido aqui. Como o nome sugere, ele definirá o prefixo
da chave estendida que
gerará os endereços. O próximo campo será uma string de predicados como
parâmetro de tipo. Ele receberá uma função
lambda com um endereço como
parâmetro e uma expressão que
retornará true se o endereço corresponder ao tipo de configuração do
endereço e false. Caso contrário, adicionaremos um campo do tipo de chave de
pub de script para que
possamos identificar qual configuração de
endereço
usar usando o tipo de chave pub do
script. Em seguida, adicionaremos por função
com esses parâmetros de tipo usaremos esse campo para definir uma função para analisar um
endereço de um determinado script, chave
pub e um prefixo. Agora vamos excluir o bean de conflito de
endereço para o endereço de alteração do Segway. Nesta refatoração,
usará apenas um bean de
configuração de endereço para os endereços de
alteração do segmento e do segmento. Vamos mudar a anotação do Bean
para refletir essa mudança. Agora, vamos alterar essa instanciação de configuração de
endereço para incluir cada
recurso relacionado a esse tipo de endereço. Alteraremos o campo do caminho de derivação para
um mapa em que a chave será um tipo de endereço e
o valor será seu caminho de
derivação correspondente. Aqui, adicionaremos duas entradas, uma para o tipo de endereço do segmento e seu caminho de derivação inicial e a outra para
a alteração do Segway e seu caminho de derivação inicial. Agora, à medida que for abordado, gerador adicionará um novo gerador de endereços de
segmento. Para o campo de
prefixos de endereço, adicionaremos o mapa a seguir uma entrada para cada
ambiente e eles são prefixos de endereço P2, WP k h. O campo de
prefixo ki estendido será a principal constante do
prefixo net segue. Como o combinador de endereços será usado o combinador de endereços
segue com a função Lambda. Então, vamos criar essa classe
e o pacote utils. E vamos criar essa função. Será uma função
que pegará um endereço e retornará
verdadeiro se o endereço começar com um
desses três prefixos presentes nos endereços do segmento. O próximo campo será igual à constante
do script P2 WP k h. Finalmente, o analisador de endereços
será uma referência
ao método de endereço do script P2 WP k
h. Vamos voltar à configuração do
endereço para substituir o tipo
do caminho de derivação. Será um mapa com tipos de
endereço como chaves e cadeias de caracteres como valores. Agora, vamos criar a classe localizadora de
configuração de endereço
no pacote api dot services.
Usaremos esse serviço como uma forma de recuperar o endereço
correto, pode ser falso e outros serviços
serão refatorados a seguir. Então, vamos adicionar a
anotação de serviços a ela. E vamos injetar uma lista
de configurações de endereço aqui. Agora, vamos criar esse
método que nos
permitirá encontrar uma configuração de
endereço por endereço. Seu tipo de retorno será
opcional do tipo configuração de endereço. Em seguida, filtraremos um fluxo
de configurações de endereço e usaremos o combinador de
endereços configuração no filtro lambda. Em seguida, retornaremos a configuração de endereço
opcional correspondente ao endereço
recebido usando o primeiro método. Agora vamos criar
outro método que retornará uma configuração
de endereço opcional do tipo. Desta vez, ele encontrará uma configuração de endereço de acordo
com seu tipo de script. Será semelhante
ao método anterior, mas usaremos o
filtro para verificar se a chave pub do script anterior corresponde à
da configuração do endereço. Também usaremos o
primeiro método definido neste caso. Agora, criaremos
um método para encontrar uma configuração de endereço
por tipo de endereço. Novamente, usaremos um filtro em
um fluxo de configurações de endereço. Desta vez, o filtro
conterá um lambda
que verificará se o tipo de endereço de configuração do endereço
é igual ao tipo de endereço
anterior ou se é igual
à alteração correspondente tipo de endereço. Desta vez, retornaremos que o
endereço pode ser falso sem o objeto opcional usando
o método orals throw. Esse método gerará
uma exceção se não encontrar a configuração de endereço
apropriada. Agora estamos prontos para começar a
refatorar outros serviços para usar nossa nova configuração de endereço
e localizador de configuração de endereço. Vamos começar com o serviço de
criação de carteira. Vamos deletar essas duas linhas. Aqui. Usaremos um FlatMap
na lista de configuração de endereços. Em seguida, passaremos um método
lambda como parâmetro, retornando
no corpo do lambda A
transformação a seguir
obterá os caminhos de derivação
da configuração de endereço recebida. Está faltando uma letra S final. Então, vamos renomear esse campo
para caminhos de derivação. Agora, obteremos o conjunto
de entrada dos caminhos de derivação. Em seguida, chamaremos o
método map no fluxo de entradas do caminho de derivação e
retornaremos uma
chave pub estendida para cada entrada usando o método de criação do
serviço de chave pub estendida. Como seus parâmetros
passarão pela chave mestra. O valor de entrada, que será o caminho de derivação,
a chave de entrada, que será o tipo de endereço, e o prefixo ki
estendido da configuração do endereço. Por fim, convertemos
o resultado em uma lista. Agora vamos ao serviço
estendido de chaves de pub. Vamos deletar essas linhas. Vamos adicionar um quarto
parâmetro a esse método. Será um prefixo ki
estendido. Aqui, substituiremos
esse argumento
pelo prefixo ki estendido, prefixo público. Agora vamos para o gerador de endereços do
segmento. Aqui, adicionaremos o prefixo
como segundo argumento e o usaremos como
um parâmetro aqui. Agora, vamos remover a
fábrica de prefixos de endereço dessa classe. E vamos adicionar o
segundo argumento a essa interface,
gerar o método dois. Agora vamos para o gerador
sequencial de endereços. Na chamada do método generate, usaremos o
prefixo de endereço factory. Então, vamos
injetá-lo nessa classe. Agora vamos chamar o método
get nele, passando o
tipo de endereço recebido como seu parâmetro. Agora vamos refatorar a fábrica do gerador de
endereços. Vamos deletar todas essas linhas. Vamos injetar o localizador de
configuração de endereço nessa classe. Aqui, chamaremos a busca por tipo de
endereço no localizador de configuração de endereço, passando o
tipo de endereço como parâmetro. Em seguida, retornaremos o gerador de endereços de configuração do
endereço do telefone. Agora, vamos refatorar a fábrica de prefixos de
endereço. Vamos remover todas essas linhas. Então, vamos injetar o endereço que
pode pensar no Finder
nessa classe. Novamente, encontraremos
a configuração do endereço por tipo de endereço
usando esse método. Em seguida, obteremos os prefixos
de
endereço da configuração do endereço encontrado. Por fim, retornaremos
o prefixo de endereço correspondente ao ambiente atual do Bitcoin, desta forma. Vamos corrigir os testes para as classes que
acabamos de refatorar, começando com o teste do gerador
sequencial de endereços. Vamos adicionar o localizador de
configuração de endereço como um campo nessa classe. E vamos atribuí-lo a uma
simulação dessa aula aqui. Agora, vamos instanciar uma
nova configuração de endereço, definindo-a para essa variável. Em seguida, vamos usar um método para definir um objeto retornado quando chamamos o método find by
address type no localizador de configuração de endereço. Nesse caso, retornará
a configuração do Segway. Então, vamos tornar esse método público na classe de
configuração de endereço. Agora vamos mudar esse parâmetro de fábrica do
prefixo de endereço para a string de rede principal. E vamos passar o localizador de configuração de
endereço para
a instanciação da fábrica do gerador de
endereços. Vamos fazer esse teste. Opa, a compilação
falhou devido a um erro
no construtor UTXO DTO.
Vamos consertar isso. Aqui. Obteremos a configuração do endereço usando o localizador de configuração de endereço. Então, vamos
injetá-lo nessa classe. Vamos excluir a lista de
configurações de endereço dessa classe. Agora, encontraremos a
configuração do endereço por tipo de endereço aqui. Em seguida, obteremos o caminho
de derivação usando o tipo de endereço recebido. Por fim, concatenaremos
a barra da string e o
índice do endereço ao resultado. Vamos fazer o teste novamente. Ótimo, o teste foi aprovado. Agora vamos corrigir o teste do serviço de criação de
carteira. Vamos deletar essas linhas. Instanciará a configuração do
endereço aqui. Em seguida, criaremos a lista de configurações de
endereço aqui. Adicionar o conjunto
configuraria a ele. Vamos remover todas essas linhas. Agora, vamos instanciar os objetos
necessários dessa forma. Vamos fazer esse teste. Grau. O teste foi aprovado. Agora vamos corrigir o teste estendido do serviço de chaves de
pub. Adicionaremos o prefixo de
rede principal que seria o último parâmetro
do método create. E vamos fazer esse teste. Ótimo, já passou. Finalmente, vamos corrigir o teste do gerador
de endereços de segmentos. Removeremos o prefixo de endereço de
fábrica dessa classe. E passaremos o prefixo de endereço
principal da rede P2 WP k h como o
segundo parâmetro desse método. Vamos fazer esse teste. Grau. O teste foi aprovado. No vídeo a seguir, continuaremos a
refatorar nosso aplicativo.
62. 60 Segwit aninhado parte 2 skillshare 2: Neste vídeo, continuaremos
a refatorar nosso aplicativo. Então, vamos começar com a classe do analisador de
endereços. Vamos injetar o localizador de
configuração de endereço nessa classe. Vamos remover esse código. Agora, usaremos o localizador de configuração de
endereço para encontrar uma configuração de endereço
por tipo de chave pub do script,
passando o tipo de
chave pub do script para esse método. Em seguida, mapearemos o resultado e aplicaremos o analisador de endereços de
configuração de endereço, passando a chave pub do script e o prefixo adequado
como seus parâmetros. Agora, usaremos o método URL para retornar uma string vazia se
um endereço não puder ser analisado. Vamos devolver essa
transformação. Agora, vamos para a classe de carteira
atual. Vamos remover o endereço
de recebimento e alterar o endereço
dessa classe. Em vez de usar
um campo para cada endereço de
recebimento e alteração, usaremos um
campo de endereços de recebimento para modelar os diferentes
endereços usados para receber Bitcoins em nossa carteira. Então, vamos adicionar o campo de
endereços de recebimento a essa classe. Será um mapa observável com tipos de
endereço como chaves
e cadeias de caracteres como valores. Irá instanciá-lo aqui com um HashMap observável
da classe de coleções FX. Vamos excluir os métodos
que usam os campos removidos. Agora vamos criar o método de definir endereços de
recebimento. Colocaremos uma entrada no mapa de endereços de
recebimento para cada chave de pub estendida. A chave de cada entrada será um tipo de endereço obtido
usando o valor do método passando o
tipo de chave pub estendida como seu parâmetro. O valor será
o primeiro endereço da chave de pub estendida. Agora, vamos criar o método de endereço
de recebimento definido. Usaremos esse método para atualizar o endereço de recebimento atual para um tipo de endereço específico. Ele aceitará um índice de endereço e um tipo de endereço
como parâmetros. Primeiro, obteremos o próximo
endereço usando o método get address ID passando
esses parâmetros. Em seguida, colocaremos o endereço
obtido
nos endereços de recebimento usando o tipo de endereço como chave. Vamos criar o método de obter endereço de
recebimento. Ele pegará um tipo de endereço e retornará o endereço de
recebimento atual desse tipo e
o obterá dos endereços de recebimento usando o tipo de endereço como
chave para a recuperação. Agora, vamos criar um getter
para os endereços de recebimento. Vamos renomeá-lo para obter endereços de recebimento
observáveis. Agora, vamos para o serviço de atualização de
endereços da carteira
atual. Vamos remover todas essas
linhas dentro de uma chamada de
execução posterior da plataforma. Vamos adicionar uma
função Lambda que usará o
endereço de recebimento do conjunto atual da carteira para definir o próximo endereço. Vamos remover esses campos,
pois não precisaremos deles. Agora, vamos refatorar o serviço de atualização
atual da carteira. Vamos remover essas duas linhas. Em seguida, vamos adicionar uma chamada ao método definido de endereços de
recebimento que
acabamos de criar na carteira
atual. Agora, vamos para o controlador da guia
Receber. Vamos remover esse código. Aqui. Obteremos os endereços de
recebimento observáveis da carteira atual
e adicionaremos um ouvinte a ela. O ouvinte será a
seguinte função lambda. Com isso, a declaração if
verificará se o endereço de recebimento que foi alterado foi a segue
qual endereço? Nesse caso, definiremos o texto do campo
do endereço de recebimento
como o endereço recém-adicionado. Agora vamos refatorar
a forma como o endereço de alteração é
usado no projeto. Então, vamos criar uma classe chamada Localizador do tipo de
endereço de alteração. Essa classe será
responsável por encontrar o tipo de endereço de
alteração apropriado para uma determinada saída de endereço. Embora possamos usar
diferentes tipos de endereço como saídas em uma transação, é
recomendável usar o
mesmo tipo para complicar terceiros descubram
qual saída foi
usada na alteração. Esse serviço nos permitirá
resolver essa preocupação. Vamos adicionar a
anotação do serviço a essa classe. Vamos injetar o localizador de
configuração de endereço nele. Agora vamos criar
o método find. Esse método
retornará um tipo de endereço e tomará um endereço
como parâmetro. Aqui, chamaremos o método find by address no localizador de configuração de endereço. Em seguida, mapearemos o valor
obtido para o
tipo de endereço de alteração equivalente usando o código a seguir. Finalmente, usamos
o método or else para retornar o tipo de endereço seg would
change. Se o
tipo de endereço não foi encontrado. Usaremos o
endereço de mudança do Segway para este caso. Embora permitamos que
nosso aplicativo envie transações para a
maioria dos tipos de endereço, precisamos fornecer esse recurso porque não implementaremos todos os tipos de endereço como destinatários endereços
em nossa carteira. Agora, vamos para o serviço de criação de
transações. Devemos refatorar
a forma como o endereço de alteração é
obtido nessa classe. Vamos adicionar a variável de
endereço de alteração aqui. Seu valor será igual ao resultado
da chamada do método de
endereço de alteração fina com o
endereço como parâmetro. Então, vamos criar esse método. Vamos primeiro substituir essas
boas
chamadas de método de endereço de alteração pela nova variável de
endereço de alteração. Aqui, obteremos o tipo de
endereço
usando o Localizador de tipo de
endereço para alterar. Então, vamos
injetá-lo nessa classe. Agora, chamaremos o método find no localizador de alteração do tipo de
endereço, passando o endereço
como parâmetro. Em seguida, retornaremos uma chamada para o método de obter
endereço de recebimento, passando o
tipo de endereço obtido como parâmetro. Agora, vamos para a classe
de configuração de endereço. Adicionaremos campos relacionados à criação
da transação. Agora. O primeiro será o construtor de entradas de transações com essa nova classe como seu tipo. Vamos criar essa classe no pacote
de serviços da API. Será uma interface. método
será chamado de Build, retornará uma entrada de transação e Seu método
será chamado de Build,
retornará uma entrada de transação e
terá um UTXO como parâmetro. Voltar para a configuração do endereço. Adicionaremos o campo de entrada mais o tamanho da
saída aqui. Nós o usaremos mais tarde na aula de calculadora de
poeira. Vamos também adicionar o campo de tamanho do
ScriptSig aqui. Ele será usado na calculadora do tamanho da
transação. Agora, vamos também adicionar o campo do signatário da
transação. Vamos criar essa classe
no pacote de serviços api dot. Será uma interface. Ele terá um método de sinal que terá os
seguintes parâmetros. Ele também lançará
uma IOException. Agora, na classe
de configuração de endereço, vamos definir os novos campos na configuração do endereço do segmento. Adicionaremos um novo construtor de entrada de
segmento
como o construtor de entrada de transações. Vamos criar essa classe
no pacote de serviços api dot. Ele implementará
a interface do Builder
de entrada de transação interface do Builder
de entrada de e implementará
o método de construção. Para implementá-lo, vamos copiar o código a seguir dentro
do método build inputs na classe
do criador da transação e colá-lo aqui. Vamos mudar esse parâmetro
para um novo ArrayList. Armazenaremos essa
entrada de transação nessa variável. Em seguida, chamaremos o método
set witness, passando por uma nova testemunha
com os mesmos argumentos que
usamos no serviço de
criadores de transações. Finalmente, retornamos
a entrada da transação. Vamos copiar essas constantes e colá-las no construtor de entrada segue
what. E vamos adicionar a anotação do
serviço aqui. Voltar para a
configuração do endereço. Adicionaremos 98 como tamanho
de entrada mais saída,
zero como tamanho do ScriptSig
e um novo signatário de
transações do Segway. Vamos criar essa classe
no pacote de serviços api dot. Vamos implementar o método do signatário da
transação. Vamos adicionar a
anotação do serviço aqui. Vamos ao serviço de
signatário da transação. Vamos copiar essa linha
e colá-la aqui. Vamos substituir esse parâmetro
pela variável de índice. E vamos substituir
o valor UTXO pela variável de valor aqui. Nossa configuração de endereço
está finalmente pronta. Agora vamos para a calculadora do tamanho da
transação. Vamos usar o comando do IDE de
código de limpeza para adicionar a palavra-chave final a cada
campo dessa classe. Vamos injetar o localizador de
configuração de endereço nessa classe. Vamos deletar esse código. Vamos redefinir a variável all
inputs para mapear o fluxo de endereços de entrada passando uma referência
ao método de tamanho de entrada. Vamos criar esse método. Ele retornará um duplo e tomará um endereço
como parâmetro. Aqui retornará
um código semelhante
ao anterior que
define o tamanho da entrada. Mas o
parâmetro de tamanho do ScriptSig será obtido ao encontrar a configuração de endereço
adequada. Usar o localizador de configuração de endereço gerará uma exceção se
não encontrarmos a configuração do endereço. Se o encontrarmos, retiraremos
o tamanho do ScriptSig. Em seguida, adicionaremos a
sequência a ela. Finalmente, somaremos os resultados do tamanho da
entrada usando o método de soma dupla. Se não encontrarmos nenhuma entrada, retornará zero como a soma. Agora, vamos deletar essas linhas. Como o tamanho da entrada. Chamaremos o
método map no fluxo de endereços de saída e usaremos o método de tamanho de saída para
retornar cada tamanho de saída. Aqui, retornaremos a
soma do valor n, o comprimento da chave pub do script e o resultado do método
script pub key size passando o endereço
como parâmetro. Usar uma instrução if
verificará se o endereço é um endereço definido
usando o método Segway. Se for, retornamos a constante da chave pub do
script. Se não for, lançaremos
a seguinte exceção. Lembre-se de que não usaremos a configuração do endereço para
calcular o tamanho da saída porque a
configuração do endereço se refere apenas
aos endereços que podemos
aceitar em nossas carteiras. Como planejamos oferecer suporte a
mais endereços de saída, então tomaremos como entradas teremos que lidar com a construção da
saída sem usar a configuração do
endereço. Finalmente, usamos o método
reduzido para
calcular a soma
dos tamanhos das saídas. E existe o método or else para retornar zero sem saídas. Vamos deletar essa constante. Agora. Vamos para a calculadora de poeira. Vamos injetar o localizador de
configuração de endereço nessa classe. Vamos adicionar o endereço como um segundo parâmetro
a esse método de poeira. Vamos remover essa linha, criaremos a variável de entrada mais tamanho
de saída. Usaremos o localizador de
configuração de endereço para encontrar a
configuração de endereço por endereço. Se uma configuração de endereço não
for encontrada. Vamos lançar uma exceção. Se for,
obtemos sua propriedade de entrada mais tamanho
de saída e a
armazenamos em uma variável. Finalmente, retornamos a
fórmula para calcular se uma saída é poeira usando a
variável que acabamos de definir. Vamos remover essa
constante dessa classe. Agora, vamos refatorar o seletor
de moedas de sorteio
aleatório único adicionar o
parâmetro de alteração de endereço a esses métodos. E passamos o endereço de alteração
para a chamada do método dust. Vamos refatorar o serviço de criadores de
transações. Agora, vamos excluir
essas constantes. Vamos injetar uma lista de construtores de chaves do script pub
nessa classe. Vamos criar essa classe no caminho
de serviços de pontos da API. Será uma interface. Ele terá um método de correspondência
que retornará um booleano e tomará como
parâmetro e endereço. E ele terá um
método de construção que retornará um script e terá um
endereço como parâmetro. Vamos terminar de injetar esse
campo nessa classe. Vamos também injetar o localizador de
configuração de endereço nessa classe. Vamos adicionar o endereço de alteração
a essas chamadas de método. Vamos remover esse código
desse método, criaremos a
variável de script e atribuiremos o resultado da seguinte transformação de
fluxo a ela. Filtrará o fluxo do script
pub key builders para encontrar aquele que corresponde
à variável de endereço. Se não encontrarmos nenhum, lançamos uma exceção. Em seguida, chamamos o método build no script pub key builder encontrado passando o endereço
como parâmetro. Finalmente, retornamos a saída da
transação contendo o valor
e a variável do script. Agora vamos remover esse método
usado dessa classe. No método de entrada de compilação, vamos remover esse código. Agora, chamaremos o método de mapa
no fluxo de UTXOs. Dentro dele passará
o seguinte lambda, encontrará a configuração do endereço
usando o endereço UTXO. Se não o encontrarmos, lançamos uma exceção. Em seguida, obtemos o construtor
de entrada da
transação da configuração do endereço e o
chamamos de método derramado, passando o UTXO para ele. Finalmente, usamos o método
collect para converter o
fluxo resultante em um ArrayList. Vamos criar a classe construtora de scripts P2 WP k
h no pacote de serviços api dot. Ele implementará a interface do script
pub key Builder. Vamos implementar os métodos
de interface. Vamos injetar o prefixo de endereço
factory nessa classe. No método match
retornará o resultado da
chamada do matcher
de endereços do método de teste Segway. No método build,
primeiro definiremos a
variável de prefixo para o prefixo de endereço
factory. O resultado da chamada do
método Get passará a constante Segway
como seu parâmetro. Em seguida, retornamos
o resultado da chamada do método de script P2 WP k h pois o parâmetro
desse método passará o resultado da chamada do back 30 para decodificar para o método hexadecimal. Primeiro, vamos ao
arquivo POM para
atualizar a biblioteca Bitcoin Java para a versão 0.4, 0.4, que tem o
melhor método 32 de que precisamos. Vamos passar o prefixo e
o endereço para esse método. Agora, vamos para a classe de signatários da
transação para obter mais refatoração. Vamos injetar o localizador de
configuração de endereço nessa classe. Vamos deletar essa linha. Em seu lugar, chamará o mesmo método passando
esses parâmetros para ele. Vamos criar esse método criar
a variável do
signatário da transação. Atribuiremos a ele
o resultado da transformação a seguir. Usaremos o
localizador de configuração de endereço para encontrar uma configuração de
endereço por tipo
de endereço que passará o
tipo de endereço UTXO DTO para esse método. Mas primeiro, vamos adicionar o campo do tipo de endereço
ao registro UTXO DTO. E vamos adicionar o tipo de
endereço
à instanciação UTXO DTO
no construtor UTXO DTO. De volta ao serviço de
signatários da transação,
obterá o signatário da
transação de configuração de endereço a
partir da configuração do endereço do telefone. Finalmente, vamos chamar o método de assinatura dos signatários da
transação, passando esses parâmetros para ele. Vamos adicionar uma
cláusula throws a esse método para indicar que esse método
pode gerar uma IOException. A refatoração está concluída. Agora vamos corrigir alguns testes, começando com o teste do seletor de moedas de
sorteio aleatório único. Vamos adicionar a
configuração do endereço ao método de configuração. Em seguida, vamos adicionar a
variável da lista de configurações de
endereço com o segmento
Config dentro dela. Agora vamos instanciar um
novo localizador de configuração de endereço, passando as
configurações de endereço para ele. Agora vamos fazer esse teste. Ótimo, já passou. Agora, vamos corrigir o teste do serviço de
criadores de transações. Como no teste anterior. Vamos instanciar uma
configuração de endereço e criar uma variável de configuração de endereço e
uma variável localizadora de configuração de endereço. Também vamos instanciar um prefixo de
endereço passando a string de teste reg e o localizador de configuração de
endereço para ele. Agora vamos criar a variável script pub key
builders que
atribuirá uma lista a ela com um novo
construtor de scripts P2 WP k h dentro dela. Vamos fazer esse teste. Ótimo, já passou. Agora, vamos corrigir o teste da calculadora
do tamanho da transação. Como nos testes anteriores, vamos instanciar uma
configuração de endereço e criar uma variável de configuração de endereço e
uma variável localizadora de configuração de endereço. Vamos mudar esses testes de caso. Colaremos os
casos de teste que você pode encontrar na página Projeto e
Recursos. Vamos importar o método das cópias
finais. Esses casos de teste são
iguais aos anteriores, mas desta vez têm
endereços reais, pois agora são importantes para a lógica da
calculadora do tamanho
da transação. Vamos fazer esse teste. Ótimo, já passou. Agora, vamos para
a aula de teste de GUI. Vamos adicionar a
constante de prefixo do segmento de
rede principal a essa chamada de método. E vamos adicionar a constante de prefixo de endereço reg test P2 WP k h como um parâmetro para
essa chamada de método. Agora eu recomendo que você execute
todos os testes do aplicativo. Todos eles devem passar.
63. Endereços de Segwit aninhados: Nesta apresentação, falaremos sobre endereços de segmentos aninhados. Então, o que é uma sequência aninhada? Qual endereço? Os endereços de
segmentos aninhados também são conhecidos como segmento
rap P2, SSH dash p2, WPA e WPA2. E endereços SSH P2. O último nome descreve
melhor o que são e endereço que codifica um script hash de pagamento para
testemunhar a chave pub. Dentro de um script de
hash pago por script. A maioria das carteiras modernas
suporta esses endereços. Sua principal vantagem é que
eles permitem que carteiras mais antigas, que geralmente suportam endereços de hash
pagos por script, mas não oferecem suporte
a endereços de
segmentos nativos , enviem bitcoins para elas. Portanto, os proprietários de endereços de
segmentos aninhados podem se beneficiar de algumas vantagens
das transações da Segway, como taxas de transação mais baratas e recebimento
de fundos de carteiras antigas. Então, por que a necessidade de seguir endereços
nativos? Você pode perguntar. O motivo é que os seguintes endereços
nativos tornam as transações ainda menores do que os endereços de segmentos
aninhados. Os endereços de segmentos aninhados foram
disponibilizados em 2017, após a atualização As regras para gerar endereços de segmentos
aninhados
foram definidas no BIP 141. Escolhemos endereços de
segmentos aninhados
como endereços de
recebimento secundários de nossas carteiras para permitir o recebimento de Bitcoins
de carteiras antigas. Então, para entender os endereços de
segmentos aninhados, vamos primeiro entender os endereços SSH
P2. P2 SSH é um acrônimo
para hash de pagamento por script. endereços SSH P2
são exatamente isso. Eles codificam um hash gerado
a partir de um script Bitcoin. Vamos ver o processo para
gerar um toucado P2 SH. Começamos com um script de resgate
serializado hexadecimal. script I'll Redeem geralmente é um script
Bitcoin com várias assinaturas, mas pode ser qualquer
outro script de Bitcoin. Usamos o algoritmo hash 160 para gerar um hash de script
a partir do script de resgate serializado. Em seguida, combinamos o hash do
script com um prefixo e aplicamos
o
algoritmo de codificação base 58 para produzir
um endereço P2 SH por meio da decodificação da base 58 Podemos obter o hash do
script de volta de um P 2 endereços SSH,
uma sequência aninhada. Qual endereço é simplesmente um script SSH P2 codificado em base 58 era um script de resgate é
um script de segmento. Agora vamos aprender como criar
uma chave pub de script P2 SH. Lembre-se de que uma chave de script
pub faz parte da saída de uma transação e é
a forma como o endereço de recebimento está
presente em uma transação. Então, começando com
um endereço SSH P2, primeiro
baseamos 58 decodificado
para obter um hash de script. Em seguida, construímos um
script que consiste em um opcode OP hash 160, o hash do script e
um opcode igual ao OP. Essa é a chave pub do
script P2 SH. Para enviar fundos para
um endereço SSH P2, você deve colocar esse script na saída
da transação junto
com o valor de qualquer carteira, mas pode enviar bitcoins
para um endereço SSH P2, pode enviar bitcoins
para uma sequência aninhada. Qual endereço? Agora, vamos ver como criar uma entrada de transação de
segue aninhada, começando com a
chave pub válida para um endereço UTXO. Em seguida, aplicamos o algoritmo hash 160 para
obter um hash de chave pub. Combinando o hash
com um prefixo zero, obtemos um script de segmento. Este é o script de resgate, que
será adicionado à entrada da
transação posteriormente. Agora assinará uma transação. Para fazer isso, primeiro produzimos um hash de assinatura a partir de
uma transação interna usando o mesmo algoritmo de
hash de assinatura que usamos para assinar uma
transação seguinte. Em seguida, combinamos o hash da
assinatura com uma chave privada válida para gerar a assinatura usando o ECDSA. Em seguida, mostramos a entrada da
transação de sinal, o índice de saída do ID da transação
e, em seguida, os campos de sequência funcionam da mesma forma que outros tipos de
transação. Adicionamos o script de resgate
no campo ScriptSig e adicionamos a assinatura e a chave pub ao campo de
testemunha. Observe que, diferentemente das entradas
nativas do seg, o ScriptSig não está vazio. Nesse caso. O campo testemunha das entradas de segmentos
aninhados tem os mesmos elementos das entradas de segmentos
nativos. Agora vamos ver como um script de segmento
aninhado é executado durante a
validação da transação pelos nós. A
validação de segmentos aninhados requer a validação de dois scripts
combinados. Dada uma chave pub de
script SSH P2 de algum UTXO e o ScriptSig
correspondente de uma entrada de transação. Ambos os scripts são combinados, formando o primeiro script
combinado. O script de resgate é passado para o script combinado como um
único elemento serializado. Nessa primeira validação,
da esquerda para a direita, cada elemento no
script combinado é avaliado, começando com o script de resgate, que é adicionado
à pilha de execução. Em seguida,
aplique o hash 160 do OP e aplique o hash 160 e
o script de resgate, transformando-o
em um hash de script. Em seguida, o hash do script e o script combinado são adicionados
à pilha de execução. Finalmente, o
opcode OP igual compara os dois scripts Hashes e retorna
true se eles forem iguais. Se não forem iguais, a
transação será considerada inválida. Em seguida, um segundo roteiro é formado pela combinação da testemunha
e do ScriptSig. Desta vez, o script de resgate
no ScriptSig é avaliado em sua totalidade, assim como nas seguintes avaliações de scripts nativos. E, como segue a avaliação
do
script nativo, o dígito zero inicial no ScriptSig aciona uma regra especial que
o
converte no script presente
no script combinado. De agora em diante, o
script combinado é executado da mesma forma que o script combinado das
transações nativas do segmento. A partir do script combinado, as chaves de assinatura e pub são adicionadas a uma pilha de execução. Em seguida, o opcode OPT up duplica a chave pub
na pilha de execução. Up hash 160 hashes, a última chave de pub
adicionada à pilha. Em seguida, a partir do script combinado, o hash da chave pub é
adicionado à pilha. opcode Up equal verify remove os dois últimos elementos
da pilha de execução
e os compara. Se forem iguais, o script
continua sendo executado. Finalmente, o object
sig opcode verifica se a assinatura é válida para a chave pub restante
na pilha. Se for válido, ele retornará
verdadeiro para a pilha de execução. Depois que todos os elementos do script forem adicionados à pilha de
execução, a
entrada da transação será considerada válida. Se o último elemento
adicionado for verdadeiro, esse processo deverá ser repetido para cada entrada da transação, todas as suas entradas devem ser válidas para que
uma transação seja
considerada válida. Apenas como um lembrete visual, vamos analisar de onde
cada elemento da chave pub do
script, ScriptSig e da testemunha vieram durante a construção da transação. O hash do script presente
na chave pub do script
veio da base 58, decodificando o endereço do
UTXO que está sendo gasto. O hash da chave pub e o
ScriptSig vieram do hash 160 de uma chave pública válida. A mesma chave pública está
presente na testemunha. A assinatura da testemunha veio
aplicando o algoritmo ECDSA, que precisa de uma chave privada válida. A chave pública e
a testemunha vieram
da chave pública derivada
da chave privada mencionada. Agora, vamos ver alguns parâmetros importantes para derivar endereços de segmentos
aninhados. Na rede principal do Bitcoin, o prefixo necessário para derivar endereços SSH
P2 é C4. Depois que a base 58 codifica um vestido com esse
prefixo, comece com o dígito três na rede de
teste do Bitcoin e no teste de registro, o prefixo necessário para derivar os endereços SSH
P2 é 05. Após a base 58, os endereços de codificação com esse prefixo começam
com o dígito para. O caminho de derivação
usado para derivar endereços de segmentos
aninhados começa com o
caminho reforçado 49 para carteiras, seguindo as diretrizes do BIP 49.
64. 62 Nested Segwit parte 3 skillshare 2: Neste vídeo, implementaremos o
endereço aninhado que seria em nossa carteira adicionaremos como outra opção para receber Bitcoins em nossa carteira. Vamos primeiro preparar
nosso aplicativo para adicionar alguns testes relacionados
ao novo tipo de endereço. Então, vamos até o Node, obter um novo cliente de endereço. Precisamos tornar nosso
aplicativo capaz de chamar nosso node para gerar endereços SSH
P2. Assim, podemos criar testes para enviar Bitcoin para esses endereços. Então, vamos usar a opção de
alteração da assinatura IDE para adicionar um novo
parâmetro a esse método. O novo parâmetro
será uma string, seu nome será do tipo endereçado e seu valor padrão
será a string back 32. Vamos adicionar uma string vazia
a essa chamada de método. Esse parâmetro é usado se
quisermos adicionar um rótulo
ao nosso novo endereço, já que não precisaremos dele, vamos defini-lo como uma string vazia. E vamos adicionar o
tipo de endereço como seu último parâmetro. Ok, agora podemos pedir ao nosso
nó que crie
endereços P2 SH se o
refator do IDE funcionasse. Agora, as chamadas atuais para
esse método terão a string de volta 32,
pois são menos parâmetros. Agora, vamos fazer o teste de
envio de Bitcoin. Vamos mover esse método
para a classe de teste de GUI. Vamos protegê-lo. Em vez de usar a
palavra-chave super aqui, vamos usar isso. Agora, vamos para a aula de teste de
recebimento de Bitcoin. Vamos copiar todo o
código dessa classe. No pacote de teste da GUI. Vamos criar uma nova classe
de teste chamada receive Bitcoin
nested segue test. E vamos colar o
conteúdo nessa aula. Vamos fazer alguns
ajustes nessa classe. Vamos mudar o nome da classe para
receber o teste Bitcoin
Nested Segue. Agora vamos mudar os nomes dos métodos de
teste. Vamos adicionar um endereço de
segmento aninhado aqui. Vamos fazer o mesmo com todos os outros métodos
de teste indicando em seus nomes que receberão Bitcoins em aninhados
seguindo quais endereços? Agora, vamos ajustar
esse primeiro teste. Vamos ajustar o nome da carteira. Em seguida, vamos modificar o parâmetro de
pesquisa aqui. Assim, a variável de endereço
é atribuída
ao valor do campo em que o segmento aninhado é endereçado. Aqui, em vez de usar o método
address is valid, usaremos o endereço
do
segmento aninhado método válido que criaremos. Vamos corrigir essa formatação de código. Agora, vamos criar
o método aninhado segue qual endereço é válido
na classe de teste de GUI Usaremos o método
válido de endereços como base. Então, vamos duplicá-lo. Vamos corrigir seu nome. Agora. Vamos mudar o tipo de endereço aqui para a constante
segway aninhada. E vamos mudar
o caminho de derivação aqui para começar com 49. Vamos criar essa constante
no tipo de endereço enum. Também vamos criar
a sequência aninhada
para alterar a constante aqui. Aqui, vamos alterar o prefixo do endereço gerado para
o prefixo
do
endereço SH da rede de teste P2. E em vez de usar o gerador de endereços de
segmentos, usará o gerador de endereços de
segmentos aninhados. Vamos adicionar esse campo
a essa classe. Usaremos a
anotação automática com fio para
injetá-la nessa classe. Vamos criar essa classe
no pacote de serviços api dot. Vou implementá-lo mais tarde. De volta à aula de teste recebida de Bitcoin
nested segue. Vamos fazer os mesmos ajustes
nos outros métodos de teste. Agora vamos para a classe de
configuração de endereço. Vamos duplicar esse bean usá-lo como base para criar
a configuração segway aninhada. Vamos alterar esses parâmetros para segmento
aninhado e mudar de sequência
aninhada. Vamos mudar esse método para chamar a configuração de
dois segmentos aninhados. Agora vamos mudar os parâmetros
de configuração do endereço. O primeiro parâmetro será o tipo de endereço do conjunto
aninhado. No segundo argumento, vamos mudar as chaves do mapa para segmento
aninhado e alteração de segmento
aninhado. E os dois caminhos de derivação. Começaremos com 49. Usaremos o gerador de
endereços de segmentos aninhados
como gerador de endereços. Vamos fazer com que ele implemente a interface do gerador de
endereços. Vamos adicionar o método de interface. Agora, vamos definir cada prefixo de endereço do
ambiente. O principal ambiente de rede. Usaremos a constante de prefixo de endereço
SSH P2 da rede principal. Os ambientes de teste net e reg
test. Usaremos a constante de prefixo de endereço
SH da rede de teste P2. Vamos mudar o prefixo ki
estendido para
a constante de prefixo do
segmento aninhado principal. O combinador de endereços será o predicado as nested segue. Vamos criar esse campo
no combinador de endereços. Será semelhante ao predicado do
segmento acima. Mas o combinador
retornará verdadeiro se o endereço começar com
três ou dois. Agora, vamos importá-lo aqui. Vamos usar a constante
SSH P2 aqui. Vamos usar o método de endereço de
segmento aninhado do script
como analisador de scripts. Usará o construtor de entrada de
segmentos aninhados como o construtor
de entrada da transação. Vamos criar essa classe
no pacote de serviços api dot. Vamos adicionar o método de interface. Como a entrada mais o tamanho da saída. Definiremos 180 como o tamanho 23 do
ScriptSig. E, como
signatário da transação,
usará o signatário de
transações aninhado do Segway. Vamos criar essa classe
no pacote de serviços api dot. E vamos adicionar o método
de interface. Nossa
configuração de sequência aninhada está pronta. Agora, precisamos implementar o gerador de
endereços de segmentos aninhados, construtor
de entrada e o signatário
da transação. Vamos começar com o gerador de endereços
seg would aninhado. Primeiro, vamos adicionar um
teste para esse serviço no pacote de teste api dot
services. Isso estenderá a classe de
especificação. Vamos adicionar o seguinte método
de configuração. Vamos adicionar a chamada de método do provedor de
anúncios de segurança. Vamos adicionar o gerador de endereços de
segmentos aninhados como um campo nessa classe. E vamos instanciá-lo aqui. Agora, vamos ao teste do gerador de
endereços do segmento. Vamos copiar esse teste
e colá-lo aqui. Vamos usá-lo como base
para nosso novo teste. Em vez de usar o gerador de endereços de
segmentos, usará o gerador de
endereços aninhado seg would aqui. Vamos mudar o prefixo
para essa constante. Vamos remover esses casos
de teste e colar os válidos
para endereços de segmentos aninhados. Eles estão disponíveis na página
Projeto e Recursos. Voltar ao gerador de
endereços de segmentos aninhados. Eu erroneamente criei essa
classe como uma classe bacana. Vamos usar esse recurso do IDE para
converter essa classe em Java. Vamos remover esse código. Vamos adicionar a
anotação do serviço a essa classe. Aqui, converteremos a chave
secundária estendida em uma chave pública. Em seguida, retornaremos o endereço do segmento
aninhado da chamada do método de
chave pública
compactada
no objeto get que passa
a variável de prefixo para ele. Vamos renomear esse
parâmetro para chave estendida. Agora vamos fazer esse teste. Ótimo, já passou. Agora vamos implementar o construtor de entrada aninhado
segue qual. Vamos adicionar a
anotação do serviço a essa classe. Vamos copiar o método de construção
no construtor de entrada de segmento e usá-lo como base para
nosso novo método de construção. Vamos também colar essas
duas constantes na classe
do construtor de
entrada segue aninhado. Agora vamos adicionar a constante segwayed
aninhada
fictícia do ScriptSig no script ArrayList. Vamos criar essa constante. Será igual à sequência
zero repetida 44 vezes. Aqui, devemos passar essa constante dentro de uma lista de
métodos, na verdade. Agora, vamos implementar o signatário de
transações aninhado do Segway. Vamos adicionar a
anotação do serviço aqui. Vamos copiar o método de assinatura
no signatário de transações do Segway e usá-lo como base para
nosso novo método de assinatura. Aqui, em vez de usar o método de assinatura dos
signatários da ECDSA da transação, usaremos o método sine
nested segue
do signatário
ECDSA da transação P2 SH. Vamos adicionar o script de resgate como o quarto argumento
nesse método. Vamos remover esse último argumento. Vamos criar a variável de
script de resgate. Essa variável será igual à chamada
do método de
script P2 WP k h. Como parâmetro,
passará o hash 160
da chave pública
compactada correspondente
da chave privada recebida. O método sign nested
segue se
encarregará de adicionar
o script de resgate
ao campo de testemunha
e a chave pública e a assinatura ao campo
ScriptSig. Ok, a
configuração de segue aninhada está finalmente pronta. Agora vamos adicionar o novo campo de segmento
aninhado à guia Receber FXML. Primeiro, vamos alterar
o endereço de recebimento e o texto da etiqueta
para o endereço do segmento. Agora, vamos duplicar
todo esse código e alterar o texto desse rótulo para o endereço aninhado que seg would. Vamos também mudar essa identificação ética dois endereços de
recebimento aninhados. Vamos mover esse campo para a
segunda linha do contêiner. Para fazer isso, vamos adicionar o
atributo de índice de linha do painel de grade a esse campo e defini-lo como um. Vamos fazer o mesmo
com esse rótulo. Agora, vamos para o controlador da guia
Receber. Vamos duplicar esse bloco
if nesta
instrução if para verificar
se a alteração no endereço é um endereço de
segmento aninhado. Nesse caso,
definiremos a sequência aninhada conteúdo do endereço de
recebimento
TextField como a alteração no endereço. Então, vamos adicionar esse
campo a essa classe. E vamos adicionar uma
anotação FXML a ela. Vamos também adicionar uma declaração de
devolução aqui. Agora, vamos fazer alguns testes. Vamos executar nosso node Bitcoin. E vamos fazer esse teste. Ótimo, os testes foram aprovados. No próximo vídeo, terminaremos de adicionar
o
suporte de segmentos aninhados à nossa carteira. Veja, sim.
65. 63 Nested Segwit parte 4 skillshare 2: Neste vídeo,
implementaremos a capacidade de enviar Bitcoin
para endereços aninhados
seguindo quais endereços. Começaremos criando
testes para esse recurso. Então, no pacote de teste da GUI, vamos criar a classe de teste send Bitcoin
nested segue. Isso estenderá a classe de teste de GUI. Vamos copiar alguns testes do teste
de envio de Bitcoin. Eles servirão como base
para nossos novos testes. Vamos copiar esse código
e colá-lo aqui. Agora, vamos copiar esse primeiro teste depois colá-lo em
nossa nova classe. Vamos fazer o mesmo
com esse teste. Vamos fazer o mesmo
com o teste do crepúsculo. Agora, vamos ajustar os novos testes. Vamos mudar esse
nome de teste para enviar Bitcoin com entradas de segmentos
aninhados e seguir quais saídas. Vamos mudar o nome da carteira
para o meu teste aos 23 anos. E vamos mudar esse
parâmetro de chamada de dois
segmentos aninhados do método de
pesquisa . Aqui, vamos mudar
esse parâmetro para o segmento de hífen SSH P2. Esse parâmetro
fará com que o nó retorne um endereço de segmento aninhado para nós, para que possamos enviar Bitcoin para ele. Agora, vamos ajustar
os casos de teste. Eu calculei anteriormente as
taxas totais esperadas para esses casos. Eles diferem das taxas de
transação com
as seguintes entradas e saídas nativas porque seus
tamanhos de transação são diferentes. Vamos fazer ajustes semelhantes
para o próximo teste. Agora, vamos criar o construtor de scripts
P2 SH. Ele implementará a interface do script
pub key Builder. Vamos implementar seus métodos. No método match,
retornará essas chamadas aninhadas do método de
teste segue passando o
endereço como seu parâmetro. Retornaremos a chamada do método de
script P2 SH
no método build, pois seu parâmetro passará o
endereço decodificado de base 58 desta forma. Vamos adicionar a
anotação do serviço a essa classe. Agora, vamos fazer o teste da calculadora
do tamanho da transação. Vamos duplicar esse método. Vamos usá-lo como base para
criar um teste para verificar o cálculo do tamanho
das transações usando
entradas e saídas de segmentos aninhados. Então, vamos mudar o
nome do método para refletir isso. Vamos remover esses
casos de teste e colar os casos de teste disponíveis
na página Projeto e Recursos. Agora, no método de configuração, vamos adicionar a configuração aninhada que
seg would na lista de configuração de
endereços. Agora vamos para a calculadora do tamanho da transação no método script pub
key size. Vamos adicionar a seguinte
declaração if para testar se o endereço recebido
é uma sequência aninhada. Qual endereço? Nesse caso, retornará o script pub
key aninhado segwayed constant. Vamos criar essa constante. Seu valor será 23. Agora vamos fazer esse teste. Ótimo, já passou. Agora vamos executar nosso node. E vamos executar o teste send
Bitcoin Nested Segue. Ótimo, os testes foram aprovados. Agora, vamos brincar um pouco com nossa carteira no ambiente
de teste da rede. Para fazer isso, vamos
mudar essa variável no
arquivo bitcoin.com para testar a rede. E vamos reiniciar nosso node. Vamos esperar que ele
seja sincronizado. Dependendo de quão
atualizada sua nota está. Isso pode levar de minutos a horas. Ok, eu pesei a soma de horas. E, finalmente, minha sincronização de avisos. Vamos executar nosso aplicativo. Vamos criar uma carteira. Primeiro. Vamos receber alguns Bitcoins em nosso endereço de segmento aninhado. Para fazer isso, vamos
usar essa torneira. Ok, a transação
apareceu na minha carteira. Vamos esperar um pouco
para que isso confirme. Ok. Agora, a transação
tem uma conformação. Agora, vamos enviar alguns fundos
para o endereço da torneira. Curiosamente, essa transação
não precisou ser alterada e acabamos sem fundos pois gastamos
nossa única contribuição. Vamos verificar a última transação
no explorador de blocos. Vamos esperar um pouco
para que isso confirme. Esperei alguns minutos
e agora tem três
conformações. O Block Explorer
mostra o mesmo. Ótimo. Tudo está
funcionando conforme o esperado. Vamos fazer mais um teste. Vamos receber mais Satoshi primeiro em nosso endereço de segmento depois em nosso endereço de
conjunto aninhado. Ok, agora que ambas as
transações foram confirmadas, vamos enviar alguns fundos para um
endereço de segmento aninhado a partir desta página. Agora, a transação
gerou a mudança. Como a enviamos para um endereço de segmento
aninhado, a alteração gerada
também foi enviada para uma sequência aninhada. Qual endereço? Depois de algum tempo, a transação foi confirmada. Ótimo.
66. 64 habilidade: legado 2: Neste vídeo,
implementaremos em nossa carteira a capacidade de enviar bitcoins
para endereços P2 pKa H, também conhecidos como endereços legados. P2, pk h foi o tipo de roupa mais
usado antes do aumento da popularidade dos endereços do segmento
nos últimos anos. Hoje em dia,
ainda é muito popular. Portanto, é importante que
nossa carteira tenha
a capacidade de enviar bitcoins
para esses endereços. Vamos começar refatorando a forma como nossa carteira cria chaves de script
pub para que
seja mais fácil adicionar
suporte para o envio bitcoins para outros
tipos de endereço no futuro. Para isso, vamos criar o registro de configuração do script
no pacote de domínios. Semelhante à configuração de endereço, essa classe conterá
parâmetros importantes para criar transações com tipos
específicos de chave pub de script. Então, vamos adicionar os
seguintes campos a ele. O construtor da chave pub
do script, o tamanho da chave pub e o predicado do
combinador de endereços, que ajudarão a identificar o
tipo de configuração do script por endereço. Agora vamos criar a classe de configuração do
script no pacote api dot config. Novamente, semelhante à classe
de configuração de endereço. Essa classe será responsável
por instanciar e definir todas as chaves de script pub quais nossa carteira possa enviar Bitcoin. Vamos adicionar a
anotação de configuração a ela. Agora, vamos criar o seguinte método anotado em
Bean. Ele retornará uma configuração de script
e definirá a configuração P2 WP. Seu
construtor de chaves script pub será o construtor de scripts P2 WP k h. O tamanho do script será igual a 22 e seu combinador de endereços
será o segmento Lambda. Vamos ao construtor de scripts P2 WP
k h. Para facilitar
a instanciação, ele removerá o
prefixo de endereço factory do serviço. Construirá a variável de prefixo
analisando o prefixo da variável de endereço
usando o método de prefixo parse. Vamos criar esse método. Primeiro, verificaremos se
o endereço começa com a constante de prefixo de
endereço net P2 WP k h de teste. Nesse caso, retornaremos
essa constante. Em seguida, faremos a
mesma declaração, mas usando a
constante de prefixo de endereço reg test P2 WP k-th. Por fim, retornaremos
a constante principal do prefixo de endereço net P2 WP k h se o código for executado
até esse ponto. Agora vamos criar o bean
para a configuração do script P2 SH. Ele usará o construtor de scripts P2
SH. Seu tamanho será 23 e seu combinador de endereços será
o segmento aninhado lambda. Agora vamos criar a configuração do
script para encontrar sua classe no pacote de serviços api
dot. Como o próprio nome sugere, esse serviço será
responsável por encontrar a
configuração de script apropriada para outros serviços. Vamos adicionar a
anotação do serviço a ela. Agora, vamos injetar a lista de configurações de script nessa classe. Spring Boot magic injetará todos os beans de configuração de script
nessa lista após o início do
aplicativo. Agora, vamos criar o método
find by address. Ele retornará uma configuração de script e tomará um endereço
como parâmetro, retornará a seguinte transformação de
fluxo aqui filtrará o script
can think stream usando o combinador
de endereços de cada script configuração. Usaremos para encontrar o
primeiro método
para filtrar a primeira
configuração do script. Se não encontrarmos nenhum, usaremos o
método de lançamento de URLs para gerar uma exceção. Agora, vamos até o serviço de
criadores de transações e
usaremos o localizador de configuração de scripts
para refatorar essa classe. Primeiro, vamos remover a lista de construtores de chaves do
script pub dessa classe, pois não a
usaremos. E vamos injetar o script
que pode pensar em Finder nessa classe. Agora, no método de saída de compilação, vamos remover esse código. Criará essa variável de script usando o localizador de configuração do script, find by address method. Em seguida, chamaremos
o script pub key builder de método build
no resultado. Agora, vamos refatorar a calculadora do tamanho da
transação. Vamos injetar o script config
Finder nessa classe. Agora, vamos remover o código no método script pub key size.
Em seu lugar, usaremos o
script config Finder para encontrar uma configuração de script por endereço e retornar o tamanho da chave pub do script. Vamos remover essas importações e constantes, pois
não as usaremos. Agora, vamos para a interface do script
pub key Builder. Vamos remover o método
match dele
e de todas as suas
implementações, já que não o usaremos mais. A refatoração está concluída. Agora, antes de adicionar o
P2 pKa H Script Config vamos criar o teste send Bitcoin legacy
no pacote de teste da GUI. Isso estenderá a classe de teste de GUI. Usaremos essa classe para
verificar se nossa carteira está enviando
corretamente uma transação
para um endereço legado. Vamos copiar o
código a seguir do
teste de envio de Bitcoin e colá-lo aqui. Vamos usá-lo como base
para nosso novo teste. Vamos mudar seu nome para se enviar Bitcoin com entradas de
segmento, saída
legada e a
configuração mudaria. Observe que, embora
possamos
enviar fundos para um endereço antigo, não
poderemos
recebê-los um endereço antigo
pertencente à nossa carteira. Portanto, usaremos
os seguintes endereços nativos para receber alterações
nessas transações. E esse nome de teste
reflete isso. Vamos mudar o nome da carteira
para o meu teste aos 26 anos. Vamos mudar esse parâmetro
para legado para que possamos criar um endereço legado qual
usaremos para enviar bitcoins. Também vamos alterar
os casos de teste usando os seguintes valores
calculados anteriormente. Esses valores diferem de outras transações
porque as chaves de pub de script P2, pKa e
H são um
pouco maiores do que as seguintes chaves de pub de script
nativo, que afetam o
tamanho da transação e o phi. Agora vamos para a classe de
configuração do script. Vamos adicionar a
palavra-chave pública aqui. Vamos criar o bean de configuração P2
pKa H pois seu construtor de
chaves de script pub
definirá um novo construtor de
scripts p2 pk H, que será criado posteriormente. O tamanho da chave do script pub
será 25 e está resolvido. Matcher serão esses
Lambda legados que criaremos mais tarde. Vamos criar o construtor de scripts
P2 pKa H no pacote de serviços api dot. Vamos implementar o método
de interface. No método build,
retornará a chamada do método de script
P para P k h, pois seu parâmetro passará
o
endereço decodificado hexadecimal base 58 usando a decodificação base 58
com o método de soma de verificação para hexadecimal. Agora, vamos para a classe de métrica de
endereço. Vamos duplicar esse campo. Vamos usá-lo como base
para esses lambda legados. Aqui, alteraremos esses
parâmetros para um, M e N. Um é o prefixo do legado
que aparece na rede principal. M e n são os prefixos válidos para os outros
ambientes. Vamos importar esses lambda
antigos aqui. Ok, agora nossa carteira pode enviar Bitcoin para endereços
antigos. Agora, vamos ajustar alguns testes. Vamos fazer o teste da calculadora
do tamanho da transação. No método de configuração, vamos instanciar o localizador de configuração do
script. Vamos passar uma lista de configurações de
script para ele. Receberá as configurações do
script
da classe de configuração do script. Então, vamos instanciá-lo aqui. Agora, vamos adicionar o
script em forma de figs aqui. Agora, vamos duplicar esse teste. Vamos renomeá-lo para
calcular o tamanho da transação para P2 WP k-th entradas de transação e p2 pk cada saída de
transação. Esse nome de teste descreve
bem o cenário que será testado. Vamos remover esses casos de teste. Colará esses
casos de teste aqui, que estão disponíveis na página Projeto
e Recursos. Vamos corrigir a formatação
desses casos de teste. Vamos fazer esse teste. Grau. Os testes foram aprovados. Agora, vamos corrigir o teste do serviço de
criadores de transações. Vamos copiar esse código
e colá-lo aqui. Vamos remover a fábrica de prefixos de
endereço e os criadores de chaves do script pub. E vamos corrigir a
instanciação do serviço aqui. Vamos fazer esse teste. Ótimo, já passou. Agora, vamos corrigir o teste do seletor de moedas de sorteio único
aleatório Será necessário esse código novamente. Então, vamos copiá-lo
e colá-lo aqui. Certifique-se de que o seletor de moedas de sorteio
aleatório único esteja instanciado corretamente. No meu caso, o ID
já fez isso. Vamos fazer esse teste. Grau. O teste foi aprovado. Agora, vamos executar nosso node. Antes disso, verifique se o arquivo
bitcoin.com tem o ambiente de teste
reg configurado. Agora vamos fazer o teste de envio de
Bitcoin Legacy. Ótimo, o teste foi aprovado.
67. 65 Salvar skillshare da carteira 2: Nos vídeos anteriores, implementamos um aplicativo totalmente funcional
que você
já pode usar para criar carteiras e enviar e receber Bitcoins. Mas se fecharmos o aplicativo, perderemos todas as informações
sobre as carteiras que
criamos neste
vídeo e, no próximo, começaremos a implementar
a capacidade salvar e carregar carteiras
em nosso aplicativo. Para armazenar os dados do nosso aplicativo, usaremos o banco de dados H SQL. Sql é um banco de dados SQL
implementado em Java. Escolhemos o H SQL
pelos seguintes motivos. Primeiro, é um banco de dados
leve. Em segundo lugar, é compatível
e fácil de usar com a biblioteca Spring Boot
Data JPA. Finalmente, ele pode ser facilmente criptografado, como
mostraremos neste vídeo. Vamos acessar o arquivo XML do poem
dot para adicionar as dependências do Spring Boot Data JPA e
do H SQL DB. Clique nesse botão para
carregar as novas dependências. Agora vamos para o arquivo de propriedades de
pontos do aplicativo. Definiremos algumas configurações
necessárias para o banco de dados. Essa configuração
determina que, a cada modificação que fizermos em
nossas classes de entidades, atualizaremos nosso
banco de dados adequadamente. No Spring Boot, classes
anotadas por entidades definiram estruturas de tabelas,
como veremos em breve. Vamos duplicar essa linha para usar como base para as
outras configurações. Temos que definir a classe do driver chamada config para a
seguinte classe. O nome de usuário e a senha. Você pode nos definir
o que quiser. Como estou usando
apenas para testes, definirei esses campos
como Y0 W por enquanto. Mas lembre-se de alterar
esses valores para cadeias de caracteres
mais seguras antes de usar essa carteira
na rede principal. Agora, vamos definir a
URL do banco de dados. Como usaremos um banco de dados baseado em
arquivos, teremos que definir essa configuração JDBC cólon H SQL DB
dois pontos,
o caminho em que queremos que os arquivos do
banco de dados residam. No meu caso, o caminho
começaremos com a pasta BYOD W
localizada no assento dr. Raiz. Dentro dessa pasta,
quero criar pastas
específicas para cada ambiente de rede
Bitcoin. Para fazer isso, vou me referir
à
variável de ambiente Bitcoin neste arquivo de propriedades de
pontos do aplicativo, colocando-a entre
colchetes e após um sinal de $1 como este. Por fim, usarei a subpasta
de dados dentro
dessa pasta e nomearei os arquivos
do banco de dados como meu banco de dados. E terminamos a
linha com ponto e vírgula. Agora, dentro do pacote BYOD W, vamos criar o pacote do
banco de dados. Dentro desse pacote, vamos
criar o pacote de entidades. E vamos criar a classe de
entidade da carteira dentro dela. Nesta classe, modelaremos os registros na tabela do banco de dados da
carteira. Para fazer isso, vamos adicionar a anotação da
entidade a ela. E a anotação da tabela com seu parâmetro de nome
igual ao Wallet. Agora, vamos adicionar alguns
campos a essa classe. Em cada campo desta classe, modelaremos uma coluna
da tabela da carteira. Nosso objetivo é salvar apenas os campos
necessários para obter os mesmos
dados da carteira após carregá-la. Então, vamos adicionar o campo ID. Adicionará esse campo para seguir
a boa prática
de sempre adicionar um identificador de incremento automático a uma tabela de banco de dados relacional. Para fazer isso, vamos adicionar duas
anotações a esse campo. A primeira é a anotação de ID, a segunda é a anotação do valor
gerado com o seguinte parâmetro. Vamos também adicionar uma anotação de
coluna com ID como parâmetro de nome. A anotação da coluna
determinará o
nome correspondente da coluna vinculada a esse campo
na tabela da carteira. Seguiremos o
estilo de maiúsculas para os parâmetros do nome da coluna que todas as letras ou minúsculas e sublinhados
separam as palavras. Agora vamos criar o campo do nome. Vamos também adicionar a
anotação da coluna a esse campo. Além do parâmetro name, vamos também adicionar o parâmetro exclusivo é igual verdadeiro e o parâmetro anulável
igual a falso. Esses parâmetros adicionarão as restrições exclusivas e não
anuláveis na tabela dessa coluna. Portanto, o aplicativo
gerará um erro se você tentar criar um registro sem um nome na tabela
da carteira. Vamos também criar o campo de semente
mnemônico com a seguinte anotação. O parâmetro length limitará o tamanho máximo desse
campo a 500 caracteres. Vamos também adicionar o parâmetro anulável
igual a falso a essa anotação. Agora, vamos adicionar o
campo
de número de endereços gerados com a anotação da coluna seguindo o estilo snake case. O último campo
será criado em. Vamos adicionar a
anotação da data criada para indicar que esse campo usará
a data atual para registrar seus valores. Agora, vamos criar
alguns construtores. Primeiro, um construtor vazio
, necessário
para o Spring Boot instanciar essa
classe corretamente. Em seguida, vamos criar
um construtor com todos os
campos dessa classe, exceto o id. Vamos criar getters
para os mesmos campos. Nossa entidade de carteira está pronta. Agora, dentro do pacote do banco de dados, vamos criar o pacote de
repositórios. E vamos criar a interface do
repositório de carteiras dentro dela. A interface do repositório da carteira será
responsável por interagir com o banco de dados
recuperando e salvando dados
na tabela da carteira. Para conseguir isso, ele estenderá a interface do repositório JPA adicionará parâmetros de tipo
a essa extensão. O primeiro teste será a entidade que
gerenciaremos esse repositório. Nesse caso, será
a classe de entidade da carteira. O segundo deve ser o tipo de
ID da entidade. Portanto,
será a classe longa. Com essa interface simples, já
temos acesso a operações
comuns de banco de dados
para a tabela da carteira, como inserir registros
e localizá-los por ID. Tudo isso é
trazido automaticamente para você
pela biblioteca Spring Boot
Data JPA. Agora vamos criar o pacote de
serviços
no pacote do banco de dados. Dentro dela, vamos criar a classe de serviço de carteira
economizada. Essa classe será
responsável por salvar a carteira
após sua criação. Vamos adicionar a
anotação do serviço a ela. Vamos injetar o
repositório da carteira nessa classe. Vamos fazer o mesmo com o campo de número inicial de endereços
gerados. Agora, vamos criar o método
de salvar carteira. Ele usará um
objeto de carteira como parâmetro. Para implementar.
Primeiro, ele instanciará um novo objeto de entidade de carteira com os seguintes parâmetros
da carteira. Em seguida, chamaremos o método de
salvamento do repositório da carteira, passando a
entidade da carteira como seu parâmetro. *****. Eu misturei a ordem
dos parâmetros aqui. Vamos consertar isso. E vamos adicionar a anotação do
qualificador para a injeção correta
desse campo aqui. É isso mesmo. Com esse código simples, conseguimos salvar facilmente as informações
da
carteira no banco de dados SQL. Agora vamos criar o pacote de
ouvintes
no pacote do banco de dados. E vamos criar uma classe
chamada save wallet listener. Dentro dela. Essa aula servirá como ouvinte para
o evento de carteira criado. Para que, após o aplicativo
criar uma carteira, ele seja responsável
por chamar o serviço de salvar carteira
para salvar a carteira. Então, vamos adicionar a
anotação do componente a ela. Ele implementará o ouvinte do
aplicativo com o evento de carteira criado
como parâmetro de tipo. Vamos implementar seu método. Aqui, chamaremos o método de
salvar carteira, passando a carteira de eventos
como seu parâmetro. Vamos criar esse método. Usaremos o serviço de economia de
carteira aqui. Então, vamos
injetá-lo nessa classe. Em seguida, chamaremos o método de salvar
carteira aqui, passando a carteira
como parâmetro. Agora, se tudo
funcionar corretamente, nosso aplicativo
salvará carteiras no banco de dados após
sua criação. Então, vamos executar nosso
aplicativo para testar esse recurso e testá-lo primeiro
no ambiente de teste de registro. Certifique-se de que a opção VM na configuração de execução
do aplicativo BYOD W esteja vazia. Para esse teste específico, não
precisaremos executar
nosso node. Vamos executá-lo. Vamos criar uma carteira. Ok, se tudo
funcionou corretamente, a carteira foi salva. Vamos fechar nosso aplicativo. Agora. Vamos ver se os arquivos do
banco de dados foram criados na pasta especificada. Ótimo, o aplicativo criou a pasta reg test e os arquivos de
banco de dados esperados nela. Vamos abri-los.
Arquivo de log de pontos Idb. Aqui podemos ver todas as
operações de banco de dados de nossos
aplicativos em SQL
escritas em texto simples. Podemos ver que ele tem um comando de inserção
contendo dados da carteira, incluindo sua semente mnemônica. Bom. Mas isso não foi salvo,
pois qualquer pessoa que obtenha esse arquivo pode conhecer todas as nossas
carteiras, sementes mnemônicas. Vamos corrigir isso em breve
criptografando esses arquivos. Por enquanto, vamos ver os dados salvos da carteira em
um formato mais legível. Para fazer isso, vamos acessar
este site para baixar o banco de dados H SQL. Clique no link de download para baixar a versão mais recente. Depois de baixá-lo, extraia
seu conteúdo em uma pasta. Vamos abrir a pasta bin localizada dentro da pasta
extraída. Agora vamos executar o swing do
gerenciador de execução em um ponto nesse arquivo. Vamos acessar as propriedades do
ponto do aplicativo em nosso aplicativo para copiar
a URL do banco de dados. Agora, vamos colar seu
conteúdo nesse campo. E vamos substituir essa
variável pelo teste de registro. Vamos adicionar aqui o mesmo nome de usuário e senha que definimos no arquivo de
propriedades do ponto do
nosso aplicativo. Vamos clicar. Ok, ótimo. Conseguimos nos conectar
ao nosso banco de dados. Agora, clique com o botão direito na pasta
pública da carteira de pontos aqui e clique na
instrução SQL select. Vamos executar esse comando
clicando nesse botão. Ótimo. Aqui estão os dados da nossa carteira
em formato de tabela. Podemos ver que nosso aplicativo salvou
com sucesso
os dados da carteira. Vamos fechar esse aplicativo. Agora, como eu disse antes, é importante
criptografarmos nossos arquivos de banco de dados. Para fazer isso, vamos adicionar
o seguinte sufixo ao URL
do banco de dados no arquivo de propriedades do ponto do
aplicativo. Aqui, definiremos uma
chave criptográfica e um tipo de criptografia. O tipo de berço será AES, que é uma
criptografia simétrica que o aplicativo
usará para criptografar dados antes de salvá-los
no banco de
dados e descriptografá-los ao recuperá-los. A chave criptográfica será a chave necessária para ambas as operações. Vamos usar o gerenciador de banco de dados SQL novamente para gerar
uma chave de criptografia válida. Clique no botão OK aqui. Vamos executar o
seguinte comando SQL. Vamos copiar a
chave gerada em um editor de texto depois copiá-la novamente para o valor da chave criptografada nas propriedades de ponto do
aplicativo. Agora vamos adicionar a mesma configuração
de banco de dados aos outros
arquivos de propriedades no projeto. Vamos remover a pasta
reg test, criar uma distorção
nos arquivos do banco de dados. E vamos executar nosso
aplicativo novamente. Vamos criar uma nova carteira. Agora, vamos abrir a pasta
reg test e o arquivo de log
my db dot gerado. Seu conteúdo é totalmente
ininteligível agora, que significa que foi criptografado
com sucesso. Vamos copiar o URL do
banco de dados novamente, incluindo o
sufixo de criptografia, e
abri-lo usando o gerenciador de banco de dados H SQL. Ótimo, podemos ver os dados
salvos da carteira novamente usando o novo URL
neste aplicativo.
68. 66 Carregar carteira parte 1 skillshare 2: Neste vídeo, começaremos a implementar
a capacidade de
carregar carteiras salvas anteriormente em nosso aplicativo. Primeiro, vamos fazer algumas refatorações
necessárias. Vamos ao serviço de criação de
carteira. Queremos poder
criar carteiras com datas e números
diferentes
de endereços gerados. Então, vamos adicioná-los como
parâmetros nesse método. Agora, vamos substituir essa
instanciação de data pela variável
created at. E vamos adicionar a
variável número
de endereços gerados como o último
parâmetro desse método. Agora, vamos até o controlador de diálogo de criação de
carteira para adicionar esses parâmetros à chamada
do método create. Vamos injetar o número
inicial de endereços
gerados nessa classe. Agora, vamos alterar a
assinatura do
método de endereços ADA para incluir
o último parâmetro que
acabamos de adicionar a essa chamada. No serviço de endereço ADD, vamos adicionar o número
de
variáveis de endereços gerados à
chamada e assinatura desse método. Vamos também passá-lo como
o último parâmetro do método de geração
do
gerador sequencial de endereços. Vamos alterar a assinatura
desse método para incluir
esse parâmetro. Agora, vamos excluir o
campo do número
inicial de endereços
gerados dessa classe. E vamos substituí-la aqui
pela variável número de
endereços gerados. Agora, vamos para o serviço de
atualização de
endereços da carteira atual e definirá o campo de número inicial de endereços
gerados como o último parâmetro
dessa chamada de método. Agora vamos criar a classe de teste da carteira de
carga no pacote de teste da GUI. Isso estenderá a classe de teste de GUI. Vamos fazer o
teste de envio de Bitcoin para copiar essa parte do código, pois precisaremos dela
para nosso novo teste. E vamos colá-lo aqui. Agora, vamos para a aula de teste de
recebimento de Bitcoin. Vamos copiar esse primeiro teste e usá-lo como base
para nosso novo teste. Vamos renomeá-lo para deve carregar carteira e receber Bitcoin. Vamos formatar esse teste. Vamos adicionar um determinado
bloco a esse teste. Aqui, vamos definir um
nome de carteira e variáveis de senha. Vamos também definir uma variável de semente
mnemônica. Usaremos o método de
criação do serviço de sementes
mnemônico para gerá-lo. Vamos injetar o serviço de semente
mnemônica na classe de teste de GUI. Agora, vamos chamar o método de criação de
carteira aqui, passando o
nome da carteira, a senha e a semente mnemônica
como seus parâmetros. Vamos criar esse método
na classe de teste da GUI. Aqui, criaremos uma carteira usando o serviço de criação de carteira. Então, vamos
injetá-lo nessa classe. Agora, vamos chamar
o método create passando esses parâmetros para ele. Agora, usaremos o serviço de
economia de carteira. Então, vamos
injetá-lo nessa classe. E vamos chamá-lo de método de
salvar carteira, passando a carteira
como parâmetro. Finalmente, vamos devolver
a carteira aqui. De volta ao teste da carteira de carga. Agora que criamos e salvamos uma carteira, tentaremos carregá-la. Então, vamos remover esse código. Vamos chamar o método load
wallet, passando o
nome da carteira como parâmetro. Vamos criar esse método
na classe de teste da GUI. Ele também usará um parâmetro de senha
opcional com uma string vazia
como valor padrão. Primeiro, tentaremos clicar em um componente com o carregamento dos textos. Esse componente será
o botão do menu de carregamento, que estará
ao lado do botão Novo
no menu na parte superior
da janela principal. Em seguida, moveremos o mouse para um componente com
a carteira de texto. Depois disso,
esperamos que apareça um submenu contendo todos os nomes das
carteiras carregadas. Em seguida, clicaremos naquele com o texto igual à
carteira chamada variável. Em seguida, esperaremos que
uma janela de diálogo
apareça com um
campo de entrada de senha e um botão OK. Então, clicaremos
nesse campo que tem o ID de ética da
senha da carteira de carregamento. Agora vamos digitar a
senha nesse campo. Em seguida, clicaremos
no botão OK. Por fim, vamos chamar
o método de hibernação para esperar o carregamento da carteira. Ok, o resto do
teste será como os testes da carteira receptora
que usamos como base para este teste enviarão Bitcoin
para a carteira carregada e esperarão que os endereços e as tabelas de
transações sejam preenchido
com valores apropriados. Agora, vamos ao arquivo FXML de pontos do
playground para criar o menu de carregamento. Vamos adicionar um controle de menu
à barra de menu. Vamos mudar seu texto para carregar. Agora, vamos adicionar um
controle de menu ao menu de carregamento. Vamos excluir esse item de menu
que foi adicionado automaticamente. Vamos mudar os textos desse
menu para carteira. E vamos excluir esse item do menu. Agora, na visualização do editor de texto, vamos adicionar um ID Fx
a essa tag de menu. Vamos configurá-lo para carregar o menu FXML. Vamos adicioná-lo ao controlador da janela
principal. Adicionará uma anotação FXML e a mudará para
um campo privado. Agora, vamos adicionar a classe do menu de
carregamento no pacote observables. Essa classe será responsável por gerenciar os itens de menu que serão adicionados
para cada carteira criarmos em nosso aplicativo. Vamos adicionar uma
anotação de componente a ela. Vamos criar o campo de
itens do menu aqui. Será um conjunto observável de entidades
de carteira do tipo carteira. Vamos instanciá-lo usando um
novo wrapper de conjunto observável, passando um novo
LinkedHashSet para ele. Agora vamos criar o bom método de itens de
menu observáveis aqui. Ele retornará os itens do menu. Agora vamos criar o ouvinte do menu de
carregamento no pacote GUI dot
listeners. Esse ouvinte será
acionado pelo
evento gooey started publicado após
o início do aplicativo. Vamos usá-lo para carregar
todas as carteiras salvas
no banco de dados e
adicioná-las ao menu de carregamento. Vamos adicionar uma
anotação de componente a ela. Ele implementará a classe de ouvinte do
aplicativo com o evento iniciado pela GUI
como seu parâmetro de tipo. Vamos implementar seu método. Usaremos o
repositório da carteira aqui. Então, vamos
injetá-lo nessa classe. Vamos também injetar o
menu de carregamento nessa classe. Em seguida, chamaremos o método final para carregar todas as carteiras
do banco de dados. Para cada carteira, chamará
o método de adição de carteira. Vamos criar esse método encapsulado na chamada de
execução posterior da plataforma, vamos chamar o método de adição do
menu de carregamento, passando a
entidade da carteira como seu parâmetro. Vamos criar esse método
e a classe do menu de carregamento. Aqui, basta chamar
os itens do menu adicionar método passando a
entidade da carteira como seu parâmetro. Agora vamos copiar essa linha. Vamos para a classe de serviço Save
wallet. Vamos colá-lo aqui. Vamos injetar o
menu de carregamento nessa classe. Com esse código, faremos com que nossa carteira recém-salva seja
adicionada ao menu de carregamento. Agora, vamos para o
playground dot FXML. Vamos copiar essas linhas e colá-las na janela
principal FXML. Agora, vamos para o controlador da janela
principal. No
método inicializado, vinculará todas as alterações no menu de carregamento
observáveis ao menu de carregamento. componente Fxml precisará
do menu de carregamento aqui. Então, vamos
injetá-lo nessa classe. Agora, vamos chamar o método get observable menu
items nele. E vamos chamar o método ad
listener
no resultado como seu parâmetro. Vamos passar pelo seguinte Lambda. O corpo do Lambda
adicionará o elemento e o armazenará na
variável da carteira dessa forma. Em seguida, usaremos uma
instrução if para verificar se o menu contém a
carteira dessa forma. Vamos criar esse método. O uso da
transformação de fluxo a seguir verificará se o menu de carregamento FXML contém um item de menu com o
mesmo nome da variável de entidade da carteira. Aqui, se o menu de carregamento FXML
não contiver a carteira, continuaremos a adicioná-la a ela. Instanciará um objeto de item de
menu passando como parâmetro,
o nome da carteira. Em seguida, adicionaremos o item de menu
ao menu de carregamento FXML, assim. Agora, vamos para a classe de teste de
GUI
no método start
antes que cada teste limpe o banco de dados
para que carteiras nomes duplicados de
madeira
não persistam. Dessa forma, evitamos falhas no
teste devido
à restrição de nome exclusivo
na tabela da carteira. Precisaremos do
repositório de carteiras aqui. Então, vamos
injetá-lo nessa classe. Em seguida, chamaremos o método
delete all nele. Agora, vamos executar nosso node. E vamos fazer o teste da carteira de
carga. Ok, o teste correu até a parte
esperada e falhou. Pudemos ver que nosso menu de
carregamento foi criado e preenchido com o nome da carteira
criada. Bom. No próximo vídeo, continuaremos
implementando esse recurso, C. Sim.
69. 67 Carregar carteira parte 2 skillshare 2: Neste vídeo,
continuaremos implementando o recurso de
carregamento de carteira. Para começar, criaremos uma janela de diálogo que
aparecerá depois de
clicarmos no nome
da carteira que queremos carregar e no menu de carregamento como
base para criá-la Usaremos a caixa de diálogo de criação de
carteira. Então, vamos para a caixa de diálogo de criação de
carteira FXML. Vamos copiar todo esse conteúdo. Vamos criar o arquivo
FXML do diálogo de
carregamento da carteira no pacote FXML. E vamos pagar o conteúdo
copiado aqui. Vamos mudar o texto do cabeçalho do
diálogo para a seguinte frase. Vamos mudar o atributo pref
height para 300. Vamos também remover essas linhas. Vamos até o Scene Builder
para ver como está. Vamos mudar o
texto desse rótulo para a senha da carteira. Na visualização do editor de texto, vamos alterar esse ID fx
para carregar a senha da carteira. E vamos mudar o controlador
FX da etiqueta de
problemas de diálogo para carregar o controlador de diálogo da
carteira. Vamos criar esse controlador. Vamos adicionar a
anotação do componente a ela. E vamos adicionar todos esses
campos FXML ao controlador. Agora, vamos até o controlador da janela
principal aqui antes de adicionar o
item de menu ao menu de carregamento FXML, chamaremos o método set on
action nele, passando o seguinte
Lambda para ele. Isso fará com que o
aplicativo execute o método de
diálogo de carregamento aberto da carteira, passando a carteira como parâmetro após
clicarmos nesse item do menu. Então, vamos criar esse método. Vamos copiar o conteúdo
do método de
diálogo de criação aberta de carteira e usá-lo como base
para nosso novo método. Vamos definir o
título do diálogo para carregar a carteira. Vamos mudar o
primeiro parâmetro de instanciação
do carregador FXML para o campo de diálogo da
carteira de carregamento. Vamos injetar esse
campo nessa classe. Vamos adicionar essa
anotação de valor aqui e alterar seu parâmetro para
o arquivo FXML da carteira de carregamento. Agora, temos que
passar a carteira para
o controlador de
diálogo de carga da carteira. Para fazer isso, vamos primeiro pegar o controlador
do carregador FXML. Então, vamos chamar esse método de
carteira definida nele, passando a carteira para ele. Vamos criar esse método. Aqui. Simplesmente definiremos o campo da entidade da
carteira como a variável da carteira. Vamos criar esse campo. Agora, vamos criar o método
inicializado que será executado
depois que a caixa de diálogo aparecer. Vamos copiar esse código e o
controlador de diálogo de criação de carteira e colar aqui. Isso definirá a
ação de fechar a janela de diálogo com
o botão de cancelamento. Também vamos copiar e colar esse código no novo método
inicializado. Isso definirá a ação do botão
OK. Mas, em vez de chamar
o método create wallet, ele chamará o
método load wallet. Vamos criá-lo. Primeiro. Recuperaremos uma nova entidade de
carteira do banco de dados e
a definiremos como
o campo da entidade da carteira. Para fazer isso, precisaremos
do repositório da carteira. Então, vamos
injetá-lo nessa classe. Em seguida, chamaremos o método
find by name nele, passando o nome da
entidade da carteira para ele. Vamos criar esse método. O método será
exatamente assim. Spring Boot Data JPA magic traduzirá automaticamente
esse nome de método em uma consulta SQL e recuperará
a entidade da carteira com o nome passado como
parâmetro do banco de dados. Agora, criaremos
um objeto de carteira. Para fazer isso, precisaremos
criar um serviço de carteira. Então, vamos
injetá-lo nessa classe. Chamaremos o método create passando os seguintes
parâmetros. Todos esses parâmetros, exceto
a senha da carteira, serão retirados
da entidade da carteira encontrada no banco de dados. A senha será retirada do campo de senha
da caixa de diálogo. Vamos injetar o
objeto de contexto nessa classe. Agora, usar o
contexto publicará um evento de carteira carregada passando isso e a
carteira criada para ela. Por fim, chamaremos
o método hide para fechar a
janela de diálogo dessa forma. Vamos criar a classe de eventos da
carteira carregada. Passará o parâmetro do controlador de
diálogo da carteira de carga para o superconstrutor. E definiremos o campo da
carteira com o
parâmetro do construtor da carteira. Vamos criar um getter
para o campo da carteira. Agora, vamos fazer uma refatoração no ouvinte de
importação de carteira criado. Queremos fazer com que ele escute eventos
de carteiras carregadas. Mas do jeito que está agora, ele só pode ouvir
o evento da carteira criada. Para mudar isso, vamos excluir essa instrução de implementação e
essa anotação Override. Vamos alterar o nome desse
método para
importar a carteira e seu
parâmetro para um objeto de carteira. Vamos mudar o
parâmetro do método
de importação da carteira para Wallet. Agora, vamos criar um método anotado com a anotação do
ouvinte do evento. Ele será chamado no evento de carteira
criada e receberá um evento de carteira
criado como parâmetro. Aqui, chamaremos o método de
importação da carteira, passando a carteira de eventos
como parâmetro. Essa refatoração continuará fazendo com que as coisas funcionem como antes. Mas agora, se quisermos
ouvir outro evento, podemos simplesmente criar outro método anotado pelo ouvinte passando o evento
que queremos como parâmetro. Isso é exatamente o que
faremos agora O evento load wallet também
chamará o método de importação de
carteira aqui, passando a carteira de eventos
como seu parâmetro. Isso fará com que o
nó Bitcoin importe a carteira, assim como quando
criamos uma nova carteira. Agora, vamos criar a classe de ouvinte de
carteira carregada no pacote de ouvintes. Vamos adicionar a
anotação do componente a ela. Vamos criar um método anotado pelo
ouvinte de eventos chamado evento de carteira descarregada. Será usado um
evento de carteira carregada como parâmetro. Aqui, chamaremos o método de
carregamento da carteira passando a carteira de eventos
como seu parâmetro. Vamos criar esse método. Aqui. Precisaremos do serviço de atualização
atual da carteira. Então, vamos
injetá-lo nessa classe. E chamaremos o método de
atualização nele. Passar a carteira como parâmetro também precisará
do serviço utxOS de atualização. Então, vamos
injetá-lo nessa classe. Em seguida, chamaremos o método de
atualização nele, passando os endereços
e o nome da carteira como parâmetros. Com essas duas linhas de código, esperamos que a carteira
atual seja alterada para a
carteira carregada e que seus endereços, transações e saldos
sejam atualizados adequadamente. Agora vamos corrigir alguns testes. Analisamos os vídeos anteriores no teste do
gerador sequencial de endereços. Vamos excluir esse
primeiro parâmetro na instanciação
do
gerador sequencial de endereços. E vamos definir 20 como o último
parâmetro desse método. Vamos fazer esse teste. Ótimo, está funcionando conforme o esperado. Vamos fazer o mesmo com o teste do serviço de
criação de carteira. Ok, está funcionando. Agora. Vamos executar nosso node. Vamos limpar e
compilar o projeto usando esse recurso do IDE Maven. E vamos fazer o teste da carteira de
carga. Falhou. O problema está no controlador da janela
principal. Aqui, temos que chamar o método get
controller do carregador FXML em vez do método load. Vamos fazer o teste novamente. Ótimo, já passou.
70. 68 Carregar carteira parte 3 skillshare 2: Neste vídeo,
adicionaremos mais testes e faremos algumas otimizações no recurso de carregamento
da carteira. Uma das características que nossa carteira terá é a negação
plausível. negação plausível
nesse contexto é um recurso de segurança
que permitirá que você oculte os endereços de sua
carteira
digitando uma senha diferente
para carregar sua carteira. Isso significa que nossa carteira não
terá senhas erradas. Cada senha inserida dará acesso a um
conjunto diferente de endereços, mas observar terceiros
não conseguirá saber se os endereços
da carteira carregada contêm a maior parte de seus fundos. Vamos criar um teste
para esse cenário. Vamos duplicar esse teste e usá-lo como base
para nosso novo teste. Vamos renomeá-lo para
deve carregar a carteira com uma senha diferente
e receber Bitcoin. Vamos reformatá-lo. Vamos aumentar a
carteira chamada número. Agora, vamos definir essa variável de senha
diferente e passá-la para o método
load wallet como seu segundo argumento. Vamos também passá-lo como o último parâmetro do método válido do
endereço. Vamos definir o parâmetro de
senha como um parâmetro opcional
para esse método, definindo seu valor
padrão como uma string vazia. Vamos substituir a string
vazia e o método das duas chaves mestras
pela variável de senha. Vamos executar nosso node. Vamos comentar esse método
e executar nosso novo teste. Ótimo, já passou. Esse teste mostra que nosso aplicativo já
suporta qualquer senha para carregar uma carteira e
que cada senha gerará um
conjunto separado de endereços. Vamos descomentar esse teste. Considerando nossa maneira de ver
uma carteira como tendo vários conjuntos de endereços de
acordo com suas senhas. Precisamos corrigir um problema
em nosso aplicativo. Quando fazemos chamadas
para nosso nó Bitcoin
por meio de nosso aplicativo, usamos o nome da nossa carteira. Isso é um problema,
pois, para operações como recuperar nossa
carteira, transações e UTXOs de nosso node
coletarão as mesmas informações para diferentes conjuntos de endereços gerados por
diferentes senhas. Para otimizar nossas notas, as chamadas
RPC e coletar apenas informações
dos endereços gerados com uma determinada senha, usaremos o primeiro
endereço de recebimento
gerado como o nome da
carteira importante para nossa nó. Para fazer isso, vamos
até o registro da carteira. Vamos criar o bom método de
primeiro endereço aqui. Ele usará o método get
addresses para retornar o primeiro
endereço da carteira. Agora, temos que substituir cada chamada no campo do
nome da carteira que foi feita para nos comunicarmos
com nosso node por uma boa chamada de método de primeiro
endereço Vamos usar nosso ID para identificar os usos de o campo do nome
e faça a refatoração. Agora, vamos acessar o serviço de atualização da carteira
atual e definir o primeiro endereço
da carteira atual. Vamos criar esse método. Aqui. Definiremos o
primeiro campo de endereço para o parâmetro recebido. Vamos criar esse campo. E vamos criar
um getter para isso. Agora, vamos substituir as chamadas relevantes do método getName da
carteira atual pelas
chamadas atuais do método get
first address. Agora vamos fazer o teste da carteira de
carga, comentar o primeiro teste e executar o teste restante. As coisas boas
continuam funcionando como antes. Vamos descomentar esse teste. Agora, vamos para a classe de
configuração de endereço. Como agora estamos usando
o primeiro endereço de carteira para interagir com nosso node, o primeiro endereço deve ser
sempre o mesmo para uma combinação de
semente mnemônica e senha. Portanto, temos que
garantir que a lista de configurações de
endereços e
seus endereços estejam
sempre na mesma ordem. Para fazer isso, vamos usar a
anotação do pedido nos dois feijões. Vamos adicionar a
anotação do pedido com zero como argumento
neste primeiro Bean. Isso fará com que o Spring
injete esse bean nas listas de configuração de
endereços
como o primeiro elemento. Vamos também mudar o
segundo argumento
do objeto de configuração de endereço
para um Hashmap vinculado. Ao contrário dos mapas gerados
pelo mapa do método, o Hashmap vinculado mantém
a ordem de inserção, conseguindo isso usando
o código a seguir. Agora vamos fazer a mesma refatoração no outro feijão de configuração do
vestido vermelho. E vamos adicionar a anotação do
pedido aqui usando uma como parâmetro, garantindo que ela
será injetada após o primeiro bean se inscrever nas configurações
de endereço. Agora, vamos fazer outra
otimização. Às vezes, a importação de endereços para nosso
node é lenta. Para evitar a
importação desnecessária de endereços para nosso node, verificaremos se
eles já foram importados. Para fazer isso, vamos criar
o nó recebido pelo cliente de
endereço no pacote do cliente
node dot. Esse cliente recuperará todos os
endereços carregados atualmente pelo nosso node. Vamos adicionar a
anotação do serviço a ela. E vamos injetar o cliente
node nele. Agora, vamos criar o método de lista de
endereços aqui. Ele retornará uma lista de objetos
de endereço de nós
como seus parâmetros. Será necessário um nome de carteira. Amen conf, que definirá o número mínimo
de conformações dos endereços retornados. O parâmetro include empty, que definirá
se a chamada
retornará endereços sem fundos. E o parâmetro include
watch only , que dirá ao
nó se queremos recuperar endereços
que o nó não conhece e suas chaves
privadas correspondentes. Vamos criar o registro
de endereço do nó no pacote domains dot node. Ele terá somente
um campo de endereço. Usando o cliente node. Vamos fazer a chamada de RPC aqui. Ele retornará uma matriz de
endereços de nós. O primeiro parâmetro do método make request será a lista recebida
pela string de endereço. Em seguida, passaremos um novo objeto de
referência de tipo
parametrizado. Em seguida, o URL da carteira. Finalmente,
descrevemos anteriormente
os parâmetros do método de vestimenta listados . Agora retornará uma conversão
da matriz de endereços do nó em uma lista de endereços de nós como esta. Agora, vamos ao serviço de
importação de carteiras. Aqui, adicionaremos uma
declaração if para verificar se os endereços da carteira
não foram importados dessa forma. Vamos criar esse método. Dentro do corpo if, usará o
método import addresses para importar os endereços somente se eles
não tiverem sido importados antes. Vamos implementar o método importante do
endereço. Obteremos os
endereços importados usando o nó recebido
pelo cliente de endereço. Então, vamos
injetá-lo nessa classe. Em seguida, chamaremos o método
de lista de endereços. Passar os parâmetros a seguir converterá o resultado
em um fluxo e usará o método map para extrair
todos os endereços de endereço do nó. Em seguida, converteremos
o resultado em um conjunto de endereços usando
o método collect. Em seguida, converteremos os
endereços da carteira em um conjunto como esse. Agora, usando o
método de remoção nos endereços da carteira, removerá todos os
endereços importados. Por fim, retornaremos que
os endereços da carteira são uma chamada de método vazia. Se o resultado for verdadeiro, todos os endereços da carteira já
foram importados. Oh, esquecemos de deletar
essa linha. Vamos fazer isso. Agora. Vamos fazer o teste de
envio de Bitcoin. De agora em diante,
adicionaremos algumas afirmações sobre o
recurso de carregamento de carteira a alguns testes. Então, se encontrarmos algum bug no processo, o
corrigiremos. Vamos começar com o
primeiro teste de envio de Bitcoin. Vamos excluir essa
linha em seu lugar. Vamos adicionar uma chamada de método de
carteira de carga de peso. Usar esse método tentará
fazer com que esse teste seja executado mais rápido. Vamos criá-lo na classe
de teste de GUI. Aqui, vamos chamar
o método da bolacha. Passando esses parâmetros. Em cada iteração
desse retorno de chamada, usaremos o método
sleep para esperar por 1 s. Em seguida, verificaremos se o
primeiro endereço da carteira atual está definido. Então, vamos injetar a
carteira atual nessa classe. Usando a lista de nós, o
cliente de carteiras verificará se o nó carregou o endereço com o
primeiro endereço da carteira atual. Então, vamos injetar esse
serviço nessa classe. Com esse código, esperará até que
o nó carregue a carteira. Agora, vamos corrigir um problema que às vezes
pode causar
falhas nos testes. Aqui, o parâmetro de tamanho
total esperado é igual à soma do índice de
iteração atual mais um. Agora, vamos criar a última variável
de endereço de
recebimento definir seu valor para o endereço de recebimento
presente na janela. Agora, vamos definir algumas outras
variáveis que nos ajudarão a comparar os valores na carteira antes e depois de carregá-la. Primeiro, o tamanho da
tabela de transações. Em seguida, o saldo da tabela
de transações da primeira linha. Agora vamos chamar o método
load wallet, passando o
nome da carteira como parâmetro. Vamos definir essa variável aqui. Agora, definiremos a tabela de
transações após a variável de carregamento. Vamos obtê-lo usando
o método de pesquisa exatamente como antes de carregá-lo. Em seguida, clicaremos
na guia de endereços e definiremos a tabela de endereços após variável de
carregamento da mesma forma. Em seguida, clicaremos na guia Receber e definiremos o último
endereço de recebimento, a variável de pós-carregamento e o texto do rótulo
após a variável de carregamento. Agora, no bloco then, vamos deletar essas duas linhas. E vamos comparar as últimas variáveis de endereço de
recebimento antes e depois de
carregar a carteira. Em seguida, vamos definir o tamanho da tabela de
endereços e variáveis
balanceadas da tabela de endereços da
primeira linha aqui. E vamos adicionar essas
duas comparações que são iguais às
que acabamos de excluir. Agora, vamos comparar os tamanhos da tabela de
endereços antes e depois de
carregar a carteira. E vamos fazer o mesmo com o saldo da
primeira linha da tabela de endereços. Agora vamos excluir
essas duas linhas, substituindo-as pelas seguintes linhas, que fazem as mesmas comparações mas usam
as variáveis refatoradas. E vamos adicionar as
seguintes comparações
das variáveis antes e
depois de carregar a carteira. Vamos comentar todos os outros
testes neste arquivo. E vamos fazer o teste
restante. O teste falhou porque
o último endereço
de recebimento antes e depois
do carregamento da carteira é diferente. No próximo vídeo,
vamos corrigir isso.
71. 69 Carregar carteira parte 4 skillshare 2: Neste vídeo,
corrigiremos o erro de ter endereços de recebimento
diferentes antes e depois de carregarmos uma carteira. Isso acontece porque estamos usando o UTXOs para atualizar o índice atual de endereços de
recebimento. Depois de carregar a carteira e
recuperar os UTXOs da carteira, as saídas antigas usadas para atualizar o
endereço de recebimento não fazem mais parte do conjunto UTXO
porque já foram gastas. Assim, o endereço de recebimento
acaba não sendo atualizado. Vamos corrigir isso transferindo
o código responsável
por atualizar os endereços de recebimento do serviço de atualização de
endereços da carteira atual atualização de
endereços da carteira atual
para uma nova classe. Na Nova Classe,
usaremos as transações recuperadas
do nó contendo todas as carteiras e endereços
usados para atualizar os endereços de
recebimento atuais. Então, vamos criar essa classe que será chamada de
atualizar o
endereço de recebimento da
carteira atual de seu serviço no pacote de serviços de pontos da GUI. Vamos adicionar a
anotação do serviço aqui. Agora, vamos copiar e
colar alguns códigos
do serviço de atualização de
endereços da carteira atual para essa classe. Vamos adicionar essa anotação de
qualificador. Agora vamos criar o método de
atualização aqui. Será necessária uma lista das transações do
node. O uso do método de mapa
obterá um fluxo de endereços do fluxo
de transações do node. Em seguida, filtraremos o
stream para que ele contenha apenas endereços
na carteira atual. Em seguida, chamaremos o método de marca
usada em cada endereço. Vamos usar esse método
do serviço de atualização de
endereços da carteira atual. Agora, chamaremos o método
atual de
obter endereços de carteira . Vamos criar esse método. Ele retornará o
resultado da chamada do método address get
addressed types. Ele retornará um conjunto
de tipos de endereço. Vamos criar esse método
na classe de endereços. Aqui, simplesmente retornará o conjunto de chaves do campo de
endereços. Agora, para cada tipo de endereço, chamaremos o método de atualização do endereço de
recebimento. Para fazer isso, o tipo
desse parâmetro de método será
alterado para o tipo de endereço. E excluiremos essa linha pois não seremos mais necessários. Agora, vamos acessar o serviço de atualização de
endereços de carteira
atuais para excluir o mesmo
código que colamos nossa nova classe e seus usos. Agora, vamos para o serviço de
atualização UTXos. Vamos injetar o
serviço de
atualização atual de endereços de
recebimento da carteira nessa classe. E vamos chamar o método de
atualização
do serviço injetado passando as transações do nó
como seu parâmetro. Agora vamos fazer o teste de
envio de Bitcoin. Vamos adicionar a chamada do método de
hibernação aqui para evitar uma
nova condição de corrida que pode acontecer às vezes garante que seu nódulo esteja funcionando. E vamos fazer esse teste. O
problema do endereço de recebimento foi corrigido, mas o teste falhou
devido a outro bug. O
saldo da transação após o carregamento uma carteira não é calculado
incorretamente. Vamos corrigir isso. Para
resolver esse bug, precisamos entender melhor como a API de
transações da lista Bitcoin Core funciona. Aqui está a documentação
da lista de transações
bitcoin Core API. Observe que, para
cada transação, a API retorna somente
um campo de endereço. O valor se refere apenas
ao valor de Bitcoin
enviado para esse endereço ser negativo
se não pertencer
à nossa carteira e
positivo caso contrário. Se a transação
tiver uma saída de alteração, a API retornará mais de um registro
para cada transação. Cada registro com
um campo
de endereço da saída da transação. Vamos ver um exemplo
do resultado dessa API para uma transação enviada de nossa carteira com uma
entrada e duas saídas. Para a mesma transação, a API retornou
três registros. Podemos ver que eles se referem
à mesma transação
examinando seus IDs de transação. Observe que os dois
primeiros registros têm o mesmo endereço. Esses registros se
referem à saída da alteração. O primeiro tem um valor positivo indicando que é um endereço
pertencente à nossa carteira. Esse é o valor da mudança. O segundo registro tem o
mesmo valor, mas como negativo. Isso significa que nossas carteiras enviaram
uma quantia para esse endereço. Também tem uma taxa negativa, que é a taxa de transação que pagamos na transação. Se somarmos o valor dos
dois primeiros registros, acabamos com zero, que é exatamente o saldo que
pagamos na transação. Finalmente, o terceiro
registro contém um valor negativo indicando que enviamos Bitcoin
para esse endereço. Ele também tem uma taxa igual à taxa do
segundo registro. Considerando como essa API funciona, a maneira correta de calcular o
saldo da transação é somar os valores
cadastrais retornados para a mesma transação e a taxa de
uma delas registradores, a transação balanceada antes carregar uma carteira está
correta porque a estamos calculando de uma forma que
considera a segunda transação criada antes de enviá-la ao
nosso node. Depois de carregarmos nossa carteira, perdemos as
informações da transação que não consideram para calcular
o saldo da transação. Então, vamos ao serviço de
transação
Update Current Wallet para corrigir o problema. Nossa nova solução não
precisará mais desse filtro. Então, vamos excluir essa
linha em seu lugar. Vamos adicionar uma chamada ao
método collect como seu parâmetro. Chamaremos os coletores de
agrupamento por método, passando uma referência ao
ID TX
da transação do nó com esse código,
obteremos um mapa em que as chaves serão
IDs de transação e os valores serão listas de transações de nós
com o mesmo ID de transação. Vamos chamar o método de valores no resultado e não o método
stream para obter um fluxo de listas de transações
de nós
com o mesmo T XID. O resto desse
método permanece como está. Vamos criar a
transação a partir do método. Ele pegará uma lista
de transações do node e retornará uma linha de transação. Vamos mover esse método aqui. Vamos primeiro obter a taxa
de transação. Será retirado de um fluxo sem taxas
de transação. Vamos criar o campo de taxa
na transação do node. Em seguida, filtraremos o
stream para ver as taxas nominais. Em seguida, pagaremos a multa primeiro para receber as
primeiras e usaremos o método de URLs para retornar zero se nenhuma taxa for encontrada. Agora, vamos calcular o valor. O uso do método map
obterá um fluxo contendo todos os valores de transação do nó do fluxo de
transações do nó. Em seguida, usaremos o método
reduzido, passando a referência do
método de adição decimal grande para
alguns valores. Por fim, usaremos
o método or else para retornar zero sem que nenhuma
transação seja encontrada. Agora vamos copiar e
colar essa linha aqui. Usaremos o ID TX da
transação do primeiro nó como o primeiro parâmetro da instanciação da linha da
transação. Em seguida, adicionaremos a taxa de transação
obtida
ao valor e passaremos o
valor como um parâmetro aqui. Por fim, passaremos a
confirmação da transação do primeiro nó a
tempo como parâmetros de instanciação da última
linha de transação . Vamos excluir esse método, pois não
precisaremos mais dele. Vamos fazer esse teste de envio de
Bitcoin novamente. O primeiro teste foi aprovado, mas o segundo falhou
devido a uma condição de corrida. Vamos corrigi-lo rapidamente com
a chamada do método de sono aqui. Faremos uma correção melhor para
esse erro no próximo vídeo. Por enquanto, vamos comentar
esta linha para executar somente a
nota do teste reprovada . O teste foi aprovado. Vamos descomentar o
resto do teste.
72. 70 Carregar carteira parte 5 skillshare 2 1: Neste vídeo, adicionaremos mais afirmações de teste para verificar
se podemos carregar corretamente uma carteira com mais
endereços gerados do que a configuração inicial do número de endereços
gerados. Mas primeiro, vamos
otimizar um método de teste para evitar algumas
condições de corrida em alguns testes. Na aula de teste de envio de Bitcoin. Vamos excluir essas duas chamadas do
método de suspensão, pois nosso fixo lidará melhor com as condições de
corrida após enviarmos bitcoins. Vamos para a aula de teste de GUI. Vamos adicionar esse parâmetro
opcional no
método de enviar Bitcoin e esperar com o valor padrão igual ao endereço de
recebimento da hashtag. Em seguida, vamos adicionar o seguinte e a
condição a esse valor de retorno. Com esse código,
só parará de esperar se o campo do endereço de recebimento for diferente da variável de
endereço. Portanto, evitamos
o erro de enviar Bitcoins para o mesmo endereço
duas vezes sequencialmente. Agora, vamos fazer o teste de
recebimento de Bitcoin. No último teste dessa classe, adicionaremos algumas
afirmações para testar se podemos
carregar corretamente uma carteira com mais endereços gerados do que a configuração inicial do número de endereços
gerados. Então, vamos definir a carteira
chamada variável e substituir o parâmetro
no método correto
para essa variável. Agora, vamos chamar o método da carteira de
carga de peso aqui e excluir as chamadas do
método de sono desse teste. Agora, depois de receber
Bitcoins sete vezes, vamos definir a última variável de
endereço de recebimento com o valor presente no campo de endereço de
recebimento. Agora, vamos copiar essa linha no teste de areia
do Bitcoin
e colá-la aqui. Vamos mudar essa variável
para abordar sua exibição em tabela. Vamos fazer o mesmo
com essa outra linha. Agora, vamos copiar e colar todas essas linhas do teste de envio de
Bitcoin para o nosso teste. Também vamos copiar e colar
essa linha em nosso novo teste para comparar o último endereço de
recebimento antes e depois de
carregar a carteira. Vamos adicionar essa linha para comparar o tamanho da tabela de transações antes e depois de
carregar a carteira. Nesta linha,
faremos o mesmo com tamanho
da tabela de endereços. E essa outra linha comparará o texto da etiqueta antes e
depois de carregar a carteira. Vamos executar nosso node. Vamos comentar os outros testes desta classe e executar nosso novo teste. O teste falhou devido
à diferença entre o último endereço de recebimento antes e depois de
carregar a carteira. Além disso, se você notou
o número de endereços na
tabela de endereços após
o carregamento, são apenas três quando o
correto seria sete. Isso ocorre porque
não estamos salvando o número de endereços
gerados
depois de gerá-los. Vamos corrigir isso. Vamos até o serviço de atualização de
endereços de recebimento da carteira
atual . Precisaremos
do repositório de carteiras aqui. Então, vamos
injetá-lo nessa classe. Agora, chamaremos o método de
incremento do número de endereços
gerados
no repositório da carteira. Como seus parâmetros,
passarão o número inicial de endereços gerados e
o nome da carteira atual. Vamos criar esse método. Vamos mudar esse parâmetro
de tipo para a classe inteira e esse nome de
parâmetro para incrementar. Como o próprio nome sugere, esse método
incrementará o número de campos de endereços
gerados em nossa carteira. Para fazer isso. Vamos adicionar a
anotação transacional a ela. Essa anotação é
um requisito
da biblioteca JPA porque ela executará a operação SQL
em duas etapas. Vamos também adicionar a anotação
modificadora. Essa anotação é necessária para métodos
de repositório que modificam registros e
tabelas, o que é o caso. Por fim, vamos adicionar a
anotação da consulta a esse método. Essa anotação
indicará a operação SQL que
queremos fazer
como parâmetro. Vamos adicionar a seguinte string. Essa
instrução semelhante a SQL adicionará
ao número de endereços
gerados o valor do incremento passado como o primeiro argumento para
o método anotado. A cláusula where fará com que
essa operação ocorra somente na carteira com o nome
igual ao parâmetro name. Para vincular os parâmetros do método
às variáveis SQL. Vamos adicionar essas duas
anotações de poemas a esses parâmetros. Agora vamos fazer nosso teste novamente. Ótimo, já passou. Nosso recurso de carteira de carga está pronto. Agora, é importante executar todos os nossos testes de aplicativos
para verificar se um bug apareceu. Mas primeiro, corrigiremos e otimizaremos
alguns de nossos testes para usar o
método de carteira de carga de peso e excluiremos algumas chamadas
do método de hibernação que
não são mais necessárias. Vamos primeiro invulgar
esses testes. E vamos fazer as otimizações
mencionadas. Nos testes de segmentos aninhados, como os
dessa classe, devemos adicionar alguns parâmetros para enviar Bitcoin e
aguardar a chamada do método. Então, vamos fazer isso. O último parâmetro
dessas chamadas deve ser o endereço de recebimento do
segmento aninhado de hashtag da string. Em alguns métodos como esse, também
precisamos definir
o ID mais um é o terceiro argumento da chamada do método send Bitcoin and wait. Agora, podemos executar todos os
nossos testes de aplicativos. Todos eles devem passar
na minha máquina. Eles estão levando meia hora. Então eu deixei isso como um
exercício para o aluno.
73. 71 Importar skillshare 2: Neste vídeo, implementaremos a capacidade de importar uma carteira
com a semente mnemônica. É importante ter
essa opção para recuperar sua carteira e os
casos em que você perde, destrói ou não tem acesso ao hardware ou aos
arquivos que contêm o aplicativo ou banco de dados com os dados da carteira. Nesses casos, você simplesmente
inseriria sua
semente de backup e, opcionalmente sua senha
no recurso de importação
do aplicativo para ter
acesso de volta à sua carteira. Mais uma coisa, você não ficará restrito a
recuperar sua carteira. Usando este aplicativo, você poderá usar sementes
mnemônicas geradas por este aplicativo para
recuperar sua carteira e outras carteiras compatíveis com BIP 39. Além disso, você poderá recuperar
o acesso
aos endereços de sua carteira Bitcoin importando sua semente mnemônica BIP 39 gerada por outras carteiras
para este aplicativo. Apenas certifique-se de que os dois
aplicativos
suportem os blocos de derivação dos
endereços que você deseja importar. Então, vamos começar criando
o teste da carteira de importação. Isso estenderá a classe de teste de GUI. Vamos copiar esse código
do
teste de envio de Bitcoin e colá-lo aqui. Agora vamos criar um teste chamado should import wallet
and receive Bitcoin. No bloco único, vamos definir
a carteira chamada variável. E vamos criar uma semente
mnemônica usando o método de criação do
serviço de sementes mnemônicas. Agora vamos chamar o método de
importação da carteira, passando o nome da carteira e semente
mnemônica como parâmetros. Vamos criar esse método. Vamos também adicionar uma senha como um terceiro
parâmetro opcional a esse método. Aqui, clicaremos em um menu
com a importação de texto. Em seguida, clicaremos no
item Menu com a carteira de texto. Agora, clicaremos
no componente com um ID FX do nome da carteira. Esse componente
será um campo de entrada no qual inseriremos o nome
da carteira importada. Em seguida, chamaremos o
método de gravação passando a
variável name como seu parâmetro para
digitar o nome nesse campo. Em seguida, clicaremos
no campo de senha, que terá um
ID FX da senha da carteira. Em seguida, escreveremos a
senha nesse campo. Em seguida, clicaremos
no campo de semente mnemônica e escreveremos a
variável de semente mnemônica nesse campo. Por fim, clicaremos
no botão OK. Vamos também adicionar a chamada
do método de
hibernação para aguardar o carregamento da carteira. Voltando ao
teste da carteira de importação usando o método de pesquisa, vamos recuperar o valor do endereço presente no campo de
endereço de recebimento. Usando o método de enviar Bitcoin
e esperar, vamos enviar 1.000 Satoshi
para o endereço recuperado. Agora, clicaremos
na guia de endereços. Em seguida, usando o método de pesquisa, obteremos a tabela de endereços
e a armazenaremos em uma variável. Clicaremos na guia de
transações, obteremos a tabela de transações
e a armazenaremos em uma variável. Além disso, vamos fazer o mesmo com o saldo total rotulado como texto. Agora, vamos definir duas
variáveis para armazenar o tamanho da tabela de endereços e
o tamanho da tabela de transações. Vamos adicionar as
seguintes afirmações nesse bloco para verificar se as variáveis definidas anteriormente
têm os valores esperados. Agora vamos duplicar esse teste. Vamos renomeá-lo para importar a carteira usada
e o bloco recebido. Neste teste,
criaremos uma carteira e receberemos Bitcoins nela
antes de importarmos a carteira, depois importaremos a carteira, geraremos um bloco em
nossa nota e verificaremos se o aplicativo carrega corretamente e atualiza a carteira importada. Então, vamos criar um determinado
bloco aqui, onde
criaremos uma carteira e
enviaremos um Bitcoin para ela. Agora, vamos deletar essa linha. Vamos mudar o nome dessa
variável para
importar o nome da carteira e aumentar
o número da carteira denominada. Usaremos essa variável para
nomear a carteira importada, pois não podemos criar duas
carteiras com o mesmo nome. Vamos passar a
variável de senha para essa chamada de método. Depois de importar a carteira, vamos gerar um bloco. Para fazer isso, vamos primeiro gerar um endereço de nota usando o cliente
node get new address. Em seguida, chamamos o método generate
to address, passando o endereço do nó como parâmetro para
gerar um bloco. Agora, vamos chamar o método de sono para esperar que o
bloco seja minerado. Por fim, vamos alterar o saldo total
esperado. Espera-se um
saldo de um
Bitcoin confirmado e zero Bitcoin
não confirmado. O resto do teste
permanece como está. Agora. Vamos até o
playground dot FXML para criar o menu de
recursos de importação. Vamos duplicar a tag do
menu de carregamento e seu conteúdo. Vamos alterar esse
atributo de texto para importar. Esse ID de correção para importar o menu FXML. Vamos também adicionar o
atributo de ação aqui com
seu valor referente
ao método open end port
wallet dialog criará esse método posteriormente para
responder a um clique neste item de menu abrindo
um janela de diálogo. Vamos até o Scene
Builder para ver como fica. Ok, o menu Importar foi
adicionado ao lado do menu de carregamento. Agora vamos copiar e colar esse código na janela
principal FXML. Vamos criar esse método no controlador
da janela principal. Seu código será
muito semelhante ao método de
diálogo de criação de carteira aberta. Então, vamos copiá-lo
e colá-lo aqui. Vamos mudar o
título do diálogo para importar a carteira. E vamos substituir o campo de diálogo de
carregamento da carteira
pelo campo de
diálogo de importação da carteira aqui. Vamos criar esse campo e
injetá-lo nessa classe. A anotação de valor
aqui apontará para
a caixa de diálogo de importação da carteira FXML. Agora vamos criar a entrada enquanto um diálogo FXML
no pacote FXML. Vamos usar o conteúdo
do diálogo de criação de carteira
FXML como base para criá-lo. Agora vamos mudar o texto do cabeçalho do
diálogo. Em vez de clicar em Criar, vamos pedir ao usuário que insira
uma semente mnemônica válida. Em seguida, vamos mudar
o controlador FX
para importar o controlador de
diálogo da carteira. Agora, vamos para
o Scene Builder. Vamos excluir o botão Criar. Vamos colocar um rótulo aqui e alterar seu texto
para a data de criação. Vamos adicionar um
controle de seletor de data à célula. Vamos clicar na área de texto da semente
mnemônica e torná-la editável. De volta ao editor de texto. Vamos mudar esse nome
Fxi de toilette e esse ID fx para a senha da
carteira. Vamos definir o
FX ID do seletor de datas para a data de criação. Agora vamos criar o controlador de diálogo de importação da
carteira no pacote de controladores. Vamos adicionar a
anotação do componente a ela. Vamos adicionar todos esses
campos FXML ao controlador. Vamos tornar todos esses
campos privados. E vamos adicionar a
anotação FXML a eles. Vamos copiar e colar o método
inicializado
do controlador de diálogo de criação de carteira em nosso novo controlador. E vamos fazer o mesmo com todas
as
entradas necessárias atendidas. Vamos mudar essa
variável de nome para o nome da carteira. Também vamos copiar e colar
esse método em nossa nova classe. No manipulador de eventos do botão OK chamaremos o método de importação da
carteira. Esse método simplesmente criará uma carteira usando o tipo de
dados do usuário. Então, vamos usar o método create
wallet
do controlador de
diálogo Create Wallet como base para criá-la. Vamos injetar o
serviço de criação de carteira nessa classe. Vamos mudar essas variáveis para as deste Controlador. E vamos injetar o número
inicial de endereços
gerados nessa classe. Vamos fazer o mesmo com
esse campo de contexto. Agora, em vez de usar uma nova data como
parâmetro para esse método, chamará o método de data de cobrança. Vamos criar esse método. Usaremos a
seguinte lógica aqui. Se o usuário
não escolher uma data, usaremos a data em que o
Bitcoin começou a funcionar. Se ele escolher,
usaremos a data escolhida. O parâmetro de data
definirá até que ponto,
no passado iremos encontrar informações sobre os endereços da
carteira importada. Quanto mais antigo o estado, mais tempo
o nó
levará para importar a carteira. Então, vamos usar o método de data
padrão para definir a data padrão. Aqui, usaremos o objeto de formato de
data simples com o seguinte parâmetro. Em seguida, tentaremos retornar a chamada
do método de
análise de formato de data simples passando a
constante de data padrão como seu parâmetro. Usaremos o
bloco catch para agrupar a exceção de análise em
uma exceção de tempo de execução. Vamos definir essa constante, que é a data em que o
Bitcoin começou a funcionar. Aqui. Se a
data de criação não for nula, redefinimos a
variável de data com o seguinte valor. Finalmente, retornamos a data. Depois de criar a carteira,
publicará o evento da
carteira importada. Vamos criá-lo no pacote de eventos de pontos da
GUI. Aqui, passaremos esse parâmetro
para o superconstrutor e definiremos o campo da carteira como
o parâmetro da carteira. Vamos criar um getter
para esse campo. Agora, vamos até o ouvinte da carteira
Save. Esse ouvinte responderá aos eventos da carteira
importada para
salvar carteiras importadas. Vamos refatorizá-lo para que ele possa ouvir mais de um evento. Para fazer isso, vamos remover
essa declaração de implementos. Vamos mudar esse método chamado evento
de carteira não criado. Vamos adicionar a anotação do
ouvinte do evento a ela. Agora, vamos criar o método de evento de
carteira sem importância, passando o
evento importado da carteira como parâmetro. Vamos copiar e colar
essa linha aqui. E vamos adicionar a anotação do
ouvinte de eventos a esse método. Definir uma anotação de pedido para métodos anotados pelo ouvinte de
eventos tornará a ordem
de execução desses ouvintes previsível. Quanto menor for o parâmetro de
anotação
do pedido, maior será a prioridade
desse ouvinte executar em comparação com outros ouvintes
do mesmo evento. Então, vamos adicionar essa
anotação a esse método. Vamos passar zero como parâmetro para tornar esse ouvinte o
primeiro desse tipo a ser executado Vamos adicionar a mesma anotação
ao método de
evento de carteira não criado. Priorizamos salvar
a carteira primeiro após sua criação para garantir
que, se os ouvintes posteriores falharem, pelo
menos salvaremos seu DataFirst. Agora vamos para o ouvinte de importação de
carteira criado. Queremos que esse ouvinte importe
a carteira
importada para o nó Bitcoin. Então, vamos duplicar o método de evento da carteira
descarregada. Vamos mudar seu nome para um evento de carteira
sem importância e torná-lo exceto o evento
apropriado. Agora vamos adicionar a
anotação do pedido a esses métodos. Os ouvintes de eventos da
carteira importados e criados receberão um como seus parâmetros e o ouvinte de eventos da
carteira carregada, zero. Dessa forma,
garantimos que, quando a carteira tentar buscar
dados do nó
, eles já serão
importados pelo nó. Agora, vamos até o ouvinte da carteira
carregada e adicionar um método de ouvinte para
o evento da carteira importada, como acabamos de fazer
na aula anterior. Agora, vamos adicionar uma
anotação de pedido aos dois métodos, passando para como parâmetro para o evento
da carteira sem importância e outra para
o método de
evento da carteira descarregada para fazer com que esses ouvintes funcionem depois
todos os outros para seus eventos. Agora, vamos executar nosso node. E vamos fazer esse teste. O primeiro teste foi aprovado, mas o segundo falhou. Vamos ver o porquê. Ok, uma exceção de violação de
restrição ocorreu porque
tentamos salvar uma carteira com o
mesmo nome duas vezes. Esquecemos de alterar a variável do nome da
carteira na chamada
do
método de importação da carteira para a variável de nome da carteira de importação. Vamos corrigir isso e
executar o teste com defeito novamente. Ótimo, já passou.
74. 72 Validar a habilidade: carteira 2: Neste vídeo, implementaremos
algumas validações antes de criar uma carteira de importação
e tentar enviar transações. A primeira validação
impedirá que a criação da carteira continue se o nome da carteira for igual ao nome da carteira
criada anteriormente. Então, vamos fazer o teste de
criação de carteira para criar um teste
para essa condição. Será chamado não deve criar uma carteira com nome
repetido. Vamos criar uma carteira
no bloco fornecido, criando as variáveis necessárias e usando-as no método
create wallet. No bloco único, vamos
adicionar um código para criar uma carteira com o mesmo nome da criada
no bloco fornecido, mas agora usando a GUI. Depois de tentar
criar a carteira, vamos adicionar a chamada do
método suspenso aqui Esperamos que o aplicativo
mostre uma janela de diálogo de alerta contendo uma mensagem dizendo que o nome da carteira já existe. Então, vamos definir uma variável
contendo a mensagem. Agora, usaremos o
método de pesquisa para obter um componente com essa mensagem e
armazená-lo na variável de consulta do nó. Por fim, clicaremos
no botão OK para fechar
a janela de diálogo. No bloco de então. Vamos adicionar a
comparação a seguir para verificar se mensagem
na janela da caixa de diálogo de
alerta é igual à variável da
mensagem de erro. Agora, vamos para o controlador de diálogo de criação de
carteira. No método create wallet, usaremos uma declaração if com
um serviço de validação de carteira para verificar se o
nome da carteira é válido. Então, vamos injetar esse
serviço nessa classe. Vamos criar esse serviço e o pacote de
serviços de pontos do banco de dados. E vamos terminar de
injetá-lo nesta classe. Na instrução if, vamos chamar o método wallet exists nela, passando o texto do nome
como parâmetro. Vamos criar esse método. Usaremos o
serviço de erro de alerta e o corpo if. Então, vamos
injetá-lo nessa classe. Agora, chamaremos o método de erro de
alerta
nele como seu parâmetro. Vamos passar essa constante. Vamos criar essa constante
na classe de mensagens de erro. Ele terá o mesmo texto
que definimos no teste. Vamos importar essa constante aqui e chamar a declaração de
retorno. Agora, vamos ao serviço de
validação de carteira. Na carteira existe, o método conduzirá o repositório da carteira. Então, vamos
injetá-lo nessa classe. Agora, retornaremos a chamada do método exists
by name para ele, passando o
nome da carteira como parâmetro. Vamos criar esse método apenas com
essa assinatura de método. O
Spring Data JPA magic já sabe como consultar as informações desejadas
do banco de dados. Vamos fazer o teste de
criação de carteira. Vamos comentar esses testes. Execute nosso node e
execute nosso novo teste. Ótimo, o teste foi aprovado. Vamos descomentar esses testes. Agora, vamos adicionar a mesma validação do nome da
carteira no recurso de importação de carteira. Então, vamos copiar esse teste e colá-lo aqui
no teste de importação da carteira. Vamos mudar seu
nome para não deve importar uma carteira com nome
repetido. Vamos fazer algumas
adaptações nesse teste. Primeiro, vamos aumentar
a carteira chamada número. Em seguida, vamos modificá-lo para importar uma carteira aqui em vez
de criá-la. E vamos mudar os parâmetros
dessas chamadas de método. Agora, vamos até o controlador de diálogo de criação de
carteira
e copie-o se bloquear aqui. E vamos colá-lo aqui no controlador de diálogo
da carteira. Vamos injetar os
serviços necessários nessa classe. Vamos mudar essa
variável para o nome da carteira. Agora, vamos comentar esses
testes e executar nosso novo teste. Grau. O teste foi aprovado. Vamos descomentar esses testes. Agora, vamos adicionar uma validação de
endereço. Ao tentar
enviar transações. Atualmente, podemos digitar qualquer coisa no campo
de endereço a ser enviado. Se tentarmos enviar uma transação para um endereço inválido e
ocorrer um erro e ela for ignorada
silenciosamente
pelo aplicativo sem que
o usuário perceba, implementaremos uma
validação que fará uma caixa de diálogo de alerta aparecerá na tela se o endereço
a ser enviado for inválido. Primeiro, vamos fazer
o
teste de envio de Bitcoin para criar um teste
para esse cenário. Digamos que não deve enviar
Bitcoin para um endereço inválido. Vamos adicionar código para criar uma carteira usando a interface gráfica
e o bloco de vento. Vamos aguardar a criação da
carteira. Agora, vamos copiar e colar esse código aqui para enviar
fundos para a carteira. Vamos criar essa variável de valor
anterior aqui e definir seu valor como 0,1. Vamos definir um para o segundo método
de intervalo chamado parâmetro. Agora vamos criar um endereço de nó e gerar um bloco para ele. Vamos clicar na guia Enviar e chamar o
método de envio de Bitcoin para tentar enviar 0,01 Bitcoin para o
endereço para enviar a variável. Como a
variável de endereço a ser enviado conterá endereços
inválidos, esperamos que uma janela de
diálogo de alerta apareça contendo uma mensagem dizendo que o endereço a ser enviado é inválido. Então, vamos criar uma
variável de mensagem de erro com a
seguinte mensagem. Agora, usaremos o
método de pesquisa para obter um componente com essa mensagem e armazená-lo
na variável de consulta do nó. Por fim, clicaremos
no botão OK para fechar
a janela de diálogo. Em seguida, bloqueie, vamos adicionar a comparação
a seguir para verificar se a mensagem na janela da caixa de diálogo de alerta é igual à variável da
mensagem de erro. Vamos definir o endereço para enviar a variável com alguns
casos de teste no bloco where. Aqui, vamos passar
nesses casos de teste disponíveis na página Projeto
e Recursos. Cada caso de teste tem um erro. As diferentes partes
do código serão detectadas. O primeiro caso de teste é uma string com um prefixo inexistente. O segundo caso tem um prefixo de teste de registro
correto, mas um endereço inválido restante. Os próximos três endereços
seriam endereços de teste de registro válidos, mas seus últimos
caracteres foram alterados. Durante a construção do endereço. Parte do endereço usa o restante do
endereço a ser criado. Essa parte é a soma de verificação do
endereço e sua função é detectar alterações de
endereço. Durante a decodificação do endereço, a
soma de verificação é verificada e
esperaríamos que ocorresse um erro
se essa verificação falhar. Os últimos três
endereços são válidos, mas não são do ambiente
de teste de registro,
portanto, devem ser
considerados inválidos. Vamos até o localizador de configuração do
script. Na chamada do método throw de URLs, vamos passar um lambda
cujo corpo retornará uma nova
exceção de criação de transação com uma constante
de endereço inválida da classe de mensagens de erro. A exceção
de criação de transação já foi detectada posteriormente
no código e sua mensagem
já é exibida em uma janela de diálogo de
alerta. Vamos criar essa constante
na classe de mensagens de erro. Ele terá o mesmo texto
que definimos no teste. Com essa modificação,
esperamos que a validação cubra
endereços com prefixos inválidos. Agora, vamos ao serviço de criadores de
transações. Vamos agrupar o código
no método de saída de construção
em um bloco try-catch. No bloco de captura,
a exceção de criação de transação
passará a exceção de criação de transação a constante de
endereço inválida. Com essa modificação,
esperamos que a validação cubra erros de decodificação de endereços
cuja verificação da soma
de verificação falhe. Vamos fazer o teste de
envio de Bitcoin. Agora, vamos comentar esses
testes e executar nosso novo teste. Os últimos três casos
de teste falharam. Nossa carteira conseguiu enviar
fundos para esses endereços. Isso aconteceu porque
a decodificação do endereço descarta os prefixos de endereço. Obviamente, as transações foram enviadas somente no ambiente de
teste de registro. Portanto, tornar esses endereços
inválidos é importante para evitar situações em que
você acha que está administrando sua carteira
em um ambiente, mas na verdade ela está
sendo executada em outro. Vamos consertar isso. Vamos para a classe de
correspondência de endereços. Vamos criar esse método
de segmento. Ele retornará um
predicado de string. E usará um ambiente
suficiente como parâmetro. Agora, criaremos
um objeto de mapa com ambientes como chaves e
predicados de cadeias de caracteres como valores. Usaremos o mapa do
método para criar esse mapa. Para cada ambiente, será
definido um Lambda para validar se o parâmetro de endereço tem o prefixo esperado
para esse ambiente. Para os seguintes endereços de rede principais, esperamos que eles não
comecem com o BCR e comecem com BC endereços de rede
de teste do
BC. Começaremos com os testes de TB e de registro. Começaremos com BCR t. Em seguida, retornaremos a
chamada do método map.get passando o ambiente
como seu parâmetro. Agora, vamos duplicar esse método e mudar seu nome para
seu segmento aninhado. Nesse caso, muitos endereços de rede. Começaremos com três testes, endereços de teste
net e reg. Começaremos com dois. Vamos duplicar esse método
e mudar seu nome para
seus endereços de rede principais legados. Começaremos com um. Teste os endereços de teste net e reg. Começaremos com M ou N. Agora, vamos remover esses
Lambdas dessa classe. Agora vamos para a classe de
configuração de endereço. Vamos adicionar esse campo de
ambiente Bitcoin. Vamos adicionar uma anotação de valor
aqui para injetar o valor
desse campo usando a configuração de propriedades de
pontos do aplicativo de
ambiente Bitcoin . Agora vamos alterar o
parâmetro do segmento aqui para chamá-lo como um método e passar o campo de
ambiente Bitcoin como seu parâmetro. Vamos fazer o mesmo com esses parâmetros de segmentos
aninhados aqui. Agora, vamos para a classe de
configuração de script. Faremos a mesma
modificação que
acabamos de fazer na classe
de configuração de endereço. Vamos injetar o
ambiente Bitcoin nessa classe e modificar os beans de configuração do
script para chamar os métodos adequados de correspondência de
endereços. Agora, antes de executar
nosso novo teste novamente, vamos corrigir alguns testes. No teste do
gerador sequencial de endereços, devemos definir o ambiente
Bitcoin
na instanciação de configuração de endereço desta forma. Vamos fazer esse teste. Ótimo, ainda está passando. Agora, vamos fazer o mesmo com o teste do serviço de
criação de carteira. Ok, ainda está passando. Vamos fazer o mesmo com o teste de sorteio único e
aleatório de um
seletor de moedas. Desta vez, temos que definir o ambiente Bitcoin na configuração
do script como. Vamos executá-lo. Ótimo
, ainda está passando. Agora, vamos corrigir o teste do serviço de
criadores de transações. Ok, ainda está funcionando. Por fim, vamos fazer
o mesmo corrigido no teste
da
calculadora do tamanho da transação. Mas desta vez, temos que configurar os ambientes Bitcoin
para testar a rede. Como usamos
endereços de rede de teste neste teste, nota, os testes foram aprovados. Agora vamos fazer o teste de
envio de Bitcoin. Vamos comentar esses
casos de teste para executar somente os três
últimos. Vamos executá-lo. Ótimo, os testes foram aprovados. Vamos descomentar esses testes. E vamos corrigir esse
teste chamado letra. Ele envia, não é enviado.
75. 73 skillshare 2: Neste vídeo, adicionaremos uma seção de rodapé à janela principal do nosso
aplicativo. O rodapé conterá uma barra de
progresso e um rótulo de texto. A barra de progresso
estará ativa quando nossa carteira se comunicar
com nosso node, o que às vezes pode levar algum tempo. O rótulo de texto mostrará
uma breve descrição
da atividade que nossa carteira está realizando durante essa comunicação. Então, vamos criar essa seção
no ponto FXML do playground. Vamos até o Scene Builder. Primeiro. Vamos adicionar uma caixa H na
parte inferior da janela principal. Vamos mudar a
largura pref da caixa H para 600 e a altura pref para 19. Agora vamos adicionar uma
barra de progresso à caixa H. Vamos também adicionar um rótulo a ele. Definiremos a margem
esquerda do rótulo como dez e seu texto como uma string vazia. Agora, no editor de texto, vamos copiar esse código aqui e colá-lo na janela
principal, ponto FXML. Agora vamos encapsular
a barra de progresso e os componentes
rotulados
em arquivos FXML. Primeiro, vamos criar
a barra de progresso FXML. Vamos excluir esse conteúdo. Vamos criar uma tag
raiz ética com um tipo apontando para a classe Java FX da
barra de progresso. Agora vamos copiar os
atributos da tag e do ponto FXML da janela principal e
colá-los em nosso novo FXML. Vamos definir essa tag XML NSF X na janela principal, FXML. Vamos excluir essa
barra de progresso em seu lugar. Vamos adicionar a tag do controlador da
barra de progresso, que será criada posteriormente. Agora, vamos criar um arquivo
FXML de ponto de rodapé para encapsular
a tag do rótulo. Vamos deletar esse código. Vamos copiar e colar
o código da tag do rótulo da janela principal FXML
para o novo FXML. Vamos mudar a tag do rótulo para uma tag raiz ética com um tipo apontando para a classe rotulada Java
FX. Vamos adicionar esse
atributo XML NSF x à nova tag. Agora vamos adicionar as
importações ausentes a esse arquivo. Volte para a janela principal. Vamos substituir a tag do rótulo
copiado
pela tag do controlador de rodapé. Agora vamos criar o controlador da barra de progresso
e importá-lo aqui. Vamos fazer o mesmo com
o controlador de rodapé. Agora, vamos para o controlador da barra de
progresso. Vamos adicionar a
anotação do componente a ela. Vamos usar o construtor do
controlador da guia Receber
como base para criar o construtor do controlador da
barra de progresso. Vamos corrigir sua anotação de nome e valor para
apontar para as corretas. E vamos excluir
a carteira atual pois não precisaremos dela. Agora, vamos copiar esse construtor e colá-lo no controlador de
rodapé. Vamos corrigir o nome do
construtor e adicionar a
anotação do componente a essa classe. Vamos fazer com que a anotação do valor
aponte para o FXML correto. Agora vamos fazer com que essa classe
estenda a classe de rótulo. E a classe do
controlador da barra de progresso estenderá a classe da barra de
progresso. Vamos até a classe de ouvinte da
GUI e adicionar os dois controladores
ao conjunto para que sejam configurados
como componentes personalizados. Agora, vamos criar um observável que
modelará o estado do progresso. Será a classe de
progresso assíncrona criada no pacote
observables. Vamos adicionar uma
anotação de componente a ela. Para definir o estado da
barra de progresso,
criará um
campo de propriedade duplo chamado progresso. Vamos instanciá-lo aqui com um novo objeto simples de
propriedade dupla usando zero como parâmetro. Posteriormente, o parâmetro zero, que define o estado da
barra de progresso como inativo, será passado para
a barra de progresso. Agora vamos criar o campo de descrição da
tarefa. Será uma propriedade de string e definiremos o texto do rótulo do
rodapé. Vamos instanciá-lo usando uma
nova propriedade de string simples. Vamos criar getters
para ambas as propriedades. O IDE criou dois
getters para cada campo, um para a propriedade e
outro para o valor
da propriedade e precisará somente dos getters
para as propriedades. Então, vamos excluir
os outros getters. Agora, vamos criar o método de
início aqui. Vamos usá-lo para definir
o valor do progresso para a constante de
progresso indeterminada. O valor dessa
constante fará com que a barra de progresso mostre uma barra
se movendo para a esquerda e para a direita, indicando que alguma tarefa está
sendo executada em segundo plano. Vamos também definir
o método stop, que retornará o
valor do progresso a zero. Portanto, a barra de progresso
ficará inativa, indicando que nenhuma tarefa está
sendo executada em segundo plano. Por fim, vamos criar o método de descrição da tarefa
definida. Ele usará uma string
como parâmetro. E ele definirá o parâmetro
de
descrição no campo de descrição da tarefa. Agora, para controlar quando a barra de progresso e o rótulo do
rodapé mudam, usaremos um aspecto. Vamos criar a classe de aspecto de
progresso no pacote de serviços de pontos da GUI. Em Spring Boot. E o aspecto é um modificador de método. Usaremos um aspecto para definir que cada
método anotado com uma anotação específica iniciará
a barra de progresso para encontrar o
texto e o rótulo do rodapé, executar o código
no método e reverta o estado da barra de
progresso e do rótulo. Para fazer isso, vamos
adicionar as anotações de aspectos e componentes
a essa classe. Vamos injetar o progresso assíncrono observável nessa classe. Agora vamos criar o método de ativação da barra de
progresso. Ele retornará um objeto. Vamos adicionar a
anotação circular a esse método, pois seu parâmetro passará uma string com
o texto na anotação,
abrirá parênteses, ativará a barra de progresso fechará o parêntese. Essa anotação define
que o aspecto
executará o código antes e
depois de seus métodos modificados. No parâmetro de ativação da
barra de progresso, definiremos que o
aspecto modificará os métodos anotados com uma
anotação com esse nome. Agora, vamos adicionar dois
parâmetros a esse método. O primeiro será o ponto
de junção anterior, que será uma alça
para o método anotado. A segunda será a barra de progresso de
ativação, que dará acesso
aos parâmetros de anotação. Então, vamos criar essa anotação, vamos criá-la em um novo pacote de anotações de
GUI. Para fazer disso uma anotação, precisamos modificar essa
palavra-chave em uma interface. Vamos adicionar a
anotação de destino a esse arquivo, pois seu parâmetro
passará a constante do método. Isso fará com que a anotação
seja válida somente em métodos, não em classes ou campos. Vamos também adicionar a anotação
de retenção passando a
constante de tempo de execução como seu parâmetro. Isso tornará essa
anotação ativa em tempo de execução. Por fim, vamos adicionar o campo de valor da string
a essa anotação. Esse campo será preenchido
pelo parâmetro passado para
essa chamada de anotação. De volta à classe de
aspectos do progresso. Aqui, dentro de uma plataforma, executada
posteriormente, uma chamada de método passará um lambda cujo corpo chamará o método assíncrono de descrição da
tarefa do conjunto de progresso, passando o valor da barra de
progresso de ativação, como seu parâmetro também o fará. chame o método de
início de progresso assíncrono aqui. Agora, chamaremos o
método proceder do ponto de
junção anterior e o objeto
retornado de armazenamento na variável de resultado. O método continue
fará com que o
método anotado seja executado e
retornará seu resultado. Agora, encapsulado em uma plataforma, o método de
execução posterior mudará novamente
os estados dos campos de progresso assíncronos. Mas, desta vez, definiremos
a descrição da tarefa como uma string vazia e chamaremos o método stop
no progresso assíncrono. Finalmente, retornaremos a variável de resultado
contendo o objeto
retornado
pelo método anotado. Agora vamos para o controlador da barra de
progresso. Vamos injetar o progresso assíncrono observável nessa classe. Vinculará o campo de progresso de
progresso assíncrono à propriedade de
progresso
desse controlador no método inicializado. Vamos para o controlador de
rodapé. Vamos injetar o progresso assíncrono observável nessa classe. No
método inicializado, vinculará o campo de descrição da
tarefa de progresso assíncrono à propriedade de
texto desse controlador. Agora, para que a
barra de progresso funcione, precisamos anotar os
métodos que queremos para rastrear o progresso com a anotação da barra de
progresso de ativação. Vamos fazer isso primeiro no serviço de importação de
carteiras. Vamos passar a string
com a carteira de
carregamento de textos como parâmetro. Vamos copiar essa anotação e colá-la aqui
no método de assinatura e envio do serviço de
transação sin. Vamos mudar seu parâmetro
para enviar a transação. Vamos também adicionar
essa anotação ao atualização
das classes de serviço utxOS método de atualização
das classes de serviço utxOS de
atualização como seu parâmetro. Vamos passar a frase
atualizando UTXOs. Agora, vamos executar nosso node. E vamos executar o teste de envio de
Bitcoin legado para verificar
a barra de progresso em ação. Como vimos, a barra de
progresso e o rótulo do
rodapé estão
funcionando conforme o esperado. Ótimo.
76. 74 Atualizar dependências skillshare 2: Neste vídeo, atualizaremos as dependências do nosso projeto. Manter as dependências de um
projeto atualizadas é uma boa prática. Ao fazer isso, nos
beneficiamos de bugs e correções de vulnerabilidades de
segurança
aplicadas às nossas dependências, mantendo nosso
aplicativo mais seguro. Então, vamos para o arquivo
xml
palm dot aumentar a versão de
nossas dependências obsoletas. Dependendo de quando
você as estiver atualizando, versões
mais recentes podem estar disponíveis. Vamos aumentar a versão inicial inicial do Spring
Boot. Para mim, a
versão mais recente é 2.7. 0.5 aumentará a versão
Java para 19. Vamos remover essa
versão divertida agora, já que não é mais
necessária, sua versão será
definida automaticamente. Vamos ver as configurações da
estrutura do projeto. Vamos atualizar a versão Java do
projeto. Se necessário, a
versão Java não está disponível. Você pode clicar em adicionar
SDK para baixá-lo. Vamos definir o nível do
idioma do projeto para o mais recente disponível. Agora, vamos aumentar a versão dos controles
Java FX. Vamos fazer o mesmo
com o JavaFX FXML. Agora, vamos atualizar o plug-in
Java FX Maven e
o plug-in G Maven
para verificar a exatidão. Vamos atualizar a versão Bitcoin
Java para 0,4,
0,4 na configuração do
plug-in de dependência do Maven. Agora vamos clicar no botão
carregar alterações do Maven. Agora vamos atualizar a versão do Bitcoin
Core Node para 23. Vamos baixá-lo no site
Bitcoin core.org. Vamos baixar a versão 23 e instalá-la na
mesma pasta da versão anterior. Eu já fiz isso, então vou pular essa parte. Agora. Certifique-se de definir o sinalizador do ambiente
de teste reg no arquivo bitcoin.com. Antes de executar nosso node, vamos excluir as
pastas de teste de registro dentro da pasta Bitcoin sem dados e da pasta do banco de dados do nosso
aplicativo. Faremos isso apenas para limpar
nosso ambiente de teste. Agora, vamos executar nosso node
examinando o console. Observe que nosso node
está executando a versão 23. Bom. Agora, precisamos fazer uma
pequena modificação para nossa carteira funcione
corretamente com a nova versão do Bitcoin
Core Node. Vamos consultar a documentação do método
RPC de criação de carteira para entendê-lo melhor. Na versão 23 do Bitcoin Core, o argumento dos descritores do
método RPC create wallet é padronizado como verdadeiro, enquanto na
versão anterior ele foi definido como falso. Isso faz com que nossa
carteira de aplicativos não consiga chamar alguns métodos de RPC que
usamos para corrigi-los Isso o
definirá manualmente como falso
para que a alteração não nos
afete mais. Então, vamos ao cliente node
create wallet. Vamos adicionar os seguintes
parâmetros aqui. Vamos adicioná-los à assinatura do método de criação de
carteira. Além disso, o parâmetro de
chaves privadas desabilitado será um booleano e definirá se a carteira de nós criada
gerará chaves privadas. Quando definido como verdadeiro,
o parâmetro blank cria uma carteira de nós
sem sementes e chaves. A senha define senha
opcional para
criptografar o NerdWallet. Como o nome sugere, o
parâmetro avoid reuse define uma política para evitar a reutilização de endereços. Finalmente, o
parâmetro de descritores define se a
carteira de nós criada é uma carteira descritora. Uma carteira descritora
é um novo tipo de carteira no Bitcoin
Core Node que não usaremos. Agora, vamos para o serviço node load
ou create wallet. Vamos adicionar essas variáveis
a essa chamada de método. Agora vamos copiar esse código
e o cliente node create wallet e colá-lo aqui. Agora vamos ao serviço de
carteira. Vamos adicionar os seguintes
valores a essa chamada de método. Aqui, definiremos as chaves privadas
desativadas e os parâmetros em branco como verdadeiros. Desde nosso aplicativo,
embora não exija que o node crie
chaves e sementes privadas para nós. A frase secreta
será uma string vazia. Definiremos o
parâmetro avoid reuse como false, pois nosso nó
gerará endereços para nós e o
parâmetro dos descritores será falso. Agora, vamos para
a aula de teste de GUI. Nessa chamada de método, vamos passar os seguintes valores. Ao contrário do
caso anterior, desta vez, queremos gerar
chaves e sementes privadas porque usaremos a carteira node para
enviar bitcoins em nossos testes. Portanto, os dois primeiros
parâmetros serão falsos. A terceira será
uma string vazia. O parâmetro de evitar reutilização
será definido como verdadeiro. Portanto, o node evitará a
reutilização de endereços para nossa carteira de teste e o
argumento dos descritores será falso. Agora vamos fazer mais uma modificação
por algum motivo após atualizar nossas dependências
quando há dois botões ok na
tela durante alguns testes, test FX acaba clicando
no botão errado. Para corrigir isso, vamos acessar
o erro ou serviço de alerta. Adicionará um ID Fx
ao botão OK de alerta
programaticamente. Para fazer isso, vamos criar
a variável ok. aqui. Usaremos o
método de pesquisa para obter a referência do botão
e atribuí-la
à variável ok., dessa forma. Em seguida, configuraremos o
ID para alertar. Ok. Agora vamos fazer o teste de
criação de carteira. Neste teste, em vez de chamar o método click on com
o parâmetro ok, vamos passar uma referência ao botão OK
da caixa de diálogo de alerta usando seu ID. Agora, este teste clicará inequivocamente
no botão certo de OK. Vamos fazer o mesmo com todos os outros testes com o
mesmo problema no projeto. Vamos corrigir o que está no teste
da carteira de importação. Agora, vamos fazer isso no teste send
Bitcoin Nested Segue. Finalmente, vamos corrigir os testes
e enviar o teste de Bitcoin. Agora, como exercício, deixarei que o aluno execute todos os testes de inscrição.
77. 75 Skillshare 2: Neste vídeo,
instalaremos e executaremos nosso aplicativo no ambiente de rede
principal. Como lidaremos
com dinheiro real, é altamente recomendável
que você garanta que todos os
testes de aplicação sejam aprovados. Além disso, é aconselhável
começar a jogar com
pequenas quantidades de Bitcoin. Primeiro, vamos atualizar a
biblioteca Bitcoin Java para a versão 0.4, 0.5 no arquivo POM. Esta versão corrige um
problema ao importar o arquivo da lista de palavras ao executar o aplicativo
após instalá-lo. Vamos até o serviço de
sementes mnemônicas e remover essas declarações,
pois não precisamos mais delas. Vamos fazer o mesmo com esse método de criação de sementes
mnemônicas
no controlador de
diálogo de criação de carteira. Agora, vamos executar nosso node
no ambiente de rede principal. Para fazer isso, vamos
acessar nosso
arquivo bitcoin.com e remover a linha de configuração do reg
test, salvar o arquivo e executar
o nó Bitcoin. Ok, agora nosso node está sendo executado no ambiente de
rede principal. Aí vem a parte triste. Pode levar dias
ou semanas para sincronizar nossa nota no ambiente principal da
rede, pois, por enquanto, ela
tem 436 GB de tamanho. No meu caso, o
console indica que o
progresso do download do blockchain é de cerca de 52%. Mais adiante neste vídeo, mostrarei o aplicativo em
execução na minha outra máquina, que já foi completamente
sincronizada. Por enquanto, vamos modificar nosso aplicativo para executá-lo
no ambiente de rede principal. No arquivo de propriedades de
pontos do aplicativo, vamos modificar o ambiente
Bitcoin configurando duas redes principais. Atribuiremos a porta 83 32
à configuração do URI RPC note. Essa é a porta padrão
que o node Bitcoin usa para expor sua API RPC
na rede principal. Em seguida, vamos definir a chave de criptografia na configuração
do URL da fonte de dados spring para essa
variável de ambiente que exige que definamos essa variável de ambiente em nosso sistema operacional antes de
compilarmos nosso código. Ao fazer isso, aumentamos a
segurança do nosso aplicativo, evitando expor as
variáveis do banco de dados em nosso código. Vamos fazer o mesmo
com os valores das configurações de nome de
usuário e senha do Spring Data Source. Agora vamos gerar
valores seguros para essas configurações. Para fazer isso, vamos usar o gerenciador
de banco de dados SQL para conseguir isso chamando a
função de chave criptografada desta forma. Vamos gerar três valores copiá-los e colá-los
em um arquivo de texto. É importante que
você mantenha esses valores em um local seguro,
pois qualquer alteração
nesses valores antes de
compilar o aplicativo novamente resultará na perda do
acesso ao banco de dados. Se isso acontecer, você ainda
terá acesso à sua carteira. Se você mantiver suas carteiras, mnemônica e senha
, precisará excluir
os arquivos do banco de dados e compilar o
aplicativo novamente. Agora, vou colar esses valores de variáveis de
ambiente diretamente no aplicativo que as propriedades dos
pontos podem corrigir. Estou fazendo isso porque,
pelo menos na minha máquina Windows, o aplicativo
não interpola esses valores com o ambiente
do sistema. Primeiro, o mesmo problema
não acontece no Linux. Então eu acho que é algum tipo de bug
estranho durante a compilação. Diga-me na seção de
comentários se você teve
o mesmo problema. Assim, podemos encontrar uma solução
para esse problema juntos. Por enquanto, podemos seguir em frente com o aplicativo
dot properties is, is in the Maven tab. Vamos clicar com o botão direito
do mouse no botão Instalar. Clique em modificar a
configuração de execução. Na guia do corredor. Vamos ativar a
caixa de seleção pular testes para que
o
comando de instalação do Maven não execute os testes do
aplicativo antes de instalar
o aplicativo. Se você estiver usando versões mais recentes do
IntelliJ AID, essa opção pode estar disponível
no ícone de configuração nesta janela. Clique no botão OK. Agora, clique duas vezes na opção de instalação
personalizada dentro da seção Executar
configuração. Ótimo, o aplicativo
foi
instalado com sucesso dentro da
pasta indicada no console. Antes de executá-lo,
certifique-se de instalar o Java SDK com a mesma
versão do aplicativo. Vou acessar o site da Oracle
para fazer o download e instalá-lo. Depois de instalá-lo, feche
e abra o terminal. Agora, copie o caminho em que seu aplicativo instalou
o arquivo JAR do aplicativo. Você pode usar o comando java
space double hyphen version para garantir que seu terminal execute
a versão correta do Java. Agora execute o comando java space, hyphen jar space, o
caminho que você acabou de copiar. Ótimo, o aplicativo
foi iniciado com sucesso no ambiente de rede
principal. Vamos tentar criar uma nova carteira. Ele
criou uma nova carteira com sucesso, mas como nosso node ainda
está afundando, a
barra de progresso do carregamento permaneceria ativa por um longo tempo antes
que pudéssemos testá-la. Agora, mostrarei a carteira funcionando no ambiente de
rede principal da minha máquina Linux, onde o
nó está 100% sincronizado. Então, acabei de instalar o aplicativo da mesma
forma que fizemos para o Windows. Isso mostra uma grande vantagem do
Java, que é a compatibilidade
perfeita entre plataformas. Vamos executar o aplicativo. De agora em diante, vou
esconder alguns dados que você
verá na tela
por motivos de privacidade. Primeiro, eu carrego uma carteira. Eu já o criei corretamente carregado conforme o esperado. Agora, vou criar uma nova carteira. Vou anotar a semente
mnemônica usando caneta e papel antes de
clicar no botão OK. Agora, vou copiar o endereço e colá-lo em um editor de texto. Agora, vou carregar a carteira
anterior, que contém alguns fundos. Agora vamos enviar alguns Satoshi
para o endereço que copiamos da tabela de endereços. Podemos ver que um novo
endereço de mudança recebeu alguns fundos. Ótimo. Na tabela de transações, vemos que uma nova
transação com confirmação
zero foi criada. Agora vamos abrir a carteira
que recebeu fundos. Podemos ver que tanto
a tabela de endereços quanto a tabela de transações têm um novo registro indicando que recebemos alguns Satoshi
com sucesso. Ótimo, tudo está
funcionando corretamente.
78. Extra class - Bitcoin Core v26: Bem-vindo à nossa primeira aula
extra sobre como atualizar nosso aplicativo para se comunicar com a versão 26 do núcleo do Bitcoin. Veremos que há
boas razões para se
manter atualizado com a versão
mais recente do Bitcoin Core. Primeiro, vamos visitar este site para baixar a versão 26 do
núcleo do Bitcoin. Clique na versão apropriada para seu sistema operacional. Como estou usando o Windows, vou baixar o arquivo. Essencialmente,
substituiremos a versão atual do núcleo
Bitcoin que temos Certifique-se de escolher o mesmo caminho
de instalação
que o atual. No meu caso, não vou continuar com a instalação, pois
já a tenho. Mas para você, deve ser tão
simples quanto clicar
no botão Avançar várias vezes antes de executar a versão recém-instalada. Vamos explorar os
benefícios imediatos que ele oferece, começando com a versão 25 do
núcleo do Bitcoin. Podemos ver em suas
notas de lançamento que ele implementa um novo índice que
acelera significativamente as digitalizações Re da carteira Para optar por esse novo filtro, basta adicionar o filtro de
bloco igual uma configuração ao nosso arquivo de configuração
Bitcoin Ao reiniciar o nó, ele começará a criar
esse novo índice Pode levar algumas
horas para ser concluído, mas depois perceberemos
que carregar uma carteira depois de algum tempo sem executar nosso nó se torna muito mais rápido Agora vamos discutir algumas
mudanças introduzidas nas notas de lançamento da
versão 26. Descobrimos que, para usar carteiras sem
descritores, precisamos definir uma configuração
RPC obsoleta em nosso arquivo de configuração Bitcoin Posteriormente, as carteiras sem
descritores serão descontinuadas em futuras versões principais.
Não se preocupe Demonstraremos como migrar nosso aplicativo para carteiras de
descritores na próxima Por enquanto, para garantir que
nossas carteiras atuais funcionem com a versão 26 do núcleo do
Bitcoin, vamos adicionar essa configuração ao
nosso arquivo de configuração do Bitcoin Enquanto isso, vamos também
adicionar que o filtro de bloco igual a uma configuração que
discutimos anteriormente Agora vamos executar nosso nó principal do
Bitcoin no ambiente de teste de registro. Estamos quase terminando, como sempre, com qualquer alteração significativa
que fazemos em nosso aplicativo Precisamos executar todos os nossos testes para garantir que tudo esteja
funcionando corretamente. Eu já fiz isso do meu
lado e descobri que um teste parou de funcionar quando executado na nova versão principal do
Bitcoin. Acontece que o teste de
não deve enviar Bitcoin com a senha errada
da classe de teste de envio de Bitcoin
falhou. No entanto, não porque a transação foi enviada
com sucesso, mas porque o erro
real retornado diferiu do esperado Eu o depurei e
descobri que a resposta de erro que o núcleo
do
Bitcoin envia na nova versão agora contém uma mensagem diferente,
que é essa Simplesmente removemos o não
do início e adicionamos a
falha no final. Agora, o mapeamento entre essa resposta de
erro do núcleo e nosso aplicativo deve
ser preciso. É isso mesmo. Agora, se você executar nossos testes, todos
eles devem passar. Na próxima aula extra, vamos nos aprofundar no
que é uma
carteira descritora e como adaptar nosso aplicativo para
criar esse tipo de vamos nos aprofundar no
que é uma
carteira descritora e como adaptar
nosso aplicativo para
criar esse tipo de
carteira. Te vejo então.