Перейти к содержанию

Спецификация кошелька

Формат импорта кошелька COOPOS (WIF)

Wallet Import Format — кодирование закрытого ключа ECDSA. В COOPOS используются те же версия, контрольная сумма и схема кодирования, что и у Bitcoin WIF; совместимость с существующими библиотеками [1].

Пример закрытого ключа в WIF:

5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAbuatmU

Это кодирование удобно для:

  • копирования и вставки закрытых ключей (снижает риск обрезки)
  • включения ключей в текстовые или редактируемые пользователем форматы
  • сокращения длины записи ключа

Менее удобно для:

  • ручной переписи ключа (ошибка в регистре буквы уже критична)
  • бинарного хранилища, где ключ уже обрабатывается кодом и проверен

Замечания:

  • Если ключ может быть записан от руки или набран заново, лучше подойдёт стандарт мнемоник BIP39.
  • Имеет смысл помечать WIF-ключ словами «Private» или «Private Key».

Закрытый ключ → WIF

    1. Используется «фиктивный» закрытый ключ из нулей. Длина 32 байта (ниже в hex).
0000000000000000000000000000000000000000000000000000000000000000
    1. В начало добавляется байт 0x80. Он соответствует mainnet Bitcoin; в COOPOS используется тот же байт версии. При кодировании байт версии помогает отличить запись как закрытый ключ. В отличие от Bitcoin, в COOPOS всегда используются сжатые открытые ключи (производные от закрытого), поэтому к закрытому ключу не добавляется суффикс 0x01.
800000000000000000000000000000000000000000000000000000000000000000
    1. Выполняется двоичный хеш SHA-256 от ключа с версией.
ce145d282834c009c24410812a60588c1085b63d65a7effc2e0a5e3a2e21b236
    1. Выполняется двоичный SHA-256 от результата предыдущего шага.
0565fba7ebf8143516e0222d7950c28589a34c3ee144c3876ceb01bfb0e9bb70
    1. Первые 4 байта второго SHA-256 — контрольная сумма.
0565fba7
    1. К ключу с версией из шага 2 добавляются 4 байта контрольной суммы.
8000000000000000000000000000000000000000000000000000000000000000000565fba7
    1. Двоичные данные из шага 6 кодируются Base58.
5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAbuatmU

WIF → закрытый ключ (проверка контрольной суммы)

  1. Начинаем с закрытого ключа в формате WIF.
5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAbuatmU
  1. Base58-декодирование строки WIF (ниже показано в HEX).
8000000000000000000000000000000000000000000000000000000000000000000565fba7
  1. Декодированные данные делятся на ключ с версией и контрольную сумму (последние 4 байта).
800000000000000000000000000000000000000000000000000000000000000000
0565fba7
  1. Двоичный SHA-256 от ключа с версией.
ce145d282834c009c24410812a60588c1085b63d65a7effc2e0a5e3a2e21b236
  1. Двоичный SHA-256 от результата предыдущего шага.
0565fba7ebf8143516e0222d7950c28589a34c3ee144c3876ceb01bfb0e9bb70
  1. Первые 4 байта второго SHA-256 — контрольная сумма.
0565fba7
  1. Сравните контрольные суммы из шагов 3 и 6.

  2. Ключ с версией из шага 3 делится на байт версии и закрытый ключ.

80
0000000000000000000000000000000000000000000000000000000000000000
  1. Если версия 0x80, ошибки нет.

Base58check

Base58Check — JavaScript-реализация этого алгоритма; ею можно кодировать и декодировать закрытые ключи COOPOS в формате WIF.

base58check = require('base58check')
wif = base58check.encode(privateKey = '00'.repeat(32), version = '80', encoding = 'hex')
assert.equal('5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAbuatmU', wif)
let {prefix, data} = base58check.decode(wif)
assert.equal(prefix.toString('hex'), '80')
assert.equal(data.toString('hex'), '00'.repeat(32))

[1] Формат Bitcoin WIF — https://en.bitcoin.it/wiki/Wallet_import_format