如果想到达顶点,就从最低层开始吧。
当谈到比特币的时候,我们会听到各种描述:“比特币是一个数据库,里面保存了交易。”,“比特币是一个虚拟机,能够执行脚本。”,“比特币是分布式账本”等等。其实,在描述一个新事物的时候,人们通常会用旧的概念来做类比,反映出新事物的某些特点。那么我们今天就来观察一下比特币的“交易”究竟是什么样的。
对于普通用户来说,我们观察到的比特币是这样的:
转账: 打开钱包->输入金额,地址->点击发送收钱: 打开钱包->等待网络同步
钱包似乎是在从一个远程的服务器上传和下载数据。事实上,比特币网络可以看作是一个只有“增”和“查”功能的数据库。那么如何才能往比特币网络中存入交易数据呢?一般来说, 比特币网络会对接收到的数据做这样的验证:
def receive_data(data) do data |> deserialize() |> valid?() |> save()end
反序列化
所以,第一步是将接收到的二进制数据进行反序列化,得到交易内容。下面是raw的比特币交易数据:
01000000011a6dae526d3c88630a97bcfe84895e6802ea367324e57a70ecd1e30fcbbb9a88000000006b483045022100fde8236c63aa891850216f736d1efaecbca2582ac9027016e4341075dc086f38022044f7aa43c33e81018c642e5dffe545e3f3ad610f8bcdd2671026592c7eadee18012102d6a0f589e7fa321c5ec21aefde732ede2d7e2a16998dda19965256b2fb3523c2feffffff030000000000000000166a146f6d6e6900000000000000020000000002faf08022020000000000001976a91442352b8a2b42a31b63ed67363a5ac5c3463c3b5a88ac42d16800000000001976a9145d3c5a1aac4c6182d987c68055d63a75ba62e22d88ac65a91300
参照 ,可以将其翻译为:
version: 1,tx_in_count: 1,tx_in: [ { previous_output: { hash: '1a6dae526d3c88630a97bcfe84895e6802ea367324e57a70ecd1e30fcbbb9a88', index: 0 }, script_bytes: 107, signature_script: 'PUSH48 3045022100fde8236c63aa891850216f736d1efaecbca2582ac9027016e4341075dc086f38022044f7aa43c33e81018c PUSH64 2e5dffe545e3f3ad610f8bcdd2671026592c7eadee18012102d6a0f589e7fa321c5ec21aefde732ede2d7e2a16998dda19965256b2fb3523c2', sequence: 4278190079 } ],tx_out_count: 3,tx_out: [ { value: 0, pk_script_bytes: 22, pk_script: 'OP_RETURN 6f6d6e6900000000000000020000000002faf080' }, { value: 0.00000546, pk_script_bytes: 25, pk_script: 'OP_DUP OP_HASH160 42352b8a2b42a31b63ed67363a5ac5c3463c3b5a OP_EQUALVERIFY OP_CHECKSIG' }, { value: 0.06869314, pk_script_bytes: 25, pk_script: 'OP_DUP OP_HASH160 5d3c5a1aac4c6182d987c68055d63a75ba62e22d OP_EQUALVERIFY OP_CHECKSIG', } ]
注意这是一个version为1的交易,version为2的交易格式可参照 。version2具体增加的功能会在之后的文章中专门了解。
验证
反序列化完成之后,交易里的信息就被提取出来了。接下来就要验证交易的合法性,我们只需要用到交易中的 tx_in
, 以及前一个交易中的tx_out
,把两个脚本结合起来运行,得到true的结果,就证明了新的交易可以转移旧的交易中对应的output里的value。当然,新交易的output里的value之和不能大于所有input里得到的value。
如何运行比特币的脚本,会在之后的文章中提到。