zoukankan      html  css  js  c++  java
  • 在搭建区块链中学习

    在搭建区块链中学习

    参考教材:Learn Blockchains by Building One

    【注:仅仅个人心得体会】

    区块链的大致样子

    block = {
        'index': 1,
        'timestamp': 1506057125.900785,
        'transactions': [
            {
                'sender': "8527147fe1f5426f9dd545de4b27ee00",
                'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
                'amount': 5,
            }
        ],
        'proof': 324984774000,
        'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
    }
    

    一些名词

    区块:一个区块链由许多个区块组成,每个区块中会包含若干元素。

    交易:sender发送给recipienter的内容的记录,记录在区块的交易信息中

    哈希值:一个区块中包含的前一个区块的哈希值,使得区块之间连接。

    时间戳:区块被挖出来的时刻

    挖矿:根据算力来进行一系列数学操作,做到符合工作量证明机制的的时候算是挖到矿,收到奖励,并形成新的区块连接到区块链的末端

    工作量证明:根据规则,找到满足规则的所需条件,作为挖到矿的证明

    创造一个新的区块并添加到区块链上说起吧

    通常情况下当挖到矿时才创建一个新的区块,挖到矿后会进行一笔交易,相当于获得一个比特币

    而挖到矿的规则制定则需要工作量证明机制来实现(自己制定)

    这里工作量证明机制是

    Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
    p is the previous proof, and p' is the new proof

    找到一个数p‘使得hash(pp')的前四位都是零

        创建新区块
        def new_block(self, proof, previous_hash=None):
            """
            Create a new Block in the Blockchain
            :param proof: <int> The proof given by the Proof of Work algorithm
            :param previous_hash: (Optional) <str> Hash of previous Block
            :return: <dict> New Block
            """
            block = {
                'index': len(self.chain) + 1,
                'timestamp': time(),
                'transactions': self.currrent_transactions,
                'proof': proof,
                'previous_hash': previous_hash or self.hash(self.chain[-1]),
            }
        # Reset the current list of transactions
        self.current_transactions = []
    
        self.chain.append(block)
        return block
    

    不断尝试找到那个p'(挖矿行为)

        简单的工作量证明机制
        def valid_proof(last_proof,proof):  
            guess = f'{last_proof}{proof}'.encode()
            guess_hash = hashlib.sha256(guess).hexdigest()
            return guess_hash[:4] == "0000"
        
        def proof_of_work(self,last_proof):
                 proof = 0
                 while self.valid_proof(last_proof, proof) is False:
           proof += 1
        return proof
    	
        
        挖矿
        def mine():
        last_block = blockchain.last_block
        last_proof = last_block['proof']
        proof = blockchain.proof_of_work(last_proof)
        
        #reward for find the proof
        # The sender is "0" to signify that this node has mined a new coin.
        blockchain.new_transaction(
                sender="0",
                recipient=node_identifier,
                amount=1,
                )
        # 调用之前的创建区块并连接到原区块链上
        previous_hash = blockchain.hash(last_block)
        block = blockchain.new_block(proof,previous_hash)
    

    创建新的交易的代码,在当前区块中,会有许多交易,而这些交易的信息都将会存储到当前区块链的区块中以便于追溯查证,并返回下一个需要挖的区块索引。

        def new_transaction(self, sender, recipient, amount):
    
                self.currrent_transactions.append({
                        'sender': sender,
                        'recipient': recipient,
                        'amount': amount,
                        })
                return self.last_block['index'] + 1
    

    共识机制,当然,区块链本就是去中心化思想,不会只有一个人保存区块链,而是一群人都保存有区块链(账本),这时候,到了联机模式。就需要制定一些大家都同意的公平规则,所谓的共识机制,进行共识机制前,会先验证你的区块链的链接是否正确,你是否随意篡改过你的区块链(账本)

    def valid_chain(self, chain):
          
            last_block = chain[0]
            current_index = 1
            
            逐个验证每个区块(也就是是否符合工作量证明机制,是否每个块是靠努力挖矿得来的)
            
            while current_index < len(chain):
                block = chain[current_index]
       
                
                #Check the hash
                if block['previous_hash'] != self.hash(last_block):
                    return False
                
                #Check the proof of work
                if not self.valid_proof(last_block['proof'], block['proof']):
                    return False
                
                last_block = block
                current_index += 1
                
            return True
    

    当然,如果出现了错误,某些人恶意篡改区块链(账本),我们必须纠正这些错误,这时候就需要制定合适的共识机制来进行处理,我们这次选择最长的验证通过的区块链作为大家的共识,如果有某个人的区块链长度小于共识区块链,就用共识区块链来代替他的区块链,来实现安全性、统一性。

    def resolve_conflicts(self):
         	每个人的neighbors中都保存了所有用户的信息,以便于实现共识
            neighbors = self.nodes
            new_chain = None
            
            ## We're only looking for chains longer than ours
            max_length = len(self.chain)
            
            先找到最长的链(共识链)
            for node in neighbors:
                response = requests.get(f'http://{node}/chain')
                
                if response.status_code == 200:
                    length = response.json()['length']
                    chain = response.json()['chain']
                    
                    #Check if the lengthis longer and the chain is valid
                    if length > max_length:
                        max_length = length
                        new_chain = chain
            决定是否更新自己的链(是否符合共识机制)           
            if new_chain:
                self.chain = new_chain
                return True
            
            return False
        
        
    

    最后再总结一下遇到的问题和解决方式

    1 已解决

    2 Json.dumps详解

    https://blog.csdn.net/weixin_38842821/article/details/108359551

    3 hashcash详解

    https://blog.csdn.net/pony_maggie/article/details/54170349

    4 UUID详解

    https://baike.baidu.com/item/UUID/5921266?fr=aladdin

    5 Python f'' 详解

    https://blog.csdn.net/qq_35290785/article/details/90634344

    6 Python textwrap 详解

    https://blog.csdn.net/qq_33169543/article/details/82840719

    7 postman一种模拟浏览器请求的脚本,我用的是火狐的RESTED插件

    8 netloc详解

    https://www.cnblogs.com/AbsolutelyPerfect/p/7474961.html

  • 相关阅读:
    Linux 中改变主机名的 4 种方法
    如何成为优秀开发人员(一):怎样算是优秀的?
    Java中需要知道的关键字
    Java集合类常见的问题
    如何在 Linux 上复制文件/文件夹到远程系统?
    你还在 Select * 吗?
    技术人解决问题的思路
    如何创建编程语言,以及设计决策中的内容?
    Java内存溢出异常(下)
    如何在 Linux 中查看可用的网络接口
  • 原文地址:https://www.cnblogs.com/Martrix-revolution/p/14655512.html
Copyright © 2011-2022 走看看