Bitcoin 钱包离线地址生成和签名实战丨区块链技术课程 #08

  • Dapplink
  • 更新于 2024-06-18 15:40
  • 阅读 169

比特币自 2009 年发布以来,经历了多次重要升级。这些升级旨在提高比特币网络的安全性、效率和功能性。

作者丨Seek

Bitcoin 概览

1 Bitcoin 简介

比特币(Bitcoin)是由一个或一群化名为中本聪(Satoshi Nakamoto)的人在 2008 年提出,并于 2009 年开始发布的去中心化数字货币。它的出现标志着一种新型金融体系的诞生,具有以下主要特点:

  • 去中心化

  • 比特币网络没有中央管理机构或中介机构,它通过一个称为区块链的分布式账本来记录所有交易。

  • 区块链技术确保了所有参与者都可以查看和验证交易,提高了透明度和安全性。

  • 有限供应

  • 比特币的总供应量被固定在2100万枚,这通过代码内的机制控制。

  • 这一机制使比特币具备了抗通胀的特点。

  • 点对点交易

  • 比特币允许用户之间直接进行交易,不需要通过银行或支付处理机构。

  • 这种点对点交易减少了交易成本和处理时间。

  • 安全性

  • 比特币使用加密技术确保交易的安全性和隐私性。

  • 每一笔交易都需要通过复杂的数学算法进行验证,从而确保系统的完整性。

  • 不可逆交易

  • 一旦比特币交易被确认,它就无法被撤销。这减少了欺诈的风险,但也意味着用户需要谨慎操作。

  • 挖矿机制

  • 新的比特币通过一个称为挖矿的过程产生。矿工们使用计算能力来解决复杂的数学问题,成功解决问题的矿工将获得比特币奖励。

  • 挖矿不仅生成新币,还维护和保护比特币网络的安全。

  • 全球流通

  • 比特币可以在全球范围内进行交易,不受地域和国界的限制。

  • 它为跨国支付提供了一种高效、低成本的替代方案。

  • 隐私和匿名性

  • 虽然比特币交易是公开记录的,但用户身份是匿名的。交易是通过地址(类似于账号)进行的,而不是通过真实身份。

    2 Bitcoin 的升级次数介绍

比特币自 2009 年发布以来,经历了多次重要升级。这些升级旨在提高比特币网络的安全性、效率和功能性。

并且比特币的 Taproot 升级给比特币带来更多的可能性,Taproot 升级带动了 BRC20 和 Bitcoin-Layer2 的发展,这里我们不在做过多的介绍,在未来的 Layer2. 的课程中我们会深入讲解这部分的内容。

P2SH(Pay-to-Script-Hash)

  • 时间:2012年

  • BIP(Bitcoin Improvement Proposal):BIP-0016

  • 内容:允许更复杂的交易脚本,支持多重签名地址。这种升级使得比特币交易更加灵活和安全

    比特币改进提案 BIP 66

  • 时间:2015年

  • BIP:BIP-0066

  • 内容:规范了交易中DER格式的签名,解决了交易签名的一致性问题,增强了网络的安全性。

    CheckSequenceVerify(CSV)

  • 时间:2016年

  • BIP:BIP-0112

  • 内容:增加了相对时间锁功能,使得交易可以在指定的时间或块高度之后才生效,这为更复杂的支付通道铺平了道路。

    Segregated Witness(SegWit)

  • 时间:2017年

  • BIP:BIP-0141, BIP-0143, BIP-0144

  • 内容:分离交易签名数据,提高了区块的有效容量,减小了交易体积,降低了交易费用。还解决了交易的可塑性问题,使得闪电网络等侧链解决方案成为可能。

    隔离见证2x(SegWit2x)

  • 时间:2017年

  • 内容:这次升级是对 SegWit 的后续提案,旨在进一步增加区块大小。然而,由于社区共识未达成,这次升级最终未能实现。

    Taproot

  • 时间:2021年

  • BIP:BIP-0340, BIP-0341, BIP-0342

  • 内容:引入了 Schnorr 签名和默克尔化抽象语法树(MAST),增强了隐私性和执行脚本验证的功能,进一步提高了交易的灵活性和效率。这是自2017年 SegWit 以来最重要的一次升级。

  • MAST(Merkelized Abstract Syntax Trees)

  • 时间:2021年

  • BIP:作为 Taproot 的一部分

  • 内容:允许将多种条件的智能合约合并为一个,使得只有满足条件的部分才被公开,提高了隐私性和效率。

  • Schnorr Signatures

  • 时间:2021年

  • BIP:作为 Taproot 的一部分

  • 内容:提供了一种更高效和安全的签名算法,允许多重签名聚合,提高了交易的隐私性和可扩展性。

    3 UTXO 介绍

UTXO(Unspent Transaction Output,未花费交易输出)模型是比特币及其他一些加密货币使用的一种记账方法。它与账户模型不同,通过追踪未花费的交易输出来记录每个地址的余额。以下是 UTXO模型的详细介绍:

3.1.模型解说

在解说 UTXO 模型之前,我想先说说一个名词,叫做 Transaction,即交易,Transaction 和 UTXO 是相辅相成的,下面先来举个例子:

张三:通过挖矿得到了120个比特币,现在张三饿了,想要花费2个比特币去购买一个面包。这是只是举例而已,以现在比特币的价格,1个比特币就可以买到一大堆面包了。

现在我们假设,李四是面包店营业主:

这样的话,在比特币中,张三付给李四将一次性付给李四 120 块,李四给张三找零 118 块,这里其实产生了两笔交易,咱们可以这样理解,张三的钱被分成了两份,其中 118 打给了自己,剩下的 2 块打给了李四。

交易与交易之间组成了网状关系,1 个交易的输出,成为了下 1 个交易的输入;下 1 个交易的输出,又成了下下 1 个交易的输入。所有的钱,在这个网络中流动,每 1 笔钱的去向、来源,都是可追溯的,而这也是区块链网络的一个重要特点。

上面的讲解可能大多数人都比较懵逼,接下来咱们用比较通俗的方式来说明 UTXO 和 Transaction 到底是什么:

在现实生活中,一笔转账对应的事一个付款人和一个收款人,而在比特币种,一笔转账对应的事多个转账人和多个收款人。

现在咱们仔细分析一下上面的这个例子,对于张三买面包这个案列:

  • 付款人:张三 120块

  • 收款人:张三 118块,李四 2块

张三的120,转118块给自己,转2块给李四,对应到交易里面,就是这笔交易有1个输入,2个输出!

下面来一个多输入,多输出的案例:

考虑如下场景:用户A和用户B之间发生了一个交易T3,A 向 B 转 100 元。 A的100元,来自T1:C向A转的80元 + T2:D向A转的30元(共110元,但A只转了100元给B,10元找零返回给A的账号)。 同理,C向A转的这80元,来自用户E、F的某次交易...... D向A转的这30元,来自用户E的某次交易......

这个交易就有2个输入,2个输出: 2个输入(也就是2个UTXO): T1: C向A转的80元 T2:D向A转的30元

2个输出: B:100元 A:10元(找零)

当你理解上面的例子时, 我们再来说一下UTXO,理解上面的例子对你理解UTXO会特别有帮助。

  • 比特币的交易中不是通过账户的增减来实现的,而是一笔笔关联的输入/输出交易事务

  • 每一笔的交易都要花费“输入”,然后产生“输出”,这个产生的“输出”就是所谓的“未花费过的交易输出”,也就是UTXO。每一笔交易事务都有一个唯一的编号,称为交易事务ID,这是通过哈希算法计算而来的,当需要引用某一笔交易事务中的“输出”时,主要提供交易事务ID和所处“输出”列表中的序号就可以了

  • 由于没有账户的概念,因此当“输入”部分的金额大于所需的“输出”时,必须给自己找零,这个找零也是作为交易的一部分包含在“输出”中

  • 旧的 UTXO不断消亡,新的UTXO不断产生。所有的UTXO,组成了UTXO Set 的数据库,存在于每个节点

  • 任何1笔 UTXO,有且仅可能被1个交易花费1次

  • 1 个 UTXO,具有如下的表达形式: 1 个 UTXO = 1个Transaction ID + Output Index

    3.2.UTXO模型的区块链钱包余额形式

深刻理解了UTXO的概念,钱包就很容易理解了, 某个人的钱包的余额 = 属于他的UTXO的总和; 在这里,你会发现一个不同于现实世界的“银行”里的一个概念,在银行里,会存储每个账号剩余多少钱。但这里, 我们存储的并不是每个账号的余额,而存的是1笔笔的交易,也就是1 笔笔的UTXO,每个账户的余额是通过UTXO计算出来的,而不是直接存储余额。

Bitcoin 钱包地址类型

Bitcoin 钱包地址有几种不同的类型,每种类型都有其特定的用途和特点。主要的几种类型包括:

P2PKH(Pay-to-PubKeyHash)地址

  • 格式:以1开头,例如,1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa。

  • 特点:这是最传统和最常见的地址类型,广泛用于比特币的早期交易。

  • 优点:兼容性好,几乎所有钱包和交易所都支持。

  • 缺点:随着时间的推移,这种地址类型的使用效率较低,交易费用可能会较高。

    P2SH(Pay-to-Script-Hash)地址

  • 格式:以3开头,例如,3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy。

  • 特点:这种地址允许更复杂的交易脚本,例如多重签名地址。

  • 优点:支持更复杂的交易和脚本,安全性更高。

  • 缺点:创建和管理比P2PKH地址更复杂。

    Bech32(SegWit)地址

  • 格式:以 bc1 开头,例如,bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwfvenl。

  • 特点:这是比特币改进提案BIP-0173中引入的新地址格式,旨在提高交易效率和减少费用。

  • 优点:交易费用更低,处理速度更快,且有助于减少交易体积。

  • 缺点:并非所有的钱包和交易所都支持这种地址类型,尽管支持率在逐步增加。

每种地址类型都有其特定的应用场景和优缺点,用户可以根据自己的需求选择合适的地址类型来存储和交易比特币。

Bitcoin 离线地址生成代码

1 NodeJs 代码

export function createAddress (params: any): any {
    const {seedHex, receiveOrChange, addressIndex, network, method } = params
    const root = bip32.fromSeed(Buffer.from(seedHex, 'hex'));
    let path = "m/44'/0'/0'/0/" + addressIndex + '';
    if (receiveOrChange === '1') {
        path = "m/44'/0'/0'/1/" + addressIndex + '';
    }
    const child = root.derivePath(path);
    let address: string
    switch(method) {
        case "p2pkh":
            const p2pkhAddress = bitcoin.payments.p2pkh({
                pubkey: child.publicKey,
                network: bitcoin.networks[network]
            });
            address = p2pkhAddress.address
            break
        case "p2wpkh":
            const p2wpkhAddress = bitcoin.payments.p2wpkh({
                pubkey: child.publicKey,
                network: bitcoin.networks[network]
            });
            address = p2wpkhAddress.address
            break
        case "p2sh":
            const p2shAddress = bitcoin.payments.p2sh({
                redeem: bitcoin.payments.p2wpkh({
                    pubkey: child.publicKey,
                    network: bitcoin.networks[network]
                }),
            });
            address = p2shAddress.address
            break
        default:
            console.log("This way can not support")
    }

    return {
        privateKey: Buffer.from(child.privateKey).toString('hex'),
        publicKey: Buffer.from(child.publicKey).toString('hex'),
        address
    };
}

代码中通过 method 来控制生成的地址类别。

Bitcoin 离线签名代码

export function buildAndSignTx (params: { privateKey: string; signObj: any; network: string; }): string {
    const { privateKey, signObj, network } = params;
    const net = bitcore.Networks[network];
    const inputs = signObj.inputs.map(input => {
        return {
            address: input.address,
            txId: input.txid,
            outputIndex: input.vout,
            script: new bitcore.Script.fromAddress(input.address).toHex(),
            satoshis: input.amount
        }
    });
    const outputs = signObj.outputs.map(output => {
        return {
            address: output.address,
            satoshis: output.amount
        };
    });
    const transaction = new bitcore.Transaction(net).from(inputs).to(outputs);
    transaction.version = 2;
    transaction.sign(privateKey);
    return transaction.toString();
}
点赞 1
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Dapplink
Dapplink
0x72fF...cdBC
首个模块化、可组合的Layer3协议。