教你用go语言实现比特币交易功能(Transaction)
比特币交易
交易(transaction)是比特币的核心所在,而区块链唯一的目的,也正是为了能够安全可靠地存储交易。在区块链中,交易一旦被创建,就没有任何人能够再去修改或是删除它。
对于每一笔新的交易,它的输入会引用(reference)之前一笔交易的输出(这里有个例外,coinbase 交易),引用就是花费的意思。所谓引用之前的一个输出,也就是将之前的一个输出包含在另一笔交易的输入当中,就是花费之前的交易输出。交易的输出,就是币实际存储的地方。下面的图示阐释了交易之间的互相关联:
注意:
有一些输出并没有被关联到某个输入上
一笔交易的输入可以引用之前多笔交易的输出
一个输入必须引用一个输出
贯穿本文,我们将会使用像“钱(money)”,“币(coin)”,“花费(spend)”,“发送(send)”,“账户(account)” 等等这样的词。但是在比特币中,其实并不存在这样的概念。交易仅仅是通过一个脚本(script)来锁定(lock)一些值(value),而这些值只可以被锁定它们的人解锁(unlock)。
每一笔比特币交易都会创造输出,输出都会被区块链记录下来。给某个人发送比特币,实际上意味着创造新的 utxo 并注册到那个人的地址,可以为他所用。
交易的主函数:
我们从头分析整个交易过程,首先利用validateaddress()方法判断输入的地址是否为有效的比特币地址,然后从我们的blotdb数据库中获取blockchain实例(我们利用一个数据库实现区块链数据的存储,这里读者可以忽略),其中读取数据库的代码如下
其中我们的区块链的基本原型为
获取完成区块链实例后,我们创建出一个utxo集合,其数据结构为
然后我们从钱包文件中获取我们的接着调用我们的转账函数。
对于一笔交易来说,其数据结构为
一笔交易来说,输出主要包含两部分: 一定量的比特币(value), 一个锁定脚本(scriptpubkey),要花这笔钱,必须要解锁该脚本。一个输入引用了之前交易的一个输出:txid 存储的是之前交易的 id,vout 存储的是该输出在那笔交易中所有输出的索引(因为一笔交易可能有多个输出,需要有信息指明是具体的哪一个)signature是签名,而pubkey是公钥,两者保证了用户无法花费属于其他人的币。
在创建新的输出时,我们必须找到所有的为花费的输出,并且确保他们有足够的价值(value),这就是findspendableoutputs
要做的事情,随后,对于每个找到的输出,会创建一个引用该输出的输入。接下来,我们创建两个输出:
- 一个由接收者地址锁定。这是给其他地址实际转移的币。
- 一个由发送者地址锁定。这是一个找零。只有当未花费输出超过新交易所需时产生。记住:输出是不可再分的。
交易必须被签名,因为这是保证发送方不会花费其他人的币的唯一方式,如果一个签名是无效的,那么这笔交易也会被认为是无效的,因为这笔交易无法被加到区块链中。考虑到交易解锁的是之前的输出,然后重新分配里面的价值,并锁定新的输出,那么必须要签名一下的数据
- 存储在已经解锁输出的公钥哈希,他识别了一笔交易的发送方
- 存储在新的锁定输出里面的公钥哈希,他识别了一笔交易的接收方
- 新的输出值
因此,在比特币里,所签名的并不是一个交易,而是一个去除部分签名的输入的副本,输入里面存储了被引用输出的scriptpubkey
如果现在进行过挖矿
参考
https://jeiwan.cc/
到此这篇关于利用go语言实现比特币交易(transaction)的文章就介绍到这了,更多相关go语言比特币交易内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!