Bitcoin Professional 2/4

Se você não tá acompanhando a série, abre o olho e segue o outro episódio dela aqui ó:

https://www.facebook.com/groups/btcbr/permalink/1615608405115988/

Antes de qualquer coisa, tenho que pedir desculpas por não ter postado esse segundo episódio da série. Comprei uma guitarra de 8 cortas e tô a semanas tentando tirar Bleed do Meshuggah (depois eu faço um tutorial de como dar aquela palhetada do inferno).

Obrigado as exatas 18 mensagens no inbox pedindo que eu fizesse o segundo episódio da série. Sem essa galera, possivelmente nem ia ter segundo episódio.

Também vale dizer que o artigo sobre anonimato deverá intermediar os artigos da série Bitcoin Professional. Minha ideia é ir alternando, um de cada vez. O que fez essa segunda parte demorar foi realizar a transação que vou colocar de exemplo aqui sendo que liquidei minha posição a um tempo.
 
Mas veja pelo lado bom, TAMO DE VOLTA, IZZZZZI, e com um conteúdo PESADÃO.

Esse módulo visa ensinar sobre como funcionam as transações das moedas virtuais (em especial das Bitcoins, mas o princípio é o mesmo para várias outras moedas também), desde a parte de construção da transação, seleção de outputs, até a seleção da fee mais apropriada para consolidar a transação.

Da mesma maneira que o módulo anterior, eu pretendo ensinar o conteúdo para que você possa realizar transações no RAW, usando somente código local para exportar a transação serializada.

Diferentemente do outro módulo, dessa vez indico usar uma biblioteca para NodeJS para construir a transação. A biblioteca em questão é a Bitcore (que pode ser encontrada aqui: https://bitcore.io/), por ser razoavelmente fácil de usar e tem uma quantidade significativa de documentação. Existem alternativas para a Bitcore e que com certeza podem suprir bem outras necessidades específicas (Ex: BitcoreJS — https://github.com/bitcoinjs/ — que usa o JavaScript do próprio navegador para executar as funções e possível é uma das mais famosas, Bitcoind — https://en.bitcoin.it/wiki/Bitcoind — que usa requisições remotas para executar as funções, o que pode ser bem útil, bitcoin-php — https://github.com/Bit-Wasp/bitcoin-php — que usa livrarias em PHP para quem está mais acostumado. Inclusive vale falar que a quantidade de commits nela é bem grande). Cada um escolhe o que vai usar, já que todas elas funcionam de maneira muito parecida.
 
 Lembrando que o meu objetivo aqui é ser agnóstico quanto a linguagem. Entenda funções como sendo uma ordem lógica de fatores, e não como funções em si (HASKELL FEELS).

Então vamos lá.

A primeira coisa que vamos aprender a fazer é transferir os BTCs de uma carteira para outra carteira. Para isso é necessário explicarmos como funcionam exatamente as transações em Bitcoin para que não ocorram confusões em relação ao conceito envolvido. Essa parte é a essência do artigo do Satoshi Nakamoto, então existe a chance de você acha-la um pouco mais complexa.

Vamos começar desembrulhando os conceitos.

Entendendo os conceitos da transação

Duas coisas antes de começarmos:

  1. Se você tiver alguma dúvida, pergunte nos comentários ou consulte a documentação do Bitcoin. Existe uma quantidade legal de material na internet.
  2. Alguns desses conceitos são explícitos na documentação, outros não. Não estou me prendendo a formalidades aqui.

Conceito 1 — Todos os endereços e todas as transações são públicas.

O Bitcoin não é um protocolo anônimo porque o seu trade-off de credibilidade é a publicidade e o consenso, e sem que isso seja público é impossível dar essa credibilidade. Difícil é conseguir fazer associações entre pessoas, carteiras e transações, uma vez que a simples propriedade de uma chave privada (ou, na maioria dos casos, a criação da chave) dá autoridade sobre os tokens administrados pela carteira.

Em exemplo ao que acabei de falar, houve um caso que ficou famoso nesses dias [ http://thehackernews.com/2017/07/cashout-bitcoin-ransomware.html ], que foi o método que os huligans-fazedores-de-ransomware usam para poder lavar o dinheiro que eles ganharam com as pragas. Seria extremamente fácil identificar os malfeitores se eles enviassem o dinheiro de alguma de suas carteiras públicas para uma Exchange e liquidassem tudo para uma moeda qualquer. A internet tentou achar essas pessoas (criando bots no Twitter para monitorar carteiras e tentar identificar o fluxo do dinheiro, como o https://twitter.com/actual_ransom/) , mas sem sucesso, uma vez que eles apelam para moedas que garantam o anonimato através de Exchanges mais liberais em relação a confirmação de identidade.

Conceito 2 — Sua carteira não tem dinheiro nenhum dentro. É sua assinatura que “tá no dinheiro”.

Atenção, esse conceito é o mais importante e o mais chato. Atenção dobrada. Qualquer dúvida comente!

Te desafio a pensar sobre uma coisa: Por que não temos um papel-moeda que represente as BTCs? Tudo bem que a ideia de dinheiro digital é mais prática, mas essa não é uma boa resposta técnica. O problema está em como os blocos de transações funcionam.

Ao invés de existir realmente algum dado dentro da sua carteira, o que sua carteira tem é a propriedade sobre uma quantidade X em bitcoin, cuja assinatura foi feita por todos os envolvidos anteriormente no processo, desde o bloco minerado, e você é o último dessa lista, significando que você tem um dinheiro não gasto na sua conta

Quando você gasta uma Bitcoin, o que de fato você está fazendo é passando a propriedade dessa última posição na lista para outra pessoa. Sendo assim, o que corre de um lado para o outro é a propriedade do token, e não o token em si, fazendo com que seja impossível ter um papel com valor. E se você pensar “então por que não emitir um papel com uma chave privada de uma carteira?”, lembre-se que o proprietário pode transferir a propriedade daquela carteira a outra e o papel perderia completamente o valor.

Se você tiver dificuldades para entender esse conceito, pense da seguinte forma:

- Pegue sua carteira (a física mesmo, em que vc guarda seus documentos):

- Sua identidade/CNH é a sua chave privada. Ela garante que você é você porque ela tem sua assinatura ali.

- Pegue o dinheiro que está na sua carteira e contabilize (Você tem R$ 20,00).

- Agora imagine que você chegue no caixa de um supermercado e na hora que vai entregar R$ 20,00 para pagar pelas suas comprar, o caixa seja o Satoshi Nakamoto (WTF) e te questione de onde veio esses R$ 20,00 (porque ela leu um exemplo escroto de um cara na internet…hehe). Ele acha que na verdade você falsificou esses R$ 20,00, mas você sabe que não falsificou nada. Como provar?

- A única maneira que você teria de dar uma resposta concreta de que aqueles R$ 20,00 não foram, sei lá, uma fração de um roubo ou fruto de uma falsificação, seria apontar todo o caminho que aqueles R$ 20,00 fizeram, pegando a assinatura de todas aquelas pessoas até que ela chegue em você.

- Você, muito avançado para seu tempo, milagrosamente TINHA UMA LISTA com todas as pessoas por quem aqueles R$ 20,00 passaram, devidamente assinada. (Eu preciso dormir mais…)

- O que você vai fazer é dar o certificado assinado por você ao Satoshi Nakamoto e ele será o último da fila a ter os R$ 20,00. Dessa forma temos todas as pessoas pagas e o dinheiro circulando.

Da mesma forma funcionaria se o valor fosse fracionado, a diferença é que teríamos duas assinaturas ao invés de uma (cada uma dando a propriedade de uma parte do valor).

Acho que agora deu para dar uma sacada melhor. Como falei, é um pouco confuso para quem está entrando agora no mundo das criptos, mas é assim que a gente faz para poder acabar com o monopólio dos bancos.

Conceito 3 — Inputs e Outputs

Cada transação feita em Bitcoins possui inputs e outputs, com exceção da transação que minerou o bloco (que não tem inputs).

Explico: Input é toda vez que a propriedade de um token é passada a você através de uma transação, e output é quando ele sai da sua propriedade. O saldo em sua conta é a soma das posições de output que você tem e que ainda não se transformaram em input em outras transações (lembre-se do “último da fila”). Para esse conceito de Ouputs não gastos, daremos o nome de UTXO (Unspent TransaXtion Output. Tx é a sigla para transaction usada pela galera das BTCs).

A exceção de quem minerou o bloco ocorre porque o minerador não tem nenhuma transação anterior dando a propriedade a ele. Então simplesmente brota o dinheiro na conta dele (por enquanto admita isso como verdade até falarmos de mineração aqui, ok?).

Essa coisa toda de somar suas posições de outputs que ainda não foram gastas para gerar o saldo em sua carteira pode parecer complexa em primeira instância (e é), mas a ideia é poder fazer aquele caminho de volta em relação ao gênesis daquele token, garantindo a confiabilidade do sistema.
 
 Para poder facilitar a verificação das origens de um saldo, o Blockchain.info já tem um botão onde é possível visualizar cada um dos UTXOs que estão compondo o saldo de uma carteira. A título de exemplo, pegue esta carteira https://blockchain.info/address/3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r [é a carteira com maior saldo unitário e Bitcoin do mundo, mas lembrando que não existe problema algum em ter várias carteiras então podem existir pessoas mais ricas que ela ] e clique em “Unspent Outputs” (ou “não gastos Saídas” se vc estiver usando a versão em português [recomendo mudar para o inglês]). Você verá várias transações (como a de hash “cd558b33246ef51876021e3274319f454ac830ca064085b85c32e6c43dd3bb15” https://blockchain.info/pt/tx/cd558b33246ef51876021e3274319f454ac830ca064085b85c32e6c43dd3bb15/1). 
 
 Nela temos um input:

1CwuyF6ej8Br21e15Yco9qXdc1NQaxmu6i (726.41340188 BTC — Output)

E dois outputs:

1FR7XggURooC2VvGMkMNvruFXEHTKQPNAf — (Spent) 30.47657993 BTC
3D2oetdNuZUqQHPJmcMDDHYoqkyNVsFk9r — (Unspent) 695.93623 BTC

Perceba que o único momento que aparece a carteira que estamos observando é no output. E é a única que precisamos ver mesmo. Neste caso, indicamos que recebemos essas Bitcoins de outra pessoa e ele está disponível em nossa conta como um UTXO.

Entretanto, em alguns casos podemos ver uma transação que tem o próprio endereço como output (como na transação https://blockchain.info/pt/tx/39d8648dbd92d2162ac8d5a0236363c361d245faa22fd2d7e4cddb64e8a781a5, que inclusive não tem somente um, mas 4 inputs da mesma carteira e um output para ela mesma). Isso quer dizer 3 coisas: 
 
 1) Quando ele foi especificar os UTXOs a serem usados na transação, ele precisou pegar mais de um UTXO para poder dar o valor que ele queria transferir. Seria como naquele exemplo que demos sobre o caixa de supermercado, e ao invés de ter apenas uma nota de R$ 20,00, você tivesse 4 notas de R$ 5,00 e tivesse que justificar de onde as 4 notas vieram para poder validar a transação.

2) Quando ele especifica o endereço dele sendo um Output e um Input, significa que parte do valor da soma daqueles UTXO deve voltar pra ele. No conceito das Bitcoins e do mundo real, isso se chama troco (change). Imagine que ao comprar suas compras no Mercadinho do Satoshi, suas compras tenham dado R$ 12,00, mas você só tenha uma nota de R$ 20,00. O Satoshi teria que devolver R$ 8 a sua carteira. É a mesma questão que ocorre aqui, mas você não precisa passar TODO o valor para ele e esperar pelo troco, você pode especificar o quanto da sua UTXO vc quer gastar com a transação e o quanto quer que volte pra você.

3) Eu posso fazer transações que visem diminuir a quantidade de UTXOs na conta. Apesar de ninguém fazer isso porque o valor não compensa. (Você vai pagar caro para fazer a transação, que inclusive é nosso próximo conceito).

A(UTXO1), A(UTXO2), A(UTXO3) -> A(UTXO4)

Então resumindo: Transações tem inputs, outputs, seu saldo é a a soma de UTXOs. Concluímos também que Satoshi Nakamoto seria um péssimo caixa de supermercado.

Conceito 4 — Fees

Uma coisa importante: existe um valor a ser contabilizado em uma transação que não é possível colocarmos no nosso exemplo de dinheiro físico: a famosa FEE. A fee (ou tarifa, na tradução mais precisa) é o valor pago por um dono de UTXO ao minerador que dará o selo de autenticidade para aquela transação ser inserida no bloco. Mais uma vez retomo que não quero falar de mineração ainda e veremos esse processo com mais detalhes no futuro, mas o cálculo de uma transação inclui a fee e temos que falar dela para poder facilitar na hora que explicarmos como fazer uma transação no RAW.

Se você ainda não sabe, mas sem os mineradores é completamente impossível fazer o sistema das Bitcoins funcionar. São eles que fazem as transações acontecerem e eles que gastam seus processadores de ASICs para poder faturar. Mineração é amor, mas o fato do algoritmo não ser resistente a ASIC centralizou o poder de mineração em poucas pools e na China, coisa que o Etherum fez melhor que as BTCs para preservar a descentralização. Enfim, mais uma vez vou evitar de falar de mineração aqui. Vou explicar esse problema em seu devido tempo.

A fee é uma parte do UTXO, e por isso ela tem que estar especificada na transação. O que muda é a maneira que vc quer especificar essa transação, uma vez que se você especificar errado vai acabar pagando uma fee absurda sem querer. Vamos visualizar como podemos expressar uma fee matematicamente dentro de uma transação.

Tomemos:

Input = X, 
Output = Y,
Troco = Z,
Fee = W

A) Se X e Y , onde X = Y, então W = X — Y = 0 e sua transação será rejeitada pela rede. Existe um cálculo mínimo através da quantidade de bytes que uma transação tem (uma simples tem aproximadamente 225 bytes) e a quantidade de fee que é atrativa para um minerador incluí-la no bloco (Calma, mais uma vez, vamos falar disso depois). O cálculo são 175 satoshis por byte da transação para até 1 dia de confirmação (que é outra coisa que vamos falar depois). Você pode sempre consultar a fee através de sites como: https://bitcoinfees.21.co/ , onde ele explica como você deve fazer para calcular uma fee legal para sua transação. Recomendo acompanhar tmb (https://www.reddit.com/r/Bitcoin/comments/6jdpp7/stop_paying_exorbitant_fees_my_026_fee/)

B) Se X e Y, onde X > Y, então W = X-Y > 0. Tem que tomar cuidado com isso inclusive ao tentar fazer uma RAW transaction de um valor pequeno dentro de um UTXO grande e acabar mandando todo resto do UTXO pro minerador. A solução está em especificar a change.

C) Se X, Y e Z, onde X > Y, então W = X-Y-Z. Especificações de troco aumentam o tamanho em bytes de uma transação, podendo aumentar o tamanho da fee, mas dando segurança e flexibilidade em relação aos UTXOs (já que podemos transformar um monte de transações em um único UTXO mais barato no futuro).

D) Se X, Y e W, onde X > Y, então Z =X-Y-W e o endereço será a conta de origem.

E) Se X e Y, onde X < Y, então a transação é automaticamente rejeitada por UTXO insuficiente. A saída nesse caso é fazer como aquela transação com 4 inputs: junte os UTXOs. Se a soma de todos os UTXOs disponíveis em sua carteira for menor que Y, então é saldo insuficiente — Soma(X[n]) < Y.

Essa é a maneira mais simples de demonstrar como funciona a especificação das fees e como ela pode te ajudar a se prevenir de fazer cagada. E lembre-se que algumas carteiras ou contas de Bitcoins podem conter taxas especiais e outros valores embutidos direto na transação (incluído nos scripts, como veremos também em outro episódio).

>>IMPORTANTE <<

Existe um problema que tange as UTXOs e as Fees que é extremamente relevante de se falar. Quando temos contato exchanges e carteiras que dizem não cobrar taxas, mas a fee da transação é muito grande podemos apostar que estamos diante de uma fraude (porque tem uma taxa ai sim) OU de um algoritmo de seleção de UTXOs não otimizado. Falo isso porque recentemente fiz uma pequena transação para uma carteira minha da Xapo, e percebi que não poderia retirar o valor da carteira, porque pasmem, eu precisava pagar uma fee de 0.0028 para o minerador. Colocando a título de comparação 280.000 satoshis eu precisaria fazer uma transação de 1600 bytes (com o pagamento médio de 175 satoshi/byte). Eu me lembro de ter feito apenas 2 depósitos de bitcoin durante toda história da conta, dois grandes, então não teria nenhum problema em fazer uma transação de 225 Bytes. E se caso eles usassem uma conta unitária (a Xapo ter uma própria conta onde ela mantivesse a liquidez dos pagamentos), ai que não faria sentido mesmo negar meu saque.

A questão da otimização das UTXOs funciona da seguinte forma: Imagine que queremos fazer a transação de 0.002 BTCs de uma conta A para uma conta B. Nessa conta A temos 4 UTXOs de valores representados por ordem de data (primeiro mais antigo, como é na maioria das APIs): { 0.001, 0.0005, 0.0005, 0.0028, 0.0005, 0.001 }. Se simplesmente selecionarmos as UTXOs através do “padrão” (da mais antiga para a mais nova), acabaremos por usar duas, três ou até mais transações (dependendo da fee), e ainda teremos que especificar conta de troco por conta da diferença dos últimos UTXOs em relação ao montante que queremos pagar. Nossa transação possivelmente ficará duas ou três vezes maior, consequentemente pagando duas a três vezes o valor da fee. Agora, em um algoritmo otimizado, podemos colocar toda a transação em um único UTXO, sem especificar a fee (assumindo que 80.000 satoshis cubram de maneira mais suficiente uma transação pequena).

A maneira mais correta de se realizar a otimização da seleção de um UTXO é a seguinte: estabelecer um número de confirmações mínimas que garantam a credibilidade da transação, pegar dentro das transações aquelas que ficam mais próximas do valor da transação — sempre extrapolando o valor da transação. Também tem de existir um mecanismo para realizar a contagem dos bytes da transação com especificação de Fee e Change e comparar ao pagamento de uma fee mais alta pela transação. Em alguns casos pode valer mais a pena pagar mais caro pela Fee do que especificar a Change do resto da UTXO. Sacou?

Essencialmente: faça um algoritmo de otimização de fee que seja verdadeiramente inteligente e fique rico num mercado que ninguém colocou a mão ainda. A Xapo seria o primeiro cliente que eu indicaria.

Conceito 5 — Broadcast

Esse conceito ele é simples e complexo ao mesmo tempo. A razão dessa dicotomia reside entre o técnico e o abstrato. No abstrato, o conceito é simples: enviar uma transação a uma porrada de node do Bitcoin e aguardar até que os mineradores incluam sua transação no bloco. Já no técnico, a coisa fica um pouco mais complicada:

[Caso eu tenha pisado muito fundo no acelerador em relação ao que é um “node”, a explicação é bem simples e pode ser consultada aqui (inclusive com um tutorial de como rodar um node :D https://bitcoin.org/en/full-node) ]

Quando rodamos um node do Bitcoin, estamos simplesmente falando para a rede que temos uma cópia do Blockchain rodando em nosso servidor e que esse bloco deve participar do consenso entre os outros blocos que já existem.

Diferentemente de uma transação feita através do banco (onde dá aquele calafrio de aparecer “não autorizada” por uma razão desconhecida — a gente sabe, você não tem dinheiro), o Blockchain não é binário ao dizer se uma transação é válida ou não. Ele inicialmente diz “Eu não sei”, depois ele fala “Olha, me falaram isso, mas não tenho certeza, confie se quiser”, e só depois que um mundo de gente concordou com aquela situação, ai ele chega e fala “tá tudo certo”.

Você pode verificar isso através do blockchain.info, na área de confirmações. No caso da transação que vimos anteriormente ( https://blockchain.info/pt/tx/39d8648dbd92d2162ac8d5a0236363c361d245faa22fd2d7e4cddb64e8a781a5), podemos observar que ela conta com 36 confirmações, significando que existem 36 nodes que autenticam aquela transação no bloco delas. A pergunta que fica é: o quão seguro isso é?

E a resposta é igualmente chata: depende do nível de segurança que vc quer dar a sua transação. Se você quiser uma resposta binária, teria que esperar a eternidade para que todos os nodes respondam que ela está ok. Só tem um problema, no tutorial que eu mandei a 3 parágrafos atrás a pessoa ensina você a inaugurar um node na sua casa. E se você não quiser autenticar a transação você vai ter que esperar o cara que leu o artigo e inaugurou um node em casa confirmar? Acabou pro cara?

Não exatamente. A questão é que você pode aceitar transações com 0 confirmações se você quiser, mas você estará sujeito a pessoas má intencionadas que executem algumas condições de corrida com sua transação. Ex: supondo que eu gastei 1BTC para comprar o carro e retirei o carro com 0 confirmações, e ao mesmo tempo fiz um broadcast para uma porrada de node dizendo que eu mandei esse BTC para outra carteira (temporalmente antes de comprar o carro). O consenso vai seguir algumas regras para tentar evitar entender que você realizou a segunda operação (como tentar dar uma importância diferente para os nodes), mas aceitando essa transação sem nenhum node ter confirmado, você fica realmente na mão.

Todo esse problema tem relação direta com a mineração e será explicado melhor no capítulo sobre mineração. Vamos voltar o foco.

A recomendação é sempre fazer o broadcast em nodes grandes. Algumas plataformas como a própria blockchain.info disponibilizam um campo para você colocar a transação serializada e lança-la no node deles ( https://blockchain.info/pushtx ). Isso é útil e interessante, porque é um canal que agiliza para quem quer garantir a confiabilidade usando um node popular.

Feito esse broadcast, basta aguardar até que mais confirmações sejam feitas e garantam a sua transação. Quanto mais confirmações, melhor.

“Conceito 6” - Scripts

Esse conceito está entre aspas porque, assim como a mineração, ele terá um capítulo inteiro só para ele, mas precisamos explicar um pouco do que ele é para podermos criar uma transação.

O script é uma sequência de funções que são executadas para poder fazer uma transação ocorrer. O script é quem faz de fato uma transação ocorrer, podendo ele ser customizado para atender a diversas necessidades. É possível até mesmo fazer um sorteio de valor em Bitcoin baseado no blockchain usando os scripts.

Em resumo, o script mais famoso é Pay To PubKey Hash (P2PKH). Essencialmente ele é um scripts simples de transação da moeda (mandar Bitcoin de A para B) usando os endereços comuns. Você pode consultar mais em (https://bitcoin.org/en/developer-guide#p2sh-scripts).

Explicados esses conceitos, vamos para a parte de construção de uma transação RAW. Agora que a coisa vai começar a ficar legal.

Criando uma transação manualmente

Essencialmente o que precisamos fazer é criar uma transação que siga os conceitos que descrevemos acima e gerarmos uma transação serializada para divulga-la através do broadcast do Blockchain.info (https://blockchain.info/pushtx). Como forma de evitar erros, o próprio blockchain.info possui uma área de “Decode Transactions” ( https://blockchain.info/decode-tx ), que tenta transformar a serialização de uma transação nos dados dela. Apesar de ser EXTREMAMENTE importante usarmos essa consulta para evitar erros (como o da fee absurda, como falei), o decode da Blockchain.info não realiza uma consulta no próprio node para verificar se as informações batem ou não, mostrando somente os dados sem serialização. Isso é ruim porque torna mais difícil encontrar erros que estejam vinculados ao Input dos UTXOs. Por isso, vamos usar o decode da BlockCypher (https://live.blockcypher.com/btc/decodetx/) , que faz essas consultas e mostra os valores que serão interpretados pelo node através da transação serializada. Já ocorreram problemas que só foram possíveis de encontrar graças a essa consulta prévia ao node antes de decodificar, por isso fique atento.

Agora vamos definir os dados que vamos precisar para poder fazer a transação:

1) A chave privada da carteira com saldo e o endereço da carteira. Para mantermos a cronologia do curso, irei usar a mesma chave privada que no primeiro episódio para realizar a transação. Relembro que nossa chave está em notação hexadecimal.

PK =" 4125442A472D4B6150645367566B59703373367638792F423F4528482B4D6251" 

A chave é pertencente a este endereço:

from_wallet = "1Dze9b2WYBzuMSHj1RnKXAn1oewGRguuoY"

2) Aqui vem a especificação mais complicada de se fazer: a seleção dos UTXOs necessários para fazer a transação do dinheiro. A maneira mais correta de se fazer isso seria criar um algoritmo de consulta a um node privado nosso (exchanges fazem isso), mas já que não queremos manter 250 GB de armazenamento inútil e temos nodes grandes como o Blockchain.info que disponibilizam uma API, podemos fazer uma consulta no node deles para receber a lista de UTXOs que podemos gastar. Aqui vou selecionar uma UTXO mais apropriada através da consulta simples do Blockchain.info.

Vou escrever uma observação importante ao final desses conceitos sobre a seleção dos UTXOs.

3) A carteira de destino. No caso, gostaria de fazer uma doação ao grande Raphaël Lima (https://www.facebook.com/raphael.lima.77398), front-man do canal Ideias Radicais (https://www.youtube.com/channel/UC-NwgkrLPYmzM-xoLr2GX-Q). Ele tem feito um trabalho fenomenal com seus vídeos. Eu sempre costumo falar que existem duas Bitcoins no mercado: a Bitcoin enquanto Solução Financeira e a Bitcoin enquanto Filosofia. Se você é um entusiasta da Bitcoin enquanto Filosofia, o canal Ideias Radicais é uma parada OBRIGATÓRIA pra você!

Importante fazer uma observação técnica sobre essa carteira: quem estava atento na última aula vai notar que essa carteira é menor do que o endereço de carteira de envio e vai ver que ela é aquele endereço compacto (com menos bytes após a compressão). Na aula passada eu falei da existência dessas carteiras, mas não tinha pego nenhum exemplo. Isso não muda nada dentro da nossa RAW, já que o bloco lê a carteira exatamente da mesma forma.

to_wallet = 1Kceqou4KDdmJNREAzvv9GD3JB2WbvohqJ

4) O valor que vamos transferir. No caso, será uma pequena quantia de 500.000 satoshis, ou 0.005 BTC. Esse valor equivale a algo próximo a R$50.

amount_to_send = 700000

5) O valor da fee, e caso especifiquemos a fee temos que falar de quem é o troco. Neste caso, eu não vou especificar a fee e quero que todo o restante do UTXO seja dado ao minerador. Como temos um valor muito pequeno, quero diminuir ao máximo o tamanho da transação para que ocupe menos bytes. Lembrando que o valor da fee é de aproximadamente 175 satoshis por byte, e nunca pode ser menor que 662 satoshis. Para mim é fácil fazer isso porque tenho controle da carteira que está enviando o dinheiro também.

6) O script da transação. Também vou usar a versão mais simples e compacta da transação, que é o script P2PKH mais básico. Nós identificamos somente o script hash (relembro que o próximo capítulo será só sobre scripts).

script_hash = 76a9146f7763594f37d4824075a0866420f316e1a01b7088ac

>> Resumo das variáveis envolvidas <<

PK = “4125442A472D4B6150645367566B59703373367638792F423F4528482B4D6251”;
from_wallet = “1Dze9b2WYBzuMSHj1RnKXAn1oewGRguuoY”;
utxos = [{
“txId”:
“amount”: 700000,
“script”:
“satoshis”:
“address”: “1Dze9b2WYBzuMSHj1RnKXAn1oewGRguuoY”
}];
to_wallet = “1Kceqou4KDdmJNREAzvv9GD3JB2WbvohqJ”;
amount_to_send = 700000;

Definidas as nossas variáveis, é hora de colocarmos todos esses dados na nossa transação. Existem duas formas de fazermos isso: da maneira mais RAW HARDCORE, que seria escrevermos todo o objeto da transação, item por item, especificação por especificação, depois serializá-lo e submeter na área de broadcast, ou podemos usar o bitcore-lib, que possui algumas facilitações na hora de escrevermos a transação, como controle de erros (ex: ele te emite um alerta caso calcule que sua fee está muito baixa para a transação), serialização simplificada e funções de verificação de assinatura.

Eu, como pessoa mórbida que sou, vou fazer os dois. Inicialmente, usaremos as facilidades da Bitcore-lib para poder criar a transação serializada — que essencialmente é um grande código que representa sua transação por inteiro. Depois vamos acessa aquela aplicação que mencionei lá em cima da BlockCypher (https://live.blockcypher.com/btc/decodetx/) e vamos fazer o decode dessa serialização juntamente com uma consulta ao node deles e explicar detalhe por detalhe de cada informação contida naquela desserialização (essa palavra existe?). Dessa forma teremos a facilidade na hora de criar a transação do zero — que honestamente é um saco de se fazer — e mesmo assim teremos um bom material de estudos para identificar cada pedaço de uma transação no RAW.

Para realizarmos uma transação no Bitcore-lib, devemos fazer da seguinte forma:

1. Definir um objeto chamado “utxos” do tipo UnspentOutput(), e suas propriedades (que você pode conferir quais são através desse link aqui (https://bitcore.io/api/lib/unspent-output).Este objeto pode conter uma única UTXO ou uma array de UTXOs. No nosso caso, estamos fazendo uma transação com um único UTXO.

2. Inserir as propriedades da transação (lembrando que estamos fazendo isso manualmente, então não tenha receio de fazer as coisas no hardcode. Sua transação só será computada quando enviarmos para o broadcast manualmente).

3. Definir um objeto transaction do tipo Transaction(), e inserir os seguintes dados nele:

.from(utxos)
.to(to_wallet, amount_to_send)
.sign(PK)

4. Serializar a transação usando `transaction.serialize()`. Lembre-se de colocar algum console.log(transaction.serialize()) para podermos copiar a string que ele vai retornar e jogarmos no decodetx do BlockCypher.

Você pode — e deve — usar as funções que o próprio bitcore-lib oferece para ver se está tudo ok com sua transação antes de fazer o broadcast. Existem funções úteis como transaction.getFee(), transaction.hasAllUtxoInfo(), transaction.verify() e transaction.isFullySigned() que podem ajudar a encontrar erros antes de executar a operação.

Relembro que este não é um curso para aprender a usar o Bitcore, então se você tiver alguma dúvida consulte a documentação.

Feito isso, é hora de executarmos a segunda etapa, analisar o resultado do Decoder da BlockCypher. Antes de mais nada é bom deixar um calmante para os paranoicos em segurança (vulgo eu): Sua chave privada não aparece em nenhum momento após assinar uma transação. Ela não vai junto da versão serializada da transação (acredite, eu li o código deles para ter certeza, e você também pode ler, o link do repositório deles é esse aqui https://github.com/bitpay/bitcore-lib). Inclusive um monte de coisa não vai junto, saca só.

Será impresso um código da transação serializada. o código será representado por vários caracteres em hexadecimal. Esse trambolho é sua transação, pronta para ser lançada no broadcast.

Pegue este código e jogue no DecodeTX da BlockCypher. É seguro você colocar essa transação em qualquer lugar, uma vez que ela não possui sua chave privada (ou mesmo sua chave pública). Esse punhado de dados será incluído em um bloco para a mineração.

>> DISCLAIMER <<

Eu havia colocado alguns exemplos de código mais a fundo aqui, entretanto tinha uma certa chatice na hora de gerar as transações e tudo mais. Para evitar essa dor de cabeça, estou disponibilizando meu script inteiro para quem souber um pouco de node e quiser fazer as próprias transações.

Se algum de vocês puder, peço a gentileza de separar os exemplos de código para serem colocados na postagem. Não posso oferecer nada além de meus sinceros agradecimentos e créditos na postagem.

const bitcore = require('bitcore-lib');
//Endereço de origem
const pk_from_buffer = require('./privateKey.js')
const pk_from = new bitcore.PrivateKey(pk_from_buffer.toString('hex'))
const publicKey_from = new bitcore.PublicKey(pk_from)
const address_from = new bitcore.Address(publicKey_from)
console.log('Endereço de origem:' + address_from);
//Endereço de destino
const pk_to_buffer = require('./anotherPrivateKey.js')
const pk_to = new bitcore.PrivateKey(pk_to_buffer.toString('hex'))
const publicKey_to = new bitcore.PublicKey(pk_to)
const address_to = new bitcore.Address(publicKey_to, bitcore)
const value = 0 //Valor da transação
const fee= 0; //Valor da fee desejada 
const change= address_from //Endereço de troco.
console.log('Endereço de destino:' + address_to);
//Adição dos UTXOs disponíveis para a transação. Lembre-se que os UTXOs aqui são Inputs.
const utxos = new bitcore.Transaction.UnspentOutput(
{
"txid" : "", //Id da transação que gerou o nosso UTXO.
"vout": 0, //Indice do nosso UTXO na transação de Input
"address": address_from, //Endereço de origem.
"script" : "76a9149e4950c695f56d705182994462706a01cb9e916c88ac", //Tipo da transação anterior. (P2PKH)
"amount": 1 //Quantidade em satoshis.
}
)
//Dados da fee. No caso da testnet eles são inúteis, mas é importante informarmos na rede comum.
//Cria um objeto para a transação
let transaction = new bitcore.Transaction()
.from(utxos)
.to(address_to, value)
.fee(fee)
.change(address_from)
.sign(pk_from)
//Mostrando a transação na tela para podermos fazer o broadcast manualmente.
console.log(transaction.serialize())

Feito tudo, e agora?

Ao enviar a transação para o Broadcast, ela vai ser recebida por um node minerador, que vai processá-la e incluí-la em um bloco. Quando isso ocorrer, a transação vai começar seu processo de confirmação, que pode levar alguns minutos. É importante ressaltar que no mesmo momento que você faz o broadcast da transação você já pode consultá-la no Blockchain.info, onde ela será sinalizada com um botão vermelho escrito “Unconfirmed Transaction”. Basta esperar que os blocos venham.

Conclusão

Não é fácil fazer uma transação no RAW. Não tem graça fazer uma transação no RAW a menos que você tenha algo em mente.

Como ultima recomentação: leiam o livro Mastering Bitcoin. A FoxBit fez uma puta ação em traduzí-lo e disponibilizá-lo. Busquem saber sobre!

Like what you read? Give Benjamin Overture a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.