abbshr.github.io icon indicating copy to clipboard operation
abbshr.github.io copied to clipboard

Biter loggers 3:Transactions

Open abbshr opened this issue 10 years ago • 0 comments

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"
        ]
    }
}

abbshr avatar May 07 '14 07:05 abbshr