区块链和比特币原理

1.比特币是什么?

比特币是一种电子货币(数字货币),比特币是基于密码学的一种货币。在2008年11月1日的时候,中本聪(目前不知道是人类还是AI,是组织还是个人?)提出了比特币的概念。他发表了一篇关于比特币的论文,也是现在比特币的"白皮书"。中本聪比特币原版论文pdf的链接:Bitcoin
在文中提出了一种去中心化的电子记账系统,传统的电子现金是银行来记账,因为银行的背后是国家的信用,去中心化电子记账系统是参与者共同记账。人们通过挖矿获得比特币,通过公开记账的方式完成支付。

2.区块链的原理

(1).默克尔树

哈希树默克尔树是一棵树,其中每个叶节点都用数据块的密码哈希标记,每个非叶节点都用其子节点标签的密码哈希标记。 。哈希树允许对大型数据结构的内容进行有效且安全的验证。哈希树是哈希列表和哈希链的概括。为了证明叶节点是给定的二进制哈希树的一部分,需要计算与该树的叶节点数量的对数成正比的哈希数,这与哈希列表相反,哈希列表的数量与叶节点本身的数量成正比。
Merkle tree
这个是二进制哈希树的示例。哈希0-0和0-1分别是数据块L1和L2的哈希值,哈希0是哈希0-0和0-1串联的哈希。

(2).区块和区块链

区块链里有很多区块,这些区块被使用链接加密,每一个区块都包含一个区块的头部和交易信息(通常用默克尔树表示),在头部信息里包含了hash数列,时间戳。根据设计,区块链可以抵抗其数据的修改。这是因为一旦记录,任何给定块中的数据都无法追溯更改,而无需更改所有后续块。
Bitcoin blockchain structure
从逻辑上讲,区块链可以看作是由5层组成:
1.基础架构(硬件)
2.网络(节点发现,信息传播和验证)
3.共识(工作证明,持股凭证)
4.数据(块,交易)
5.应用程序 (dApps)
因为任何给定块中的数据都无法追溯更改,而无需更改所有后续块。针对这一点
Blockchain
区块链的形成。主链(黑色)由从创始区块(绿色)到当前区块的最长的一系列区块组成。主链之外存在孤立块(紫色)。

允许参与者独立且相对便宜地验证和审核交易。使用对等网络和分布式时间戳服务器自主管理区块链数据库。他们认证通过大规模协作搭载集体自身利益。这样的设计促进了健壮的工作流程,其中参与者对数据安全性的不确定性是微不足道的。区块链的使用消除了数字资产无限重现的特征。它确认了每个价值单位仅转移了一次,从而解决了长期存在的双重支出问题。区块链已被描述为一种价值交换协议。区块链可以维护所有权,因为当正确设置以详细说明交换协议时,它可以提供强制要约和接受的记录。

一个简单的例子:在ABCD四个人里发起了交易。其中A转给了B100个比特币。因为这是去中心化的记账方式。所以在这四个人每个人自己的账本上都会有记录这笔交易,都会记录了A转给了B100个比特币。这就是一条会被记录区块的交易信息每一个区块的大小为1MB,可以存放大约4k条信息。 在这个区块里我为什么会以A为准来通知其他人呢?平时交易里我们将会将谁为准呢?还有我们为什么要记账呢?对我们有什么好处吗?这些都是在设计上会遇到的问题。
Example

3.使用区块链记账的原因

正所谓无利不起早,中本聪在设计区块链的论文里提到了激励的方案。记账的人会得到两种收益:第一种是手续费的奖励,第二种是打包区块的奖励(来自系统的奖励)。每一个交易的发起都会收取用户小额的手续费,这些手续费都会奖励给到那些记账打包的用户上。在第二个奖励中也就是系统奖励给记账打包的那个人。在中本聪的论文里他写到这个系统会每十分钟生成一个区块,每当生成一个区块会奖励一定的数量的比特币。从2008年开始是50个比特币,每过四年会衰减一半。以此类推,获得比特币的数量会越来越少。我们可以根据这个算法算出大约世界上有2100万个比特币,所以说比特币随着时间的推移会越来越难

4.每个区块谁是所谓的"中心"

(1).通过工作量证明机制来获得打包的权力

中本聪在论文中也写到了,每个用户或者节点会通过工作量证明的机制来争夺记账的权力。每个区块第一个可以计算出来的用户就是下一个区块的产生者。通过工作量证明来选择用户的唯一方法就是让用户解决”数学“问题。这个数学问题是基于SHA256算法的问题,所以唯一的办法只能一个一个尝试,谁最先得到这个问题的答案,谁就可以获得打包的资格,这也被称为所谓的挖矿

(2).SHA256算法

安全哈希(SHA)算法是由美国国家标准技术研究院作为美国联邦信息处理标准发布的一系列加密哈希函数SHA代表安全哈希算法。SHA-1和SHA-2是该算法的两个不同版本。它们在结构(从原始数据创建结果散列的方式)和签名的位长方面都不同。SHA-2视为SHA-1的后继产品,因为它是一个整体改进。首先,人们把位长作为重要的区别。SHA-1是一个160位的哈希。SHA-2实际上是一个“哈希”系列,并具有各种长度,最流行的是256位(SHA256),最终输出的是一个256位的二进制数。以下是SHA256算法的伪代码:

Initialize hash values:
(first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19

Initialize array of round constants:
(first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
k[0..63] :=
   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2

Pre-processing (Padding):
begin with the original message of length L bits
append a single '1' bit
append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K + 64 is a multiple of 512
append L as a 64-bit big-endian integer, making the total post-processed length a multiple of 512 bits
such that the bits in the message are L 1 00..<K 0's>..00 <L as 64 bit integer> = k*512 total bits

Process the message in successive 512-bit chunks:
break message into 512-bit chunks
for each chunk
    create a 64-entry message schedule array w[0..63] of 32-bit words
    (The initial values in w[0..63] don't matter, so many implementations zero them here)
    copy chunk into first 16 words w[0..15] of the message schedule array

    Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array:
    for i from 16 to 63
        s0 := (w[i-15] rightrotate  7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift  3)
        s1 := (w[i- 2] rightrotate 17) xor (w[i- 2] rightrotate 19) xor (w[i- 2] rightshift 10)
        w[i] := w[i-16] + s0 + w[i-7] + s1

    Initialize working variables to current hash value:
    a := h0
    b := h1
    c := h2
    d := h3
    e := h4
    f := h5
    g := h6
    h := h7

    Compression function main loop:
    for i from 0 to 63
        S1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25)
        ch := (e and f) xor ((not e) and g)
        temp1 := h + S1 + ch + k[i] + w[i]
        S0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22)
        maj := (a and b) xor (a and c) xor (b and c)
        temp2 := S0 + maj
 
        h := g
        g := f
        f := e
        e := d + temp1
        d := c
        c := b
        b := a
        a := temp1 + temp2

    Add the compressed chunk to the current hash value:
    h0 := h0 + a
    h1 := h1 + b
    h2 := h2 + c
    h3 := h3 + d
    h4 := h4 + e
    h5 := h5 + f
    h6 := h6 + g
    h7 := h7 + h

Produce the final hash value (big-endian):
digest := hash := h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7

(3).通过C++语言形成的SHA256核心算法代码

#pragma once
 
#ifndef SHA256_H
#define SHA256_H
#include <string>
 
class SHA256
{
    
    
protected:
	typedef unsigned char uint8;
	typedef unsigned int uint32;
	typedef unsigned long long uint64;
 
	const static uint32 sha256_k[];
	static const unsigned int SHA224_256_BLOCK_SIZE = (512 / 8);
public:
	void init();
	void update(const unsigned char* message, unsigned int len);
	void final(unsigned char* digest);
	static const unsigned int DIGEST_SIZE = (256 / 8);
 
protected:
	void transform(const unsigned char* message, unsigned int block_nb);
	unsigned int m_tot_len;
	unsigned int m_len;
	unsigned char m_block[2 * SHA224_256_BLOCK_SIZE];
	uint32 m_h[8];
};
 
std::string sha256(std::string input);
 
#define SHA2_SHFR(x, n)    (x >> n)
#define SHA2_ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define SHA2_ROTL(x, n)   ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define SHA2_CH(x, y, z)  ((x & y) ^ (~x & z))
#define SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define SHA256_F1(x) (SHA2_ROTR(x,  2) ^ SHA2_ROTR(x, 13) ^ SHA2_ROTR(x, 22))
#define SHA256_F2(x) (SHA2_ROTR(x,  6) ^ SHA2_ROTR(x, 11) ^ SHA2_ROTR(x, 25))
#define SHA256_F3(x) (SHA2_ROTR(x,  7) ^ SHA2_ROTR(x, 18) ^ SHA2_SHFR(x,  3))
#define SHA256_F4(x) (SHA2_ROTR(x, 17) ^ SHA2_ROTR(x, 19) ^ SHA2_SHFR(x, 10))
#define SHA2_UNPACK32(x, str)                 \
{                                             \
    *((str) + 3) = (uint8) ((x)      );       \
    *((str) + 2) = (uint8) ((x) >>  8);       \
    *((str) + 1) = (uint8) ((x) >> 16);       \
    *((str) + 0) = (uint8) ((x) >> 24);       \
}
#define SHA2_PACK32(str, x)                   \
{                                             \
    *(x) =   ((uint32) *((str) + 3)      )    \
           | ((uint32) *((str) + 2) <<  8)    \
           | ((uint32) *((str) + 1) << 16)    \
           | ((uint32) *((str) + 0) << 24);   \
}
#endif

5.区块链和比特币的安全

区块链和比特币安全吗?它们是如何防止伪造,篡改和双重支付呢?身份认证技术在生活中可以是人脸识别、签字、指纹等。但是它们一旦数字化,都可以通过复制的方法伪造,所以比特币采用了电子签名的方法。电子签名技术主要采用了非对称加密方式。首先比特币会产生随机数,这项技术会通过随机数产生私钥(只有用户自己知道)通过私钥进行加密,再通过私钥产生公钥(可以公开的)可以通过公钥进行解密,最后会产生一个公开的地址,用户就可以通过地址进行匿名的交易了。典型的算法是RSA,比特币采用椭圆曲线加密算法。

转换过程

1、首先使用随机数发生器生成一个私钥,它是一个256位的二进制数。私钥是不能公开的,相当于银行卡的密码。

2、私钥经过SECP256K1算法生成公钥,SECP256K1是一种椭圆曲线加密算法,功能和RSA算法类似,通过一个已知的私钥,生成一个公钥,但是通过公钥不能反推出私钥。

3、同SHA256算法一样,RIPEMD160也是一种HASH算法,由公钥可以得到公钥的哈希值,而通过哈希值无法推出公钥。

4、将一个字节的版本号连接到公钥哈希头部,然后对其进行两次SHA256运算,将结果的前4字节作为公钥哈希的校验值,连接在其尾部。

5、将上一步的结果使用BASE58进行编码,就得到了钱包地址(相当于银行账户)。比如A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa

(1).解决伪造的交易记录

Compare auth
该图展示了A给B1个比特币这个事件,通过hash运算得到摘要之后,用私钥对摘要进行加密得到密码。由于私钥的唯一性,摘要具有唯一性。通过广播的方式,A传递出去的消息有:A转给B 1个比特币,A的公钥,A的密码。
当然我们可以假设,A转给B 1个比特币的消息是假的,并根据此hash运算得到了摘要1。而利用A的公钥解密密码得到了摘要2,此时摘要1和摘要2不同,显然"A给B 1个比特币"是伪造的消息。

(2).防止篡改交易记录

为了防止篡改事件的发生,区块链会根据最长链原则来保护整个区块链:

当区块链出现分支的情况下,即有不止一个人在近乎相同时间内挖出了下一个块,链的走向出现了分支,一般而言使用最长链原则进行选择。假设用户群体A选择上链继续挖矿,用户群体B选择下链继续挖矿。如果群体A先挖出下一个矿,上链新块,则群体B转到新块后继续挖矿。通常情况下,下链被废弃。

也就是说明在区块链出现分支的地方会比较上下链谁先挖出第二个区块(谁的链最先变成长的支链),长的保留,短的放弃。
所以我们可以根据最长链原则,如果有人想篡改区块链上某一区块的信息,他就要在该区块处引出一条分支,并且打造一条新链使得新链超过原链长度。即他一人控制的矿机算力要超过全世界剩余的矿机算力对抗(比谁更快)。这个实现的概率很小。就比如一个人控制了世界上90%的矿机去篡改一条链的交易记录,为何他不利用这么多的矿机去正经的挖矿呢?

(3).防止双重支付的交易

双重支付事件发生时候,比如A只有100个比特币,但同时广播了消息"A给B 100个比特币"(记为消息b)和"A给C
100个比特币"(记为消息c),群体D先接收到消息b,则不会去确认消息c。同理,群体E先接收到消息c,则不会去确认消息b。这时候就要看群体D和E中谁先能计算出那道数学题,先挖出矿的可以把自己确认的消息写到新块中,而另一条消息则失效。

Double payment
版权声明
本文被以下参考引用内容外均为J0hn原创内容,最终解释权归原作者所有。如有侵权,请联系删除。未经本人授权,请勿私自转载!

6.参考资料

[1]. BMoney http://www.weidai.com/bmoney.txt
[2]. Wikipedia https://en.wikipedia.org/wiki/Bitcoin
[3]. Wikipedia https://en.wikipedia.org/wiki/SHA-2
[4]. Wikipedia https://en.wikipedia.org/wiki/Blockchain
[5]. Youtube https://www.youtube.com/watch?v=g_fSistU3MQ&t=11s
[6]. BitcoinOrg https://bitcoin.org/bitcoin.pdf

猜你喜欢

转载自blog.csdn.net/sjhjohn/article/details/114994837