比特币,以太坊,小蚁交易设计模式精解析



  • 原创: 财神下山
    链接:https://mp.weixin.qq.com/s/GMHhiUYVLRuhs6ja0EXo6g

    在上一篇文章中,财神讲解了公钥,私钥,以及地址的诞生过程,这应该可以算是区块链的入门级知识,对理解区块链帮助很大:(原创)比特币里的私钥,公钥,地址是如何产生的?

    那么,今天来分享一下区块链里的一些关于交易的知识,如有不当请留言指出。

    开始,先给几个单词吧:

    Block:区块, 在每个block里面,都记录了过去一段时间内网络上发生的所有转帐交易记录,把所有的block串连在一起就形成一个链条,即我们说的区块链。一个完整的区块链就记录了从诞生到现在的所有交易记录,因为叫作帐本。

    Transaction: 交易记录,一个transaction须包含vin或from(发送者), vout或to(接收者), value(值)等基本信息。

    比特币的交易过程

    比特币采用的是UTXO设计模式来记录“帐户余额”的,关于UTXO 也有详细介绍,比特币最反直觉设计UTXO,看完这个就懂了

    实现A 发送 比特币 给 B

    钱包客户端会打包一个Transaction结构体,当然包含了vin, vout,value 等最基本的信息了。

    那这个value就是你要转帐的UTXO(这里指比特币)。但是转帐前提是得证明这些UTXO是你的,你才可以花费这个UTXO。所以,比特币交易的时候会有两个脚本:输出脚本(scriptPubKey)和 认领脚本(scriptSig)。

    输出脚本把接收方的公钥加入进来了,即只有拥有这个公钥的人才可以动用这笔收入。(谁可以花UTXO)

    认领脚本则用来证明自己可以满足交易输出脚本的锁定条件,即对某个UTXO(比特币)的拥有权。

    以 P2PKH 为例,输出脚本的格式为
    scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

    一个交易如果要花费这个输出,在引用这个输出的时候,需要提供认领脚本格式为
    scriptSig: <sig> <pubKey>
    其中, 是拿 pubKey 对应的私钥对交易(全部交易的输出、输入和脚本)hash 值进行签名,pubKey 的 hash 值需要等于 pubKeyHash。

    当某个人使用某个UTXO时,需要把认领脚本附在输出脚本前面,能够被正确执行说明允许花费UTXO,也就是这些比特币是你的,能花。

    即完整指令为:
    <sig> <pubKey> OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

    比特币的脚本是非图灵完备的,就是说它不支持循环语句,因此不会产生死循环,而以太坊支持合约类的链是图灵完备的,为了防止某个合约陷入死循环,因此每执行一条语句都将花费一定量的gas,当你事先给定的gas被消耗完了,此不管合约有没有结束,都要中止,而且还会回撤到未执行前,但手续费不退。

    当这样一个Transaction 通过某一个节点(钱包)广播到网络中,先进入交易池中等待矿工来临幸打包(优先确认矿工费高的),矿工通过验证脚本是否有效输出,验证通过后经p2p网络转发给附近的节点,直到所有网络其它节点,并打包交易进入一个新的Blcok中。一个交易就结束了。

    以太坊交易过程

    以太坊有强大的智能合约平台,每个开发者都可以在则链上部署一个智能合约,当然无规矩不成方圆,为了调用方便,以太坊也定制了很多开发的标准,其中以ERC20标准使用最为广泛,我们接触到的大多数以太坊代币都是ERC20系列的。

    以太坊没有采用比特币的UTXO模式(类似于真实钱包使用场景),而是采用了更简单的帐户模型,(类似于我们银行系统的记帐,直接改余额),这两种模式各有优势。

    那么,一个ETH Transaction就会是这样:
    0_1540339253071_226ffc40-7ef7-4e7e-b31d-dd8939068fb0-image.png

    直接给出了from(发送方)的钱包地址,to(接收方)的钱包地址,以及value(发送金额), 都是采用了16进制。

    一个ERC20代币的转帐记录则有些不同,它会同时触发两条交易记录:

    一条是eth 的transaction,但是 value 为是0,并且to 不再是真正接收方的地址,而是这个token的合纸地址。
    另一条记录才是真正的交易记录,有from, 但是to 是为空的,真正的接收地址,金额 都在input 字段里面,需要拆分解析出来。(这里面还有一个以太坊的漏洞存在,地址攻击法)

    input 字段是一个很复杂的字段,1. 指令的hash;2. 接收账户;3. 数量,由这三个部分拼接而成。调用 合约的所有信息都编码在其中,然后传递给智能合约解析执行,转帐transfer只是其中的一种而已。

    例如:
    0xa9059cbb000000000000000000000000772e6665c080bbafc7e9c65aabf5f36bf9507d3000000000000000000000000000000000000000000000000000000000aba9500

    蓝色表示指令:0xa9059cbb代表转帐
    红包表示接收地址:0x772e6665c080bbafc7e9c65aabf5f36bf9507d3, 前面补了很多0
    黑色表示:转帐金额是 aba9500 (也是16进制)

    NEO(小蚁)交易过程

    NEO作为国产公链,对飚以太坊,但是NEO和以太坊有点设计上不同,NEO仍然采用了UTXO的设计模式,所以和比特币更加相似。

    NEO在继承比特币的基本上,又扩展了类似以太坊的智能合约平台,通过智能合约也可以在NEO链上发行很多token,这些token都遵循一个合约的标准接口,即NEP5系列,就像以太坊上的以太币(ETH)和ERC20代币。

    举个UXTO交易结构的例子吧:
    0_1540339298741_550e954c-f572-4365-8d88-e917d5a0c86e-image.png

    以上就是NEO的一条transaction,vout 里指定是value,和 接收方钱包address,vout就新生成的一笔UXTO。

    vin 是代表发送方,但没直接给出地址,而是另一个transaction id +UTXO索引,意思就是 这笔即将要花费的UTXO 是来自另一笔交易的输出,这就解释了每一笔交易的可追溯性。

    通过vin里的txid就可以追溯到这个UXTO的来源了,现在是时候花出去了。

    但是,在NEP5的资产的交易记录,又在另一个日志文件里记录了。这个不再讲解,官方有文档介绍。

    以上大致的解释完了比特币,小蚁系,以太坊系的转帐过程与结构体。不知不觉写了好多,初学者看了肯定好晕,当有过一定基础后或许会简单的多。

    作者简介:财神下山,大数据,区块链开发工程师。支点专栏作者,ono专栏作者。