Go区块链之交易一

引言:

交易是比特币的核心,区块链唯一的目的就是安全可靠的存储交易数据,使得交易数据在创建之后不可更改。由于实现真正的交易比较复杂,我们将交易分为2部分来实现。本文将大体实现交易机制,交易的具体细节实现,容后再述。

什么是交易?

一般的web应用需要创建如下数据表用于实现支付逻辑:用户账户、交易。用户账户表用于存储用户信息和余额,交易信息表用于存储钱从一个账户转账到另一个账户。然而在比特币交易的实现方式完全不同:

1.没有账户的概念

2.没有余额的概念

3.没有地址

4.没有金币

5.没有发送方和接收方

由于区块链是一个公开透明的数据库,并不希望存储用户的钱包等敏感信息。金币不在账户中保存,钱不再从一个地址转到另一个地址,没有账户保存账户余额,区块链仅保存交易信息。那交易又包含什么信息呢?

比特币交易

一个交易由输入输出构成:

go交易结构

一笔新的交易的输入指向之前一笔旧的交易的输出(矿工费除外,即每个区块的第一笔交易)。交易输出是真正保存金币的地方。

交易间相互关联的示意图

需要注意的是:

1.存在未被输入引用的输出,即未被花费的金币

2.在一笔交易中,输入可能来源于多比旧的交易的输出

3.一笔输入必须引用一个交易的输出

在本文中,我们将继续使用钱、金币、花费、发送、账户等字眼。但是在比特币中并不存在这种概念,交易仅仅将价值由脚本锁定,该脚本指定只有锁定这笔交易的用户可以解锁使用该笔交易的输出。

交易输出

交易输出结构

实际上,比特币使用交易输出存储金币(Value),存储的意思是使用一个脚本对交易输出加锁。在比特币中,该脚本定义了输出加锁解锁的逻辑。这种脚本语言非常底层(为了避免黑客攻击或者误用)。由于我们尚未实现地址的概念,因此这里不再赘述该脚本的加解锁。我们可以直接定义加解密使用设定的字符串。

需要注意的是一笔交易中的输出是一个整体,不可分割,即每个交易输出的Value都不可分割。

交易输入

交易输入

交易输入指向以前交易的输出,因此交易输入中的TxId为指向交易的Id,Vout为指向交易的交易输出的索引,ScriptKey为交易输出提供数据。如果数据正确,交易输出可以解锁,即该笔交易输出的Value可以用于生成新的交易输出。这种机制保证了,一个用户只能使用自己加锁的金币。

先有鸡还是先有蛋?

在比特币中,交易输入来源于交易输出的逻辑类似鸡蛋问题。在比特币中,先有蛋而后有鸡。交易输入来源于交易输出,交易输出为交易输入提供来源。

当一个矿工在挖掘一个区块的时候,他会在区块的交易前加一笔coinbase交易,该交易输入不需要指向之前的交易输出,这笔交易是对矿工挖出区块的奖励。

CoinBase 交易

一笔coinbase交易只有一个交易输入,该交易输入的TxId为空,Vout为-1,同时CoinBase交易不使用ScriptKey,保存特定字符串。

区块链保存交易数据

区块结构
数据库存储区块使用序列化和反序列化工具

相应的创世区块和区块生成需要修改:

区块新建

ProofOfWork需要做相应的修改:

pow挖矿计算

在这里,我们仍然使用哈希来代表每个区块交易,其算法如下图:

我们简单的将所有交易的id进行join然后计算出其哈希,作为挖矿的数据准备。在比特币中,采用merlerk tree对交易进行处理。容后再述。

未花费交易输出

为了实现交易,我们需要找到某个用户所有的未花费交易输出(Unspent Transaction Outpus,UTXO)。未花费意味着,该交易输出未被新的交易输入引用。对应第一张图中的:

1.Tx0 Output1

2.Tx1 Output0

3.Tx3 Output0

4.Tx4 Output0

当然,当我们查看余额时,我们只需要对应地址可以解锁的输出。在交易输入输出中,我们定义了简单的加锁逻辑。

在交易中,为了找到UTXO,我们可先查找有交易输出未被引用的交易,其实现如下:

在以上代码中,我们将被交易输入引用的交易存储在spentTXO中,循环每个交易查看,交易输出,若满足交易输出未被引用则将其append到unspentTX中。

在上述代码中,我们找到了存在未被引用的output的交易,且存在output可以被指定address解锁的交易序列。接下来,我们从中找出,address锁定的output,即UTXOs:

若想查看address对余额,我们只需要将UTXO中的Value相加即可,具体实现如下:

转账

为了将coin从一个address转入另一个address,我们需要实现一笔交易(非coinBase)。首先我们需要从未花费交易中找到足够的余额和对应tx,作为新的一笔交易的输入引用。

用以上交易,作为新的交易的输入,并生成新的交易输出,建立交易。

最后,我们将一笔笔交易加入区块,并计入区块链。

测试

区块三:lisi转给wangwu5Coin(交易来源区块一的第0个输出),区块四:wangwu转给zhaoliu8Coin(交易来源区块二,区块三两笔交易)
区块一:zhangsan转给lisi10Coin(交易来源创世区块中交易的第1(序号从0开始)个输出),区块二:zhangsan转给wangwu5Coin(交易来源区块一交易的第1(序号从0开始)个输出)
创世区块,奖励zhangsan50Coin
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容