比特币交易开发实战(二)

时间:2018-07-19作者:klpeng分类:IT综合浏览:2713评论:0

上次介绍了通过 BlockCypher 的 Api 来创建并发送普通地址的比特币交易,但对于比特币中的隔离见证地址这种方式就不能用了,所以我们再推荐另外一种创建比特币交易的方式——通过 bitcoinjs-lib 来创建交易。

Bitcoinjs-lib

在之前的文章就已经介绍过 bitcoinjs-lib 这个库了,它是一个比特币 JS 工具库,是众多比特币工具库中使用人数比较多的,它包含了创建钱包、导入钱包、创建交易等功能。

bitcoinjs-lib 没有提供说明文档,但提供了一套比较完整的测试案例,通过测试案例我们就可以知道 Api 的使用方法。

普通地址的交易

使用 bitcoinjs-lib 创建比特币交易,主要是通过 TransactionBuilder 这个 Api 来完成,下面是普通地址一对一交易的代码示例。

// 创建钱包
const alice = bitcoin.ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy');
// 构建交易 builder
const txb = new bitcoin.TransactionBuilder();

// 添加交易中的 Inputs,假设这个 UTXO 有 15000 satoshi
txb.addInput('61d520ccb74288c96bc1a2b20ea1c0d5a704776dd0164a396efec3ea7040349d', 0);
// 添加交易中的 Outputs,矿工费用 = 15000 - 12000 = 3000 satoshi
// addOutput 方法的参数分别为收款地址和转账金额
txb.addOutput('1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP', 12000);

// 交易签名
txb.sign(0, alice);
// 打印签名后的交易 hash
console.log(txb.build().toHex());

 

 

这里要注意, addInput 方法的第一个参数是交易的 hash(每一笔比特币交易都有一个 hash 号来作为唯一标识),而第二个参数是这笔交易中的 Outputs 的索引,这个索引指向的 Output 首先必须是一个 UTXO,其次必须和转出地址相关。比如一笔交易包含了 2 个 Output:

  • 地址 A,索引 0
  • 地址 B,索引 1

如果是从地址 A 转账出去的交易,那么就应该选索引 0。

隔离见证地址的交易

隔离见证地址的交易需要用到隔离见证地址的回执脚本 redeemScript ,用于签名方法的第三个参数,代码示例如下:

第一行testnet指:bitcoin.networks.testnet

const keyPair = bitcoin.ECPair.fromWIF('cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA', testnet);
const pubKey = keyPair.getPublicKeyBuffer();
const pubKeyHash = bitcoin.crypto.hash160(pubKey);
// 得到隔离见证地址的回执脚本
const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash);

// 构建交易 builder
const txb = new bitcoin.TransactionBuilder();

// 添加交易中的 Inputs,假设这个 UTXO 有 15000 satoshi
txb.addInput('61d520ccb74288c96bc1a2b20ea1c0d5a704776dd0164a396efec3ea7040349d', 0);
// 添加交易中的 Outputs,矿工费用 = 15000 - 12000 = 3000 satoshi
// addOutput 方法的参数分别为收款地址和转账金额
txb.addOutput('1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP', 12000);

// 交易签名
txb.sign(0, keyPair, redeemScript, null, 15000);
// 打印签名后的交易 hash
console.log(txb.build().toHex());

 

 

隔离见证地址的交易和普通地址交易的区别就仅仅在签名函数上,其他地方基本相同。

这里要说明一点,交易的签名次数是根据交易中的 Inputs 来决定的,如果 Inputs 有多个的话,就需要多次调用 txb.sign 方法。

我们得到交易的签名 hash 后,就可以通过第三方的 Api 进行广播了。

获取 UTXO

创建比特币交易时调用 bitcoinjs-lib 的 Api 其实并不难,比较难的是如何添加交易中的 Inputs。

Inputs 需要获取转出地址的 UTXO,那有什么简便的方式来获取地址的 UTXO 呢?所幸 BlockChain 提供了一个 Api 可以来获取地址的 UTXO,Api信息如下:

{
    "unspent_outputs":[
        {
            "tx_age":"1322659106",
            "tx_hash":"e6452a2cb71aa864aaa959e647e7a4726a22e640560f199f79b56b5502114c37",
            "tx_index":"12790219",
            "tx_output_n":"0",
            "script":"76a914641ad5051edd97029a003fe9efb29359fcee409d88ac", (Hex encoded)
            "value":"5000661330"
        }
    ]
}

 

 

在返回的结果中有我们需要的交易 hash 和索引值,以及用来计算需要多少个 input 的 value 值,这样就可以算出交易需要哪些 Inputs 了。

size 的计算公式

在比特币的交易中,如果矿工费用设置过高或者过低,交易都不能成功生成,所以我们还需要计算交易中的矿工费用,这里有一个公式可以大致预估出交易所需的 size,然后将 size 再乘以 每比特的价格 就可以得到矿工费用了。

size = inputsNum * 180 + outputsNum * 34 + 10 (+/-) 40
  • inputNum 指交易中的 Input 个数
  • outputNum 指交易中的 Output 个数
  • 最后一部分是加减 40

总结

通过 bitcoinjs-lib 的 Api 我们不但可以完成普通地址的交易,而且还可以完成隔离见证地址的交易,而且调用的第三方 Api 更少(只需要一个广播交易的 Api),但缺点就是需要自己去统计交易的 Inputs 和 Outputs,但只要我们熟悉了统计方法其实也挺简单的。

 

原文:https://ww.colabug.com/3572151.html

打赏
文章版权声明:除非注明,否则均为彭超的博客原创文章,转载或复制请以超链接形式并注明出处。
相关推荐

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

猜你喜欢