Chave Pública

Um ponto na curva elíptica

Diagrama mostrando uma chave pública sendo calculada a partir de uma chave privada.

Uma chave pública é a parte "pública" de um par de chave privada e chave pública.

Ela é calculada a partir da chave privada, o que significa que há uma conexão matemática entre as duas.

Chave Pública

Calcule a chave pública a partir de uma chave privada.

0 bytes

Chave Pública

Coordenadas
0d
0d

Uma chave pública é apenas um ponto em uma curva elíptica. A chave pública final são essas coordenadas em hexadecimal.

Compressão

A curva é simétrica no eixo x, então a chave comprimida guarda só a coordenada x e se o y é par ou ímpar. A x-only é usada em saídas Taproot.

0 bytes

Nunca digite sua chave privada em um site, nem use uma chave privada gerada por um site. Sites podem facilmente salvar a chave privada e usá-la para roubar seus bitcoins.

A chave pública é usada para que você possa "receber" bitcoins. Ao fazer uma transação, uma saída pode ser travada a uma chave pública, de modo que só o dono da chave privada consiga destravá-la e gastá-la em uma transação futura.

Criando

Como você cria uma chave pública?

Diagrama mostrando uma chave pública como um ponto em uma curva elíptica.

Uma chave pública é criada por meio de multiplicação de curva elíptica.

Em termos técnicos, você multiplica um ponto inicial (o ponto gerador) na curva elíptica secp256k1 pela chave privada (um número aleatório), e isso resulta em um novo conjunto de coordenadas x e y, que é a chave pública.

Ícone Ferramenta Chave Privada

Chave Privada

Gere um número aleatório de 256 bits.

Bits

0b
0 bits
0d
0x
0 bytes

Nunca use uma chave privada gerada por um site, nem digite sua chave privada em um site. Sites podem facilmente salvar a chave privada e usá-la para roubar seus bitcoins.

Ícone Ferramenta Multiplicação na Curva Elíptica

Multiplicação de Ponto (EC Multiply)

Multiplique um ponto na curva elíptica secp256k1.

Ponto 1
x:
0d
y:
0d
0d
Ponto 1 × Multiplicador
x:
0d
y:
0d

Então uma chave pública é apenas um ponto na curva elíptica.

Não vou entediá-lo com os detalhes da matemática de curvas elípticas neste momento, porque você não precisa entendê-la para conseguir criar suas próprias chaves públicas. Mas você pode se aprofundar nela se quiser, e a matemática não é tão difícil quanto parece.

Código

# exemplo de chave privada
private_key = "ef235aacf90d9f4aadd8c92e4b2562e1d9eb97f0df9ba3b508258739cb013db2"

# --------------------------
# Parâmetros da curva Secp256k1
# --------------------------
# y^2 = x^3 + ax + b
$a = 0
$b = 7 # usando variáveis globais por conveniência

# módulo primo
$p = 2 ** 256 - 2 ** 32 - 2 ** 9 - 2 ** 8 - 2 ** 7 - 2 ** 6 - 2 ** 4 - 1

# número de pontos na curva
$n = 115792089237316195423570985008687907852837564279074904382605163141518161494337

# ponto gerador (o ponto inicial na curva usado para todos os cálculos)
$g = {
  x: 55066263022277343669578718895168534326250603453777594175500187360389116729240,
  y: 32670510020758816978083085130507043184471273380659243275938904335757337482424,
}

# --------------------------
# Matemática de Curva Elíptica
# --------------------------
# Inverso Modular - O Ruby não tem uma função embutida para encontrar inversos modulares, então aqui vai uma usando o algoritmo de Euclides estendido.
def modinv(a, m = $p)
  m_orig = m         # guarda o módulo original
  a = a % m if a < 0 # garante que a é positivo
  y_prev = 0
  y = 1
  while a > 1
    q = m / a

    y_before = y # guarda o valor atual de y
    y = y_prev - q * y # calcula o novo valor de y
    y_prev = y_before # define o y anterior como o y antigo

    a_before = a # guarda o valor atual de a
    a = m % a # calcula o novo valor de a
    m = a_before # define m como o a antigo
  end
  return y % m_orig
end

# Dobrar - Soma um ponto da curva a ele mesmo.
def double(point)
  # inclinação = (3x^2 + a) / 2y
  slope = ((3 * point[:x] ** 2) * modinv((2 * point[:y]))) % $p # usa o inverso modular para fazer a "divisão"

  # novo x = inclinação^2 - 2x
  x = (slope ** 2 - (2 * point[:x])) % $p

  # novo y = inclinação * (x - novo x) * y
  y = (slope * (point[:x] - x) - point[:y]) % $p

  # retorna as coordenadas x, y do ponto
  return { x: x, y: y }
end

# Somar - Soma dois pontos.
def add(point1, point2)
  # dobra se os dois pontos forem iguais
  return double(point1) if point1 == point2

  # inclinação = (y1 - y2) / (x1 - x2)
  slope = ((point1[:y] - point2[:y]) * modinv(point1[:x] - point2[:x])) % $p

  # novo x = inclinação^2 - x1 - x2
  x = (slope ** 2 - point1[:x] - point2[:x]) % $p

  # novo y = inclinação * (x1 - novo x) - y1
  y = ((slope * (point1[:x] - x)) - point1[:y]) % $p

  # retorna as coordenadas x, y do ponto
  return { x: x, y: y }
end

# Multiplicar - Usa as operações de dobrar e somar para multiplicar rapidamente um ponto por um inteiro (ex.: uma chave privada).
def multiply(k, point = $g) # multiplica o ponto gerador por padrão
  # cria uma cópia do ponto inicial (para uso na soma mais adiante)
  current = point

  # converte o inteiro para sua representação binária (para uso no algoritmo de dobrar e somar)
  binary = k.to_s(2)

  # algoritmo de dobrar e somar para multiplicação rápida
  binary.split("").drop(1).each do |char| # ignora o primeiro caractere binário
    # 0 = dobrar
    current = double(current)

    # 1 = dobrar e somar
    if char == "1"
      current = add(current, point)
    end
  end

  # retorna o ponto final
  return current
end

# -------------------------
# Chave Privada Para Chave Pública
# -------------------------
# converte a chave privada para um inteiro
k = private_key.to_i(16)

# multiplica o ponto gerador por essa chave privada
point = multiply(k, $g) # este ponto é a chave pública

# converte os valores x e y deste ponto para hexadecimal
x = point[:x].to_s(16).rjust(64, "0")
y = point[:y].to_s(16).rjust(64, "0")

# formato de chave pública não comprimida (pouco usado hoje em dia, só mostrando como fica)
public_key_uncompressed = "04" + x + y

# formato de chave pública comprimida (todo valor x tem um y que pode ser um de dois pontos possíveis)
if (point[:y] % 2 == 0)
  prefix = "02" # se y é par
else
  prefix = "03" # se y é ímpar
end

public_key_compressed = prefix + x # usa apenas a coordenada x completa

# -------
# Resultados
# -------
puts private_key           #=> ef235aacf90d9f4aadd8c92e4b2562e1d9eb97f0df9ba3b508258739cb013db2
puts public_key_compressed #=> 02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737

Bibliotecas

Na maioria das linguagens você pode usar uma biblioteca de curva elíptica já existente para ajudar a criar chaves públicas (em vez de ter que programar a matemática você mesmo). Por exemplo:

require 'ecdsa' # sudo gem install ecdsa

# Esta chave privada é só um exemplo
privatekey = "ef235aacf90d9f4aadd8c92e4b2562e1d9eb97f0df9ba3b508258739cb013db2"

# Multiplicação de curva elíptica
group = ECDSA::Group::Secp256k1 # Seleciona a curva usada no Bitcoin
point = group.generator.multiply_by_scalar(privatekey.to_i(16)) # Multiplica por inteiro (não por hex)

# Converte o ponto da chave pública para uma chave pública hexadecimal comprimida
publickey = ECDSA::Format::PointOctetString.encode(point, compression: true).unpack("H*").join

puts publickey

Conceitos básicos da curva elíptica

O uso da multiplicação de curva elíptica dá uma conexão matemática da sua chave privada para a sua chave pública.

Ela também tem duas propriedades importantes:

1. Não se sabe como trabalhar de trás para frente para obter a chave privada.

Você pode ir para frente usando a multiplicação de curva elíptica, mas não dá para fazer a matemática para voltar.

Diagrama mostrando como você não consegue trabalhar de trás para frente para calcular uma chave privada a partir de uma chave pública.

Isso significa que há uma conexão matemática indo da sua chave privada para a sua chave pública, mas ninguém consegue usar sua chave pública para descobrir qual é a sua chave privada.

Portanto, você pode divulgar sua chave pública e, ao mesmo tempo, manter sua chave privada em segredo.

2. Você pode provar que tem a chave privada sem revelá-la.

Basicamente, usando um pouco mais de matemática de curvas elípticas, você pode criar uma assinatura digital que prova que você tem a chave privada correspondente a uma chave pública, sem nunca ter que revelar sua chave privada de verdade.

É como dizer que você tem a senha de uma conta, mas sem ter que mostrar a ninguém sua senha de verdade para provar isso.

Diagrama mostrando que uma assinatura é calculada a partir de uma chave privada e também mantém uma conexão matemática com a chave pública.

Isso é graças à mágica da matemática de curvas elípticas.

Formatos

Como é uma chave pública?

Uma chave pública é apenas uma coordenada x e uma coordenada y, então, no fim das contas, são só dois números de 256 bits muito grandes:

x: 81591541406288143274758265124625798440200740391102527151086648448953253267255
y: 64573953342291915951744135406509773051817879333910826118626860448948679381492

No entanto, ao exibir uma chave pública, normalmente começamos convertendo esses números em dois valores hexadecimais de 32 bytes:

x: b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737
y: 8ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4

Em seguida, concatenamos essas coordenadas x-y e adicionamos um prefixo 02, 03 ou 04 para indicar se estamos usando uma chave pública comprimida ou não comprimida:

chave pública (não comprimida): 04b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a87378ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4
chave pública (comprimida):     02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737

Chave pública não comprimida (legada)

Diagrama mostrando o formato de uma chave pública não comprimida.

Uma chave pública não comprimida tem 65 bytes de comprimento e contém as coordenadas x e y completas. Ela tem um byte de prefixo 04 para indicar que é uma chave pública não comprimida.

Por exemplo:

x: b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737
y: 8ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4

chave pública (não comprimida): 04b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a87378ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4

As chaves públicas não comprimidas eram usadas nas primeiras versões do bitcoin, antes de descobrirmos que poderíamos usar chaves públicas comprimidas de 33 bytes, mais curtas.

Então não há motivo para usar chaves públicas não comprimidas hoje em dia, a menos que você realmente queira ou precise por algum motivo.

Você não pode usar chaves públicas não comprimidas dentro dos scripts de travamento modernos P2WPKH ou P2WSH. Porém, você ainda pode usá-las em scripts de travamento legados, como P2PK, P2PKH, P2SH e P2MS.

Chave pública comprimida

Diagrama mostrando o formato de uma chave pública comprimida.

Uma chave pública comprimida tem 33 bytes de comprimento. Ela contém a coordenada x completa e um prefixo para indicar se a coordenada y é par ou ímpar.

x: b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737
y: 8ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4

chave pública (comprimida): 02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737

Veja bem, devido à estrutura da curva elíptica, quando você calcula a chave pública a coordenada y só pode ser um de dois valores possíveis. Então, em vez de armazenar a coordenada y completa, só precisamos indicar qual dos dois valores possíveis é a coordenada y.

Diagrama mostrando a simetria da curva elíptica em torno do eixo x, com dois valores possíveis para y.

E acontece que a coordenada y será sempre par ou ímpar.

Você deve usar chaves públicas comprimidas por padrão. Elas são mais curtas (o que economiza espaço dentro dos dados brutos da transação) e você evita problemas de compatibilidade com scripts de travamento modernos (ex.: P2WPKH e P2WSH só permitem usar chaves públicas comprimidas).

Descomprimir a chave pública

Você pode descomprimir uma chave pública comprimida resolvendo a equação da curva y2 = x3 + 7.

Isso vai lhe dar os dois valores possíveis de y para a chave não comprimida. Você pode então usar o prefixo da chave comprimida para determinar qual valor de y usar.

# Chave pública comprimida
compressed = "02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737"

# Separa a chave comprimida em prefixo e coordenada x
prefix = compressed[0..1] #=> 02
x = compressed[2..-1]     #=> b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737

# Converte a coordenada x de string hexadecimal para inteiro
x = x.to_i(16)

# Parâmetros da curva Secp256k1
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f # corpo primo

# Calcula os valores de y usando a equação da curva y^2 = x^3 + 7
y_sq = (x**3 + 7) % p # tudo é módulo p

# A Secp256k1 é escolhida de uma forma especial para que a raiz quadrada de y seja y^((p+1)/4)
y = y_sq.pow((p+1)/4, p) # usa exponenciação modular

# Usa o prefixo para selecionar o valor correto de y
# * prefixo 02 = y é par
# * prefixo 03 = y é ímpar
if (prefix == "02" && y % 2 != 0) # se o prefixo é 02 e y não é par, usa o outro valor de y
  y = (p - y) % p
end
if (prefix == "03" && y % 2 == 0) # se o prefixo é 03 e y é par, usa o outro valor de y
  y = (p - y) % p
end

# Constrói a chave pública não comprimida
x = x.to_s(16).rjust(64, "0") # converte para hex e garante que tem 32 bytes (64 caracteres)
y = y.to_s(16).rjust(64, "0")
uncompressed = "04" + x + y

# Resultado
puts uncompressed #=> 04b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a87378ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4

Existem dois valores possíveis de y por causa da raiz quadrada usada para resolver a equação. Isso ocorre porque a raiz quadrada de qualquer número tem duas respostas possíveis (ex.: √16=+4 ou -4).

Uso

Como as chaves públicas são usadas no Bitcoin?

Diagrama mostrando como você recebe bitcoins quando alguém trava uma saída de transação à sua chave pública.

Uma chave pública é usada quando você quer "receber" bitcoins.

Quando alguém lhe envia bitcoins em uma transação, essa pessoa coloca sua chave pública dentro do cadeado em cima de uma das saídas. Isso efetivamente "trava" aquela saída à sua chave pública, e ela só pode ser destravada usando a chave privada para criar uma assinatura que prova que você é o dono da chave pública.

Isso porque há uma conexão matemática entre a chave privada e a chave pública, e as assinaturas que você gera usando a chave privada também terão uma conexão matemática com a chave pública. Essa conexão matemática entre a chave pública e a assinatura é o bastante para "destravar" a saída e gastá-la mais tarde.

Diagrama mostrando como as chaves (chave privada e chave pública) são usadas para travar e destravar bitcoins em transações.

Esta é uma explicação simplificada. No mundo real, a chave pública é primeiro convertida em um endereço antes de ser compartilhada com outras pessoas. No entanto, o mecanismo subjacente é o mesmo.

Os seguintes scripts de travamento travam saídas diretamente a uma chave pública:

Os seguintes scripts de travamento também normalmente contêm uma chave pública:

Localização

Onde você encontra chaves públicas?

Chaves públicas podem ser encontradas dentro do ScriptPubKey ou do ScriptSig de transações brutas.

A chave pública estará em um local diferente dependendo do tipo de script de travamento colocado em uma saída. Estes são alguns exemplos de locais típicos de chaves públicas dentro da blockchain:

P2PK

Pay To Public Key

A chave pública de um P2PK fica dentro do ScriptPubKey, na saída:

Bruto

01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804233fa04e028b12ffffffff0130490b2a010000004341047eda6bd04fb27cab6e7c28c99b94977f073e912f25d1ff7165d9c95cd9bbe6da7e7ad7f2acb09e0ced91705f7616af53bee51a238b7dc527f2be0aa60469d140ac00000000

Separado

{
  "version": "01000000",
  "inputcount": "01",
  "inputs": [
    {
      "txid": "0000000000000000000000000000000000000000000000000000000000000000",
      "vout": "ffffffff",
      "scriptsigsize": "08",
      "scriptsig": "04233fa04e028b12",
      "sequence": "ffffffff"
    }
  ],
  "outputcount": "01",
  "outputs": [
    {
      "amount": "30490b2a01000000",
      "scriptpubkeysize": "43",
      "scriptpubkey": "41047eda6bd04fb27cab6e7c28c99b94977f073e912f25d1ff7165d9c95cd9bbe6da7e7ad7f2acb09e0ced91705f7616af53bee51a238b7dc527f2be0aa60469d140ac"
    }
  ],
  "locktime": "00000000"
}

Transação: 18a16d322b235f636ab90e62e79a9f20a0b9c14e8da51e9dc0974f99f82ee444

Nota: este script de travamento P2PK contém uma chave pública não comprimida.

O P2PK é o script de travamento mais simples para travar uma saída a uma chave pública, pois o script de travamento contém a chave pública diretamente.

Estes scripts de travamento P2PK são bem menos comuns que os mais populares P2PKH e P2WPKH. Esses scripts P2PK são encontrados com mais frequência dentro de transações coinbase antigas, entre 2009 e 2011.

P2MS

Pay To Multisig

A(s) chave(s) pública(s) de um P2MS ficam dentro do ScriptPubKey, na saída:

Bruto

01000000014563f26698c0ea3ebd85d4767457370d7e2ebbe922a7736dbf70e1d0f8a9aa9c000000008a473044022039294d5c8843a6776d4a2032cf03549f41c634ba5e65898c7816973919e485b902205af1f61f6d7d6a5f32cbe46676303c141fe499288b1be0d8f0c4e80d4c0ecb5701410454ffbc96ef3c26acffa431066915308865d990e044c507e0ab3d26af34a8ba5b4cb3028fe7c91926bb8be47d652dc70ab300e3022f8259db5f79306b601fc66effffffff0190c9190000000000c9524104d81fd577272bbe73308c93009eec5dc9fc319fc1ee2e7066e17220a5d47a18314578be2faea34b9f1f8ca078f8621acd4bc22897b03daa422b9bf56646b342a24104ec3afff0b2b66e8152e9018fe3be3fc92b30bf886b3487a525997d00fd9da2d012dce5d5275854adc3106572a5d1e12d4211b228429f5a7b2f7ba92eb0475bb14104b49b496684b02855bc32f5daefa2e2e406db4418f3b86bca5195600951c7d918cdbe5e6d3736ec2abf2dd7610995c3086976b2c0c7b4e459d10b34a316d5a5e753ae00000000

Separado

{
  "version": "01000000",
  "inputcount": "01",
  "inputs": [
    {
      "txid": "4563f26698c0ea3ebd85d4767457370d7e2ebbe922a7736dbf70e1d0f8a9aa9c",
      "vout": "00000000",
      "scriptsigsize": "8a",
      "scriptsig": "473044022039294d5c8843a6776d4a2032cf03549f41c634ba5e65898c7816973919e485b902205af1f61f6d7d6a5f32cbe46676303c141fe499288b1be0d8f0c4e80d4c0ecb5701410454ffbc96ef3c26acffa431066915308865d990e044c507e0ab3d26af34a8ba5b4cb3028fe7c91926bb8be47d652dc70ab300e3022f8259db5f79306b601fc66e",
      "sequence": "ffffffff"
    }
  ],
  "outputcount": "01",
  "outputs": [
    {
      "amount": "90c9190000000000",
      "scriptpubkeysize": "c9",
      "scriptpubkey": "524104d81fd577272bbe73308c93009eec5dc9fc319fc1ee2e7066e17220a5d47a18314578be2faea34b9f1f8ca078f8621acd4bc22897b03daa422b9bf56646b342a24104ec3afff0b2b66e8152e9018fe3be3fc92b30bf886b3487a525997d00fd9da2d012dce5d5275854adc3106572a5d1e12d4211b228429f5a7b2f7ba92eb0475bb14104b49b496684b02855bc32f5daefa2e2e406db4418f3b86bca5195600951c7d918cdbe5e6d3736ec2abf2dd7610995c3086976b2c0c7b4e459d10b34a316d5a5e753ae"
    }
  ],
  "locktime": "00000000"
}

Transação: 581d30e2a73a2db683ac2f15d53590bd0cd72de52555c2722d9d6a78e9fea510

Nota: este script de travamento P2MS contém 3 chaves públicas não comprimidas.

Um P2MS permite que você trave uma saída a várias chaves públicas e exige assinaturas de algumas ou de todas essas chaves públicas para destravá-la.

Um script de travamento P2MS padrão pode conter até 3 chaves públicas. Já um script de travamento multisig não padrão pode conter até 20 chaves públicas de uma vez.

É raro encontrar scripts de travamento P2MS brutos na blockchain, pois esse tipo de cadeado é mais comumente encapsulado dentro de um P2SH.

P2PKH

Pay To Public Key Hash

A chave pública de um P2PKH fica dentro do ScriptSig, na entrada:

Bruto

0200000001cc8e9c87148eae3bc918c94b13c0971d7959474e37d040c777aab7d8f621bfa2000000006a47304402204321dc44fa1207aa353ce1b0270887910c10825b284cfc5dc1e5451da43defd002204b0cab71575f765d11f52b1f03bdc3d11b00a6d94e1f2185530c6f82bdae2e7d012102e9698e55e8b3bca5aa108e094e4b0b42ce0dd697268c77ccc14ef54bd336088efeffffff02404b4c00000000001976a9148ca7043a7bf78518c3dfc9c756f3af8fef4ce6db88acc9a30a08020000001976a914b8b5866bc6828bb1e9c9ddc132fe42965355c19b88acd1bf0b00

Separado

{
  "version": "02000000",
  "inputcount": "01",
  "inputs": [
    {
      "txid": "cc8e9c87148eae3bc918c94b13c0971d7959474e37d040c777aab7d8f621bfa2",
      "vout": "00000000",
      "scriptsigsize": "6a",
      "scriptsig": "47304402204321dc44fa1207aa353ce1b0270887910c10825b284cfc5dc1e5451da43defd002204b0cab71575f765d11f52b1f03bdc3d11b00a6d94e1f2185530c6f82bdae2e7d012102e9698e55e8b3bca5aa108e094e4b0b42ce0dd697268c77ccc14ef54bd336088e",
      "sequence": "feffffff"
    }
  ],
  "outputcount": "02",
  "outputs": [
    {
      "amount": "404b4c0000000000",
      "scriptpubkeysize": "19",
      "scriptpubkey": "76a9148ca7043a7bf78518c3dfc9c756f3af8fef4ce6db88ac"
    },
    {
      "amount": "c9a30a0802000000",
      "scriptpubkeysize": "19",
      "scriptpubkey": "76a914b8b5866bc6828bb1e9c9ddc132fe42965355c19b88ac"
    }
  ],
  "locktime": "d1bf0b00"
}

Transação: faf2987fd2240d9c46575cc35c354eeca71b794c482f3cc49fba1a5f9a80808c

Nota: este script de destravamento P2PKH contém uma chave pública comprimida.

Com o P2PKH, o script de travamento inicial em uma saída (em uma transação anterior) na verdade contém um hash de chave pública. A chave pública de fato só é revelada quando você vai gastar a saída como uma entrada em uma nova transação.

Então, embora um P2PKH faça o mesmo trabalho de um P2PK ao "travar" uma saída a uma chave pública, a chave pública original é encontrada dentro do ScriptSig (script de destravamento) em vez do ScriptPubKey (script de travamento).

Esta foi a forma mais popular de travar uma saída a uma chave pública até 2016, antes de o P2WPKH ser introduzido na atualização Segregated Witness. Isso porque o P2PKH tem seu próprio formato de endereço (o que facilitava enviar bitcoins ao usar uma carteira de bitcoin), enquanto o P2PK não tem.

P2WPKH

Pay To Witness Public Key Hash

A chave pública de um P2WPKH fica dentro da Testemunha da entrada:

Bruto

020000000001013aa815ace3c5751ee6c325d614044ad58c18ed2858a44f9d9f98fbcddad878c10000000000ffffffff01344d10000000000016001430cd68883f558464ec7939d9f960956422018f0702483045022100c7fb3bd38bdceb315a28a0793d85f31e4e1d9983122b4a5de741d6ddca5caf8202207b2821abd7a1a2157a9d5e69d2fdba3502b0a96be809c34981f8445555bdafdb012103f465315805ed271eb972e43d84d2a9e19494d10151d9f6adb32b8534bfd764ab00000000

Separado

{
  "version": "02000000",
  "marker": "00",
  "flag": "01",
  "inputcount": "01",
  "inputs": [
    {
      "txid": "3aa815ace3c5751ee6c325d614044ad58c18ed2858a44f9d9f98fbcddad878c1",
      "vout": "00000000",
      "scriptsigsize": "00",
      "scriptsig": "",
      "sequence": "ffffffff"
    }
  ],
  "outputcount": "01",
  "outputs": [
    {
      "amount": "344d100000000000",
      "scriptpubkeysize": "16",
      "scriptpubkey": "001430cd68883f558464ec7939d9f960956422018f07"
    }
  ],
  "witness": [
    {
      "stackitems": "02",
      "0": {
        "size": "48",
        "item": "3045022100c7fb3bd38bdceb315a28a0793d85f31e4e1d9983122b4a5de741d6ddca5caf8202207b2821abd7a1a2157a9d5e69d2fdba3502b0a96be809c34981f8445555bdafdb01"
      },
      "1": {
        "size": "21",
        "item": "03f465315805ed271eb972e43d84d2a9e19494d10151d9f6adb32b8534bfd764ab"
      }
    }
  ],
  "locktime": "00000000"
}

Transação: 1674761a2b5cb6c7ea39ef58483433e8735e732f5d5815c9ef90523a91ed34a6

Nota: este código de destravamento P2WPKH contém uma chave pública comprimida.

O P2WPKH é funcionalmente similar ao P2PKH. A principal diferença é que o código de destravamento vai dentro do campo Testemunha da entrada, em vez do ScriptSig.

Você só pode usar chaves públicas comprimidas com um P2WPKH.

Resumo

Se você gerou sua própria chave privada, o próximo passo é usá-la para calcular a chave pública correspondente.

Isso envolve mais matemática do que gerar a chave privada inicial, porque a chave privada é só um número aleatório, mas a chave pública exige que você use a multiplicação de curva elíptica para calcular um ponto específico na curva.

Porque é só isso que uma chave pública é: um par de coordenadas x e y.

É interessante entender como a matemática de curvas elípticas funciona, mas não é essencial para conseguir gerar seu próprio conjunto de chaves para usar no Bitcoin. Então não se assuste com todo o código e os termos técnicos. O código não é, na verdade, tão complexo quanto parece, então é só tentar.

Se eu consegui descobrir como calcular uma do zero sem nenhuma experiência prévia com criptografia, você também consegue.

Daqui, tudo o que você precisa fazer é conseguir converter a chave pública em um endereço, e então você poderá começar a enviar e receber bitcoins usando chaves que você gerou inteiramente por conta própria.

Você sempre pode se aprofundar nos detalhes das curvas elípticas e afins depois, se quiser.

Boa sorte.

Recursos