Python创建区块链,邀请伴侣一块来测试!
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_gif/yAyQKzCbAHaibMZruy7pmtdd3Datgn3gBdDCnicmanRH151QsUJYuJZZlEBZIuj3sHV4mPbxYGmRRWDG5kwhuuZA/640?wx_fmt=gif&tp=webp&wxfrom=5&wx_lazy=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">对数字货币的崛起感到新奇的<span style="color: black;">咱们</span>,并且想<span style="color: black;">晓得</span>其<span style="color: black;">背面</span>的技术——区块链是<span style="color: black;">怎么样</span>实现的。作者认为最快的学习区块链的方式是自己创建一个,本文就跟随作者用Python来创建一个区块链。在实践中学习,<span style="color: black;">经过</span>构建一个区块链<span style="color: black;">能够</span>加深对区块链的理解。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;">准备工作</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">本文<span style="color: black;">需求</span>读者对Python有基本的理解,能读写基本的Python,并且需要对HTTP请求有基本的<span style="color: black;">认识</span>。点击查看<span style="color: black;">►</span><a style="color: black;">Python难懂?买一次西瓜就懂了!</a>;<span style="color: black;">HTTP请求:http://www.runoob.com/http/http-tutorial.html(复制到浏览器查看)</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">咱们</span><span style="color: black;">晓得</span>区块链<span style="color: black;">是由于</span>区块的记录<span style="color: black;">形成</span>的不可变、有序的链结构,记录<span style="color: black;">能够</span>是交易、文件或任何你想要的数据,重要的是它们是<span style="color: black;">经过</span>哈希值(hashes)链接起来的。</span></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">环境准备</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">保证</span><span style="color: black;">已然</span>安装Python3.6+, pip , Flask, requests,安装<span style="color: black;">办法</span>:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">pip install Flask==0.12.2 requests==2.18.4</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">同期</span>还需要一个HTTP客户端,<span style="color: black;">例如</span>Postman,cURL或其它客户端。参考</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">https://github.com/xilibi2003/blockchain</span></p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><span style="color: black;">起始</span>创建Blockchain</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">新建一个文件 blockchain.py,本文所有的代码都写在这一个文件中。</span></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">Blockchain类</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">首要</span>创建一个Blockchain类,在构造函数中创建了两个列表,一个用于储存区块链,一个用于储存交易。以下是Blockchain类的框架:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">Blockchain</span>(<span style="color: black;">object</span>):</span> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(<span style="color: black;">self</span>)</span></span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> <span style="color: black;">self</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.chain = []</p> <span style="color: black;">self</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.current_transactions = []</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">new_block</span><span style="color: black;">(<span style="color: black;">self</span>)</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> <span style="color: black;"># Creates a new Block and adds it to the chain</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> pass</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">new_transaction</span><span style="color: black;">(<span style="color: black;">self</span>)</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> <span style="color: black;"># Adds a new transaction to the list of transactions</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> pass</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> @staticmethod</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">hash</span><span style="color: black;">(block)</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> <span style="color: black;"># Hashes a Block</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> pass</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> @property</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">last_block</span><span style="color: black;">(<span style="color: black;">self</span>)</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> <span style="color: black;"># Returns the last Block in the chain</span> pass
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Blockchain类用来管理链条,它能存储交易,加入新块等,下面<span style="color: black;">咱们</span>来进一步完善这些<span style="color: black;">办法</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">块结构</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">每一个</span>区块包含属性:索引(index),Unix时间戳(timestamp),交易列表(transactions),工作量证明(稍后解释)以及前一个区块的Hash值。以下是一个区块的结构:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">block = {</p> <span style="color: black;">index</span>: <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">timestamp</span>: <span style="color: black;">1506057125.900785</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">transactions</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: [</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> <span style="color: black;">sender</span>: <span style="color: black;">"8527147fe1f5426f9dd545de4b27ee00"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">recipient</span>: <span style="color: black;">"a77f5cdfa2934df3954a5c7c7da5df1f"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">amount</span>: <span style="color: black;">5</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ],</p> <span style="color: black;">proof</span>: <span style="color: black;">324984774000</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">previous_hash</span>: <span style="color: black;">"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"</span>}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">到<span style="color: black;">这儿</span>,区块链的概念就清楚了,<span style="color: black;">每一个</span>新的区块都<span style="color: black;">包括</span>上一个区块的Hash,这是关键的一点,它<span style="color: black;">保证</span>了区块链不可变性。<span style="color: black;">倘若</span>攻击者破坏了前面的某个区块,<span style="color: black;">那样</span>后面所有区块的Hash都会变得不正确。<span style="color: black;">不睬</span>解的话,慢慢消化。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">加入交易</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">接下来<span style="color: black;">咱们</span>需要添加一个交易,来完善下new_transaction<span style="color: black;">办法</span>:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">Blockchain</span><span style="color: black;">(object)</span>:</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ...</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">new_transaction</span><span style="color: black;">(self, sender, recipient, amount)</span>:</span> <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"""</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">生成新交易信息,信息将加入到下一个待挖的区块中</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param sender: Address of the Sender
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param recipient: Address of the Recipient
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param amount: Amount
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: The index of the Block that will hold this transaction
</p> """
</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.current_transactions.append({</p> <span style="color: black;">sender</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: sender,</p> <span style="color: black;">recipient</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: recipient,</p> <span style="color: black;">amount</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: amount,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> })</p> <span style="color: black;">return</span> self.last_block[<span style="color: black;">index</span>] + <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">方法向列表中添加一个交易记录,并返回该记录将被添加到的区块(下一个待挖掘的区块)的索引,等下在用户提交交易时会有用。</span></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">创建新块</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">当Blockchain实例化后,<span style="color: black;">咱们</span>需要构造一个创世块(<span style="color: black;">无</span>前区块的<span style="color: black;">第1</span>个区块),并且给它加上一个工作量证明。<span style="color: black;">每一个</span>区块都需要经过工作量证明,俗<span style="color: black;">叫作</span>挖矿,稍后会继续讲解。为了构造创世块,<span style="color: black;">咱们</span>还需要完善new_block(), new_transaction() 和hash() <span style="color: black;">办法</span>:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">import</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> hashlib</p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> json</p><span style="color: black;">from</span> time <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> time</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">Blockchain</span><span style="color: black;">(object)</span>:</span> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(self)</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">self.current_transactions = []</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.chain = []</p> <span style="color: black;"># Create the genesis block</span> self.new_block(previous_hash=<span style="color: black;">1</span>, proof=<span style="color: black;">100</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">new_block</span><span style="color: black;">(self, proof, previous_hash=None)</span>:</span> <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"""</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">生成新块</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param proof: The proof given by the Proof of Work algorithm
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param previous_hash: (Optional) Hash of previous Block
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: New Block
</p> """
</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> block = {</p> <span style="color: black;">index</span>: len(self.chain) +<span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">timestamp</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: time(),</p> <span style="color: black;">transactions</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: self.current_transactions,</p> <span style="color: black;">proof</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: proof,</p> <span style="color: black;">previous_hash</span>: previous_hash <span style="color: black;">or</span> self.hash(self.chain[<span style="color: black;">-1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p> <span style="color: black;"># Reset the current list of transactions</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.current_transactions = []</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.chain.append(block)</p> <span style="color: black;">return</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> block</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">new_transaction</span><span style="color: black;">(self, sender, recipient, amount)</span>:</span> <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"""</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> 生成新交易信息,信息将加入到下一个待挖的区块中</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param sender: Address of the Sender
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param recipient: Address of the Recipient
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param amount: Amount
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: The index of the Block that will hold this transaction
</p> """
</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.current_transactions.append({</p> <span style="color: black;">sender</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: sender,</p> <span style="color: black;">recipient</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: recipient,</p> <span style="color: black;">amount</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: amount,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> })</p> <span style="color: black;">return</span> self.last_block[<span style="color: black;">index</span>] + <span style="color: black;">1</span><span style="color: black;"> @property</span> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">last_block</span><span style="color: black;">(self)</span>:</span> <span style="color: black;">return</span> self.chain[<span style="color: black;">-1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p><span style="color: black;"> @staticmethod</span> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">hash</span><span style="color: black;">(block)</span>:</span> <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"""</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> 生成块的 SHA-256 hash值</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param block: Block
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: </p> """
</span> <span style="color: black;"># We must make sure that the Dictionary is Ordered, or well have inconsistent hashes</span> block_string = json.dumps(block, sort_keys=<span style="color: black;">True</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">).encode()</p> <span style="color: black;">return</span>hashlib.sha256(block_string).hexdigest()
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">经过</span>上面的代码和注释<span style="color: black;">能够</span>对区块链有直观的<span style="color: black;">认识</span>,接下来<span style="color: black;">咱们</span><span style="color: black;">瞧瞧</span>区块是怎么挖出来的。</p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">理解工作量证明</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">新的区块依赖工作量证明算法(PoW)来构造,PoW的<span style="color: black;">目的</span>是找出一个符合特定<span style="color: black;">要求</span>的数字,<strong style="color: blue;">这个数字很难计算出来,但容易验证</strong>。这<span style="color: black;">便是</span>工作量证明的核心思想。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">为了方便理解,举个例子:假设一个整数 x 乘以另一个整数 y 的积的 Hash 值必须以 0 结尾,即hash(x * y) = ac23dc…0,设变量 x = 5,求 y 的值?用Python实现如下:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">from</span> hashlib <span style="color: black;">import</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> sha256</p>x = <span style="color: black;">5</span>y = <span style="color: black;">0</span> <span style="color: black;"># y未知</span><span style="color: black;">while</span>sha256(<span style="color: black;">f<span style="color: black;">{x*y}</span></span>.encode()).hexdigest()[<span style="color: black;">-1</span>] != <span style="color: black;">"0"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> y += <span style="color: black;">1</span>print(<span style="color: black;">fThe solution is y = <span style="color: black;">{y}</span></span>)
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">结果是y=21. <span style="color: black;">由于</span>:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">hash(5 * 21) = 1253e9373e...5e3600155e860</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">在比特币中,<span style="color: black;">运用</span><span style="color: black;">叫作</span>为Hashcash的工作量证明算法,它和上面的问题很类似。矿工们为了争夺创建区块的权利而争相计算结果。<span style="color: black;">一般</span>,计算难度与<span style="color: black;">目的</span>字符串需要满足的特定字符的数量成正比,矿工算出结果后,会<span style="color: black;">得到</span>比特币奖励。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">当然,在网络上非常容易验证这个结果。</span></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">实现工作量证明</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">让<span style="color: black;">咱们</span>来实现一个<span style="color: black;">类似</span>PoW算法,规则是:寻找一个数 p,使得它与前一个区块的 proof 拼接成的字符串的 Hash 值以 4 个零开头。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">import</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> hashlib</p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> json</p><span style="color: black;">from</span> time <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> time</p><span style="color: black;">from</span> uuid <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> uuid4</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">Blockchain</span><span style="color: black;">(object)</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ...</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">proof_of_work</span><span style="color: black;">(self, last_proof)</span>:</span> <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"""</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> 简单的工作量证明:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> - <span style="color: black;">查询</span>一个 p 使得 hash(pp) 以4个0开头</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> - p 是上一个块的证明, p 是当前的证明</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param last_proof: </p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: </p> """
</span> proof = <span style="color: black;">0</span> <span style="color: black;">while</span>self.valid_proof(last_proof, proof)<span style="color: black;">is</span> <span style="color: black;">False</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> proof += <span style="color: black;">1</span> <span style="color: black;">return</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> proof</p><span style="color: black;"> @staticmethod</span> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">valid_proof</span><span style="color: black;">(last_proof, proof)</span>:</span> <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"""</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> 验证证明: <span style="color: black;">是不是</span>hash(last_proof, proof)以4个0开头?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param last_proof: Previous Proof
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param proof: Current Proof
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: True if correct, False if not.
</p> """
</span> guess = <span style="color: black;">f<span style="color: black;">{last_proof}</span><span style="color: black;">{proof}</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.encode()</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">guess_hash = hashlib.sha256(guess).hexdigest()</p> <span style="color: black;">return</span> guess_hash[:<span style="color: black;">4</span>] == <span style="color: black;">"0000"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">衡量算法<span style="color: black;">繁杂</span>度的办法是修改零开头的个数。<span style="color: black;">运用</span>4个来用于演示,你会<span style="color: black;">发掘</span>多一个零都会大大<span style="color: black;">增多</span>计算出结果所需的时间。<span style="color: black;">此刻</span>Blockchain类基本<span style="color: black;">已然</span>完<span style="color: black;">成为了</span>,接下来<span style="color: black;">运用</span>HTTP requests来进行交互。</span></p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">Blockchain<span style="color: black;">做为</span>API接口</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">咱们</span>将<span style="color: black;">运用</span>Python Flask框架,这是一个轻量Web应用框架,它方便将网络请求映射到 Python函数,<span style="color: black;">此刻</span><span style="color: black;">咱们</span>来让Blockchain运行在基于Flask web上。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">咱们</span>将创建三个接口:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">/transactions/new 创建一个交易并添加到区块</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">/mine 告诉服务器去挖掘新的区块</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">/chain 返回<span style="color: black;">全部</span>区块链</span></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">创建节点</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">咱们</span>的Flask服务器将扮演区块链网络中的一个节点。<span style="color: black;">咱们</span>先添加<span style="color: black;">有些</span>框架代码:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">import</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> hashlib</p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> json</p><span style="color: black;">from</span> textwrap <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> dedent</p><span style="color: black;">from</span> time <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> time</p><span style="color: black;">from</span> uuid <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> uuid4</p><span style="color: black;">from</span> flask <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> Flask</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">Blockchain</span><span style="color: black;">(object)</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ...</p><span style="color: black;"># Instantiate our Node</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">app = Flask(__name__)</p><span style="color: black;"># Generate a globally unique address for this node</span>node_identifier = str(uuid4()).replace(<span style="color: black;">-</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">, )</p><span style="color: black;"># Instantiate the Blockchain</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">blockchain = Blockchain()</p><span style="color: black;">@app.route(/mine, methods=)</span><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">mine</span><span style="color: black;">()</span>:</span> <span style="color: black;">return</span> <span style="color: black;">"Well mine a new Block"</span><span style="color: black;">@app.route(/transactions/new, methods=)</span><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">new_transaction</span><span style="color: black;">()</span>:</span> <span style="color: black;">return</span> <span style="color: black;">"Well add a new transaction"</span><span style="color: black;">@app.route(/chain, methods=)</span><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">full_chain</span><span style="color: black;">()</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> response = {</p> <span style="color: black;">chain</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: blockchain.chain,</p> <span style="color: black;">length</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: len(blockchain.chain),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p> <span style="color: black;">return</span> jsonify(response), <span style="color: black;">200</span><span style="color: black;">if</span> __name__ == <span style="color: black;">__main__</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> app.run(host=<span style="color: black;">0.0.0.0</span>, port=<span style="color: black;">5000</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">简单的说明一下以上代码:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">第15行: 创建一个节点.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">第18行: 为节点创建一个随机的名字.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">第21行: 实例Blockchain类.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">第24–26行: 创建/mine GET接口。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">第28–30行: 创建/transactions/new POST接口,<span style="color: black;">能够</span>给接口发送交易数据.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">第32–38行: 创建 /chain 接口, 返回<span style="color: black;">全部</span>区块链.</p>第40–41行: 服务运行在端口5000上.
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">发送交易</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">发送到节点的交易数据结构如下:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p><span style="color: black;">"sender"</span>: <span style="color: black;">"my address"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p><span style="color: black;">"recipient"</span>: <span style="color: black;">"someone elses address"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p><span style="color: black;">"amount"</span>: <span style="color: black;">5</span>}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">之前<span style="color: black;">已然</span>有添加交易的方法,基于接口来添加交易就很简单了</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">import</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> hashlib</p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> json</p><span style="color: black;">from</span> textwrap <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> dedent</p><span style="color: black;">from</span> time <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> time</p><span style="color: black;">from</span> uuid <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> uuid4</p><span style="color: black;">from</span> flask <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> Flask, jsonify, request</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">...</p><span style="color: black;">@app.route(/transactions/new, methods=)</span><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">new_transaction</span><span style="color: black;">()</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> values = request.get_json()</p> <span style="color: black;"># Check that the required fields are in the POSTed data</span>required = [<span style="color: black;">sender</span>, <span style="color: black;">recipient</span>, <span style="color: black;">amount</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p> <span style="color: black;">if</span> <span style="color: black;">not</span> all(k <span style="color: black;">in</span> values <span style="color: black;">for</span> k <span style="color: black;">in</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> required):</p> <span style="color: black;">return</span> <span style="color: black;">Missing values</span>, <span style="color: black;">400</span> <span style="color: black;"># Create a new Transaction</span>index = blockchain.new_transaction(values[<span style="color: black;">sender</span>], values[<span style="color: black;">recipient</span>], values[<span style="color: black;">amount</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">])</p> response = {<span style="color: black;">message</span>: <span style="color: black;">fTransaction will be added to Block <span style="color: black;">{index}</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p> <span style="color: black;">return</span> jsonify(response), <span style="color: black;">201</span>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></strong></span></h3>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;">挖矿</span></strong></span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">挖矿正是神奇所在,它很简单,做了一下三件事:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">计算工作量证明PoW</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">经过</span>新增一个交易授予矿工(自己)一个币</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">构造新区块并将其添加到链中</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">import</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> hashlib</p><span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> json</p><span style="color: black;">from</span> time <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> time</p><span style="color: black;">from</span> uuid <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> uuid4</p><span style="color: black;">from</span> flask <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Flask, jsonify, request</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">...</p><span style="color: black;">@app.route(/mine, methods=)</span><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">mine</span><span style="color: black;">()</span>:</span> <span style="color: black;"># We run the proof of work algorithm to get the next proof...</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">last_block = blockchain.last_block</p> last_proof = last_block[<span style="color: black;">proof</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> proof = blockchain.proof_of_work(last_proof)</p> <span style="color: black;"># 给工作量证明的节点<span style="color: black;">供给</span>奖励.</span> <span style="color: black;"># 发送者为 "0" <span style="color: black;">显示</span>是新挖出的币</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> blockchain.new_transaction(</p> sender=<span style="color: black;">"0"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">recipient=node_identifier,</p> amount=<span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> )</p> <span style="color: black;"># Forge the new Block by adding it to the chain</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> block = blockchain.new_block(proof)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> response = {</p> <span style="color: black;">message</span>: <span style="color: black;">"New Block Forged"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">index</span>: block[<span style="color: black;">index</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">],</p> <span style="color: black;">transactions</span>: block[<span style="color: black;">transactions</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">],</p> <span style="color: black;">proof</span>: block[<span style="color: black;">proof</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">],</p> <span style="color: black;">previous_hash</span>: block[<span style="color: black;">previous_hash</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">],</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p> <span style="color: black;">return</span> jsonify(response), <span style="color: black;">200</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">重视</span>交易的接收者是<span style="color: black;">咱们</span>自己的服务器节点,<span style="color: black;">咱们</span>做的大部分工作都只是围绕Blockchain类<span style="color: black;">办法</span>进行交互。到此,<span style="color: black;">咱们</span>的区块链就算完<span style="color: black;">成为了</span>,<span style="color: black;">咱们</span>来<span style="color: black;">实质</span>运行下。</p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">运行区块链</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">你<span style="color: black;">能够</span><span style="color: black;">运用</span>cURL 或Postman 去和API进行交互,<span style="color: black;">起步</span>server:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">$ <span style="color: black;">python</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> blockchain.py</p>* Runing<span style="color: black;">on</span> http://127.0.0.1:5000/ (Press CTRL+C to quit)
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">让<span style="color: black;">咱们</span><span style="color: black;">经过</span>请求 http://localhost:5000/mine 来进行挖矿</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">经过</span>post请求,添加一个新交易</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">倘若</span>不是<span style="color: black;">运用</span>Postman,则用一下的cURL语句<span style="color: black;">亦</span>是<span style="color: black;">同样</span>的:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">$ <span style="color: black;">curl</span> -X POST -H <span style="color: black;">"Content-Type: application/json"</span> -d </span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"sender": "d4ee26eee15148ee92c6cd394edd974e",</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"recipient": "someone-other-address",</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"amount": 5</p>}
<span style="color: black;">"http://localhost:5000/transactions/new"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">在挖了两次矿之后,就有3个块了,<span style="color: black;">经过</span>请求 http://localhost:5000/chain <span style="color: black;">能够</span>得到所有的块信息。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p> <span style="color: black;">"chain"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: [</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> <span style="color: black;">"index"</span>: <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"previous_hash"</span>: <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"proof"</span>: <span style="color: black;">100</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"timestamp"</span>: <span style="color: black;">1506280650.770839</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"transactions"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: []</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> },</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> <span style="color: black;">"index"</span>: <span style="color: black;">2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"previous_hash"</span>: <span style="color: black;">"c099bc...bfb7"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"proof"</span>: <span style="color: black;">35293</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"timestamp"</span>: <span style="color: black;">1506280664.717925</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"transactions"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: [</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> <span style="color: black;">"amount"</span>: <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"recipient"</span>: <span style="color: black;">"8bbcb347e0634905b0cac7955bae152b"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"sender"</span>: <span style="color: black;">"0"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ]</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> },</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> <span style="color: black;">"index"</span>: <span style="color: black;">3</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"previous_hash"</span>: <span style="color: black;">"eff91a...10f2"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"proof"</span>: <span style="color: black;">35089</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"timestamp"</span>: <span style="color: black;">1506280666.1086972</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"transactions"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: [</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> <span style="color: black;">"amount"</span>: <span style="color: black;">1</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"recipient"</span>: <span style="color: black;">"8bbcb347e0634905b0cac7955bae152b"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">"sender"</span>: <span style="color: black;">"0"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ]</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ],</p> <span style="color: black;">"length"</span>: <span style="color: black;">3</span>}
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一致性(共识)</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">咱们</span><span style="color: black;">已然</span>有了一个基本的区块链<span style="color: black;">能够</span>接受交易和挖矿。<span style="color: black;">然则</span>区块链系统应该是分布式的。既然是分布式的,<span style="color: black;">那样</span><span style="color: black;">咱们</span><span style="color: black;">到底</span>拿什么<span style="color: black;">保准</span>所有节点有<span style="color: black;">一样</span>的链呢?这<span style="color: black;">便是</span>一致性问题,<span style="color: black;">咱们</span><span style="color: black;">想要</span>在网络上有多个节点,就必须实现一个一致性的算法。</span></p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">注册节点</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">在实现一致性算法之前,<span style="color: black;">咱们</span>需要找到一种方式让一个节点<span style="color: black;">晓得</span>它相邻的节点。<span style="color: black;">每一个</span>节点都需要<span style="color: black;">保留</span>一份<span style="color: black;">包括</span>网络中其它节点的记录。<span style="color: black;">因此呢</span>让<span style="color: black;">咱们</span>新增几个接口:</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">/nodes/register 接收URL形式的新节点列表</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">/nodes/resolve 执行一致性算法,<span style="color: black;">处理</span>任何冲突,<span style="color: black;">保证</span>节点<span style="color: black;">持有</span>正确的链</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>修改下Blockchain的init函数并<span style="color: black;">供给</span>一个注册节点<span style="color: black;">办法</span>:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">...</p><span style="color: black;">from</span> urllib.parse <span style="color: black;">import</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> urlparse</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">...</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">Blockchain</span><span style="color: black;">(object)</span>:</span> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">__init__</span><span style="color: black;">(self)</span>:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ...</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> self.nodes = set()</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ...</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">register_node</span><span style="color: black;">(self, address)</span>:</span> <span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"""</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Add a new node to the list of nodes</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param address: Address of node. Eg. http://192.168.0.5:5000
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: None</p> """
</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> parsed_url = urlparse(address)</p> self.nodes.add(parsed_url.netloc)
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">咱们</span>用 set 来储存节点,这是一种避免重复添加节点的简单<span style="color: black;">办法</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">实现共识算法</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">前面<span style="color: black;">说到</span>,冲突<span style="color: black;">指的是</span><span style="color: black;">区别</span>的节点<span style="color: black;">持有</span><span style="color: black;">区别</span>的链,为<span style="color: black;">认识</span>决这个问题,规定最长的、有效的链才是<span style="color: black;">最后</span>的链,换句话说,网络中有效最长链才是<span style="color: black;">实质</span>的链。<span style="color: black;">咱们</span><span style="color: black;">运用</span>一下的算法,来达到网络中的共识。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">...</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">import requests</p><span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">Blockchain</span>(<span style="color: black;">object</span>)</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ...</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">valid_chain</span><span style="color: black;">(<span style="color: black;">self</span>, chain)</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> <span style="color: black;">""</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> Determine if a given blockchain is valid</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :param chain: A blockchain
</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: True if valid, False if not
</p> "
</span><span style="color: black;">""</span> last_block = chain[<span style="color: black;">0</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p> current_index = <span style="color: black;">1</span> <span style="color: black;">while</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> current_index < len(chain):</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> block = chain</p> print(f<span style="color: black;">{last_block}</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> print(f<span style="color: black;">{block}</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> print(<span style="color: black;">"\n-----------\n"</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> <span style="color: black;"># Check that the hash of the block is correct</span> <span style="color: black;">if</span> block[<span style="color: black;">previous_hash</span>] != <span style="color: black;">self</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.hash(last_block):</p> <span style="color: black;">return</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> False</p> <span style="color: black;"># Check that the Proof of Work is correct</span> <span style="color: black;">if</span> <span style="color: black;">not</span> <span style="color: black;">self</span>.valid_proof(last_block[<span style="color: black;">proof</span>], block[<span style="color: black;">proof</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]):</p> <span style="color: black;">return</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> False</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> last_block = block</p> current_index += <span style="color: black;">1</span> <span style="color: black;">return</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> True</p> <span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">resolve_conflicts</span><span style="color: black;">(<span style="color: black;">self</span>)</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> <span style="color: black;">""</span><span style="color: black;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">"</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">共识算法解决冲突</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> <span style="color: black;">运用</span>网络中最长的链.</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> :return: True <span style="color: black;">倘若</span>链被取代, 否则为False
</p> "
</span><span style="color: black;">""</span> neighbours = <span style="color: black;">self</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.nodes</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> new_chain = None</p> <span style="color: black;"># Were only looking for chains longer than ours</span> max_length = len(<span style="color: black;">self</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.chain)</p> <span style="color: black;"># Grab and verify the chains from all the nodes in our network</span> <span style="color: black;">for</span> node <span style="color: black;">in</span> <span style="color: black;">neighbours:</span> response = requests.get(f<span style="color: black;">http://{node}/chain</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> <span style="color: black;">if</span>response.status_code ==<span style="color: black;">200</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p> length = response.json()[<span style="color: black;">length</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p> chain = response.json()[<span style="color: black;">chain</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">]</p> <span style="color: black;"># Check if the length is longer and the chain is valid</span> <span style="color: black;">if</span>length > max_length<span style="color: black;">and</span> <span style="color: black;">self</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.valid_chain(chain):</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> max_length = length</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> new_chain = chain</p> <span style="color: black;"># Replace our chain if we discovered a new, valid chain longer than ours</span> <span style="color: black;">if</span> <span style="color: black;">new_chain:</span> <span style="color: black;">self</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.chain = new_chain</p> <span style="color: black;">return</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> True</p> <span style="color: black;">return</span> False
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">第1</span>个<span style="color: black;">办法</span> valid_chain() 用来<span style="color: black;">检测</span><span style="color: black;">是不是</span>是有效链,遍历<span style="color: black;">每一个</span>块验证hash和proof;第二个<span style="color: black;">办法</span> resolve_conflicts() 用来<span style="color: black;">处理</span>冲突,遍历所有的邻居节点,并用上一个<span style="color: black;">办法</span><span style="color: black;">检测</span>链的有效性,<strong style="color: blue;"><span style="color: black;">倘若</span><span style="color: black;">发掘</span>有效更长链,就替换掉自己的链。</strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">让<span style="color: black;">咱们</span>添加两个路由,一个用来注册节点,一个用来<span style="color: black;">处理</span>冲突。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">@app.route(<span style="color: black;">/nodes/register</span>, methods=[<span style="color: black;">POST</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">])</p><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">register_nodes</span><span style="color: black;">()</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> values = request.get_json()</p>nodes = values.get(<span style="color: black;">nodes</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p> <span style="color: black;">if</span> nodes is <span style="color: black;">None:</span> <span style="color: black;">return</span> <span style="color: black;">"Error: Please supply a valid list of nodes"</span>, <span style="color: black;">400</span> <span style="color: black;">for</span> node <span style="color: black;">in</span> <span style="color: black;">nodes:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> blockchain.register_node(node)</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> response = {</p> <span style="color: black;">message</span>: <span style="color: black;">New nodes have been added</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">total_nodes</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: list(blockchain.nodes),</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p> <span style="color: black;">return</span> jsonify(response), <span style="color: black;">201</span>@app.route(<span style="color: black;">/nodes/resolve</span>, methods=[<span style="color: black;">GET</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">])</p><span style="color: black;"><span style="color: black;">def</span> <span style="color: black;">consensus</span><span style="color: black;">()</span></span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> replaced = blockchain.resolve_conflicts()</p> <span style="color: black;">if</span> <span style="color: black;">replaced:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> response = {</p> <span style="color: black;">message</span>: <span style="color: black;">Our chain was replaced</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">new_chain</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: blockchain.chain</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p> <span style="color: black;">else:</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> response = {</p> <span style="color: black;">message</span>:<span style="color: black;">Our chain is authoritative</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">chain</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: blockchain.chain</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p> <span style="color: black;">return</span> jsonify(response), <span style="color: black;">200</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">▲</span>向右移动,查看完整文本</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">你<span style="color: black;">能够</span>在<span style="color: black;">区别</span>的<span style="color: black;">设备</span>运行节点,或在一台机机开启<span style="color: black;">区别</span>的网络端口来模拟多节点的网络,<span style="color: black;">这儿</span>在同一台<span style="color: black;">设备</span>开启<span style="color: black;">区别</span>的端口演示,在<span style="color: black;">区别</span>的终端运行一下命令,就<span style="color: black;">起步</span>了两个节点:http://localhost:5000 和 http://localhost:5001</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">pipenv</span>
</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> run python blockchain.py</p>pipenv run python blockchain.py -p <span style="color: black;">5001</span>
<img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;">
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">而后</span>在节点2上挖两个块,<span style="color: black;">保证</span>是更长的链,<span style="color: black;">而后</span>在节点1上<span style="color: black;">拜访</span>接口/nodes/resolve ,<span style="color: black;">此时</span>节点1的链会<span style="color: black;">经过</span>共识算法被节点2的链取代。</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;">好啦,你<span style="color: black;">能够</span>邀请<span style="color: black;">伴侣</span>们<span style="color: black;">一块</span>来测试你的区块链!</span></strong></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">End.</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">作者:Daniel van Flymen;译者:Tiny熊</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">源自</span>:learnblockchain</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">原文链接:https://learnblockchain.cn/2017/10/27/build_blockchain_by_python/</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
你的见解独到,让我受益匪浅,非常感谢。 我完全同意你的观点,说得太对了。 外链发布论坛学习网络优化SEO。 可以发布外链的网站 http://www.fok120.com/ 外链论坛的成功举办,是与各位领导、同仁们的关怀和支持分不开的。在此,我谨代表公司向关心和支持论坛的各界人士表示最衷心的感谢! 你的努力一定会被看见,相信自己,加油。
页:
[1]