Использование bitgo-utxo-lib для создания мультиподписного кошелька/адреса для Zcash, также известного как ZEC.
В этой статье будет показано, как создать функциональный адрес ZCash с мультиподписью, используя модуль Node.js NPM bitgo-utxo-lib. Кошельки на основе мультиподписи обеспечивают дополнительный уровень безопасности по сравнению с обычными кошельками на основе одной подписи. Функциональность гарантирует, что в подписании транзакции для расходования средств, хранящихся на счете, участвует как минимум более 1 стороны. В этом руководстве основное внимание уделяется разработке оффчейн-кошелька, в основном известного как управление внешним кошельком, чтобы избежать использования демонов полного узла для достижения этой цели. Мы расскажем, как создать учетную запись или адрес с мультиподписью 2 из 3, что подразумевает, что из 3 сторон как минимум 2 стороны должны подписать транзакцию, чтобы потратить средства, хранящиеся на этой учетной записи / адресе.
Предпосылки
Вам необходимо иметь базовые знания о запуске Node.js и использовании модулей npm. Итак, чтобы перечислить их, вам нужно:
- Node.js (выше v8)
- Редактор кода VS или, может быть, какой-нибудь редактор кода
Начиная
Предполагая, что вы выполнили вышеуказанные шаги, давайте двигаться дальше. Прежде всего создайте каталог, инициализируйте его проектом npm по умолчанию и установите модули bitgo-utxo-lib и bitcoinjs-lib в зависимостях проекта. Откройте окно терминала (у меня Ubuntu) и запустите:
$ mkdir multisig-zec/ && cd ./multisig-zec $ npm init -y $ npm install bitgo-utxo-lib bitcoinjs-lib --save
На момент написания этой статьи использовались следующие версии (package.json проекта):
"dependencies": { "bitcoinjs-lib": "^4.0.2", "bitgo-utxo-lib": "^1.2.1" }
Затем создайте новый файл с именем index.js в текущем рабочем каталоге. Начните с импорта обоих модулей в код, как показано ниже:
let bitcoinjs = require('bitcoinjs-lib'); let bitgoUtxoLib = require('bitgo-utxo-lib');
bitgo-utxo-lib — это модуль npm, опубликованный командой Bitgo (большой их фанаткой), изначально являвшейся ответвлением bitcoinjs-lib. А bitcoinjs-lib — это библиотека с открытым исходным кодом, которая позволяет нам беспрепятственно работать с большинством криптовалют на основе UTXO. Возвращаясь к тому, где мы были, следующим шагом будет создание 3 случайных ECPair с использованием эталонного объекта bitgoUtxoLib, как показано ниже:
let ecPair1 = bitgoUtxoLib.ECPair.makeRandom({ network: bitgoUtxoLib.networks.zcash }); let ecPair2 = bitgoUtxoLib.ECPair.makeRandom({ network: bitgoUtxoLib.networks.zcash }); let ecPair3 = bitgoUtxoLib.ECPair.makeRandom({ network: bitgoUtxoLib.networks.zcash });
Здесь мы создали 3 случайных ECPair, используя эталонный объект, а сетевая часть в приведенном выше коде указывает сетевую совместимость ZEC созданных нами ECPair. В нашем случае мы создаем ECPair, совместимый с mainnet, если вы хотите создать ECPair, совместимый с testnet, просто замените bitgoUtxoLib.networks.zcashрасстаться сbitgoUtxoLib.networks.zcashTest
Теперь следующим шагом будет извлечение общедоступной части ECPair путем получения publicKey в формате буфера, как показано ниже:
const keyPairs = [ ecPair1.getPublicKeyBuffer(), ecPair2.getPublicKeyBuffer(), ecPair3.getPublicKeyBuffer() ];
Это вернет нам массив publicKeyBuffer, соответствующий ECPair, который мы создали на предыдущих шагах. Теперь следующие 2 шага включают использование bitcoinjs-lib для создания экземпляра с несколькими подписями, а затем создание хэша скрипта поверх объекта экземпляра с несколькими подписями для дальнейшего извлечения общедоступного адреса, как показано ниже:
// Create a multisig script object const p2ms = bitcoinjs.payments.p2ms({ m: 2, pubkeys: keyPairs, network: bitgoUtxoLib.networks.zcash }); const p2sh = bitcoinjs.payments.p2sh({ redeem: p2ms, network: bitgoUtxoLib.networks.zcash });
Теперь, когда у нас есть объект P2SH, совместимый с Zcash, мы извлечем необходимую информацию из экземпляра P2SH, такую как публичный адрес, redeemScript (который необходим, когда вы создаете транзакцию, чтобы потратить средства, заблокированные в этой учетной записи) и сведения о подписавшемся (Очень важные данные). Ниже приведен код для извлечения публичного адреса и redeemScript:
const publicAddress = bitgoUtxoLib.address.fromOutputScript(p2sh.output, bitgoUtxoLib.networks.zcash); const redeemScript = p2sh.redeem.output.toString('hex'); console.log('Multisig Address : ', publicAddress); //address starting with t console.log('Redeem Script : ', redeemScript);
Не забудьте сохранить вышеуказанные данные, так как без redeemScript вы не сможете потратить средства внутри (хотя их можно восстановить с помощью созаемщиков). Теперь важный шаг для сохранения данных, связанных с ECPair, которые мы создали выше, поскольку закрытые ключи, соответствующие созданным выше ECPair, будут использоваться для подписи транзакции с мультиподписью, и вы всегда можете сгенерировать тот же адрес с мультиподписью, когда у вас есть открытые ключи со-подписанты (мы создали выше или могут быть уже существующими) в том же порядке.
console.log('** Wallet 1 details : ', { publicKey: ecPair1.getPublicKeyBuffer().toString('hex'), privateKey: ecPair1.toWIF(), publicAddress: ecPair1.getAddress() }); console.log('** Wallet 2 details : ', { publicKey: ecPair2.getPublicKeyBuffer().toString('hex'), privateKey: ecPair2.toWIF(), publicAddress: ecPair2.getAddress() }); console.log('** Wallet 3 details : ', { publicKey: ecPair3.getPublicKeyBuffer().toString('hex'), privateKey: ecPair3.toWIF(), publicAddress: ecPair3.getAddress() });
Сохраните приведенный выше вывод в безопасном месте, о котором вы можете подумать (если вы используете адрес для хранения крупных средств). Весь код при установке будет выглядеть примерно так:
let bitcoinjs = require('bitcoinjs-lib'); let bitgoUtxoLib = require('bitgo-utxo-lib'); let ecPair1 = bitgoUtxoLib.ECPair.makeRandom({ network: bitgoUtxoLib.networks.zcash }); let ecPair2 = bitgoUtxoLib.ECPair.makeRandom({ network: bitgoUtxoLib.networks.zcash }); let ecPair3 = bitgoUtxoLib.ECPair.makeRandom({ network: bitgoUtxoLib.networks.zcash }); const keyPairs = [ecPair1.getPublicKeyBuffer(), ecPair2.getPublicKeyBuffer(), ecPair3.getPublicKeyBuffer()]; const p2ms = bitcoinjs.payments.p2ms({ m: 2, pubkeys: keyPairs, network: bitgoUtxoLib.networks.zcash }); const p2sh = bitcoinjs.payments.p2sh({ redeem: p2ms, network: bitgoUtxoLib.networks.zcash }); const publicAddress = bitgoUtxoLib.address.fromOutputScript(p2sh.output, bitgoUtxoLib.networks.zcash); const redeemScript = p2sh.redeem.output.toString('hex'); console.log('Multisig Address : ', publicAddress); console.log('Redeem Script : ', redeemScript); console.log('** Wallet 1 details : ', { publicKey: ecPair1.getPublicKeyBuffer().toString('hex'), privateKey: ecPair1.toWIF(), publicAddress: ecPair1.getAddress() }); console.log('** Wallet 2 details : ', { publicKey: ecPair2.getPublicKeyBuffer().toString('hex'), privateKey: ecPair2.toWIF(), publicAddress: ecPair2.getAddress() }); console.log('** Wallet 3 details : ', { publicKey: ecPair3.getPublicKeyBuffer().toString('hex'), privateKey: ecPair3.toWIF(), publicAddress: ecPair3.getAddress() });
Лучшая часть этого кода заключается в том, что его можно использовать полностью в автономном режиме и выполнять изолированным методом, чтобы обеспечить максимальную конфиденциальность и безопасность вашей конфиденциальной информации. Вы также можете клонировать/форкнуть мой репозиторий github: https://github.com/mannutech/medium-learning/, где я также буду продолжать загружать новые уроки.
В следующей статье будет рассказано, как создать мультиподписной адрес из существующих строк publicKey в ZEC. Следите за новыми репортажами.
БОНУСНЫЕ СТАТЬИ:
Ссылки на изображения: