主页 > imtoken官网最新版 > 比特币钱包开发:隔离见证分析和编程实践

比特币钱包开发:隔离见证分析和编程实践

imtoken官网最新版 2023-01-17 08:55:39

目标是了解什么是隔离见证交易地址类型编程实践:生成隔离见证地址

您可能在想,这个隔离见证对我们的比特币钱包开发有什么影响?那你就知道了。

一、什么是隔离见证

Segregated Witness在英文中称为SegWit,是Segregated Witness的缩写。隔离见证是比特币的升级计划。它由 Pieter Wuille(比特币核心开发者,Blockstream 联合创始人)于 2015 年 12 月首次提出,旨在解决比特币面临的一系列严重问题。主要由 BIP-141 定义。

我们可以这样理解隔离见证:

Witness:在比特币中,是指对交易合法性的验证,用来证明它具有某些交易的输出。数据。

比特币钱包地址生成

隔离:就是将见证数据与交易信息分离,分开存放。

隔离见证解决的问题

SegWit 是比特币核心的提议更新,比特币核心是目前大多数企业使用的最流行的比特币标准客户端。最初,该更新旨在解决交易可扩展性问题,这是比特币软件的一个众所周知的弱点。虽然这种攻击媒介对用户的破坏性不是最大的,但迄今为止它已在多个攻击案例中被利用,因此强调了修补此漏洞的必要性。

目前,比特币的可扩展性问题主要是由于区块容量不足,这里的问题是当前区块被硬编码到 1 兆字节的限制,这不足以承受用户每分钟数百次尝试发送的交易。结果,许多用户不得不排队等待交易得到确认,这可能需要数小时甚至数天。随着网络规模的扩大,交易强度也在扩大,但块大小限制保持不变,这意味着问题会越来越严重。

比特币钱包地址生成

SegWit 的解决方案由两部分组成:

segwit的优势二、交易地址类型

地址使用 Base58check 20 字节哈希进行格式化,以生成 P2PKH 或 P2SH 比特币地址。目前最常见的方式是用户交换支付信息。

普通比特币交易地址有两种:

比特币钱包地址生成

Segwit 为比特币建立两个新的交易地址:

Segwit 不会在全网同时实现,为了新老客户共存,钱包开发者会独立升级钱包软件,增加隔离见证功能。升级到segwit钱包后,使用P2WPKH和P2WSH支付类型,传统钱包使用P2PKH和P2SH支付类型。两种形式的见证脚本 P2WPKH 和 P2WSH 都可以嵌入到以“3”开头的 P2SH 地址中。 P2PKH 是一个以“1”开头的地址。

例如,假设有两个人:lixu,zhangsan,lixu的钱包没有升级到segwit,但是zhangsan的钱包已经升级了可以处理segwit交易。 lixu 和 zhangsan 都可以使用普通地址交易比特币钱包地址生成比特币钱包地址生成,但 zhangsan 可能会使用 segwit 来降低交易费用。在这种情况下,zhangsan 的钱包需要构造一个包含 segwit 脚本的 P2SH 地址。 lixu 的钱包认为这是一个普通的 P2SH 地址,可以在不知道 segwit 的情况下进行支付。然后张三的钱包可以通过隔离交易进行支付,充分利用隔离交易,降低交易费用。

所以我们需要构建与普通地址兼容的segwit地址。

比特币钱包地址生成

三、编程实践:生成隔离见证地址代码

var bitcoin = require('bitcoinjs-lib');
var bip39 = require("bip39")
var bip32 = require("bip32")
const myNetwork = bitcoin.networks.bitcoin
const mnemonic = 'eternal list thank chaos trick paper sniff ridge make govern invest abandon'
// const mnemonic = bip39.generateMnemonic()
const seed = bip39.mnemonicToSeed(mnemonic, "lixu1234qwer")
const root = bip32.fromSeed(seed, myNetwork)
for(var i = 0; i < 3; i++) {
    const path = "m/44'/0'/0'/0/"+i
    console.log("路径:", path)
    const keyPair = root.derivePath(path)
    const privateKey = keyPair.toWIF()
    console.log("私钥:", privateKey)
    const publicKey = keyPair.publicKey.toString("hex")
    console.log("公钥:", publicKey)
    let address = getAddress(keyPair, myNetwork)
    console.log("普通地址:", address)
    let segWitAddress = getSegWitAddress(keyPair, myNetwork)
    console.log("隔离见证:", segWitAddress, "\n")
}
function getAddress(keyPair, network) {
    const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey , network:network})
    return address
}
function getSegWitAddress(keyPair,myNetwork) {
    const { address } = bitcoin.payments.p2sh({
        redeem: bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network: myNetwork}),
        network: myNetwork
    })
    return address
}

输出

7EBFC423-8E93-471E-B336-C2AF46969391

比特币钱包地址生成

验证

4C5D6822-8F20-49A9-BFCC-9D3CCB933A42

C78D7E3D-CF91-4874-9C0E-5141956BAFA7

代码分析

这里只解释 getSegWitAddress 方法的实现。其他代码分析请参考上一章“从生成助记词到扩展子地址”。

const { address } = bitcoin.payments.p2sh({
        redeem: bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network: myNetwork}),
        network: myNetwork
    })

这是将p2wpkh地址嵌套在p2sh地址中作为它的remove字段。另请注意,需要在两种地址类型中指定网络类型。以上代码是在比特币官方网络中运行的,即指定 const myNetwork = bitcoin.networks.bitcoin。