通过blockchain_go分析区块链交易原理

原文链接-石匠的Blog

1.背景

在去中心化的区块链中进行交易(转账)是怎么实现的呢?本篇通过blockchain_go来分析一下。需要进行交易,首先就需要有交易的双方以及他们的认证机制,其次是各自的资金账户规则。在分布式账本系统里面,需要有机制能够准确验证一个用户身份以及对账户资金的精确计算,不能出现一丁点差错。在区块链中交易通过Transaction表示,而账户的自己并不是在每个节点上保存每个用户的一个余额的数字,而是通过历史交易信息计算而来(历史交易不可篡改),其中的关键机制是UTXO。

2.身份认证

在区块链身份认证是采用RSA非对称加密体系完成,每个用户在会拥有一个“钱包”,钱包是通过安全的椭圆曲线加密算法生成,其中包括一对公私钥。私钥自己保留不能暴露,用作加密,签名等,公钥公开给所有人,用于信息验证等。只要是用私钥签名的信息,就可以通过配对的公钥解码认证,不可抵赖。在blockchain_go中,钱包实现如下:

// Wallet stores private and public keys type Wallet struct { PrivateKey ecdsa.PrivateKey PublicKey []byte } // NewWallet creates and returns a Wallet func NewWallet() *Wallet { private, public := newKeyPair() wallet := Wallet{private, public} return &wallet } func newKeyPair() (ecdsa.PrivateKey, []byte) { curve := elliptic.P256() //椭圆曲线 private, err := ecdsa.GenerateKey(curve, rand.Reader) //生成私钥 if err != nil { log.Panic(err) } pubKey := append(private.PublicKey.X.Bytes(),private.PublicKey.Y.Bytes()...) //合成公钥 return *private, pubKey }

钱包最重要的功能就是为用户提供身份认证和加解密的公私钥对。

3.什么是Transaction

区块链中的Transaction(交易)就是一批输入和输出的集合,比如A通过交易给B10个代币(token),那么交易就是A输入10代币,输出变成B得到10代币,这样A就减少10代币,B增加10代币,再将这个交易信息存储到区块链中固化后,A和B在区块链中的账号状态就发生了永久性不可逆的变化。

在blockchain_go中transaction的定义如下:

// TXInput represents a transaction input type TXInput struct { Txid []byte Vout int Signature []byte PubKey []byte } // TXOutput represents a transaction output type TXOutput struct { Value int PubKeyHash []byte } type Transaction struct { ID []byte //交易唯一ID Vin []TXInput //交易输入序列 Vout []TXOutput //交易输出序列 }

从定义可以看到Transaction就是输入和输出的集合,输入和输出的关系如下图:

其中tx0,tx1,tx2等是独立的交易,每个交易通过输入产生输出,下面重点看看一个交易的输入和输出单位是怎么回事。

先看输出TXOutput:

Value : 表示这个输出中的代币数量

PubKeyHash : 存放了一个用户的公钥的hash值,表示这个输出里面的Value是属于哪个用户的

输入单元TXInput:

Txid : 交易ID(这个输入使用的是哪个交易的输出)

Vout : 该输入单元指向本次交易输出数组的下标,通俗讲就是,这个输入使用的是Txid中的第几个输出。

Signature : 输入发起方(转账出去方)的私钥签名本Transaction,表示自己认证了这个输入TXInput。

PubKey : 输入发起方的公钥

通俗来讲,一个TXInput结构表示 :

我要使用哪个交易(Txid)的哪个输出数组(Transaction.Vout)的下标(Vout)作为我本次输入的代币数值(TXOutput.Value)

因为交易的输入其实是需要指明要输入多少代币(Value),但是TXInput中并没有直接的代币字段,而唯一有代币字段的是在TXOuput中,所以这里使用的方式是在TXInput中指明了自己需要使用的代币在哪个TXOutput中。

TXInput中的Signature字段是发起用户对本次交易输入的签名,PubKey存放了用户的公钥,用于之前的验证(私钥签名,公钥验证)。

3.什么是UTXO

UTXO 是 Unspent Transaction Output 的缩写,意指“为花费的交易输出”,是中本聪最早在比特币中采用的一种技术方案。因为比特币中没有账户的概念,也就没有保存用户余额数值的机制。因为区块链中的历史交易都是被保存且不可修改的,而每一个交易(如前所述的Transaction)中又保存了“谁转移了多少给谁”的信息,所以要计算用户账户余额,只需要遍历所有交易进行累计即可。

从第三节的交易图可以看到,每笔交易的输入TXInput都是使用的是其他交易的输出TXOutput(只有输出中保存了该输出是属于哪个用户,价值多少)。如果一笔交易的输出被另外一个交易的输入引用了(TXInput中的Vout指向了该TXOutput),那么这笔输出就是“已花费”。如果一笔交易的输出没有被任何交易的输入引用,那么就是“未花费”。分析上图的tx3交易:

tx3有3个输入:

input 0 :来自tx0的output0,花费了这个tx0.output0.

input 1 :来自tx1的output1,花费了这个tx1.output1.

input 2 :来自了tx2的output0,花费了这个tx2.output0.

tx3有2个输出:

output 0 :没有被任何后续交易引用,表示“未花费”。

output 1 :被tx4的input1引用,表示已经被花费。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjzyz.html