比特币(BTC)属于加密货币,但不加密。
区块链上的所有交易都是公开的,比如账户地址、转账金额、交易记录、源代码等。比特币(BTC)主要使用加密哈希和签名功能。
哈希(哈希)
什么是哈希函数?
1.hash函数,也叫“Hash”,简单理解就是对某个东西的映射操作,即A-Hash(A)
2.我们通常使用数组或链表来存储元素。一旦存储的内容极其庞大,就会占用大量的空间。而且在找出一个元素是否存在的过程中,数组和链表都需要循环比较,通过哈希计算可以大大减少比较的次数。
例如:
现在有四个数字{2,5,9,13},所以我们需要找出13是否存在。如果我们使用一个数组来存储,我们需要写一个循环来遍历它四次,然后才能找到它。时间复杂度为O(n);
但是存储时首先使用散列函数。在这里,我使用任意函数:H[key]=key% 3。
那么对应于四个数字{2,5,9,13}的散列值是:
H[2]=2 % 3=2
H[5]=5 % 3=2
H[9]=9 % 3=0
H[13]=13 % 3=1
然后将它们存储在相应的位置。查13的时候,只要先用哈希函数算出它的位置,然后再去那个位置看看它是否存在。在这个例子中,只需要查找一次,时间复杂度为O(1)。
但是你发现什么问题了吗?
使用哈希函数计算哈希值时,不同的键可能得到相同的结果。一个地址如何存储多个数据?这就是碰撞(冲突),解决碰撞(冲突)的方法有链接法(拉链法)、开放寻址法等等。
加密哈希函数加密哈希函数的属性:
1.抗碰撞性(抵抗散列碰撞)
函数:对于一个消息:m,求它的哈希值:H(m),
这个哈希值可以看作是这个消息的摘要,用来检测这个消息的篡改。
例如:
我有一个非常大的文件,存储在云存储服务器上,以后需要的时候再下载回来。那么我怎么知道我后来下载的版本和我当初上传的版本一致呢?
这使用了哈希函数的CollisionResistance属性:
在上传这个文件之前,我会计算一个哈希值来购买这个哈希值并存储在本地。以后下载完,我再算一个哈希值。如果相同,说明上传的文件没有被篡改。
目前还没有可以从数学上证明具有抗碰撞特性的哈希函数。
理论上无法证明,只能靠实践经验。经过长期实践,有些哈希函数找不到人为制造哈希碰撞的方法,所以被认为是抗碰撞的。还有一些哈希函数曾经被认为是抗碰撞的,但我们已经找到了人为制造哈希碰撞的方法,比如MD5,它曾经是一个非常流行的哈希函数,但现在我们知道如何人为制造哈希碰撞。
2、隐藏
哈希函数的计算过程是单向不可逆的。
给定一个X,可以计算出X的哈希值H(x ),但是从哈希值H(x)无法推导出X,也就是说,哈希值H(x)没有透露任何关于输入X的信息.
但是你不知道进入X的信息吗?
如果想知道输入的信息,可以用蛮力求解的方法,遍历输入X的所有可能值,看哪个输出哈希值等于原来的值,这样就可以猜出原来的输入是什么了。
所以隐藏的性质的前提是输入空间很大,使得暴力求解不可行,输入的分布要相对均匀,各种值的可能性都差不多。如果输入空间也很大,但大多数情况下数值都集中在少数几个值上,那么就很容易被破解。
隐藏的本质有什么作用?
隐藏可以与抗碰撞结合起来实现数字承诺(有时称为密封信封的数字等价物-数字等价物密封信封)。
密封信封在现实生活中有什么用?
例如:
一个人说他可以预测第二天的股市,哪些股票会涨跌。怎样才能证明他的预测是否准确?
一种方法是让这个人前一天在电视上宣布预测结果,然后看看第二天的预测结果是否准确。然而,这样做会有一个问题。如果提前公布预测结果,可能会影响最终结果。如果这个人很有名,大家都渴望信任,导致本来不会涨的股票涨停。所以预测的结果不能提前公开。而是把结果写在一张纸上,用信封封好,交给第三方公证人保管。实际结果出现后,打开封条进行对比。
在电子世界里,区块链科技也提供了一个很好的解决方案:把预测结果作为输入X,计算一个哈希值H(x),并公布这个哈希值H(x)。由于其隐藏性质,X从散列值H(x)中是未知的。当预测的结果到来时,发布X,如果可以根据X得到发布的Hash(x),则预测是正确的。
在实际使用中,为了让X足够大,足够均匀,会在X后面随机拼接一个随机数nonce,整个数都是Hash。
3、益智友好
除了密码学中要求的这两个性质,比特币系统中还需要第三个性质:谜题友好。
这个属性要求哈希值的计算事先是不可预测的。也就是说,只看输入,很难猜出最终的哈希值是什么。所以如果你要计算的哈希值落在某个范围内,你一次只能尝试一个输入,看看哪个输入落在那个范围内。
例如:
比特币“地雷”。“挖矿”其实就是找一个随机数。这个随机数与块头中的其他信息相结合作为输入,并取出一个散列。哈希值应小于或等于指定的目标阈值。
h(块标题)=目标
区块链是由区块组成的链表。每个块都有一个块头,块头里有很多阈值,其中一个是我们可以设置的随机数。然后挖掘的过程就是不断尝试各种随机数,使整个块头经过哈希后落在指定的范围内。
h(块标题)=目标
挖掘的过程中没有捷径可走。只有不断尝试大量的随机数,才能找到满足要求的解,所以这个过程被作为工作的POW-Proof。
虽然挖掘过程需要大量的工作才能找到一个符合要求的随机数,但是只要有人找到这样的随机数,那么这个随机数公布后很容易被别人验证不符合要求,因为这个随机数是块的一部分,所以只需要计算一次hash值,看它是否小于等于目标阈值。所以挖掘很难,但是验证很容易。
比特币系统使用的哈希函数是SHA-256(安全哈希算法)
符号
比特币系统中的账户管理
日常生活中要开户,就拿着证件去银行开户。这就是集中账户管理系统。
比特币是去中心化的,没有银行这样的机构,所以每个用户自己决定开户,不需要任何人的批准。开户的过程非常简单,就是创建一个公钥和私钥对。
公钥和私钥的概念来自于非对称加密算法,
最早的系统是对称加密算法。
例如:
两个人想互相交流。我想给你发送一些信息,但通信网络可能被窃听。然后我们两个会提前讨论一个加密密钥。我会把信息加密,然后发给你。收到后,可以用密钥解密。因为加密和解密使用相同的密钥,所以称为对称加密系统。
但是对称加密系统的密钥不能明文公布,所以非对称加密系统使用一对密钥,而不是单个密钥。公钥用于加密,私钥用于解密。比如我要给你发一条消息,我会用你的公钥加密,你收到后再用你的私钥解密。这样,公钥就不具有保密性,可以向公众公开,私钥只需要存储在本地,不需要传递给他人,解决了对称加密系统中密钥分发不方便的问题。
在比特币系统中,如果要创建账户,会在本地生成一对公钥和私钥。公钥相当于银行卡号,别人会给你转账。你只需要知道你的公钥,私钥相当于账号密码。如果你知道私钥,你就可以从账户中转账。
问题:当初说比特币系统是不加密的,所有信息都是公开的。公钥和私钥的需求是什么?
实际上是用来签名的。
例如:
我要转10个比特币给你,然后我会把交易送到区块链。别人怎么知道这个交易确实是我发起的?这就需要我在发布这个交易的时候用私钥来签名,然后别人收到这个交易之后会用我的公钥来验证这个签名的正确性。
问题:每个人的公钥和私钥都是独立生成的,那么两个人生成的公钥和私钥完全一样怎么办?比如一个人想盗取比特币,他不断生成大量的公钥和私钥,然后比较生成的公钥和区块链中已有的公钥是否相同。如果是这样,他就用相应的私钥从他的账户中偷钱。
这种攻击理论上是可能的,但实际上是不可行的,因为256位哈希值产生相同公钥和私钥的可能性微乎其微,概率甚至小于地球爆炸的概率,而且从来没有过这样的先例。