区块链技术学习笔记

区块链技术学习笔记

部分一:链表,哈希,挖矿等

开篇

很多年没有看到像区块链这样有生命力的事物了。它像一个欣欣向荣的新大陆一样,把技术理想主义者,围观者,投资者,投机者,甚至流氓骗子各色人等聚集在一起。

在此乱象中,我深感于现在区块链,观点太多,事实太少。我作为一个个体去摸这头大象的时候,比较擅长的是以技术的角度切入,看它到底是如何工作,如何发展的,从而把这一只象腿摸清楚。我把自己的学习记录下来。这些记录可能很入门,甚至有错误,但是或许对于同样感兴趣的人有所帮助。

链表

从技术角度看,区块链的底层是精妙设计的链表数据结构①。

什么是链表呢?就是有顺序的一串数据块,一个跟在另一个后面,这个顺序是严格规定的,不能乱。区块链,食物链,供应链,资金链,甚至鄙视链,描述的就是这样有顺序的一串物品②。

我们以比特币为例,来剖析这个链表。

为了构成链表,链表的数据块里面有两个基本的部分:区块头,和数据本身。区块头里面有一个字段指明了上一个区块的id,而所有区块的id既不是顺序的,也不是随机的,而是区块头这80个字节的两次哈希值。

哈希 Hash

这可能是区块链里面最让非理工科出身的学习者费解的概念了。听起来很吓人,实际很简单。哈希就是一个算法,能把任意长度的内容(无论是一个数,还是文章,图像,视频,总之就是任何数字化的信息)转换成一串看似没有规律的固定长度的数字(哈希值),并保证结果唯一,而从这个结果几乎没有办法推算出原始数据。比特币用的是叫做SHA256的哈希算法。

比如:1 的SHA256哈希结果是: 0x6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b

2 的SHA256哈希结果是:

0xd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35

我们把这个哈希值看成乱码好了,因为唯一的规律就是没有规律。同时,在原始数据中哪怕有一点点改动,产生的哈希就会产生巨大的变化。这个特性常常用来做“数字指纹”。

用日常例子来打个比方。比如按照配方做菜就是个哈希过程:有了配方精确的做菜容易,而从菜品推测出配方难得多。给出两个数算出他们的平方和比较容易,给出一个数求是哪两个数的平方和就难很多。哈希算法就大概这么个意思。

区块头和id

刚才讲到,每个区块的id从它的区块头的80个字节数据两次SHA256哈希得到。区块链的一个精妙的设计就是,它对于的id是有要求的。只有满足特定的规则的id才是合法的。这个规则就是:区块头的哈希值必须小于一个数,直观看到的就是,每个新的区块的长达64个字符的id必须以比如18个零开头④,一个合法的区块id是长成这个样子的:0000000000000000003c19cdbebe2df5c7f82558e2c80a0c7341e25072b732a2

区块头这80个字节里面的6个字段,5个是不能改的,它们是:

1. 版本号         最近一直是0x20000000 ⑥

2. 上一个块的哈希值    这个是排队时候的队尾,改了就排不到队里了

3. 数据的哈希       这个是区块里的交易数据,也不能改③

4. 时间          不能改,就是现在的时间。

5. 难度          每个给定的时间全网的难度是一样的④

只有第六个字段是随便写的,这个数字叫做No nce

6. No nce

网络上任何一台机器只要找到一个合适的数字填到自己的这个区块的No nce位置,使得区块头这6个字段(80个字节)的数据的哈希值的哈希值以18个以上的0开头,谁就找到了那个金子⑦!既然我们无法事先写好一个满足18个0的数字然后反推Nounce,唯一的做法就是从0开始一个一个的尝试,看结果是不是满足要求,不满足就再试下一个,直到找到。

这个过程被戏称为挖矿。其实我觉得这个过程和淘金更像。淘金者做的事情很简单,却很重复,就是对于河里所有沙子,拿起来一个,判断是不是金子。如果不是,扔掉再拿一个。如此重复几百万次,总有一个是金子。而在区块链世界,那64个十六进制的字符串,第一个是0的概率是1/16,第二个也是0的概率再乘以1/16,第18个还是零的概率可想而知。所以大家为了找到这个金子一般的No nce一般要花费十几亿次尝试,虽然每次算哈希的工作并不那么费时间,重复十几亿次还是要耗费巨大的计算机资源和电力资源。

比特币体系的另外一个精妙设计就是它动态的调整难度,以无论有多少台矿机在寻找那个珍贵的正确的No nce,都保证大约每10分钟产生一个块。这也是一个类似经济学的算法。它每2016的块(也就是2周)就计算一下前面2016个块平均每个块花了多少时间,如果低于10分钟就按照低的比例调高难度,如果高于10分钟调低难度。这样矿机无论增减,比特币都可以按照每10分钟找到一个块的金数字并且生成一个合法的块。

找到了那个金子一样的数字以后呢?

谁找到了那个数字,谁都可以向全网广播这个新块了。而真正的财富秘密在于在这个新块的数据区的交易数据里面,第一条交易中,挖矿的人可以凭空的给一个地址(通常是自己的)发放12.5个比特币。这是规则认可的,就好像赌场里荷官可以合法的从桌上拿一部分钱进自己的口袋一样。这12.5个比特币是比特币网络上唯一没有发款人,只有收款人的交易,新的比特币就这样凭空诞生了。这个激励每4年减半,再过两年就只有6.25个了,这样2140年左右两千一百万个比特币就基本上全产生了并且不会增加了。

区块链的网络

刚才描述的是在一台电脑上的样子。实际上,这一串数据是通过P2P网络分布在无数的电脑(节点)上的。任何矿工找到了那个金子数字后就立刻全网络刚播新找到的块。如果所有节点在一个大的聊天室里面倒也简单,但实际上这个广播是跟烽火台一样接力的传递的。每个节点告诉周围的,然后它再告诉周围的。有意或无意的,就会有两个或多个矿工近似同时对于网络的一部分分别宣布发现了新块。这个时候的规则就是,每个节点只会接受最长(多)的链并且丢弃较短的链⑤。经过几个节点后一定有一个胜出,另外一个被抛弃,而添加新块是需要算力的,最终一定是拥有最大算力的一方获胜。这也就是如果没有人掌超过50%的算力就无法控制区块链。

小结

以比特币体系为例,最底层就是一串这样以80个字节的区块头开始,约1M的数据跟着的数据。用哈希这样的算法,一层一层的锁定,形成了固若金汤的链条。再把它分布在成千上万的节点上,再又成千上万的矿机通过挖矿来保持算力高压,让篡改数据需要算力门槛。同时,任何人对于历史数据,哪怕就改了很小的一部分,数据的哈希就变了,区块头就变了,它的两次哈希结果就变了,它后面的块就连不上来了,就会被立刻发现。如此几层嵌套,一个人类到现在为止最为安全和防篡改的公共信息系统诞生了。

下面几篇会记录一下钱包,公钥密钥,智能合约,发放通证(Token),区块链应用,区块链对于组织的影响等等方面继续记录学习过程。感谢阮一峰,华宏伟,王哲,赵君,Tim Chen的指正和帮助。

后注

注①:这个跟其他的各种“本质是”并不矛盾,比如区块链本质是分布式账本也对,这个是在链表结构上面构建的,也有人说本质是加密货币,这也对,因为货币是在分布式账本之上构建的。这些说法之间不是非此即彼的矛盾关系,而是不同层次的应用的问题。

注②:自然界谁吃谁的顺序,生产中的谁供货给谁,再组装后工会给谁的顺序,资金从哪里流到哪里,再流到哪里等等,都是这样的数据结构。

注③: 区块头的第三个字段其实不是数据的直接哈希,而是一个树状结构Merkle根。

注④:刚才所说的18个零是一种近似的说法。严格地说,是算出来的本块的ID必须小于一个叫做叫做目标数的数。这个数越小(就是开始的0越多),就越难。

注⑤:严格的意义说最长的链不是最多区块的链,而是链上的所有块的难度总量最大的链。

注⑥:只给感兴趣的人看:0x20000000 (十进制536870912)是从BIP9开始规定的新的版本号规则,开始用一个位数表示一个独立的功能,以区分未来的软分叉。0x20000000 相当于block的第五个版本。

注⑦:以我写文章的时候最新的一个块为例,它的80位区块头是这样的:

000000205d9a3e3dec3e207c3afa9c0be901eaece34b99973a50330000000000000000008565d5bf3819014d521429f02b8cf9d27e226b80998f61d87cd51846c9ab6f9551eb9c5aa3895517ed52e1d4

非常不方便的地方在于比特币选择了小端存储,就是习惯意义的倒着写数字的方式。按照颜色,如上就是:版本号上一个块的哈希数据哈希时间难度Nounce 。这个80位数字的两次SHA256哈希就是这一个块的id,18个零开头,满足要求:00000000000000000043752089261f2b6699cd988d9f5b1732a5a259b50984cf

区块链技术学习笔记

部分二:智能合约,代币(Token)等

智能合约(Smart Contract)是区块链一个重要的功能。说到智能合约,我们得把视野从比特币转到以太坊,因为完整的支持智能合约是以太坊和比特币的重大差别。

让我们发个币吧

听说区块链上可以发币,想发行一个自己的币 ①?来,直接上代码!

我希望你即使不懂代码,也要放下对未知的恐惧,静下心来一行一行读。毕竟这代码简单到大多数人都能看懂。

contractXMT {

mapping (address => uint) public balanceOf;

functionXMT() public {

balanceOf[msg.sender] = 1000;

}

functiontransfer(address to, uint value) public {

require(balanceOf[msg.sender] >= value);

require(balanceOf[to] + value >= balanceOf[to]);

balanceOf[msg.sender] -= value;

balanceOf[to] += value;

}

}

惊人之处来了。如上代码不是概念性的伪代码,而是可以运行的真实代码。

首先它定义了一个记录每个账户有多少余额的数组:balanceOf

mapping (address => uint) public balanceOf;

看不懂的同学就把它当作有两列的表格,第一列是账号,第二列是余额。用 balanceOf [ 账号 ] 就可以查到这个账号的余额,也可以更改余额。

接下来是两个功能:初始化和转账。

初始化函数XMT( )很简单,就是合约建立的时候,任性的把1000个币全都给创建者。

balanceOf[msg.sender] = 1000;

大家要问,币是怎么产生的?没什么产生过程,想给谁多少就是多少。初始的时候写一个亿也就有了一个亿的币。如此随意的就能产生币,希望会引发大家在夜深人静的时候,对于货币到底是什么这样的深层思考。

我们接着看:

转账代码 transfer( ) 核心是两句:

balanceOf[msg.sender] -= value;

balanceOf[to] += value;

谁发起的转账,就把他(msg.sender)的账户余额减去转账金额(value)那么多,然后把收款人(to)的余额加上那么多②。

别小看这两句话。仔细琢磨一下,这其实就是账户和转账的本质。这简单的两句话是银行体系这么多年花了多少的硬件软件,人力物力才能达到的效果。

大家常常听说谁谁谁又发币了。从技术角度,就是在以太坊上部署了包含这三行代码的一个合约。在以太坊的官方网站上就有一段100多行的标准代码:https://ethereum.org/token。这段代码里面还有其他一些功能,比如可以给这个代币指定名称,符号,还有授权转账,销毁等功能。大家只要拷贝这个代码,指定你的新币的名称(比如 Xiaomao Token),符号(比如:XMT) ⑦,还有初始发行量比如:1,000,000,000),一个新的币就诞生了。整个过程3分钟应该够了。把参数改一下再部署一下代码,第二个新币又诞生了。

这新生的货币,虽然没啥用,但在安全性方面和以太币天生是一样的。这就像家长给孩子发了一些饭票,而这饭票的防伪技术和美元一模一样。看起来相当的大材小用,但如果把发货币成本降到几乎为零,把防伪能力提升到已知的最高水平,随着时间的推移,难说不会产生什么重要的应用。

部署代码

代码看懂了,下一步呢?怎么运行这代码?这代码到底在哪里运行呢?接着我们看部署过程。

部署代码,你需要在以太坊的客户端里,把这段代码粘贴进去,并且按“部署”按钮。客户端就会把这种人可以读懂的代码③编译成字节码,然后生成一笔从你的地址,发给一个空地址(0x0)的交易,并把字节码存在一个给定的字段里面(叫input),签名后发到整个网络上。接下来的操作和普通交易完全一样。矿工收到了以后立刻开始打包,算nonce,找到了以后再发送给全网络。这个可以被执行的代码,就永久的以只可读取不可更改的方式,存在了区块链上。

智能合约建立后会返回一个地址。每个币都唯一的对应于一个智能合约,也就是对应于一个地址。比如著名的EOS币,就是地址为 0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 的智能合约发行的。你可以把这个地址想象成以太坊世界里的门牌号。币是以这个唯一的门牌号来区分的,而不是那三位的名字。

调用合约

现在,合约的代码安全的存在区块链上了。那么接下来这些代码什么时候执行呢?

一个智能合约里面有多个函数。调用智能合约里的一个函数,和发起一笔普通转账交易一样。很多的客户端已经内置进去了。你提供合约的地址,提供调用的函数,以及传入参数,然后发送消息就开始执行了⑤。你可以把它理解为从门牌号的屋子里面拿东西或者放东西进到给定的屋子。

消息发出以后,所有的矿工都执行这段代码,并且试图把结果打包到自己的数据块中,胜出的矿工获得挖矿的收益。所有的节点收到这个新的区块,也用自己的虚拟机执行一遍代码,确认结果和收到的块内结果无异之后才当作合法区块接受。

区块链就是通过这种超额的浪费,看似无意义的算nonce,看似无意义的反反复复,没完没了的执行同一段代码,来保证了一个安全的系统。这事儿就跟早上叠被子晚上还得展开一样,看似不产生价值,实则是房(shu)间(ju)整(an)洁(quan)不可或缺的一环。

花费 Gas

既然代码要被所有节点反复执行,那么问题就来了:要是谁写了巨长无比的代码,或者谁写了有问题的代码,死循环不结束了怎么办?以太坊的解决方法就是引入gas,每执行一个操作都是收费的。怎么收费呢?

首先每个交易的代码执行量越大,需要的gas就越多。字节码每一个操作都有固定的gas花销。以发币代码为例,如下是以太坊给我发的账单。总共执行了320步字节码的操作。有的操作很便宜,比如压栈(PUSH1),只要3个单位的gas,有的就很贵,比如在区块链上存数据(SSTORE)就一下子花了20,000个单位,而读取数据(SLOAD) 中等, 200个单位。如下加在一起就是1,300,213个单位的gas。只要执行这段代码,就是要这么多gas,好像汽车修理店工时的概念。

提交的时候每个人都可以出价,声明自己愿意为每个单位gas付多少钱(price)。这个有点像修理店的每工时的价钱。比如你可以出8 gwei/gas,或20 gwei/gas ⑥。矿工们大多数都是按照这个价钱排序优先打包出钱多的。出钱少就慢,甚至没人理。

矿工的费用 = gas单位数 * 单位价格。

如下图所示交易,1,300,213 gas * 2 gwei/gas = 2,600,426 gwei,或0.002600426 以太币,折合1.832美元。最终把这笔交易打包进区块链的矿工获得这部分费用。

除了价格以外,还需要指定一个gas limit,就是你为了这段代码最多愿意付多少单位的gas。这就是为了预防代码出现问题,无限循环下去,直到把你的账户里的钱耗尽为止。如上图,gas limit设为1,300,213个,这段代码实际上也只用了1,300,213个单位的gas,还好,正好没有超过限制。否则超过了程序执行会嘎然而止,已经花的gas不退。

智能合约的价值

智能合约第一次认可了代码的自主权。代码可以拥财产,可以和人一样平等的在区块链上交易。一个合约的代码一旦发布,谁都改不了了,连上帝都无能为力。这就是信任的来源。大家可以像坚信自然定律一样坚信这个合约如代码所写的执行。你不需要相信任何人,只需要认真的读智能合约的代码,就可以确定性的知道这个合约将如何执行。

如上从技术层面简单的介绍了一下智能合约的过程。但智能合约和区块链真正的价值不在技术,而是它们对于价值传递以及信任建立的贡献。

我们看到的人类发展总是多条线并进,一条是生产效率,蒸汽机,电力,计算机,互联网,人工智能等都在这条线上;区块链是生产关系的进步这条线上的,这条线上曾经有过货币,现代公司制度,股票,现在有了区块链。

晚一些我再聊一下它对信任的贡献,还有可能对于社会的改变。

后注

① 很多专业人士希望把token翻译成通证,而不是代币。“通证”更加符合单词原意,符合事物本质,也希望避免被当作货币监管。这像极了“网志”和“博客”两个译名之争。结果博客被接受,更加准确,拗口,后来出现的网志不再有人提起。这个结果或许可以预测通证这个翻译的结果。

②Transfer函数前面的两句require,第一个是要求你的余额必须大于转账金额,第二个是要求转账金额不要过大以至于大于256位整数能容纳的数字。msg.sender 是内置的,可以获取消息的发送人的地址。

③可以搜索Remix,或MyEtherWallet。Solidity的语法和JavaScript很像,专门用于以太坊上编写智能合约。

④这里解释一下技术细节。建立合约的时候,用户发起一笔发款人为自己,收款人为空地址 0x0 的交易,并把字节码放到交易里面叫做输入(Input)的字段里面。矿工就会生成一个新的合约地址并把代码存在这个地址里。

⑤技术实现,其实是在交易数据的Input字段加上了一个编码后的数字。比如这串数字:a9059cbb00000000000000000000000007fdf7518745170e3d9de26874578b6c0a72b9dc0000000000000000000000000000000000000000000000000000000000000010

颜色是我为了区分加的,前四字节a9059cbb是函数名 ,"transfer(address,uint256)"这个字符串的SHA3-256哈希结果a9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b的前4位,用来指定是哪一个函数,根据函数定义,就知道后32位是第一个参数:地址 ,也就是0x07fdf7518745170e3d9de26874578b6c0a72b9dc。接下来32个字节是

金额 ,相当于十进制16。大家看得出,现在的区块链从抽象水平上基本上还停留在计算机的DOS和汇编语言的时代。

⑥ 1 gwei 就是 1,000,000,000 个wei。这个g就跟内存单位多少GB的G是一个概念,就是10亿的意思。10的18次方个wei就等于一个以太币。所以1 gwei看起来很大,其实也就是10的9次方分之1个以太币而已。一个以太币在我写这篇文章的时候是764美元,你大概有概念了是多少钱了吧。

⑦ 发币时候指定的名称,符号,仅仅就是一个字付串,是可以重复的。你可以发一个币叫USD,RMB,或任何你能想象的名字。Token是以发行这个Token的智能合约的地址唯一指定的,和名字无关。

部分三:钱包,私钥,地址等

钱包

判断一个人是否真的了解区块链的一个简单的测试是问一句:“我转钱给你。你的钱包地址是啥?” 这个试金石可以轻松区分很多伪专家。在成熟的互联网世界,没有邮件地址还说得过去,毕竟没有邮件地址也可以点外卖,但是现在百废待兴的区块链世界,一切都如此原始,没有自己的钱包地址就是一个旁观者。

要开始,先要搞一个钱包,获得自己的地址。比如这就是一个合法的比特币地址:

1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm

这就像银行账户一样,有了它任何人都可以给你转账了。有非常多的软件可以帮你生成自己的地址。

受互联网网站的思维惯性影响,还有银行开户程序的影响,很多人以为要搞一个钱包地址还需要到什么地方注册一下。其实不然。任何人都可以自己独立的,不联网的生成自己的钱包。这是怎么做到的呢?钱包里面到底包含什么呢?

公钥私钥

这涉及到一个密码学上的一个基本概念:公钥密钥。公钥和密钥一对一对儿的出现,公钥加密的东西可以拿私钥解开,私钥加密的东西可以用公钥解开。大家就想像成一个带锁的盒子和一把钥匙的关系吧。这个特性用来加密和签名。

加密的过程好像是把自己的盒子写上自己的地址发的全世界都是,谁都可以免费要一个。谁要给你寄信就把信放到盒子里面锁上,然后寄给你。寄件人和收件人都很放心,因为路途上没有任何人(包括寄件人)可以打开盒子了。世界上能够知道信的内容就只有你和寄信的人。

签名的过程也很容易理解。就是写着你名字的钥匙发的满世界都是,谁都可以免费拿一个。而这把钥匙能打开的盒子只有你有,谁都不给。如果有人得到了一个盒子,拿你发的钥匙可以打开,盒子里的东西一定是你发的,因为这把钥匙能够打开的盒子,这个世界上只有你有,你无法抵赖。

区块链世界用了这个精妙设计的公钥私钥体系,但是不是用来加密,主要用于签名。你手里面握着私钥,打死你也不说的私钥。而你的地址,就是那个满世界皆知的公钥。钥匙信息可以被公钥打开,则说明一定是知道私钥的人加密的。所以任何的交易一旦用你的私钥加密了,收到的人验证一下用你的公钥可以解密,那就认为是你授权的操作。

钱包地址的生成

比特币世界几个关键的信息是按照这个顺序生成的:先生成私钥,再由私钥算出公钥,再由公钥经过一系列哈希算出钱包地址。

私钥 ---> 公钥 --> 钱包地址

上面的推导次序是单向的,反向不可能。就是说从钱包地址无法得到公钥,从公钥无法得到私钥。

比特币的公钥变形出来的钱包地址,可以想象成用户名,这全世界都可以知道;私钥可以想象成密码,这个只有自己可以知道。

私钥是一切的开端

私钥一个大于零,小于2的256次方的一个任意数字①。你就随便挑吧。挑中了这就是你的了。比如,你可以任性的把私钥设置成这样:

0000000000000000000000000000000000000000000000000000000000000001

就是数字1。好记吧?(千万别真的真么做。我举着个例子就是为了演示用一个大家能猜到的私钥是多么危险)

然后通过椭圆曲线函数,就可以对应的公钥②:

0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8

然后经过一系列让人眼花缭乱的哈希,最终形成比特币地址如下:

1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm

私钥就像《阿里巴巴和四十大盗》的故事里面的“芝麻开门”。世界上任何人只要知道“芝麻开门”这个咒语,就可以在那座大山里面找到那个山洞并且打开大门。比特币的世界就是这样无情。一个人是否拥有一个账户,不看他是谁,就是看他是不是知道那个秘密。四十大盗知道咒语可以拿宝贝,阿里巴巴知道也可以拿。至于这个山洞里面有没有金银财宝是另外一件事情了。

既然所有看这篇文章的人都知道了这个地址的私钥(数字1),我们就共同拥有了这个地址里面的钱,任何一个人都可以花里面的全部的钱。

在比特币的世界,虽然无法知道地址背后的人是谁,但这个地址历史上所有的交易都是公开信息。很多网站和工具可以让你查询。来,让我们来查询一下这个账户,看看咱们有多少钱 :-)

真可惜,余额为零。这个并不惊讶。

但让我惊讶是,这个地址从2011年到最近的2018年3月9日,居然有过1201笔交易,总共收到过7.8个比特币,即便按照最近跳楼的币价,也是24万块钱人民币呢。这期间任何一个时间点,这个地址里的钱,就是放在大马路上任何人都可随手拿走的钱。多危险呀!

所以所有的钱包软件都是尽量的生成一个越随机越好的私钥。好在随机生成的私钥足够安全。有多安全呢?我们的大脑是无法理解256位私钥到底能存多大的数字。这么说吧,2的256次方大约是10的78次方,也就是10后面78个零。而现在人类观测到的全宇宙的所有的原子才10的78到80次方左右。也就是说私钥的可能性大约是全宇宙的原子数那么多。从整个宇宙中随机找出一个原子给你,这是你的私钥,你觉得和别人冲突,或者被别人猜中的可能性有多少?

钱到底存在哪里?

首先,钱不存在钱包里。

很多钱包软件可以显示余额,完成交易,但钱不在钱包里。钱包唯一记录就是一个私钥 ③,大多数的私钥不像例子里面那么容易猜,看起来就是乱码。如果谁有本事背的下来这个密码,其实你就不需要任何钱包。有些工具允许你交易的时候直接输入私钥就可以了。

那钱存在哪里呢?

钱的数量存在区块链上,而区块链的链表结构存在成千上万的电脑上。如果你下载一个比特币的客户端,同步以后有大约100多G的数据。里面包含了从第一笔交易到现在快10年的所有数据。所以回答这个问题,钱并不存在在任何地方(不存在一种刻着中本聪头像的纸币或金币),钱的余额存在无数的电脑共同维护的一个账本里。

密码和助记词

既然唯一重要的是私钥,为什么很多钱包还需要密码呢?这是一个双重保护。把私钥明文的存在电脑硬盘或手机上不是个好主意,对于黑客甚至是亲近的朋友拿到硬件一个简单的搜索就能找到钱包文件。所以大多数钱包是把私钥再用一个密码加密一下,然后只存储加密过的私钥。没有密码就无法容易的访问私钥。因为人类起的密码就那么8-10位常常是有规律的文字,其安全性远低于机器生成的256位的私钥,但也总比没有好。但千万不要以为这个密码就是你的比特币或以太币密码。它仅仅是是一个保护密码的密码。丢了存私钥的文件,有密码也没有用了。

还有一个大家使用钱包中经常遇到的,就是钱包帮你生成一串12个单词的句子,让你把这个句子抄下来保存好。比如这样的:

voice again pupil thumb strategy toss extend unusual neutral shuffle claim cave

这是什么呢?和私钥又是什么关系呢?

它叫助记词(mnemonic code),其实就跟以前地下工作者用的密码本一样,也跟“A for alpha, B for Brave, C for Charlie ”的原理类似。,BIP39(Bitcoin Improvement Proposal 39)定义了2048个单词的列表,每个单词都有编号,比如

voice ==>1964

again ==> 38

...

cave ==> 295

然后把这些数字按照一些复杂的算法拼起来就可以还原出来私钥了 ④。

现有钱包的问题

如上就是比特币等的钱包,私钥,地址等的现有运作方式。但问题是很明显的:

密码不可改。密码改了,公钥就变了,地址就变了,也就是另外一个钱包了。密码一旦泄露,也没有办法改变。

密码忘了。如果你的私钥忘了怎么办?无解。忘了就是忘了。没有找回密码功能。大量早年的比特币都随着一次不小心的电脑格式化消失了。严格的说,那些比特币没有消失,我们还能看到它们就在自己曾经拥有的那个地址里面,但我们就像忘记密码的四十大盗,只能看不能花了。此事现在无解。

假装不记得密码。典型例子就是离婚的时候,夫妻双方有一大笔财产在比特币里,一方坚持说把私钥弄丢了,法官无法证明这个人是真的忘了还是假的。另外的情况就是有些公司宣称被黑客偷走了比特币,而没有任何人可以证明小偷是另有其人还是就是自己。

这些问题都需要未来的创新来解决。

总结

前面几篇文章介绍了区块链的一些最基本的技术,从链表,哈希,挖矿等 到 智能合约,代币(Token)等,还有本文的钱包,私钥和地址等。

我花时间先谈技术的本意不是为了证明技术多重要,而是通过抽丝剥茧来帮助大家理解区块链的底层技术是多么的简洁,容易理解。希望这可以缓解很多人的区块链焦虑。因为从底层来说,技术没有什么复杂,但是设计的非常精妙,而且像互联网底层技术一样实用。

接下来,我想我会把视野更多的放到技术背后的商业和哲学的层面了。毕竟,区块链对于世界的影响,不是技术本身,而是它对于生产关系,对于价值传递等等的巨大改变。这里面牵扯到代币经济(Token Economy),代币促进的网络效应,ICO,区块链应用等等好多的内容。

后注

注①:严格地说是 1.158 * 10^77,比2^256稍微小一点点

注②:这个公钥其实是一个坐标。0x04是标记位,后面两个256位的数字是椭圆曲线上的坐标值: (79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

③:虽然公钥,地址都是可以从私钥确定的算出来,很多钱包软件里面为了方便也存储了公钥和地址。

④:技术细节:实际上不是简单的拼接。2048个可能性就是11位,所以是很多个11位拼出来。还有最后几个单词是有可能是校验位,以发现用户输入错误。同时最终拼出来的也不是私钥本身。但大家只要知道这个东西最终可以找到私钥就好。

感谢王建硕,华宏伟,赵君,宫亮,Tim,王哲对本文的帮助。如果感兴趣可以订阅公众号token经济”以后一起学习交流。

区块链技术学习笔记


分享到:


相關文章: