• Nenhum resultado encontrado

Endereços Bitcoin

No documento Dominando Bitcoin (páginas 76-83)

Um endereço bitcoin é uma string de dígitos e caracteres que pode ser compartilhada com qualquer pessoa que queira lhe enviar dinheiro. Os endereços produzidos a partir de chaves públicas consistem

em uma string de números e letras, iniciando com o dígito "1". Aqui está um exemplo de um endereço bitcoin:

1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy

O endereço bitcoin é o que mais comumente aparece como "destinatário" dos fundos em uma transação. Se fôssemos comparar uma transação bitcoin a um cheque de papel, o endereço bitcoin é o beneficiário, que é o que escrevemos na linha "à ordem de". Num cheque de papel, aquele beneficiário pode algumas vezes ser o nome de um possuidor de conta bancária, mas pode também incluir corporações, instituições, e até mesmo dinheiro. E por cheques de papel não precisarem especificar uma conta, ao invés disso, usam um nome abstrato como receptor dos fundos, isto torna cheques de papel muito flexíveis como instrumentos de pagamento. As transações bitcoin usam uma abstração similar - o endereço bitcoin - para torná-las muito flexíveis. Um endereço bitcoin pode representar outra coisa, como um script de pagamento, como veremos em [p2sh]. Por hora, vamos examinar o caso simples, um endereço bitcoin que representa uma chave pública, e é derivado dela.

O endereço bitcoin é derivado da chave pública através do uso de hashing criptográfico de uma via. Um "algoritmo de hashing", ou simplesmente "algoritmo de hash" é uma função injetiva (de uma via) que produz uma impressão digital ou "hash" a partir de uma entrada de tamanho arbitrário. Funções de hash criptográficas são extensivamente usadas em bitcoin: nos endereços bitcoin, nos endereços de scripts, e no algoritmo de prova-de-trabalho da mineração. Os algoritmos utilizados para produzir um endereço bitcoin a partir de uma chave pública são Secure Hash Algorithm (SHA) e o RACE Integrity Primitives Evaluation Message Digest (RIPEMD), especificamente SHA256 e RIPEMD160.

A partir da chave pública K, nós computamos o hash SHA256, e então computamos o hash RIPEMD160 do resultado, produzindo um número de 160 bits (20 bytes).

onde K é a chave pública e A é o endereço bitcoin resultante.

TIP Um endereço bitcoin não é a mesma coisa que uma chave pública. Endereços bitcoin sãoderivados a partir de uma chave pública utilizando-se uma função de sentido único.

Os endereços bitcoin são quase sempre apresentados aos usuários em uma codificação chamada "Base58Check" (veja Codificação Base58 e Base58Check), que usa 58 caracteres (um sistema numérico de Base58) e um checksum para ajudar a legibilidade humana, evitar ambiguidade, e proteger contra erros em transcrição e digitação de endereços. O Base58Check também é utilizado de várias outras formas no bitcoin, sempre que há a necessidade de um usuário ler e transcrever corretamente um número, tal como um endereço bitcoin, uma chave privada, uma chave encriptada, ou um hash de um script. Na próxima seção, examinaremos a mecânica da codificação e decodificação Base58Check, e as represetnações resultantes. Chave pública para endereço bitcoin: conversão de uma chave pública em um endereço bitcoin ilustra a conversão de uma chave pública em um endereço bitcoin.

Figure 5. Chave pública para endereço bitcoin: conversão de uma chave pública em um endereço bitcoin

Codificação Base58 e Base58Check

A fim de representar números grandes de uma forma compacta, utilizando poucos símbolos, muitos sistemas de computador utilizam uma mistura alfa-númerica com base (ou raiz) maior do que 10. Por

exemplo, enquanto o sistema decimal tradicional utiliza os 10 numerais de 0 a 9, o sistema hexadecimal utiliza 16, com as letras de A até F como os seis símbolos adicionais. Um número representado no formato hexadecimal é menor ao equivalente em decimal. Ainda mais compacto, a representação Base64 utiliza 26 letras em caixa baixa, 26 letras em caixa alta, 10 numerais e mais dois caracteres como "+" e "/" para transmitir dados binários sobre mídias baseadas em texto, como o email. A Base64 é normalmente utilizada para anexar arquivos binários em emails. A Base58 é a codificação binária baseada em texto desenvolvida para o bitcoin e utilizada e muitas outras criptomoedas. Ela oferece um equilíbrio entre uma representação compacta, leitura e detecção de erro e prevenção. A Base58 é um subconjunto da Base64, utilizando caixa alta, caixa baixa, letras e números porém omitindo alguns caracteres que são frequentemente confundidos e podem parecer idênticos quando mostrados com certas fontes. Sendo específico, a Base58 é a Base64 sem o 0 (número zero), O (o maiúsculo), l (ele minúsculo), I (i maiúsculo), e os símbolos "\+" e "/". Ou, mais simplesmente, é um conjunto de letras maiúsculas e minúsculas mais os números, sem os quatro caracteres mencionados.

Example 1. O alfabeto Base58 do bitcoin

123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz

Para acrescentar segurança extra contra erros de digitação ou transcrição, o Base58Check é um formato de codificação Base58, frequentemente usado em bitcoin, que tem um código de verificação de erros embutido. O checksum é composto de quatro bytes adicionais, acrescidos ao final dos dados sendo codificados. O checksum é derivado do hash dos dados codificados e, portanto, poder ser usado para detectar e prevenir erros de transcrição e digitação. Quando o software decodificador se depara com um código Base58Check, ele calcula o checkum dos dados e o compara com o checksum incluído no código. Se os dois não corresponderem, tem-se uma indicação de que o erro foi introduzido e o dado Base58Check é inválido. Por exemplo, isso previne um endereço bitcoin mal digitado de ser aceito pelo software da carteira como um destino válido, um erro que, do contrário, resultaria na perda de fundos. Para converter dados (um número) no formato Base58Check, primeiro adicionamos um prefixo aos dados, chamados de "byte de versão", que serve para identificar facilmente o tipo de dado codificado. Por exemplo, no caso de um endereço bitcoin, o prefixo é zero (0x00 em hexa), enquanto o prefixo usado para codificar uma chave privada é 128 (0x80 em hexa). Uma lista de prefixos comuns é apresentada em Base58Check prefixo de versão e exemplos de resultados codificados.

Em seguida, computamos o checksum "duplo-SHA", o que significa que aplicamos o algoritmo de hash SHA256 duas vezes no resultado anterior (prefixo e dados):

checksum = SHA256(SHA256(prefix+data))

Pegamos apenas os primeiros quatro bytes do hash de 32 bytes resultante (hash do hash). Esses quatro bytes servem como código de verificação de erro, ou checksum. O checksum é concatenado ao final. O resultado é composto de três itens: um prefixo, os dados, e um checksum. Esse resultado é codificado

usando o alfabeto Base58 descrito previamente. Base58Check encoding: um formato para codificar dados do bitcoin de maneira inequívoca, versionada e verificada. ilustra o processo de codificação Base58Check.

Figure 6. Base58Check encoding: um formato para codificar dados do bitcoin de maneira inequívoca, versionada e verificada.

No bitcoin, a maior parte dos dados apresentados ao usuário é codificada em Base58Check para torná- los mais compactos, fáceis de ler e para facilitar a detecção de erros. A versão de prefixo na codificação Base58Check é usada para criar formatos facilmente distinguíveis, que quando são codificados em Base58 contém caracteres específicos no início do payload codificado em Base58Check. Esses caracteres facilitam a identificação pelas pessoas do tipo de dado que está sendo codificado e como utilizá-lo. Isso é o que diferencia, por exemplo, um endereço bitcoin codificado em Base58Check que começa com o número 1 de uma chave privada codificada em Base58Check no formato WIF que inicia com o número 5. Alguns exemplos de versão de prefixo e os caracteres Base58 resultantes são demonstrados em Base58Check prefixo de versão e exemplos de resultados codificados.

Type Prefixo de versão (hex) Base58 prefixo de resultado

Endereço Bitcoin 0x00 1

Endereço Pay-to-Script-Hash 0x05 3

Endereço Bitcoin Testnet 0x6F m ou n

Chave Privada WIF 0x80 5, K ou L

Chave Privada Criptografada em

BIP38 0x0142 6P

Chave Pública Estendida em

BIP32 0x0488B21E xpub

Vamos ver o processo completo de criação de um endereço bitcoin, desde a chave privada, até a chave pública (um ponto na curva elíptica), para um endereço que sofre hash duplo e, finalmente, a codificação Base58Check. O código C++ em Criando um endereço bitcoin codificado em Base58Check a partir de uma chave privada demonstra todo o processo passo-a-passo, desde a chave privada até o endereço bitcoin codificado em Base58Check. O código de exemplo usa a livraria libbitcoin que foi apresentada em [alt_libraries] para algumas funções auxiliares.

Example 2. Criando um endereço bitcoin codificado em Base58Check a partir de uma chave privada #include <bitcoin/bitcoin.hpp>

int main() {

  // Private secret key.   bc::ec_secret secret;

  bool success = bc::decode_base16(secret,

  "038109007313a5807b2eccc082c8c3fbb988a973cacf1a7df9ce725c31b14776");   assert(success);

  // Get public key.

  bc::ec_point public_key = bc::secret_to_public_key(secret);

  std::cout << "Public key: " << bc::encode_hex(public_key) << std::endl;   // Create Bitcoin address.

  // Normally you can use:

  // bc::payment_address payaddr;

  // bc::set_public_key(payaddr, public_key);   // const std::string address = payaddr.encoded();   // Compute hash of public key for P2PKH address.

  const bc::short_hash hash = bc::bitcoin_short_hash(public_key);   bc::data_chunk unencoded_address;   // Reserve 25 bytes   // [ version:1 ]   // [ hash:20 ]   // [ checksum:4 ]   unencoded_address.reserve(25);

  // Version byte, 0 is normal BTC address (P2PKH).   unencoded_address.push_back(0);

  // Hash data

  bc::extend_data(unencoded_address, hash);

  // Checksum is computed by hashing data, and adding 4 bytes from hash.   bc::append_checksum(unencoded_address);

  // Finally we must encode the result in Bitcoin's base58 encoding   assert(unencoded_address.size() == 25);

  const std::string address = bc::encode_base58(unencoded_address);   std::cout << "Address: " << address << std::endl;

  return 0; }

cada vez que é executado, como demonstrado em Compilando e executando o código addr.

Example 3. Compilando e executando o código addr # Compila o código addr.cpp

$ g++ -o addr addr.cpp $(pkg-config --cflags --libs libbitcoin) # Roda o executável addr

$ ./addr

Public key: 0202a406624211f2abbdc68da3df929f938c3399dd79fac1b51b0e4ad1d26a47aa Address: 1PRTTaJesdNovgne6Ehcdu1fpEdX7913CK

No documento Dominando Bitcoin (páginas 76-83)