abbshr.github.io
abbshr.github.io copied to clipboard
Biter loggers 3:Transactions
Log 4:拆开Blocks看Transactions
Bitcoins 结构简图
Bitcoins:{
BlockChain <Master>:{
Block0:{
Transaction0 :{ …… }
Transaction1 :{ …… }
Transaction2 :{ …… }
……
}
Block1:{
Transaction0 :{ …… }
Transaction1 :{ …… }
Transaction2 :{ …… }
……
}
……
}
BlockChain <Abandon>:{
……
}
……
}
货币的主要用途是交易,BitCoins也自然如此,因此交易(Transactions)作为BlockChains的原子构成(从上图可知)是很重要的。
每个Block都是由多条Transactions(简写为Tx)组成。每条tx记录了每笔Bitcoins交易的详细信息。
每个Block的首条tx记录被称为Coinbase tx。其特点是只有输出而没有输入,因为这条tx是Bitcoin系统为了回报_挖矿_而生成的Bitcoin奖励。(这也是Bitcoins的发行方式)
该Block中其余的tx都是允许有几个输入和几个输出。输入代表从前一比交易中获得bitcoins,输出代表花费(其实是转帐)目前这笔交易中的bitcoins。一旦某个Tx的一个输出成为另一个Tx的输入,那么该笔比特币即为已花费。
每笔tx有在此block中唯一的Hash值来标识,它是通过对交易数据做两次SHA256加密运算得出。
这些tx信息是全网公开的,以明文形式存储(比特币系统里的所有数据都是明文的),只有当需要转移货币所有权时,才需要用私钥签名来验证。
交易结构:
- 首条交易(被称作:Generation tx)
{
# hex包含了这个tx的全部信息,以下内容均可由hex解析出来
"hex" : "……",
# txid由hex键经过两次SHA256加密生成
# Note:运算结果结果应该是按小端字节次序(little endian)读取的
# 唯一标识了这个交易
"txid" : "……",
# 本次交易的版本号
"version" : 1,
# 在给定时间之前该交易信息被“锁定”(即不能被录入到blocks中)
"locktime" : 0,
# generation交易的输入,为一个数组
"vin" : [
{
"coinbase" : "……",
"sequence" : 4294967295
}
],
# 交易的输出,同为一个数组
"vout" : [
{
"value" : 50.01000000,
"n" : 0,
"scriptPubKey" : {
"asm" : "……",
"hex" : "……",
"reqSigs" : 1,
"type" : "pubkey",
"addresses" : [
"1LgZTvoTJ6quJNCURmBUaJJkWWQZXkQnDn"
]
}
}
],
# 标记这个tx属于哪个blocks
"blockhash" : "……",
"confirmations" : 145029,
"time" : 1301705313,
"blocktime" : 1301705313
}
- 普通交易:
{
# 键名与含义大至于上面的相同,唯一区别是“vin键”,下面有解释。
"hex" : "……",
"txid" : "……",
"version" : 1,
"locktime" : 0,
# 普通tx的输入
"vin" : [
{
"txid" : "……",
"vout" : 0,
"scriptSig" : {
"asm" : "……",
"hex" : "……"
},
"sequence" : 4294967295
},
{
"txid" : "……",
"vout" : 1,
"scriptSig" : {
"asm" : "……",
"hex" : "……"
},
"sequence" : 4294967295
},
{
"txid" : "……",
"vout" : 1,
"scriptSig" : {
"asm" : "……",
"hex" : "……"
},
"sequence" : 4294967295
}
],
"vout" : [
{
"value" : 0.84000000,
"n" : 0,
"scriptPubKey" : {
"asm" : "……",
"hex" : "……",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"1A3q9pDtR4h8wpvyb8SVpiNPpT8ZNbHY8h"
]
}
},
{
"value" : 156.83000000,
"n" : 1,
"scriptPubKey" : {
"asm" : "……",
"hex" : "……",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"1Bg44FZsoTeYteRykC1XHz8facWYKhGvQ8"
]
}
}
],
"blockhash" : "……",
"confirmations" : 147751,
"time" : 1301705313,
"blocktime" : 1301705313
}
以上,第一个block中的首笔交易,第二个是含有三输入两输出的普通交易。
注释已经注明,他们之间的区别是在vin(交易来源)字段:
对于首笔交易自然没有输入,其vin字段的值为:
{
# coinbase字段允许挖矿者写入自定义的信息,
# 如中本聪在首个 block 的首条 transaction 中写入了:
# “04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73”
# 转码过来之后就是:
# “The Times 03/Jan/2009 Chancellor on brink of second bailout for banks”
"coinbase" : "……",
"sequence" : ……
}
普通交易的vin字段:
{
"txid" : "……",
"vout" : 0,
"scriptSig" : {
# 公钥
"asm" : "……",
# 签名
"hex" : "……"
},
"sequence" : ……
}
txid hash算法
上面已经说了,txid是由hex生成的,下面就是txid的计算方法:
funtion getTxid(hex) {
bin = new Buffer(hex, 'hex');
buf_BE = crypto.createHash('sha256').update(crypto.createHash('sha256').update(bin).digest()).digest();
buf_LE = Array.protptype.reverse.call(buf_BE); // 转换为小段次序
txid_hash = buf_LE.toString('hex');
}
Note:其他字段解释(引自比特币实验室)
sequence:若该笔交易的所有输入交易的sequence字段,均为INT32最大值(0xffffffff),则忽略lock_time字段。否则,该交易在未达到Block高度或达到某个时刻之前,是不会被收录进Block中的。
lock_time:是一个多意字段,表示在某个高度的Block之前或某个时间点之前该交易处于锁定态,无法收录进Block。
0 立即生效
< 500000000 含义为Block高度,处于该Block之前为锁定(不生效)
= 500000000 含义为Unix时间戳,处于该时刻之前为锁定(不生效)
从解析后的Transaction结构中,可以得到每个tx的每笔花费信息,包括花费数量、转帐地址以及后续交易的hex等等,如:
{
# 本次转帐金额
"value" : 0.84000000,
"n" : 0,
# 公钥
"scriptPubKey" : {
"asm" : "……",
"hex" : "……",
"reqSigs" : 1,
"type" : "pubkeyhash",
# 转帐地址
"addresses" : [
"1A3q9pDtR4h8wpvyb8SVpiNPpT8ZNbHY8h"
]
}
}