本文介绍比特币的交易签名和UTXO
比特币和以太坊最大的区别是比特币发起交易是基于UTXO(Unspent Transaction Output)
说utxo大家可能听不懂,但是我们来亲自签一笔交易就会明白了
首先需要依赖包
const bitcoin = require('bitcoinjs-lib');
要签名首先我们需要获得一个账户的UTXO,也就是至少一笔的未被花费的交易支票,我们可以使用接口来获得这样的支票
https://blockchain.info/unspent?active=你的地址
{
"unspent_outputs":[
{
"tx_hash":"23bfcc8d8f14e792946ebfeda4f8608b1b96e1efaae8c18ca0b5fab1a362c5c0",
"tx_hash_big_endian":"c0c562a3b1fab5a08cc1e8aaefe1961b8b60f8a4edbf6e9492e7148f8dccbf23",
"tx_index":56365906,
"tx_output_n": 1,
"script":"76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac",
"value": 890000,
"value_hex": "0d9490",
"confirmations":231264
}
]
}
这里是一个UTXO,里面有890000的satoshi,记载着tx_hash(交易hash值)和value(交易包含的比特币)
签名首先需要知道的是每一笔支票被交易时都会花完支票中的所有的比特币,意思是说除了这笔支票的转出金额,剩下的比特币都将被当做矿工费,所以我们需要在交易中写好找零地址,也就是转出地址应当包括转出目标地址和自己的一个地址作为找零地址
签名代码可以参考官网示例
set = bitcoin.ECPair.fromWIF(privatekey);//导入私钥用于签名
txb = new bitcoin.TransactionBuilder();//初始化交易对象
amount+=1e4;//消费金额是转出金额加上10000的矿工费
txb.setVersion(1);//设置交易版本号
var tot=0;//用于记录UTXO总量
for(var i=0;i<tx.length;i++){//将UTXO的相关信息依次填入交易体中
txb.addInput(tx[i].tx_hash_big_endian, tx[i].tx_output_n);
tot+=tx[i].value;
}
txb.addOutput(toaddress, amount-1e4);//填入转出目标地址和对应的金额
txb.addOutput(from, tot-amount); //填入找零地址,也就是原地址,并填入把找零金额
for(var i=0;i<tx.length;i++){//对交易体中的UTXO依次签名
txb.sign(i, set);
}
console.log(txb.buildIncomplete().toHex());//得到最终交易序列
最终可以得到,需要注意的是填入UTXO作为input时应该填入的是tx_hash_big_endian参数,而不是大家以为的tx_hash(这绝对是个坑)
扫描二维码关注公众号,回复:
2280600 查看本文章
像这样的序列
你可以通过这个网站验证交易序列是否正确,还可以通过接口来发送交易,发送成功后会返回
当这样的一笔交易被发出之后,将会为找零地址和转出地址产生新的UTXO,从这里我们可以看出,从比特币的第一笔UTXO开始,伴随着不断地交易,会分成多个UTXO,而交易则改变了它们的所有权。