在以太坊世界中, 当我们发起一笔转账交易, 可以从 Etherscan 这样的以太坊区块链浏览器上搜索查看交易的详细信息, 我在之前有写过详细的关于 Etherscan 的使用教程, 那么今天, 让我们来到比特币的世界, 学习如何使用blockchain.info区块链浏览器查询比特币区块链上的交易信息。
前言
1. 什么是 UTXO 机制
为了方便大家理解后续 Blockchain 上所显示的内容, 我们还是要首先讲解一下 UTXO 机制, 这也是比特币和以太坊的一个重要的区别。UTXO 代表 Unspent Transaction Output, 它是比特币交易的基本单位是未经使用的一个交易输出[1]。UTXO 是不能再分割、被所有者锁住的或记录于区块链中的并被整个网络识别成货币单位的一定量的比特币[2]。
举一个很详细的例子来说明, 小明的妈妈想去买两瓶酱油, 一瓶酱油的价格是 6 元钱, 但是由于小明的妈妈需要在家做饭, 所以委托小明去商店购买, 小明的妈妈给小明 1 张 10 元, 一张 5 元, 和 一张 1 元, 并承诺其中的 1 元钱做为小明的 “跑腿费”。于是小明将 1 元钱先 “纳入麾下”, 然后到商店, 将 15 元给到售货员, 换取两瓶酱油花费 12 元。售货员找回 3 元钱, 小明回到家将三元钱还给妈妈。
在这个故事中, 10 元和 5 元属于小明妈妈的 output[注1], 而对于小明来说, 他充当的是 矿工的角色, 所以小明妈妈给小明的 1 元钱是矿工费, 而对于商店售货员来说, 他的 12 块钱是 input, 而找回的 3 元钱, 对于小明妈妈而言, 就是 UTXO。
这里还要提到有趣的一点, 就是上述小明妈妈最初拿出的 10 元和 5 元分别是一个 UTXO, 是小明妈妈在买其他货物的时候, 作为找零获得的。并且 10 元和 5 元都是不可分割的。同时如果一个 UTXO 比一笔交易所需数量大, 它仍会被当做一个整体而消耗掉, 但是同时会在交易中生成零头。
图1-1
2. 比特币找零地址
上述这个故事中, 有一个概念我们要着重讲解一下, 就是 “找零机制”。首先我们要知道, 找零地址可以是我们之前使用的地址 (即转账地址), 也可以是新的地址。如果我们在转账的时候, 不设置找零地址的话, 那么所有的 “找零” 都将支付给矿工。在上述例子中, 如果小明买完酱油之后, 小明的妈妈忘记向小明要回找零的 3 元钱, 那这笔钱是不是就被小明 “私吞” 了呢? 同样, 如果你有 100 个 BTC, 转账给朋友 1 个 BTC之后, 忘记设定找零地址, 那么剩下的 99 个 BTC 将全部 “无偿” 捐献给打包这笔交易的矿工。听上去是不是很可怕?
但是, imToken 的用户则无需担心忘记设置找零地址, 因为 imToken 已经自动帮你完成这一切, 即每次转账都会新为你生成一个找零地址[注2]。
那么有的人会问道, 为什么每次都要生成一个新的地址, 用于接收找零代币? 直接使用原地址接收找零不好吗? 这个问题我们会在下边谈到。
基础篇
3. 如何查询转账地址信息
如果你对上述概念还是一知半解, 没有关系, 我通过实战操作再来帮助你深入理解。打开 https://blockchain.info/ 网站, 输入你的 BTC 转账地址, 点击 Search 按钮, 进行查询。
图 3-1
这里可以看到, 我当前地址曾经一共收到过 0.01 个BTC (Total Received 所显示), 但是由于我使用 imToken 发起过一次转账交易, 所以当前的地址中所剩 BTC 为 0 (Final Balance 所显示)。
这里有一个问题, 我当前地址本来有 0.01 个 BTC, 而我只转出 0.001 个 BTC, 为什么当前地址余额变成了 0 ?
其实这就是文章开篇提到的比特币 UTXO 机制, 比特币为了安全性和匿名性, 可以在每次使用一个地址转账过后, 将 “找零” 转向新的地址。可以看到图 3-2 的 Transactions 类目下一笔转账交易竟然出现两个 “收款地址”, 一个是真正的转账目标地址, 另一个则是找零地址。但是我们单从地址上无法分辨到底哪个是找零地址, 哪个是转账地址, 只能通过已知哪个是目标地址, 然后使用排除法判断。但通过我测试, 一般情况下第一个都是转账地址, 第二个为找零地址 (多笔转账不适宜)。
图 3-2
4. 如何查询交易是否成功
如图 4-1, 我使用 imToken 中生成的 BTC 地址 19Fbiok5SuP7YWReGDwMp
77tfx1vVDVih1 向 1Aqyai7gLr44DPmPdW3S24YeEKfiiW9foV 地址转账0.0009 个 BTC, 这时候交易属于 Uncomfirmed Transaction 转账, 也就是说还没有矿工确认打包。BTC 和以太坊目前都是 POW 机制, 即交易需要矿工打包确认。不同的是, 以太坊的出块速度是 15 秒, 而比特币需要 10 分钟。
图 4-1
我们普遍认为确认一笔比特币交易确认需要 6 个区块确认, 但是一般情况下只要看到 1 个区块确认, 即 1 Comfirmation(如图 3-2), 就基本可以确定这笔交易成功了, 同时也可以使用 imToken 查看到余额的变化。
图 4-2
5. 如何查询矿工费
比特币和以太坊一样, 转账也需要支付足够的矿工费。比特币的最小计数单位是 “聪” (Satoshi, 简称 sat)。其实在比特币的底层协议中, 并没有规定每笔交易的矿工费需要多少, 只是要求地址中总输入(input)不小于总输出(output), 所以从理论上来说, 如果一笔转账交易不支付矿工费, 也是会被矿工打包, 并且交易成功, 但是时间确是不确定的, 有可能会等上很多年。
目前比特币的转账矿工费, 是按照交易数据字节大小和 input 以及 output 的数量来来确定的。数据越大, 交易数量越多, 矿工费越多。一般情况下每笔交易的字节数在 200 ~ 300 bytes, 而每个 bit 你所愿意支付的费用可以自定义, 例如使用 imToken 设置 20 sat/b, 以图 5-1 为例。
图 5-1
这笔交易的数据大小是 226 bytes, 而我设置的矿工费是 20 sat/b, 所以我消耗的矿工费是 gas fee = 226 * 20 * 10e-8, 大约是 0.0000452 个 BTC。
但其实绝大多数钱包服务商在计算用户交易矿工费的时候, 是提前估算好的, 所以会存在一些偏差。
进阶篇
6. From -> To OR Input -> Output
用户在使用 Blockchain 查询 BTC 交易的时候, 会发现很多和使用 Ethereum 的不同之处。因为以太坊属于 account 模型, 它是 “From -> To“ 结构, 我们发起转账时, 每一个 TxId 都包含一个付款地址和一个收款地址。
而比特币则不然, 它是 UTXO 机制, 即多个 input 可以对应多个 output[注3], 大家可以回忆一下开篇我们讲到的故事, 小明的妈妈给小明 10 元和 5 元, 这是两个 output, 而 input 是 12 元, 但我们可以认为 12 元其实是多个 input, 包括给采购商的价格、给政府的税收、店家的利润以及成本等等。
图 6-1
所以我们在查询一笔 BTC 交易的时候, 如果输入交易号进行查询, 可能会出现多个地址同时向一个地址发起一笔交易, 也可能会出现一个地址向多个地址同时发起交易。图 6-1 向我们展示了多个 output 对应一个 input。
7. 关于 Unable to decode output address
我们在使用 blockchain.info 查询一些交易信息的时候, 会发现如图7-1这样的情况, 有些收款地址显示为 Unable to decode output address, 却看不到真正的收款地址。那么这个是怎么回事呢?
点击交易号, 进入该笔交易的详情, 我们可以看到 Output Scripts 里:`RETURN PUSHDATA(32) [some garbage]` 这个脚本从 `OP_RETURN` 开始, 被称为空数据输出, 用于用户在区块链中存储任意数据。由于这些输出数据不同于代币转账, 是不能进行花费的, 所以 scripts 脚本不能对他进行有效评估。但其实这样的数据输出大多是伴随着一个正常转账输出出现的。举个例子, 这有点像转账信息备注, 比如图7-2, 用户在做这笔 0.577 个 BTC 转账的时候, 就可以将转账的一些信息写入这笔交易 “ Alice send to Bob”. 但是这样的信息是无法进行消费的, 所以会永远处于 Unspent 状态, 并且出现 Unable to decode output address (无法解析输出地址) 这样的情况。
结语
8. UTXO 的好处
上边我们在讲到找零地址的时候, 抛出一个问题, 为什么比特币在做每笔转账的时候, 都要设置新的找零地址。其实这一点, 中本聪在<<比特币: 一种点对点的电子现金系统>> 里边, 在谈及隐私 (Privacy) 特性时有提到: “作为额外的预防措施, 使用者可以让每次交易都生成一个新的地址, 以确保这些交易不被追溯到一个共同的所有者。” [4]
所以说, 比特币的 UTXO 机制, 更好的保障了比特币的匿名性。如果我们在查看一个有多笔输出的钱包地址情况下, 很难确认哪个是找零地址, 哪个是收款地址, 除非我们是当事人。
作者注:
注[1]: input 和 output 是一个相互转化的关系, 因为你当前钱包的余额是由 input 得来, 而当你发起转账时, 他就变成了 output. 所以说 input 和 output 是一个抽象出来的概念。
注[2]: 在使用 imToken 的时候, 如果你是使用助记词导入的比特币钱包, 那么每次的找零地址, 会是一个新的地址。如果你是 WIF 导入, 既使用明文私钥导入钱包, 那么每次转账的找零地址, 就是你当前钱包的地址, 不会生成新的接收地址。
注[3]: 这里所说的多个 input 对应多个 output 可以是1个 input 对应多个 output, 也可以是多个 output 对应 1 个 input或者多个 input 对应 多个 output。