精华内容
下载资源
问答
  • python实现区块链

    千次阅读 2020-07-04 11:54:49
    return "区块内容:%s\n哈希值:%s" % (self.transaction, self.hash) 区块链结构: # 区块链结构 class BlockChain: ''' blocks:包含的区块列表 ''' def __init__(self): self.blocks = [] # 添加区块 def add...

    区块结构:

    # 区块结构
    class Block:
        '''
        pre_hash:父区块哈希值
        transaction:交易列表
        timestamp:区块创建时间
        hash:区块哈希值
        nonce:随机值
        '''
    
        def __init__(self, transaction, pre_hash):
            # 将传入的父区块的哈希值和数据保存到类变量中
            self.pre_hash = pre_hash
            self.transaction = transaction
            # 获取当前时间
            self.timetamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
            self.hash = None
            self.nonce = None
    
            # 计算区块的哈希值
            message = hashlib.sha256()
            message.update(str(self.pre_hash).encode('utf-8'))
            message.update(str(self.transaction).encode('utf-8'))
            message.update(str(self.timetamp).encode('utf-8'))
            self.hash = message.hexdigest()
    
        def __repr__(self):
            return "区块内容:%s\n哈希值:%s" % (self.transaction, self.hash)
    

    区块链结构:

    # 区块链结构
    class BlockChain:
        '''
        blocks:包含的区块列表
        '''
    
        def __init__(self):
            self.blocks = []
    
        # 添加区块
        def addBlock(self, block):
            self.blocks.append(block)
    

    交易类:

    在实际的区块链中,数据不是简单的字符串,而是一个个交易记录, 包含交易的发送方、接收方、交易数量以及用来验证交易的发送方公钥和签名,所以定义一个包含这几个字段的交易类。

    class Transaction:
        # 初始化交易
        def __init__(self, sender, recipient, amount):
            if isinstance(sender, bytes):
                sender = sender.decode('utf-8')
            self.sender = sender  # 发送方
            if isinstance(recipient, bytes):
                recipient = recipient.decode('utf-8')
            self.recipient = recipient  # 接收方
            self.amount = amount  # 交易数量
    
        # 验证交易可靠性,需要发送方的公钥和签名
        def setSign(self, signature, pubkey):
            self.signature = signature  # 发送方
            self.pubkey = pubkey  # 公钥
    
        # 交易分为:挖矿所得、转账交易
        # 挖矿所得无发送方,以此进行区分显示不同内容
        def __repr__(self):
            if self.sender:
                s = "从%s转到%s %d 个加密货币" % (self.sender, self.recipient, self.amount)
            else:
                s = "%s挖矿获取 %d 个加密货币" % (self.recipient, self.amount)
            return s
    

    钱包:

    存放账户(一对唯一的公钥和私钥),即钱包的本质是生成和管理密钥对的工具。

    # 钱包
    class Wallet:
        def __init__(self):
            # 基于椭圆曲线生成一个唯一的密钥对,代表区块链上一个唯一的账户
            self.__private_key = SigningKey.generate(curve=SECP256k1)
            self.__public_key = self.__private_key.get_verifying_key()
    
        # 生成签名
        # 通过公钥生成地址(公钥->hash->base64->地址)
        @property
        def address(self):
            h = hashlib.sha256(self.__public_key.to_pem())
            return base64.b64encode(h.digest())
    
        @property
        def pubkey(self):
            # 返回公钥字符串
            return self.__public_key.to_pem()
    
        def sign(self, message):
            # 生成签名(是一串二进制字符串)
            h = hashlib.sha256(message.encode('utf8'))
            # 将二进制字符串转为ASCII进行输出
            return binascii.hexlify(self.__private_key.sign(h.digest()))
    
        # 验证签名是否正确
        def verifySign(self, pubkey, message, signature):
            verifier = VerifyingKey.from_pem(pubkey)
            h = hashlib.sha256(message.encode('utf8'))
            return verifier.verify(binascii.unhexlify(signature), h.digest())
    

    测试钱包的功能:

    # 测试钱包功能
    wallet = Wallet()
    print(wallet.address)  # 钱包地址
    print(wallet.pubkey)  # 钱包公钥
    
    data = "交易数据"
    sg = wallet.sign(data)  # 生成签名
    print(sg)
    
    # 判断签名是否正确
    print(wallet.verifySign(wallet.pubkey, data, sg))

    工作量证明:

    引入共识机制,选择最简单的PoW(工作量证明机制)。其原理是通过不断计算,找到一个随机数(nonce),使得生成的哈希值满足一定条件。

    # 工作量证明
    class ProofOfWork:
        def __init__(self, block, miner, difficult=5):
            self.miner = miner
            self.block = block
            # 工作量难度,默认为5,表示有效的哈希值以5个0开头
            self.difficult = difficult
            # 挖矿奖励,美完成一个区块可获得1个加密数字货币
            self.reward = 1
    
        # 挖矿函数:寻找nonce的值
        def mine(self):
            i = 0
            prefix = '0' * self.difficult
            while True:
                message = hashlib.sha256()
                message.update(str(self.block.pre_hash).encode('utf-8'))
                message.update(str(self.block.transaction).encode('utf-8'))
                message.update(str(self.block.timetamp).encode('utf-8'))
                message.update(str(i).encode('utf-8'))
                digest = message.hexdigest()
                if digest.startswith(prefix):
                    self.block.nonce = i
                    self.block.hash = digest
                    return self.block
                i += 1
    
                # 添加奖励
                t = Transaction(sender="", recipient=self.miner.address, amount=self.reward)
                sig = self.miner.sign(json.dumps(t, cls=Transaction))
                # sig = self.miner.sign(t)
                t.setSign(sig, self.miner.pubkey)
                self.block.transaction.append(t)
    
        # 验证区块有效性
        def validate(self):
            message = hashlib.sha256()
            message.update(str(self.block.pre_hash).encode('utf-8'))
            message.update(str(self.block.transaction).encode('utf-8'))
            message.update(str(self.block.timetamp).encode('utf-8'))
            message.update(str(self.block.nonce).encode('utf-8'))
            digest = message.hexdigest()
    
            prefix = '0' * self.difficult
            return digest.startswith(prefix)
    

    getBalance()函数获取区块链中账户的加密数字货币信息

    # 获取区块链中加密数字货币情况
    def getBalance(user):
        balance = 0
        for block in bc.blocks:
            for t in block.transaction:
                if t.sender == user.address.decode():   # 如果用户是发送方
                    balance -= t.amount
                elif t.recipient == user.address.decode():  # 如果用户是接收方
                    balance += t.amount
        return balance

    测试整个区块链的交易情况:初始化一个区块链和3个钱包,查看钱包余额。

    # 创建一个区块链
    bc = BlockChain()
    
    # 测试交易功能
    a = Wallet()
    b = Wallet()
    c = Wallet()
    
    print("a:%d个加密货币" % (getBalance(a)))
    print("b:%d个加密货币" % (getBalance(b)))
    print("c:%d个加密货币" % (getBalance(c)))
    

    运行结果:余额均为 0

    a:0个加密货币
    b:0个加密货币
    c:0个加密货币

     

    展开全文
  • 3.1 python 实现区块链环境准备 安装 postman 安装 python 创建文件目录 lesson1 安装 pip 命令:pip install pipenv pipenv --python=python 安装 flask 命令 pipenv install flask0.12.2 安装 requests 命令 ...

    3.1 python 实现区块链环境准备

    安装 postman
    安装 python

    创建文件目录 lesson1
    安装 pip
    命令:pip install pipenv
    pipenv --python=python
    安装 flask
    命令 pipenv install flask0.12.2
    安装 requests
    命令 pipenv install requests
    2.18.4

    使用 pycharm 在刚才目录下新建项目
    new project --> 选择目录 --> pipenv --py 查看响应地址

    3.2 创建 blockchain.py

    “”"
    首先创建一个Blockchain类,
    在构造函数中创建了两个列表,一个用于储存区块链,一个用于储存交易。
    “”"

    加入交易

    “”" new_transaction()
    生成新交易信息,信息将加入到下一个待挖的区块中
    :param sender: Address of the Sender
    :param recipient: Address of the Recipient
    :param amount: Amount
    :return: The index of the Block that will hold this transaction
    方法向列表中添加一个交易记录,并返回该记录将被添加到的区块(下一个待挖掘的区块)的索引,
    等下在用户提交交易时会有用。
    “”"

    #创建新块
    当Blockchain实例化后,我们需要构造一个创世块(没有前区块的第一个区块),并且给它加上一个工作量证明。
    每个区块都需要经过工作量证明,俗称挖矿,稍后会继续讲解。
    为了构造创世块 self.new_block(pre_hash=1, proof=100) ,我们还需要完善new_block(), new_transaction() 和hash() 方法
    “”"
    生成新块 new_block()
    :param proof: The proof given by the Proof of Work algorithm
    :param previous_hash: (Optional) Hash of previous Block
    :return: New Block
    “”"

    构造block的json对象

    清空当前交易信息

    把生成的区块加入到链条中

    返回当前块

    “”" hash()
    生成块的 SHA-256 hash值 hashlib.sha256()
    :param block: Block
    :return:
    “”"

    block为json对象,需转换为string,然后编码 json.dumps().encode()

    We must make sure that the Dictionary is Ordered, or we’ll have inconsistent hashes

    工作量证明

    新的区块依赖工作量证明算法(PoW)来构造,PoW的目标是找出一个符合特定条件的数字,这个数字很难计算出来,但容易验证。
    让我们来实现一个相似PoW算法,规则是:寻找一个数 p,使得它与前一个区块的 proof 拼接成的字符串的 Hash 值以 4 个零开头。
    “”"
    简单的工作量证明:

    • 查找一个 p’ 使得 hash(pp’) 以4个0开头
    • p 是上一个块的证明, p’ 是当前的证明
      :param last_proof:
      :return:
      “”"
      “”"
      验证证明: 是否hash(last_proof, proof)以4个0开头?
      :param last_proof: Previous Proof
      :param proof: Current Proof
      :return: True if correct, False if not.
      “”"

    验证工作量证明

    testPOW = BlockChain()

    testPOW.proof_of_work(100)

    代码:

    区块结构

    {

    “index”:0, //索引

    “timestamp”:"",//时间戳

    “transactions”:[//交易信息

    {

    “sender”:"",//交易发送者

    “recipient”:"",//交易接受者

    “amount”:5,//交易的金额

    }

    ],

    “proof”:"",//工作量证明

    “previous_hash”:"",//前区块的hash值

    }

    定义类

    import hashlib
    import json
    from time import time

    from flask import Flask

    class BlockChain:
    # 定义结构函数
    def init(self):
    self.chain = [] # 链
    self.current_transactions = [] # 当前交易信息
    # 创世区块 工作量证明:任意值;上一个区块的hash:任意值
    self.new_block(proof=100, previou_hash=1)

    # 新区块
    def new_block(self, proof, previou_hash=None):
        # 构造block的json对象
        block = {
            "index": len(self.chain) + 1,
            "timestamp": time(),
            "transactions": self.current_transactions,
            "proof": proof,
            "previous_hash": previou_hash or self.hash(self.last_block)
        }
    
        # 清空当前交易信息
        self.current_transactions = []
        # 把生成的区块加入到链条中
        self.chain.append(block)
    
        return block
    
    # 新的交易信息,参数:交易信息三元素。 返回 int
    def new_transaction(self, sender, recipient, amount) -> int:
        # 将交易信息添加到当前交易信息数组中
        self.current_transactions.append(
            {
                "sender": sender,
                "recipient": recipient,
                "amount": amount
            }
        )
        # 返回将来所在区块:上一区块索引+1
        return self.last_block["index"] + 1
    
    # 静态的 计算HASH之后的摘要信息
    @staticmethod
    def hash(block):
        """
        生成块的 SHA-256 hash值
        :param block: <dict> Block
        :return: <str>
        """
        # block为json对象,需转换为string,然后编码
        block_string = json.dumps(block, sort_key=True).encode()
        return hashlib.sha256(block_string).hexdigest()
    
    # 作为属性处理
    @property
    def last_block(self):
        return self.chain(-1)
    
    # 工作量证明
    def proof_of_work(self, last_proof: int) -> int:
        proof = 0
        # 不停的尝试一个值,至到其满足某个条件
        while self.valid_proof(last_proof, proof) is False:
            proof += 1
    
        print(proof)
        return proof
    
    # 条件:上一区块工作量证明和需验证的值进行hash运算
    @staticmethod
    def valid_proof(last_proof: int, proof: int) -> bool:
        # 将两个值拼接后,进行编码
        guess = f'{last_proof}{proof}'.encode()
        # 计算编码后的guess的hash
        guess_hash = hashlib.sha256(guess).hexdigest()
    
        print(guess_hash)
        # 判断hash前四位是否为0
        return guess_hash[0:4] == "0000"
    

    验证工作量证明

    testPOW = BlockChain()

    testPOW.proof_of_work(100)

    3.3 Blockchain作为API接口
    使用Python Flask框架,这是一个轻量Web应用框架,它方便将网络请求映射到 Python函数,现在让Blockchain运行在基于Flask web上。
    创建三个接口:
    /transactions/new 创建一个交易并添加到区块
    /mine 告诉服务器去挖掘新的区块
    /chain 返回整个区块链

    创建节点

    展开全文
  • 手把手教你用Python实现区块链

    千次阅读 2019-01-12 22:06:52
    手把手教你用Python实现区块链极简区块链看图代码框架哈希开始区块检测 本博客适合对区块链概念有所了解的 极简区块链 看图 代码框架 import hashlib //哈希运算库 import datetime class ...

    手把手教你用Python实现区块链


    本博客适合对区块链概念有所了解的


    极简区块链

    看图

    在这里插入图片描述
    在这里插入图片描述

    代码框架

    import hashlib  //哈希运算库
    import datetime
    
    class DingDingBlock():
        def __init__(self, index, timestamp, data, last_hash): //四要素
            self.index = index
            self.timestamp = timestamp
            self.data = data
            self.last_hash = last_hash
            self.hash = self.hash_DingDing()
    
        def hash_DingDing(self):
             pass
        def validate(self):
             pass
    
    def create_first_DingDingBlock()://创世区块
        return DingDingBlock(0, datetime.datetime.now(), "荆轲刺秦王", "0")
    
    def create_DingDingBlock(last_block)://后续区块
       pass
    
    //检测
    

    哈希

        def hash_DingDing(self):
            sha = hashlib.sha256()   
            datastr = str(self.index) + str(self.timestamp) + str(self.data) +str(self.last_hash)
            sha.update(datastr.encode("utf-8"))    
            return sha.hexdigest()
    

    开始

    def create_first_DingDingBlock():
        return DingDingBlock(0, datetime.datetime.now(), "荆轲刺秦王", "0")
    
    def create_DingDingBlock(last_block):
        this_index = last_block.index + 1
        this_timestamp = datetime.datetime.now()
        this_data = "穿山甲说"+str(this_index)
        this_last_hash = last_block.hash
        return DingDingBlock(this_index, this_timestamp,  this_data, this_last_hash)
    
    DingDingBlockChain = [create_first_DingDingBlock()]
    head_block = DingDingBlockChain[0]
     print(head_block.index, head_block.timestamp, head_block.data, head_block.last_hash, head_block.hash)
    for i in range(88):
        DingDingBlock_add = create_DingDingBlock(head_block)
        DingDingBlockChain.append(DingDingBlock_add)
        head_block = DingDingBlock_add
         print(head_block.index, head_block.timestamp, head_block.data, head_block.last_hash, head_block.hash)
    

    输出:
    在这里插入图片描述

    区块检测

    import hashlib
    import datetime
    
    class DingDingBlock():
        def __init__(self, index, timestamp, data, last_hash):
            self.index = index
            self.timestamp = timestamp
            self.data = data
            self.last_hash = last_hash
            self.hash = self.hash_DingDing()
    
        def hash_DingDing(self):
            sha = hashlib.sha256()
            datastr = str(self.index) + str(self.timestamp) + str(self.data) +str(self.last_hash)
            sha.update(datastr.encode("utf-8"))
            return sha.hexdigest()
    
        def validate(self):
            if self.hash != self.hash_DingDing():
                print("**区块{}被修改**\n".format(self.index))
    
    def create_first_DingDingBlock():
        return DingDingBlock(0, datetime.datetime.now(), "荆轲刺秦王", "0")
    
    def create_DingDingBlock(last_block):
        this_index = last_block.index + 1
        this_timestamp = datetime.datetime.now()
        this_data = "穿山甲说"+str(this_index)
        this_last_hash = last_block.hash
        return DingDingBlock(this_index, this_timestamp,  this_data, this_last_hash)
    
    DingDingBlockChain = [create_first_DingDingBlock()]
    head_block = DingDingBlockChain[0]
    # print(head_block.index, head_block.timestamp, head_block.data, head_block.last_hash, head_block.hash)
    for i in range(88):
        DingDingBlock_add = create_DingDingBlock(head_block)
        DingDingBlockChain.append(DingDingBlock_add)
        head_block = DingDingBlock_add
        # print(head_block.index, head_block.timestamp, head_block.data, head_block.last_hash, head_block.hash)
    
    #检测错误
    DingDingBlockChain[10].data = "穿山甲死了"
    
    for i in range(89):
        DingDingBlockChain[i].validate()
    

    结果:
    在这里插入图片描述

    更完善的检测

    DingDingBlockChain[10].data = "穿山甲死了"
    DingDingBlockChain[10].hash =  DingDingBlockChain[10].hash_DingDing()
    
    def validate():
        for i ,block in enumerate(DingDingBlockChain):
            DingDingBlockChain[i].validate()
            if  DingDingBlockChain[i-1].hash_DingDing() != DingDingBlockChain[i].last_hash:
                print("检测出错误区块{}".format(i-1))
    
    if __name__ == "__main__":
        validate()
    

    在这里插入图片描述

    展开全文
  • 20分钟,我用Python实现区块链架构!

    千次阅读 2018-10-21 22:20:56
    文章目录区块链到底多神奇一起动手创建一个极简的区块链为“瘦小的”区块链“增肥”添加POW共识算法开采新的区块测试零基础Python实现区块链架构视频观看地址联系我们 区块链到底多神奇 这是篇技术文,我们会...



    区块链到底多神奇

    这是篇技术文,我们会用Python一步步搭建一个完整的区块链。不过,在此之前,咱们还是先说说你什么你该学习如何从零搭建一个区块链

    我们可以把区块链看做一个公共数据库,其中新数据存储在一个称为区块的容器中,然后被添加到一条不可更改的链上(也就是区块链),同时,链上保存着之前的数据记录。这些数据是比特币或其他加密货币之前的交易信息,被分门别类地添加到链上

    区块链的诞生,引发了以比特币和莱特币为首的加密货币的崛起。由于加密货币的去中心化属性。对于那些本来就不信任银行系统的人来说,简直是带来了新世界。此外,区块链还给分布式计算带来了革新,出现了很多诸如以太坊这样的新平台,也引入了智能合约的概念

    俗话说实践出真知。接下来,我将用不超过50行的 Python 代码创建一个简单的区块链,并给它取了一个名字 SmartCoin。以此帮助大家理解区块链。


    一起动手创建一个极简的区块链

    首先,我们先对区块链进行定义。在区块链中,每个区块上都有一个时间戳,有时还会有一个索引。在SmartCoin中,我们两个都有。同时,为了保证整个区块链的完整性,每一个区块都有一个唯一的哈希值,用于自我标识。比如比特币,每一个区块的哈希值是由区块的索引、时间戳、数据以及前一个区块的哈希,经过加密后得到的。其中,数据可以选取任意值。下面来看看定义区块的代码:

    import hashlib as hasher
    
    class Block:
        def __init__(self, index, timestamp, data, previous_hash):
            self.index = index
            self.timestamp = timestamp
            self.data = data
            self.previous_hash = previous_hash
            self.hash = self.hash_block()
    
      def hash_block(self):
          sha = hasher.sha256()
          sha.update(str(self.index) + 
                          str(self.timestamp) + 
                          str(self.data) + 
                            str(self.previous_hash))
        return sha.hexdigest()
    

    完成了!区块链的基本框架就这样搭建出来了。考虑到我们要做的是「区块链」,因此,我们还需要往链上加区块。我之前提到过,其中每一个区块需要包含链上前一个区块的哈希值。你可能会问,区块链的第一个区块是怎么出现的呢??当然,作为第一个区块(也叫创世区块),自然很特殊。在多数情况下,它是手动地被添加到链上,或者通过独特的逻辑将它添加到链上。

    下面,我们就简单一点,通过创建一个函数,让它返回一个创世区块。这个区块的索引为0,此外,它所包含的数据以及前一个区块的哈希值都是一个任意的值。创建创世区块的函数代码如下:

    import datetime as date
    
    def create_genesis_block():
        # Manually construct ablock with
        # index zero andarbitrary previous hash
        return Block(0, date.datetime.now(), "GenesisBlock", "0")
    

    这样,创世区块已经创建好了,我们还需要一个函数来生成链上更多的区块。该函数将链上前一个区块作为参数,为后面的区块生成数据,并返回具有带有数据的新区块。当生成的新区块包含了前一个区块的哈希值,区块链的完整性就会随着每个区块的增加而增加这样的操作虽然看起来有点复杂,但如果不这么做,其他人就会很容易篡改链上的数据,甚至把整条链都给换了。所以,链上区块的哈希值就充当了密码证明,确保区块一旦被添加到区块链上,就不能被替换或者删除。下面是这个函数的代码:

    def next_block(last_block):
    
        this_index =last_block.index + 1
    
        this_timestamp =date.datetime.now()
    
        this_data = "Hey! I'm block " +str(this_index)
    
        this_hash = last_block.hash
    
        returnBlock(this_index, this_timestamp, this_data, this_hash)
    

    到这里,一个简单的区块链就基本完成了!今天的的例子中我们通过Python列表来创建区块链,其中最重要的部分是创世区块(当然,还需要其他区块)。因为我们要创建的SmartCoin是一个比较简单的区块链,所以我会通过循环的方式,只添加20个新的后续区块。具体实现如下:

    # Create the blockchain and add the genesis block
    
    blockchain = [create_genesis_block()]
    
    previous_block = blockchain[0]
    
    
    # How many blocks should we add to the chain
    
    #after the genesis block
    
    num_of_blocks_to_add= 20
    
    
    # Addblocks to the chain
    
    for iin range(0, num_of_blocks_to_add):
    
       block_to_add= next_block(previous_block)
    
       blockchain.append(block_to_add)
    
       previous_block = block_to_add
    
       # Telleveryone about it!
    
       print "Block #{} has been added to theblockchain!".format(block_to_add.index)
    
       print "Hash:{}\n".format(block_to_add.hash)
    

    上面讲到的区块链是非常简洁的,区块的创造也相对简单。但是如果要使SmartCoin成为一个真正的加密货币,我们需要控制每次产出的区块数量和币的数量。


    为“瘦小的”区块链“增肥”

    SmartCoin上的数据从交易中产生,每个区块上的数据均由一系列交易组成。我们将交易定义为:每笔交易均为一个JSON对象,这个JSON对象包括币的发送者、接受者和交易数量。

    注意:下文我们会谈到为什么交易是以JSON格式保存的。

    {
      "from":"71238uqirbfh894-random-public-key-a-alkjdflakjfewn204ij",
      "to":"93j4ivnqiopvh43-random-public-key-b-qjrgvnoeirbnferinfo",
      "amount": 3
    }
    

    在了解了什么是交易之后,我们需要一个方法,将交易添加到之前的区块链网络节点中(这些节点由普通的电脑组成),为此,我们将创造一个简单的HTTP服务器,便于交易用户将交易信息上报节点。一个节点能够接收一个带有交易信息的POST请求来作为请求主体。这就是为什么交易是JSON格式的原因。我们需要将它们传送到服务器的请求主体中。

    首先需要安装一个网络服务器框架:

    
    from flask import Flask
    from flask import request
    
    node = Flask(__name__)
    
    # Store the transactions that
    
    # this node has in a list
    
    this_nodes_transactions = []
    
    @node.route('/txion',methods=['POST'])
    
    def transaction():
    
        if request.method == 'POST':
    
          # On each new POST request,
    
          # we extract the transaction data
    
          new_txion = request.get_json()
    
          # Then we add the transaction to our list
    
          this_nodes_transactions.append(new_txion)
    
          # Because the transaction was successfully
    
          # submitted, we log it to our console
    
          print "New transaction"
    
          print "FROM:{}".format(new_txion['from'])
    
          print "TO:{}".format(new_txion['to'])
    
          print "AMOUNT:{}\n".format(new_txion['amount'])
    
          # Then we let the client know it worked out
    
          return "Transaction submissionsuccessful\n"
    
    node.run()
    

    这样我们就完成了对用户间互相发送SmartCoin信息的保存。这就是为什么大家将区块链称为公共账本和分布式账本的原因:所有交易存储在网络内的每个节点之中,重要的是,对所有用户是可见的。


    添加POW共识算法

    但是,问题来了,我们从哪里获取SmartCoin呢?(目前)哪儿都不行!实际上SmartCoin是不存在的。我们需要挖掘新的SmartCoin区块把它创造出来,一个新的区块被挖出后,一个SmartCoin就会产生出来,作为奖励给与挖矿者。矿工将SmartCoin转给其他人之后,币就开始流通了。

    我们不希望挖出SmartCoin的过程过于简单,因为会产生太多的SmartCoin,而且会变得越来越不值钱。同时,我们也不希望这个过程特别难,因为这样的话,SmartCoin的数量不足,这会导致币价过高,同时流通缓慢。我们通过工作量证明算法控制挖矿的难度。工作证明算法本质上是生成一种难以创建但易于验证的算法。就像字面意思一样,它就是证明一个节点(计算机)完成了多少工作量。

    在SmartCoin中,我们要创建的是一个简单的PoW算法。要创建一个新的区块,矿工的电脑需要增加一个数字。当该数字可被9(“SmartCoin”中的字母数)和最后一个区块的证明编号整除时,一个新的SmartCoin区块就会被开采出来,矿工也会得到一个SmartCoin作为奖励

    # ...blockchain
    
    # ...Block class definition
    
    miner_address ="q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"
    
    def proof_of_work(last_proof):
    
        # Create a variable that wewill use to find
    
        # our next proof of work
    
        incrementor = last_proof + 1
    
        # Keep incrementing the incrementor until
    
        # it's equal to a number divisible by 9
    
        # and the proof of work of the previous
    
        # block in the chain
    
        while not (incrementor % 9 == 0 andincrementor % last_proof == 0):
    
          incrementor += 1
    
        # Once that number is found,
    
        # we can return it as a proof
    
        # of our work
    
        return incrementor
    
    @node.route('/mine', methods =['GET'])
    
    def mine():
    
        # Get the last proof of work
    
        last_block = blockchain[len(blockchain) - 1]
    
        last_proof = last_block.data['proof-of-work']
    
        # Find the proof of work for
    
        # the current block being mined
    
        # Note: The program will hang here until a new
    
        #      proof of work is found
    
        proof = proof_of_work(last_proof)
    
        # Once we find a valid proof of work,
    
        # we know we can mine a blockso
    
        # we reward the miner by addinga transaction
    
        this_nodes_transactions.append(
    
          { "from":"network", "to": miner_address, "amount": 1 }
    
      )
    
        # Now we can gather the dataneeded
    
        # to create the new block
    
        new_block_data = {
    
          "proof-of-work":proof,
    
          "transactions":list(this_nodes_transactions)
    
        }
    
        new_block_index = last_block.index + 1
    
        new_block_timestamp = this_timestamp =date.datetime.now()
    
        last_block_hash = last_block.hash
    
        # Empty transaction list
    
        this_nodes_transactions[:] = []
    
        # Now create the
    
        # new block!
    
        mined_block = Block(
    
            new_block_index,
    
            new_block_timestamp,
    
            new_block_data,
    
            last_block_hash
    
      )
    
      blockchain.append(mined_block)
    
      # Let the client know we mined a block
    
      return json.dumps({
    
            "index":new_block_index,
    
            "timestamp":str(new_block_timestamp),
    
            "data": new_block_data,
    
            "hash": last_block_hash
    
      }) + "\n"
    

    现在,我们可以控制在一个特定时间段内可开采的区块数量,到这里,我们就可以自由掌握一定时间内多少个区块可以被开发出来了。但是就像前面所说的,这一切操作只是在一个节点上进行的。但区块链应该是去中心的,我们怎么保证这条链在其他节点上也是一样的呢?我们可以让每个节点对外广播自己链的版本,其他节点既可以接收广播,又可以自己对外广播同样的内容。此后,每个节点需要去对其他节点所发出的信息进行验证,验证通过后,网络上的所有节点则可以达成一致。这称为一致性算法。

    在这个例子中,我们所采用的一致性算法相当简单:如果一个节点的链与其他节点的链不同(即有争议时),那么网络上最长的链会保留而较短的链将会被删除,如果所有节点都达成一致,那么则进行下一步:

    @node.route('/blocks',methods=['GET'])
    def get_blocks():
      chain_to_send = blockchain
      # Convert our blocks into dictionaries
      # so we can send them as json objects later
      for block in chain_to_send:
         block_index = str(block.index)
         block_timestamp =str(block.timestamp)
         block_data = str(block.data)
         block_hash = block.hash
         block = {
            "index": block_index,
            "timestamp": block_timestamp,
            "data": block_data,
            "hash": block_hash
        }
      # Send our chain to whomever requested it
      chain_to_send = json.dumps(chain_to_send)
      return chain_to_send
    
    def find_new_chains():
        # Get the blockchains of every
        # other node
        other_chains = []
        for node_url in peer_nodes:
           # Get their chains using a GETrequest
           block = requests.get(node_url +"/blocks").content
           # Convert the JSON object to aPython dictionary
           block = json.loads(block)
           # Add it to our list
           other_chains.append(block)
      return other_chains
    
    def consensus():
       # Get the blocks from other nodes
       other_chains =find_new_chains()
       # If our chain isn't longest,
       # then we store the longest chain
       longest_chain = blockchain
       for chain in other_chains:
          if len(longest_chain) < len(chain):
            longest_chain = chain
      # If the longest chain wasn't ours,
      # then we set our chain to the longest
      blockchain = longest_chain
    

    开采新的区块测试

    在这一步中,我们会运行完整的SmartCoin服务器代码,到这里我们离大功告成就只差一步了。运行完SmartCoin的代码后,在终端里运行以下命令(假设你用的是cURL)。

    1. 创建一个交易
    curl"localhost:5000/txion" \
         -H "Content-Type:application/json" \
         -d '{"from": "akjflw","to":"fjlakdj", "amount": 3}'
    
    1. 开采新的区块
    curl localhost:5000/mine
    
    1. 查看结果。我们通过客户端窗口看这个
    {
    
      "index": 2,
    
      "data": {
    
        "transactions": [
    
          {
    
            "to": "fjlakdj",
    
            "amount": 3,
    
            "from": "akjflw"
    
          },
    
          {
    
            "to":"q3nf394hjg-random-miner-address-34nf3i4nflkn3oi",
    
            "amount": 1,
    
            "from": "network"
    
          }
    
        ],
    
        "proof-of-work": 36
    
      },
    
      "hash": "151edd3ef6af2e7eb8272245cb8ea91b4ecfc3e60af22d8518ef0bba8b4a6b18",
    
      "timestamp": "2017-07-2311:23:10.140996"
    
    }
    

    大功告成! 我们自己创建了一条完整的区块链!现在 SmartCoin可以在多台节点上运行,SmartCoin也可以被开采了。


    零基础Python实现区块链架构视频观看地址

    视频观看地址:https://study.163.com/course/introduction/1005810016.htm

    零基础Python实现区块链架构


    联系我们

    刘虹:华为认证讲师、10余年软件研发及企业培训经验,丰富的企业应用软件开发经验、深厚的软件架构设计理论基础及实践能力. 为华为、中兴、唯品会、思科、诺基亚、深交所、中国银行、华润集团、顺丰速递、香港OOCL、中国国债中心、海南航空等国内外百余家知名企业提供企业培训服务。 项目开发历程: 区块链落地解决方案 (证券、电影),基于大数据技术推荐系统 ,医疗保险大数据分析与统计推断,华润银行公众号二次开发 ,风暴金融H5跨平台APP,携程酒店APP


    技术讨论、商务合作都可以通过下面方式联系我们

    联系我们

    展开全文
  • 3-1 python 实现区块链环境准备   1、HTTP 超文本传输协议——Postman/curl  2、Python——PyCharm 3、工具:pip、pipenv、Flask/requests   3-2 建立项目,确定区块结构   cmd中: C:\Users\Tai Park&...
  • python实现区块链代码

    2018-02-28 17:28:00
    加密算法是python自带的 需要导入hashlib import hashlib as hash sha = hasher.sha256() sha.update('your content') print sha.hexdigest() 输出:baca6a6db216faf43b107e5f00e20eaf22edc75e922de5ccc08c1.....
  • 作者:Boblee,人工智能硕士毕业,擅长及爱好python,基于python研究人工智能、群体智能、区块链等技术,并使用python开发前后端、爬虫等。1、私钥、公钥、地址之间的关系...
  • 1.设置好区块链的对应方法 #一个区块应该包括的内容 # { # 'index':0, #索引 # 'timestamp':"", #时间戳 # 'trascations':[ #交易信息 # {"sender":"", #交易发送者 # recipient":"",#交易接收者 # "amout":""} #...
  • import hashlib import random import string import json import threading from decimal import Decimal from time import time class MyThread(threading.Thread): ... def __init__(self, target, args=()): ...
  • 根据Tiny熊老师《区块链入门与去中心化应用实战》一课整理   思维导图png版:链接:https://pan.baidu.com/s/1VhUyC8MtvLLImP-8vpzdCA 密码:sl6e 思维导图pdf版:链接:...
  • 区块链blockchain_go的python实现
  • Python区块链简单记账本实现

    千次阅读 2018-03-22 14:12:28
    在上一篇《Python之区块链入门》中讲述了区块链的基础知识,并用Python实现了区块和区块链的结构。在本篇中,将基于上面的内容实现一个简单的记账本功能。记账本的功能如下:实现基本的收支记录;计算当前余额;对...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 639
精华内容 255
关键字:

python实现区块链

python 订阅