比特币协议是怎样工作的(下)

Author: 小小梦, Created: 2017-01-19 18:30:04, Updated:

比特币协议是怎样工作的(下)

  • 比特币

    现在,让我们离开Infocoin,转向的真正的比特币协议。比特币和我们刚才一步步建立起来的Infocoin没有多大的差别,除了一个明显的改变。

    要使用比特币,首先你得在电脑里安装一个钱包。为了让你更好的理解,下图是一个叫做Multibit的钱包的截图。你可以在左上角看到比特币的余额——0.06555555 个比特币,按截图的当时的交易价格来算将近70美元。截图右边显示了两个最近的交易,他们是存入这0.06555555个比特币。

    img

    假设你是一个商家,你已经准备好了一个在线商店,你决定允许客户用比特币支付。你需要做的是,用你的钱包程序新生成一个比特币地址。它会自动生成一对公钥和私钥,然后hash你的公钥来形成你的比特币地址。

    img

    然后你将你的比特币地址发给要付给你钱的人。你可以用邮箱,或者直接放到你的网页上。这是安全的,因为你的地址只不过是hash了的公钥,你可以放心的公布给任何人(没人能通过它来得到你的私钥)。 我会在后面解释为什么比特币地址用的是公钥的hash值而不是公钥本身。

    现在那个准备付钱的人需要创建一个新的交易。让我们看一个真实的转入0.319个比特币的交易数据。下面这个就将近是原始数据了,这里有三个地方的改变:1)数据没有连续化;2)加了行编号,为了更好理解;3)省略了hash数据的一长串数字,只保留了前6位。

    1.  {"hash":"7c4025...",
    2.  "ver":1,
    3.  "vin_sz":1,
    4.  "vout_sz":1,
    5.  "lock_time":0,
    6.  "size":224,
    7.  "in":[
    8.    {"prev_out":
    9.      {"hash":"2007ae...",
    10.      "n":0},
    11.    "scriptSig":"304502... 042b2d..."}],
    12. "out":[
    13.   {"value":"0.31900000",
    14.    "scriptPubKey":"OP_DUP OP_HASH160 a7db6f OP_EQUALVERIFY OP_CHECKSIG"}]}
    
    • 让我们一行一行解释。

      第1行,交易hash值(16进制),他是用来代表这个交易的唯一标记。

      第2行,告诉我们这个交易用的是第一版本的比特币协议。

      第3、4行,告诉我们这个交易有一个输入和一个输出。(一个交易可以有多个输入和多个输出)

      第5行,是一个锁定时间(lock_time),可以用它来控制这个交易什么时候完成。现在大多数的比特币交易锁定时间都是0,也就是马上完成交易。

      第6行,告诉我们这个交易的大小有多少个字节(bytes),注意,这个不是交易的钱。

      第7到11行,这一段定义了这个交易的输入部分,确切的说,8到10行告诉我们要转走钱的这个输入值的钱是从上一个交易输出值里得来的。那个2007ae…就是上一个交易的16进制的hash值,用来指向上一个交易。n=0说的是它是上一个交易里面的第一个输出,我们过一会儿会看到多个输入和输出是什么样子,所以现在先不用担心。11行是那个发送钱的人的数字签名:304502… 空格之后是他的公钥:04b2d… 同样这两个都是16进制

      这里输入部分值得注意的是,它并没有说前一个交易中的比特币,有多少会转给后一个。实际上,在前一个交易里面n=0的输出内所有的比特币都被转移了。比如说,如果前一个交易里的第一个输出(n=0)里面有2个比特币,那么这两个比特币在新的这个交易中都会被花掉。这看起来很不方便,就好像用20美元的现金去买一个面包一样。解决办法是提供一个找零钱的机制,这一点可以通过多个输入和输出的方式解决,下一部分就会讲到。

      第12到14行,这段定义了交易的输出。具体说,13行告诉我们输出的钱的数量,这里是0.319个比特币。14行比较复杂,值得注意的是字符串a7db6f…是收取比特币的地址。这一行其实是一段比特币的脚本语言,在这里不细讲脚本语言的细节。你只需要知道a7db6f…是收取的地址就行了。

      现在,你可以看到比特币是如何解决我们之前提到的“序列号从哪里来”的问题了。第一,比特币并不是分开的一个个单独的“币”,而是一长串存在于blockchain里的交易。通过保存一个交易账本来实现比特币是一个很聪明的想法。第二,通过这种方式,我们不需要一个中央机构来发布序列号。序列号可以通过hash交易本身来得到。

      我们可以一直顺着交易链一直往回看。最终到头的时候,有两种可能,第一,你可能会走到第一个比特币交易,这个交易存在一个block里,我们把这个block叫做“Genesis block (初始区块)”。这是一个特殊的交易,它没有输入,只有50个比特币的输出。换句话说,它是最最早的比特币供应。Genesis block被比特币客户端区别对待,这里不去细讲。

      第二个顺着交易链一直往回看得到的结果可能是你到达了一个被称作“coinbase”的交易。除了Genesis block之外,每个block里都开始于一个特殊的coinbase交易。这个交易是用来奖赏验证这个block里交易的挖矿者的。它用了和上述类似的数据形式,具体也不细讲了,对coinbase交易感兴趣的话可以看这里。

      上面的描述不是很清楚的是,在11行里面被数字签名的东西到底是什么。最显然的是办法是让支付者把整个交易进行数字签名。现在来说它不是这样做的,一些交易被忽略了。这使得交易的一部有了可塑性,也就是说,它们可以在以后进行修改。然而,这个可塑的内容里并不包括交易的数量,付款人和收款人。可塑性的问题在比特币社区内有很多讨论,有人希望去取消它,这里不细谈。

  • 有多个输入和输出的交易

    上一段里面我们讲了一个只有单个输入和单个输出的交易数据。实际上,大多比特币交易都是有多个输入或者多个输出的。我们先看看这个交易的原始数据

    1. {"hash":"993830...",
    2. "ver":1,
    3. "vin_sz":3,
    4.  "vout_sz":2,
    5.  "lock_time":0,
    6.  "size":552,
    7.  "in":[
    8.    {"prev_out":{
    9.      "hash":"3beabc...",
    10.        "n":0},
    11.     "scriptSig":"304402... 04c7d2..."},
    12.    {"prev_out":{
    13.        "hash":"fdae9b...",
    14.        "n":0},
    15.      "scriptSig":"304502... 026e15..."},
    16.    {"prev_out":{
    17.        "hash":"20c86b...",
    18.        "n":1},
    19.      "scriptSig":"304402... 038a52..."}],
    20.  "out":[
    21.    {"value":"0.01068000",
    22.      "scriptPubKey":"OP_DUP OP_HASH160 e8c306... OP_EQUALVERIFY OP_CHECKSIG"},
    23.    {"value":"4.00000000",
    24.      "scriptPubKey":"OP_DUP OP_HASH160 d644e3... OP_EQUALVERIFY OP_CHECKSIG"}]}
    
    • 像之前一样,我们一行行解释,大部分和刚才的是一样的。

      第1行,交易的hash值,用来作为这个交易的唯一标记。

      第2行,比特币协议的版本,第一版。

      第3、4行,是说这个交易里有3个输入,2个输出。

      第5行,锁定时间(和之前的一样)。

      第6行,交易的字节大小。

      第7到19行,定义了所有的输入,每一个都对应这前一个交易的输出。第一个输入是8到11行。其内容形式和之前的一样。 第二个输入是12到15行,第三个是16到19行。

      第20到24行,定义了所有的输出,第一个输出是21和22行,和之前一样,21行说的是里面有0.01068个比特币。22行是一段比特币的脚本语言。字符串e8c30622…是收款人的地址。 第二个输出是23和24行,格式同上。

      看起来有些奇怪的是,虽然每个输出都有记录着比特币的数量,但是输入却没有。当然每个输入有多少比特币可以从它的上一个交易中得到。在一个普通的比特币交易中,所有的输入价值之和要大于多有的输出(除了刚才说的Genesis block和coinbase交易之外),如果输入之和大于输出,那么多余的比特币就会作为交易费提供给这个交易所在的block的挖矿者。

      多个输入和输出的作用是找零。假设我想要给你0.15个比特币。我可以花掉我之前收到的0.2个比特币。当然,我不想给你全部0.2个,所以解决办法就是,我给你发0.15个比特币,然后再给我自己的另外一个比特币地址发0.05个比特币。这样,那0.05就是给我的找零。这个概念和你在现实商店里的找零不太一样,这个更像是你给你自己付钱。但是大致意思是一样的。

  • 结语

    比特币背后的基本概念就算是描述完了。当然,我也忽略了许多细节——这毕竟不是一个正式的说明书。但是我想描述的是通常使用的比特币背后的概念。

    虽然比特币后面的规则是简单和容易理解的,这并不意味着这些规则将产生的所有可能结果也容易理解。对于比特币可以说的还有很多,我会在以后的文章中阐述一些。但是现在,我姑且做一些零碎的总结。

    比特币有多么匿名?许多人说比特币可以匿名使用。这个说法形成于类似Silk Road之类的黑市。然而这个说法是虚构的。Blockchain是公开的,也就意味着任何人都可以看所有的比特币交易。虽然比特币地址并没有直接和真实世界里人物的身份相对应,但计算机科学家们已经做了很多工作去解密“匿名”的社交网络。Blockchain是他们一个极好的目标。在不远的将来,如果大多数比特币用户身份还都不能相对有信心的识别出来,那我感到会非常惊奇。这个识别不一定会完全确认,但是足够提供有着很大可能性的目标。此外,身份将会是可追溯的,这意味着那些2011年在Silk Road上卖毒品的人,仍然可以在2020年在blockchain上找到。这些反匿名技术对计算机科学家来说是众所周知的,甚至可以说包括NSA(美国国家安全局)也知道。如果说NSA或者其他机构已经反匿名了很多用户的话,我并不会觉得奇怪。比特币被吹捧成匿名的这个说法是有点滑稽的。它不是匿名的,相反,比特币可能是迄今为止世界上最为公开和透明的金融工具。

    你能通过比特币发财吗?也许吧,Tim O’Reilly 曾经说过 “钱就像是汽车里面的油——你需要注意,否则就会困在路边上——但是生活不是围绕着加油站转圈!” 大多数对比特币的兴趣似乎来自于那些人生目标仅仅是找到一个大的加油站的人。我必须承认,这个让人困惑。我相信更有趣的、更享受的是把比特币或者其他数码货币看做一个塑造新的人类合作行为的工具。那是理性上的迷人,提供了巨大的创新的可能,它是有社会价值的,同样也可能会赚到一些钱。但是如果赚钱是你的主要目的,那我相信有其他更容易成功的办法。

    我所忽略的细节:虽然这篇文章描述了比特币背后的主要概念,但有很多细节我并没有提到。其中之一是协议里面的很棒的节省空间的技巧,基于一个叫做Merkle tree的数据结构。这是细节,但它是一个极其精彩的细节,如果你喜欢数据结构的话,很值得去看看。你可以通过比特币白皮书了解大概情况。第二,我几乎没有提到比特币网络——其中一些问题比如,这个网络如何处理拒绝了的服务器攻击,节点是如何加入和离开网络的,等等。这是个很有意思的话题,但同时也是包含很多细节的话题,所以我在这里忽略了。你可以通过上面的一些链接来阅读更多与之相关的东西。

    比特币脚本:在这篇文章里,我解释了比特币作为一个在线的电子货币。但是这只是更大更有趣的故事之中的一小部分。正如我们所见,每个比特币交易里都有一段比特币脚本语言。这个脚本在这篇文章里被简化成了类似于这样的话 “我Alice要给Bob 10个比特币”。 但是这个脚本语言可以同时被用来表述更复杂的交易。换句话说,比特币是一个可编程的货币。在以后的文章里,我会解释这个脚本系统和如何将比特币脚本作为一个平台来支持各种各样的令人惊叹的金融产品。

    如果觉得有帮助,建议你Tip给这篇文章的原作者Michael Nielsen, 他的地址是17ukkKt1bNLAqdJ1QQv8v9Askr6vy3MzTZ , 你也可以follow他的Twitter 。 或者关注他的将要出版的关于neural networks and deep learning新书的第一章。

    也欢迎关注译者的微博:杨硕1015 如有不顺之处,请见谅

转载自 简书 杨硕 的 文章


More