blockchain - CSDN
精华内容
参与话题
  • 区块链(BlockChain)介绍 | 系列目录

    千次阅读 2018-08-21 11:21:29
    AI、Block Chain、IoT是今天科技圈出现频率最高的三个词,比特币价格的走高和ICO的流行,也将区块链逐步的带向大众视野。关于区块链,大家听到最多的可能是空气币、ICO、去中心化、比特币这些词,区块链的迅速流行跟...

    AI、Block Chain、IoT是今天科技圈出现频率最高的三个词,比特币价格的走高和ICO的流行,也将区块链逐步的带向大众视野。关于区块链,大家听到最多的可能是空气币ICO去中心化比特币这些词,区块链的迅速流行跟财富是有很大关系的,我不懂经济也就不班门弄斧了,这个系列主要从技术的角度来探讨区块链技术。按照圈内的黑话,我们是属于“链圈”的,“币圈”的事情这里就不会涉及。


    我的一个初步设想是想写个区块链技术系列,先介绍区块链的基础原理,再到很火的基于以太坊的智能合约开发,然后再探究Hyperledger的相关技术,穿插着写写区块链技术的最新发现(比如BCH的虫洞技术),最后是相关源代码的阅读。

    暂列大纲如下:

    1. 区块链基础

      • 基础概念介绍
      • 区块链密码学基础
      • 比特币网络和脚本
      • 分布式共识算法介绍
      • 智能合约
      • 挖矿
    2. 基于以太坊的智能合约的开发实战

    3. Hyperleder Fabric学习
    4. 比特币源代码导读系列

    此目录持续更新中!

    展开全文
  • 区块链现在有多火看看比特币的价格也就知道了,不过作为一个有逼格的程序员,我们不应只关注到币的价值(为啥我没去买比特币,T-T),而应该去关注技术的本质,这个号称“第四次工业革命”的区块链技术。...

    区块链现在有多火看看比特币的价格也就知道了,不过作为一个有逼格的程序员,我们不应只关注到币的价值(为啥我没去买比特币,T-T),而应该去关注技术的本质,这个号称“第四次工业革命”的区块链技术。不过很多人估计对这个技术不太了解,包括我自己。既然不懂不如自己动手撸一个,实践出真知。在翻阅文章的时候刚好找到了这篇文章,下面让我们自己动手搭建一个简单的区块链。

    简单的说,区块链就是一个不可变、有序的链(chain)结构,链中保存着称之为块(block)的记录,这些记录可以是交易,文件或是任意你想要的数据。其中重要的是它们通过哈希链接在一起。

    如果你不懂哈希,可以查看一下这里,不过作为开发者应该都懂吧。。。

    准备

    这里我们会以python实现一个区块链,因此需要首先安装python,这里我是用的是python2.7版本,需要安装flask以及Requests库。

    pip install Flask requests
    

    同时还需要一个http客户端,比如postman或curl。

    1、创建区块链

    新建一个blockchain.py文件,我们这里只使用这一个文件。

    区块链表示

    我们首先创建一个Blockchain类,并且在构造函数中创建两个空的list,一个用于储存我们的区块链,另一个用于储存交易。

    Blockchain类的定义如下:

    class Blockchain(object):
        def __init__(self):
            self.chain = []
            self.current_transactions = []
    
        def new_block(self):
            # 创建一个新的块,并添加到链中
            pass
    
        def new_transaction(self):
            # 添加一笔新的交易到transactions中
            pass
    
        @staticmethod
        def hash(block):
            # 对一个块做hash
            pass
    
        @property
        def last_block(self):】
            # 返回链中的最后一个块
            pass
    

    我们的Blockchain类用来管理链,它会存储交易信息,以及一些添加新的块到链中的辅助方法,让我们开始实现这些方法。

    块(Block)长啥样?

    每个块都包含如下属性:索引(index),时间戳(Unix时间),交易列表(transactions),工作量证明(proof,稍后解释)以及前一个块的hash值,下面是一个区块的例子:

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

    现在,链的概念应该很清楚了–每个新的区块都包含了上一个区块的hash值。这很重要,因为它保障了整个区块链的不可变性:如果攻击者毁坏了一个之前的块,那么后续所有的块的hash值都将错误。没有理解?停下来细想一下,这是区块链背后的核心思想

    添加交易到区块

    我们需要一个添加交易到区块的地方,实现一下new_transaction方法:

    class Blockchain(object):
        ...
    
        def new_transaction(self, sender, recipient, amount):
            """
            添加一笔新的交易到transactions中
            :param sender: <str> 发送者地址
            :param recipient: <str> 接收者地址
            :param amount: <int> 数量
            :return: <int> 包含该交易记录的块的索引
            """
    
            self.current_transactions.append({
                'sender': sender,
                'recipient': recipient,
                'amount': amount,
            })
    
            return self.last_block['index'] + 1
    

    在new_transaction方法向列表中添加一个交易记录后,它返回该记录将被添加到的区块的索引–下一个待挖掘的区块。这在后面用户提交交易记录的时候会有用。

    创建一个新的区块

    当我们的Blockchain实例化之后,我们需要为它创建一个创世块(第一个区块,没有前区块,类似于链表的head),并且给该创世块添加一个工作量证明(proof of work),工作量证明是挖矿的结果。我们后面在来讨论挖矿。

    除了在我们的构造函数中创建一个创世块之外,我们也要实现new_block(), new_transaction() 和 hash()方法:

    import hashlib
    import json
    from time import time
    
    class Blockchain(object):
        def __init__(self):
            self.chain = []
            self.current_transactions = []
    
            # 创建创世块
            self.new_block(previous_hash=1, proof=100)
    
        def new_block(self, proof, previous_hash=None):
            """
            创建一个新的块,并添加到链中
            :param proof: <int> 证明
            :param previous_hash: (Optional) <str> 前一个块的hash值
            :return: <dict> 新的区块
            """
    
            block = {
                'index': len(self.chain) + 1,
                'timestamp': time(),
                'transactions': self.current_transactions,
                'proof': proof,
                'previous_hash': previous_hash or self.hash(self.chain[-1]),
            }
    
            # 重置存储交易信息的list
            self.current_transactions = []
    
            self.chain.append(block)
            return block
    
        def new_transaction(self, sender, recipient, amount)):
            """
            添加一笔新的交易到transactions中
            :param sender: <str> 发送者地址
            :param recipient: <str> 接收者地址
            :param amount: <int> 数量
            :return: <int> 包含该交易记录的块的索引
            """
    
            self.current_transactions.append({
                'sender': sender,
                'recipient': recipient,
                'amount': amount,
            })
    
            return self.last_block['index'] + 1
    
        @property
        def last_block(self):
            # 返回链中的最后一个块
            return self.chain[-1]
    
        @staticmethod
        def hash(block):
            """
            创建区块的SHA-256哈希值
            :param block: <dict> Block
            :return: <str>
            """
    
            # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
            block_string = json.dumps(block, sort_keys=True).encode()
            return hashlib.sha256(block_string).hexdigest()
    

    上面的代码应该比较直观,我们差不多完成了区块链的表示了。不过你应该比较好奇新的区块是怎么创建或者挖出来的。

    理解工作量证明(proof of work,pow)

    工作量证明(POW),简单的说就是一份证明,该证明可以用来确认你做过一定量的工作。工作量证明的目标就是找到一个能解决一个问题的数字,这个数字不好找但是很容易证明(该数字就是问题的答案),这就是工作量证明背后的核心思想(俗称挖矿)。

    我们举一个简单的例子,方便理解:

    假设有一个问题,一个整数x乘以整数y,对积做hash,hash值必须以0结尾,即hash(x * y) = ac23dc…0。我们假设X的值为5,求y的值大小?用Python实现如下:

    from hashlib import sha256
    x = 5
    y = 0  # y是未知数
    while sha256(str(x*y).encode()).hexdigest()[-1] != "0":
        y += 1
    print('The solution is y = ' + str(y))
    

    可以看到如下的结果:

    The solution is y = 21
    

    在比特币中使用的工作量证明算法叫做Hashcash,它和我们上面的简单例子相差不大。矿工们为了获得能够创建新的区块权利,需要使用该算法参与计算竞争。通常,问题的难度取决于需要在字符串中查找的字符个数,矿工算出结果后,会获得相应的奖励币。

    tips:比特币网络中任何一个节点,如果想生成一个新的区块并写入区块链,必须能够解出比特币网络给出的工作量证明问题。这道题关键的三个要素是工作量证明函数、区块及难度值。工作量证明函数是这道题的计算方法,区块决定了这道题的输入数据,难度值决定了这道题的所需要的计算量,谁最先解出问题,谁就能生成新的区块并写入区块链。

    工作量证明简单实现

    为我们的区块链实现一个相似的算法,规则跟上述的例子差不多:
    找到一个数字p,该数字与前一个块的proof值的hash值以4个0开头

    import hashlib
    import json
    
    from time import time
    from uuid import uuid4
    
    class Blockchain(object):
        ...
    
        def proof_of_work(self, last_proof):
                """
                简单工作量证明(POW)算法:
                 - 找到一个数字p',使得hash(pp')值的开头包含4个0, p是上一个块的proof,  p'是新的proof
                :param last_proof: <int>
                :return: <int>
                """
    
                proof = 0
                while self.valid_proof(last_proof, proof) is False:
                    proof += 1
    
                return proof
    
            @staticmethod
            def valid_proof(last_proof, proof):
                """
                验证Proof: hash(last_proof, proof)值开头是否包含4个0?
                :param last_proof: <int> 上一个Proof
                :param proof: <int> 当前Proof
                :return: <bool>
                """
    
                guess = (str(last_proof)+str(proof)).encode()
                guess_hash = hashlib.sha256(guess).hexdigest()
                return guess_hash[:4] == "0000"
    

    为了调整算法的难度,我们可以修改需要匹配的0的个数。但4已经足够了,你会发现增加一个数字会大大增加计算的时间。

    我们的Blockchain类差不多完成了,接下来可以开始用http请求进行交互了。

    2、Blockchain作为api

    我们将使用Python Flask框架,这是一个轻量级的Web应用框架,它能方便的将请求映射到 Python函数,这允许我们通过http请求跟区块链进行交互。
    我们会创建3个方法:

    /transactions/new 创建一个新的交易,并添加到区块中
    /mine 告诉服务器服挖掘一个新的块
    /chain 返回整个区块链
    

    设置flask

    我们的服务器会作为区块链网络中的一个节点,让我们添加一下代码:

    import hashlib
    import json
    from textwrap import dedent
    from time import time
    from uuid import uuid4
    
    from flask import Flask
    
    
    class Blockchain(object):
        ...
    
    
    # 实例化我们的节点
    app = Flask(__name__)
    
    # 为这个节点生成一个全局的唯一地址
    node_identifier = str(uuid4()).replace('-', '')
    
    # 实例化区块链
    blockchain = Blockchain()
    
    @app.route('/mine', methods=['GET'])
    def mine():
        return "We'll mine a new Block"
    
    @app.route('/transactions/new', methods=['POST'])
    def new_transaction():
        return "We'll add a new transaction"
    
    @app.route('/chain', methods=['GET'])
    def full_chain():
        response = {
            'chain': blockchain.chain,
            'length': len(blockchain.chain),
        }
        return jsonify(response), 200
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000)
    

    代码相对简单,就不做说明了。

    交易请求

    用户发给服务器的交易请求如下:

    {
     "sender": "my address",
     "recipient": "someone else's address",
     "amount": 5
    }
    

    我们在Blockchain类中已经定义了添加交易的方法,因此接下来的事情比较简单:

    import hashlib
    import json
    from textwrap import dedent
    from time import time
    from uuid import uuid4
    
    from flask import Flask, jsonify, request
    
    ...
    
    @app.route('/transactions/new', methods=['POST'])
    def new_transaction():
        values = request.get_json()
    
        # 检查需要的字段是不是都有
        required = ['sender', 'recipient', 'amount']
        if not all(k in values for k in required):
            return 'Missing values', 400
    
        # 创建一个新的交易
        index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
    
        response = {'message': f'Transaction will be added to Block {index}'}
        return jsonify(response), 200
    

    挖矿

    挖矿是里面的神奇所在,而且很简单,只需要做如下三件事:

    • 计算工作量证明

    • 增加一个交易,授予矿工(自己)一个币

    • 构造新区块并将其添加到链中

      import hashlib
      import json
      from time import time
      from uuid import uuid4
      from flask import Flask, jsonify, request

      @app.route(’/mine’, methods=[‘GET’])
      def mine():
      # 运行工作量证明算法,获取下一个proof
      last_block = blockchain.last_block
      last_proof = last_block[‘proof’]
      proof = blockchain.proof_of_work(last_proof)

       # 由于找到了proof,我们获得一笔奖励
       # 发送者为"0", 表明是该节点挖出来的新币
       blockchain.new_transaction(
           sender="0",
           recipient=node_identifier,
           amount=1,
       )
      
       # 创建新的区块,并添加到链中
       previous_hash = blockchain.hash(last_block)
       block = blockchain.new_block(proof, previous_hash)
      
       response = {
           'message': "New Block Forged",
           'index': block['index'],
           'transactions': block['transactions'],
           'proof': block['proof'],
           'previous_hash': block['previous_hash'],
       }
       return jsonify(response), 200
      

    注意挖出来的新区块的接收者就是我们服务器节点的地址,我们做的大部分工作都只是调用Blockchain类的一些方法。到此,我们可以开始跟我们的区块链交互了。

    3、与我们的区块链交互

    你可以通过cURL或Postman去跟API交互。
    启动服务器:

    $ python blockchain.py
    * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    

    让我们试着通过Get请求http://localhost:5000/mine来挖一个块:

    mine.png

    让我们通过POST请求http://localhost:5000/transactions/new创建一笔新的交易,post body包含交易的结构信息:

    new.png

    我重启服务器然后挖了两个块之后,现在总共有三个块(包含创世块),我们可以通过http://localhost:5000/chain请求获取所有的块信息。

    chain.png

    4、一致性

    我们已经有了一个可以接受交易以及挖矿的基础区块链。但是区块链系统应该是去中心化的,既然区块链是去中心化,我们该如何确保所有的节点都有同样的链呢?这就是一致性问题,如果想要在我们的区块链网络中运行多个节点,我们就需要实现一个一致性算法。

    注册新节点

    在实现一致性算法之前,我们需要找到一种方法让一个节点知道它相邻的节点。我们网络中的每个节点都需要保存一份其它节点的记录信息。因此让我们增加一些接口:

    1、/nodes/register 接收以url表示的新节点列表
    2、/nodes/resolve 实现一致性算法,解决冲突,确保每个节点都有正确的链信息
    

    我们需要修改Blockchain的构造函数,添加一个注册节点的方法:

    ...
    from urlparse import urlparse
    ...
    
    
    class Blockchain(object):
        def __init__(self):
            ...
            self.nodes = set()
            ...
    
        def register_node(self, address):
            """
            添加一个新的节点到节点列表中
            :param address: <str> 节点地址:比如'http://192.168.0.5:5000'
            :return: None
            """
    
            parsed_url = urlparse(address)
            self.nodes.add(parsed_url.netloc)
    

    我们通过set()来储存节点列表,这是一种简单方法让我们避免添加重复节点。

    实现一致性算法

    之前提到,冲突发生在节点之间有不同的链信息。为了解决冲突,我们定义一条规则:最长的、有效的链才是权威的链,换句话说,网络中最长的链才是实际的链。通过这个算法,我们让网络中的所有节点保持一致性。

    ..
    import requests
    
    class Blockchain(object)
        ...
    
        def valid_chain(self, chain):
            """
            确定一个给定的区块链是否有效
            :param chain: <list> 区块链
            :return: <bool> True 有效, False 无效
            """
    
            last_block = chain[0]
            current_index = 1
    
            while current_index < len(chain):
                block = chain[current_index]
                # 检查block的hash值是否正确
                if block['previous_hash'] != self.hash(last_block):
                    return False
    
                # 检查工作量证明是否正确
                if not self.valid_proof(last_block['proof'], block['proof']):
                    return False
    
                last_block = block
                current_index += 1
    
            return True
    
        def resolve_conflicts(self):
            """
            一致性算法,通过将我们的链替换成网络中最长的链来解决冲突
            :return: <bool> True 我们的链被取代, 否则为False
            """
    
            neighbours = self.nodes
            new_chain = None
    
            # 我们只查看比我们链长的节点
            max_length = len(self.chain)
    
            # Grab and verify the chains from all the nodes in our network
            for node in neighbours:
                response = requests.get('http://'+node+'/chain')
    
                if response.status_code == 200:
                    length = response.json()['length']
                    chain = response.json()['chain']
    
                    # 检查该节点的链是否比我们节点的链长,以及该链是否有效
                    if length > max_length and self.valid_chain(chain):
                        max_length = length
                        new_chain = chain
    
            # 如果找到比我们长且有效的链,则替换我们原来的链
            if new_chain:
                self.chain = new_chain
                return True
    
            return False
    

    valid_chain()方法主要负责检查链是否有效,历遍链中的所有块,检查块的hash值以及工作量证明是否正确。
    resolve_conflicts()负责解决冲突,通过历遍附近节点,通过valid_chain方法验证该节点的链是否正确,如果该节点链正确且该链比我们节点的链长度长,则用该链替换我们的链。
    让我们添加两个方法,一个用来注册附近节点,一个用来解决冲突:

    @app.route('/nodes/register', methods=['POST'])
    def register_nodes():
        values = request.get_json()
    
        nodes = values.get('nodes')
        if nodes is None:
            return "Error: Please supply a valid list of nodes", 400
    
        for node in nodes:
            blockchain.register_node(node)
    
        response = {
            'message': 'New nodes have been added',
            'total_nodes': list(blockchain.nodes),
        }
        return jsonify(response), 201
    
    
    @app.route('/nodes/resolve', methods=['GET'])
    def consensus():
        replaced = blockchain.resolve_conflicts()
    
        if replaced:
            response = {
                'message': 'Our chain was replaced',
                'new_chain': blockchain.chain
            }
        else:
            response = {
                'message': 'Our chain is authoritative',
                'chain': blockchain.chain
            }
    
        return jsonify(response), 200
    

    你可以在不同的机器上运行节点,这里我们在一台机器上启动不同端口来代表不同的节点。假设我们有两个节点:
    http://localhost:5000http://localhost:5001

    运行两个节点,并将第二节点注册到第一个节点中:

    register.png

    然后在第二个节点(5001端口)挖了一些块,确保该节点的链长度比第一个节点长。然后在第一个节点调用GET /nodes/resolve请求,可以看到节点1的链通过一致性算法被替换掉了。
    在这里插入图片描述

    嗯。。现在可以邀请你的朋友来测试你的区块链了。可以到这里查看 Blockchain.py

    参考:
    工作量证明

    展开全文
  • 谈谈目前我对区块链(Blockchain)的认识

    万次阅读 热门讨论 2016-11-27 21:16:31
    从 IBM Bluemix 云平台的过程中,发现了 Blockchain 这个服务,我才知道有这样一种强大火热的技术存在;只前只是知道有比特币,还申请过一个账户也想去挖矿,但后来也是不了了之了,并没有去研究过它背后的技术。前...

    从 IBM Bluemix 云平台的过程中,发现了 Blockchain 这个服务,我才知道有这样一种强大火热的技术存在;只前只是知道有比特币,还申请过一个账户也想去挖矿,但后来也是不了了之了,并没有去研究过它背后的技术。前些天看到“关于区块链,你在畅想它,还是开启它?”的话题,根据自己的了解发了一下自己的一点不成熟的看法。为了更深入的了解它,昨天又去参加了“区块链技术与互联网金融的创新和挑战 ”的线下活动,现场聆听了朱志文,李赫,汪波等老师的分享,收获很多。

    比特币

    想了解区块链,就不能不了解比特币。比特币是区块链技术的第一个实际应用,正是因为它在比特币应用上的成功,才让越来越的多人关注它。

    2008年底,比特币之父中本聪发表了一个关于他研究的电子现金系统的九页白皮书,2009年初,中本聪在位于芬兰赫尔辛基的一个小型服务器上挖出了比特币的第一个区块——创世区块,并将当天泰晤士报头版一则关于救助银行的新闻标题写入创世区块,这也代表着比特币诞生了。

    最早的区块链开发便是基于比特币的区块链网络进行开发了,由于比特币是全球最广泛使用和真正意义的去中心化,就区块链应用来说,比特币就是世上最强大的锚,拥有最大的权威性。因此,围绕比特币的各种区块链技术非常多。

    以太坊

    可以说除了比特币外,以太坊目前在区块链平台是最吸引眼球的。 以太坊是一个图灵完备的区块链一站式开发平台,采用多种编程语言实现协议,采用Go语言写的客户端作为默认客户端(即与以太坊网络交互的方法, 支持其他多种语言的客户端)。

    IBM HyperLedger

    IBM HyperLedger 又叫 fabric,他的目标是打造成一个由全社会来共同维护的一个超级账本,fabric源于IBM,初衷为了服务于工业生产,IBM将44,000行代码开源,是了不起的贡献,让我们可以有机会如此近的去探究区别于比特币的区块链的原理。目前就Elwin所知,fabric还未进入真正的商用阶段,更多是试验和探索,不过相对于很多其他区块链,从技术底蘊他又是比较可信和靠谱的。

    IBM Bluemix 云平台上提供的云服务 Blockchain 就是建立在Linux Foundations的Hyperledger Project开源代码之上。


    区块链是什么?

    定义:区块链是一个分布式账本,一种通过去中心化、去信任的方式集体维护一个可靠数据库的技术方案。

    区块链(Blockchain)是指通过去中心化和去信任的方式集体维护一个可靠数据库的技术方案。

    区块链是比特币的底层技术,它可以理解为一种公共记账的机制(技术方案),它并不是一款具体的产品。其基本思想是:通过建立一组互联网上的公共账本,由网络中所有的用户共同在账本上记账与核账,来保证信息的真实性和不可篡改性。而之所以名字叫做“区块”链,顾名思义,是因为区块链存储数据的结构是由网络上一个个“存储区块”组成一根链条,每个区块中包含了一定时间内网络中全部的信息交流数据。随着时间推移,这条链会不断增长。

    比较形象的描述见下图:


    虽然说现在的银行可能基于中心服务器的部署,但也肯定在很多地方很多节点上做了备份;

    区块链的特点是每一个节点都保存完整的备份。

    区块链分为公有链,私有链,联盟链

    • 私有链:封闭生态的存储网络,所有节点都是可信任的,如某大型集团内部多数公司。
    • 行业链:半封闭生态的交易网络,存在对等的不信任节点,如房地产行业A、B、C、D公司。
    • 公有链:开放生态的交易网络,这层主要是为行业链和私有链提供全球交易网络。

    区块链技术非用不可么?


    区块链是万能的吗?

    虽然区块链保证了数据的不可篡改,但是对于人录入的一些信息的真实性它是无法验证的。

    在防止信息的泄漏方面,引入的黑盒的机制,但具体怎么样,有待进一步了解。

    最适合的应用场景是金额,但目前大家也都是在探索阶段,很少有进入实际应用阶段,国家也是对它保持着高度的关注。


    可以使用什么语言开发呢?

    个人觉得区块链只是一套方案实现的机制,并不局限于编程语言。

    你可以使用:Solidity,Go,Java,c++,Python,PHP,自定义语言来开发它。

    当然,如果你是基于现有的开源项目开发的话,就有一定的限制了。

    结束语

    区块链发展的时间还比较短,但它的火热程度从我昨天去参加活动的感觉来说却非同一般。

    国家对它保持着高度的关注,各大保险公司、银行等金额业都对它进行研究、学习、试水。

    但它也存在着一些问题需要去探索,去解决。如:性能,51%攻击,“双花”问题。

    不是任何场景都适合使用区块链。

    但在某些场景,我相信它会带来非常好的前景,更好的解决目前面临的困境。

    相关参考:

    区块链技术到底是什么鬼,为何被疯炒?

    掰一掰区块链共识机制与分布式一致性算法

    区块链应用开发入门

    区块链技术与互联网金融的创新和挑战 ”的线下活动PPT下载

    “区块链”究竟是什么鬼

    ===========文档信息============ 
    版权声明:非商用自由转载-保持署名-注明出处 
    署名(BY) :testcs_dn(微wx笑) 
    文章出处:[无知人生,记录点滴](http://blog.csdn.net/testcs_dn)

    展开全文
  • Blockchain区块链的通俗解释

    千次阅读 2016-12-26 10:34:45
    以交易为例,逐步理解blockchain 本文基本复制于简书(简书中提到的英文原文是googleweb工程师写的,需要翻墙,请恕我才疏学浅,英文原文中关于不对称加密的描述我没有理解透彻,感觉该工程师的逻辑有点乱。如果今后...

    以交易为例,逐步理解blockchain

    本文基本复制于简书(简书:“白羊Jerry”提到的英文原文是googleweb工程师写的,需要翻墙,请恕我才疏学浅,英文原文中关于不对称加密的描述我没有理解透彻,感觉该工程师的逻辑有点乱。如果今后你有看到关于鲍勃和爱丽丝的例子,那很可能出自这篇文章。。。幸好简书的译文很通俗易懂。为尊重作者,白羊Jerry的原文地址:http://www.jianshu.com/p/64469b2abea6?mType=Group)

     

    区块链的概念首次在2008年末由中本聪(SatoshiNakamoto)发表在比特币论坛中的论文《Bitcoin:A Peer-to-Peer Electronic Cash System》提出。论文中区块链技术是构建比特币数据结构与交易信息加密传输的基础技术,该技术实现了比特币的挖矿与交易。中本聪认为:第一,借助第三方机构来处理信息的模式拥有点与点之间缺乏信任的内生弱点,商家为了提防自己的客户,会向客户索取完全不必要的信息,但仍然不能避免一定的欺诈行为;第二,中介机构的存在,增加了交易成本,限制了实际可行的最小交易规模;第三,数字签名本身能够解决电子货币身份问题,如果还需要第三方支持才能防止双重消费,则系统将失去价值。基于以上三点现存的问题,中本聪在区块链技术的基础上,创建了比特币。


    基于第三方认证的交易系统

    假设小A(卖)和小B(买)是朋友,也可以不是朋友。有一天,小B准备花100元买小A的游戏机。为了记录本次交易,他们要记账。

    于是找来小C作为第三方见证人,签署了一个合同:

    小B花100元买小A的游戏机 2016.12.21 签字:小A 小B 见证人:小C

    一式三份,人手一张,基于这份合同:

    1.      小A,小B,或第三方都无法否认合同的存在,因为这里有小C的一份存根

    2.      如果一个合同在小C这里没有存根,那么对于本次交易来说一定是伪造的

    如果小C撕毁了合同,或者不承认,小A完全可以说,游戏机是借给小B玩的,还要收回的。这就对小B造成了欺诈(小B花了100元却没有买到游戏机)。第三方的信用在这个体系中扮演重要角色,小C的信用一定要很好才可以。

     

    基于加密认证的交易记录

    过了不久,小A和小C结婚了!两人都否认这个交易没有发生,小B手头的合同是假的。小B交还了游戏机,白白浪费了100元。但小B特别想要这个游戏机,于是他不要找别人做见证了,找了一个新的交易认证方式,公钥加密算法(不要纠结算法细节,先肤浅地了解一下blockchain吧):

    公钥加密算法,又称为不对称加密。指的是加密时需要用到一对密钥,公钥和私钥。用私钥加密的内容,可以用公钥很轻松的解开,但是想要加密出同样的内容,不知道私钥几乎是不可行。

    接着,小B又来用100元买小A的游戏机了:

    1.      双方约定各自持有一对密钥

    2.      小A、小B互相告知了自己的公钥,用于解密对方的私钥

    3.      小B花100元买小A的游戏机

    4.      小A写收据,记录本次交易。然后用自己的私钥加密,发送给小B

    现在这段内容就成了合同,如果这段合同用小A的公钥解密之后,是一段合法的合同(别人的公钥解密后可能存在乱码等不合法的地方),那么一定是小A签发的。除非小A口头上不承认。。。(这样很可能会被暴打一顿)

    双方不断买卖游戏机,产生了很多记录,有的小A签发的,有的是小B签发的。总之按顺序走一遍交易记录,就知道各自手上的游戏机和资金数量。

    他们的交易链看起来是酱紫的:

    1.      小B花100元买小A的游戏机,时间:xxxx

    2.      小A花100元买小B的游戏机,时间:xxxx

    3.      小B花100元买小A的游戏机,时间:xxxx

    4.      小B又花100元买小A的游戏机,时间:xxxx

    5.      ….

    用两人的公钥解密以上收据,就知道每条收据是谁签发的了。由于小A和小B的公钥是公开的,任何人都可以计算出他俩的账户余额,也不需要第三方证明数据真伪了。

     

    多方交易&认证机制

    接下来,小C也加入到交易中来。他也准备用这个方法做交易认证。假设,现在的状态是,小B花100元买了小A的游戏机。交易过程如下:

    1.      小B花100元买小A的游戏机,时间xxxx

    表示目前小B账面上有游戏机,小A账面上有100元。

    因为小C也加入了交易,他拿到一份当前交易记录链的拷贝。这时候,小A找到小C说:“之前我把游戏机100元卖给小B了,现在我花100元买你的游戏机。你要是还想用游戏机,就用这100元去找小B买吧。”交易链变成了:

    1.      小B花100元买小A的游戏机,时间xxxx

    2.      小A花100元买小C的游戏机,时间xxxx

    趁小B和小C还没沟通,小A立刻找到小B说:“我把100元还给你,你把游戏机还给我吧。”小B说,行啊。(实际上小A账目上只有游戏机,没有100元,但是在小B看来,小A有100元。于是小B写了收据,标明小A账目划去100元,加入游戏机,小B账目加入100元,划去游戏机。小B的游戏机就给了小A了。)于是交易记录变成了:

    1.      小B花100元买小A的游戏机,时间xxxx

    2.      小A花100元买小B的游戏机,时间xxxx

    当小C来找小B兑换游戏机时,才发现小A账目上并没有更多的100元买小B的游戏机了。小B损失了游戏机,账目上也没有被划入100元。而这时,小A已经跑了。

    虽然数据记录都是由本人签发,但是由于账单的不统一,仍然给了小A钻空子的机会。这个问题怎么解决呢?

    最简单的办法,每次更新账单的时候,要求所有人都在场,这样所有人都会同步更新账单了。但是,这样太麻烦了,有没有更好的方案?

     

    分布式共识网络机制

    如果我们想把这套机制用全球邮票交易上,那么每次交易都需要所有人在场是不可能的。

    我们需要一个系统,让全世界的人,不管地理和时区差异,都能够利用非对称加密在不需要第三方认证的情况下可靠交易。计算机网络可以解决地理和时区差异,剩下的问题,就是如何保证全网的账单一致性。一个方案是采用一个中心数据库记录所有交易,这样刚才的例子中,小A在向小C买了游戏机后,再找小B时,小B对照中心数据库,就会说:“你已经把我买游戏机的100元转到小C账户下了,你已经没有100元买我的游戏机了。”

    但是这个中心数据库不就又是一个第三方了吗,如果数据库被攻击或者管理员恶意修改怎么办?

    为了去中心化,需要一个P2P网络,也就是节点之间的地位是平等的,每个节点都可以存储一份全局账单。现在问题是如何保证各个节点之间账单的一致性。研究表明,P2P网络能保证一个“弱一致性”,于是我们的需求稍微退一步,就变成了:

    1.      会有部分节点的账单暂时与全网账单不同步

    2.      整个系统最终会统一到一个账单下来

    3.      当出现账单冲突时(像刚才的例子,小A分别和小B、小C各做了一份账单),最后会按照一个可预计的方式解决(比如时间在前面的才有效)

    4.      系统必须可以低于Sybil攻击

     

    防御Sybil攻击

    在分布式系统中取得一致性的方法,本质都是“少数副总多数的投票制”,大部分节点认为正确的当前账单就是最后的合法唯一账单。这个环节会有很多问题,哪些人可以参与投票?每个人投票的权重一样吗?

    假设所有人都可以投票的话,按照之前的机制,只需要一对密钥就可以试图修改那个全局账单了,如果某一个恶意参与者通过程序伪造大量密钥对,试图达到大多数然后修改账单呢?这就是Sybil攻击。

    就好像淘宝交易刷单一样,通过程序,大量伪造的客户可以下很多假单,然后刷信誉,怎么办?有一个办法,就是让刷单的行为变得“昂贵”,例如每次下单,淘宝要收一块钱交易费,这样刷一万个信誉是要付出一万元的成本的。

     

    工作量证明机制

    在这个P2P交易网络里,任何人都可以很容易生成一对密钥参与到交易中,但提交交易记录成了一个很难的事情,它需要消耗大量的计算力。这又是怎么回事?

    我们前面提到,要提交一段交易,参与者只需要用自己的私钥签署内容发到网上就可以了。现在不是这样了我们要求内容里必须包含一些签发者目前所知的全网账单的摘要信息,另外,加密后的内容里,必须前N位是0.为了达到这个目标,消息内容里有一个填充字段,加密者必须不断地试着用各种填充值去试验,使得最后加密的结果前N位是0.现在常用的加密算法是SHA-256,具有相当的随机性,也就是说,内容发生了一点点变化,加密结果都会大相径庭,没有规律可循,参与者只能不停地去尝试直到成功为止。

    这个机制的结果导致加密一个交易记录是一个非常费时间的工作,但是认证消息仍然非常简单,首先查看加密内容前N位是不是0,然后用签发者的公钥解开就可以看到内容了。

    这个机制如何确保全网账单的一致性?只是大家提交记录变得费劲了而已,那如何识别出哪些是伪造的记录呢?

     

    建立区块链

    在区块链网络中有很多地位相同的节点,每个节点都有自己维护的当前账单,最终以大多数人持有的账单作为全网一致性的账单。那么区块链技术是怎么保证全网账单会收敛到一个统一的账单上的呢?

    首先我们来了解一下区块链账单的数据结构到底是是什么样子。为了防止Sybil攻击,区块链中每个交易记录都要花很多计算力才能生成,普通交易者没有足够的计算能力,只能将账单内容签名后,发送到网络中,寻求别人的帮助,这时候,著名的“矿工”登场了。

    矿工一般是有足够计算能力的节点,他们会收集很多条交易记录装在一起,然后用矿工自己的密钥,尝试各种填充位进行加密,直到符合前述的数据要求,然后就立刻向全网广播这个block,让其他节点知道一个新的block产生了。每个block里除了包含收集到的交易数据之外,还要带上这个block基于的上一个block的ID,这样所有的block组成一个blockchain,就是全网账单,这也就是“区块链”这个名字的由来。

    那么矿工消耗成本区计算block是为了什么?

    其实很简单,每一个交易者发出交易请求时,需要指定一定的交易费,矿工在组装完交易记录后,还会增加一个新的交易记录到block里,声明该block里的所有交易费归自己所有。在比特币的协议中有一个巨大的比特币池,每一个block的第一条记录还可以声明从这个池中划出固定量的比特币归该矿工所有,这些利益是矿工的动力来源。

    接下来,再看看之前描述的场景:

    1.      小A和小C完成了一个交易,小A花100元买了小C的游戏机。小A账户扣除100元、加入游戏机。小C账户加入100元、扣除游戏机。

    2.      趁着小B和小C没有沟通,小A又找到小B,要用100元换回游戏机。

    为了说明整个系统的运作流程,假设小B同意了。小B要求小A先向全网发出一条用小A的密钥签名的交易记录,内容是“小A用账目下的100元买小B的游戏机,时间xxxx”。于是小A向交易网络里发出交易记录,指定交易费,请求别人帮忙将其挂载到全局账单上。

    网络上的矿工收集到交易记录(包括该条),并开始打包这些交易记录成block,将该记录附加在他们所认为的最新的系统账单末尾,然后向全网广播这条新block的产生。

    这里有好几种情况:

    1.      这个人的系统账单是最新的,也就是,他所知道的全局账单里,已经包含了小A和小C的交易记录。

    小B收到新的block,组成blockchain,计算之后发现小A并没有100元,他已经用100元买了小C的游戏机。

    2.      这个人的系统账单不是最新的,他不知道小A买了小B的游戏机。他将小A与小B的交易记录加在新block里,然后添加到他所知道的全网账单链里,然后广播出去。

    现在网络里的全网账单出现分叉了。假设在小A和小C的交易之前,全网账单链为b1, b2,…bi, 收到小C广播的交易记录和之后小B的交易记录的人,往下构造的账单是b1,b2, …bi, bz, bh. 而没有收到小C记录的人,构造的账单是b1,b2, … bi, bh(漏掉了bz)

    3.      这个人的账单是最新的,他构造了一个blockA,发到全网,与此同时,另外一个人持有的账单也是最新的,他也构造了一个blockB发到全网。哪一个block才会被承认?注意,因为AB两个block里都有一条声明交易费的记录,所以只有最后承认的block的生成者才能获得这个交易费用。

    这里有好几个问题,先来澄清一下全网账单挂载的方式。

     

    竞争机制

    1.      任何人都可以在全网帮别人确认交易,这也就是类似比特币的矿工,通过帮人计算确认交易,获得交易费用。

    2.      个体之间没有互相协调机制,每个人算出一个block之后都要立刻发送给他所知道的其他参与者,而其他参与者收到block时,首先用block里附带的公钥检验内容是否正确,如果正确,将该block加到他们的账单里,然后通知全网。

    3.      如果收到block的人正在生成block,他们只能放弃当前工作,将收到的block挂到自己的全网账单里,并且重新生成新的block(记得前面我们提到过,block的内容里包括它基于的上一个block,现在最新的block已经被收到的block替换了,所以得重新根据最新的block再次去计算填充值,直到加密结果符合要求—前面有N个0)。

    这个时候有人要问了,我干嘛要丢弃我自己算了半天的成果,我不能无视新收到的block吗?

    另外,如果两个人同时发给我block怎么办?

    甚至有人发给我他以为正确其实错误的block怎么办?

     

    解决blockchain冲突

    解决方案很简单:哪个blockchain最长就用哪个。如果节点收到多个block,并且他们的blockchain长度是一样的,就需要同时保存这几个blockchain,在多个chain上同时工作,并且不断地监听新的block消息,添加到对应的chain上,知道最后它知道哪个更长,就立刻转到该chain上工作,其他的被废弃掉。

    这里就涉及到一个概念,每个节点目前维护的blockchain,可能是错的!也许过了一段时间,它会看到一个更长的chain,那时候它才知道它需要换到哪个chain上了。

    是不是有点不靠谱?每个节点维护自己的chain,互相广播新的block,感觉会是一团乱啊?但是根据推算,这个链会较快的收敛到一个结果上来。所有节点不停的废弃链和在链尾添加新的block,但是链身总会稳定的收敛到一个一致性的结果。。。。哲学家应该懂。。。

    于是在前面的例子中,小A发出交易,小B开始监听新来的block,首先小B要找到包含该交易记录的block,然后为了保险起见,他会继续坚挺block,直到发现有好几个block链接在那一条block之后(一般来说,后面接上5个block就基本稳定了)也就是说,该block被全网节点接受了,小B可以开始真正算算自己和小A的账单了。

    1.      如果矿工拿到的chain不是最新的,漏掉了小A和小C的交易,小B监听到小A发出的block后,又继续听了后面的block,跟收到的其他矿工发出的block一比就发现这个chain比较短,该链就被放弃了,那么小A也没法忽悠小B了,以为他账目上并没有100元。同样,因为被废弃了,该矿工声明的交易费也拿不到了。

    2.      矿工P和矿工Q都发出了正确的block,这个时候就要看谁的更快被多数节点接受了,这也就是为什么比特币挖矿这么费机器的原因,算得越快,越容易被接受,也就能得到更多比特币。

    3.      无视别人发来的block的人,很明显他们的block生产速度慢于别人,如果不立即转到新的block上,只会导致自己剩下的全部都是无用功。请与时俱进!

    这个时候,小A还可以耍诡计,钻漏洞。他可以在和小C的交易记录的block(设为blockP)被接受后,也就是很多个block挂载到该block之后,构造一个假的block链接在blockP之前的block后,并且不停的构造block使得这个假chain的长度超过目前全局链的长度。这样他的chain就是公认的了,并且没有他跟小C的交易记录。这个方案可行,但是全网里其他人一收到小A最早的交易信息后就开始往下扩充了,小A要欺骗他们换到自己的假chain上来,就需要比他们算的都快,快到什么程度呢?目前数学给出的答案是,要能战胜全网50%的计算力才行。一旦P2P网络到了成千上万个节点的时候,想达到这个计算力是不可能的,这也是比特币自称去中心化的基础。

     

    结尾

    刚刚这个交易网络,其实就是blockchain的原型。它的价值不仅仅是比特币这个产物,话句话说,如果我们在每个block里存储的内容不是transaction,而是别的东西呢?它就演化成了一个分布式的,无法被伪造的存储系统,特别是,在blockchain上演出的新功能“智能合约”,就将合约的执行融合到了分布式网络中,比如,小A和小B打赌,如果明天是晴天,小A就给小B100元。于是小A和小B认定了一个权威的天气机构,生成了一个交易信息放到blockchain里,不过该交易是有条件的,等到第二天,是晴天,该权威机构就用自己的私钥签发一个晴天的消息到blockchain里,网络里无数的确认者就用该天气机构的公钥确认了晴天的消息后,执行了小A向小B的转账,并且将该block提交到网络中。这个过程完全不可逆,不可伪造。

    这样就是为什么很多银行和金融机构开始对blockchain感兴趣的原因。在这个机制下,很多交易的中间环节可以被省掉,极大节省了金融体系运作的成本。

    展开全文
  • 今天我想介绍区块链如何运作的基本知识,以及它如何以安全的方式追踪资金。 我将介绍UTXO模型,比特币和Qtum使用它。... 首先我想给出一些定义,以免你对比特币一无所知。 单向散列(或简称“散列”) - 一种将数字数量...
  • BTCTRADE.IM正式上线USC充值业务

    千次阅读 2017-11-25 13:37:31
    ​ 11月24日,数字交易货币服务平台BTCTRADE.IM正式上线USC充值业务,并同步开放BCD/USC交易。...BTCTRADE.IM相关负责人表示,之所以选择USC作为平台的平稳数字货币,是因为USC的发行将严格按照1USC=1USD的...
  • blockchain

    2020-07-30 23:30:14
    python开发简单的区块链集群 区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法。
  • Blockchain

    2017-12-22 17:31:48
    notes
  • BlockChain

    2017-06-11 13:28:40
    "最近在一级市场互联网金融领域有一种黑技术特别的火,那就是区块链(BlockChain)。这是比特币(BitCoin)技术中的核心部分,其功能简单而言类似于一种账本,记录所有的交易数据。" 根据知乎上的“标准答案”,这...
  • Blockchain for Cloud

    2020-07-09 14:25:02
    A Software Defined Fog Node Based Distributed Blockchain Cloud Architecture for IoT(解决了什么问题) Background: 由于其视野和资源的有限性,一个fog节点无法为用户提供永久的、全面的计算服务[7]。因此,...
  • Blockchain is a decentralized ledger that maintains a continuously growing list of data records secured from tampering and revision. Every user is allowed to connect to the network, send new ...
  • The Science of the Blockchain,区块链核心算法分析...............................................................................................................................
  • Beginning Blockchain

    2020-03-10 23:33:46
    Beginning Blockchain is a book for those willing to learn about the technical fundamentals of Blockchain, practical implications, and hands- on development aspects of Blockchain applications. ...
  • 区块链中Blockchain

    千次阅读 2016-10-09 19:42:28
    Blockchain 也叫区块链,可以认为它是 HashTree(散列树)的一种,也正因如此它有着一些和 HashTree 相同的性质: 图片来自 http://happypeter.github.io/bitcoin_basics/book/017_merkle_tree.html 即...
  • BlockChain白皮书

    2020-07-15 23:31:02
    区块链白皮书,第二版版本,详细介绍了区块链方面的知识,对于初学者很有用
  • In 25 concise steps, you will learn the basics of blockchain technology. No mathematical formulas, program code, or computer science jargon are used. No previous knowledge in computer science, ...
  • 一、blockchain的数据结构 type BlockChain struct { chainConfig *params.ChainConfig // 初始化配置 cacheConfig *CacheConfig // 缓存配置 db ethdb.Database // 底层的数据储存 triegc *prque.Prque ...
  • Bitcoin is starting to come into its own as a digital currency, but the blockchain technology behind it could prove to be much more significant. This book takes you beyond the currency ("Blockchain ...
  • 以太坊源码分析(19)core-blockchain分析

    千次阅读 2018-05-14 08:51:44
    从测试案例来看,blockchain的主要功能点有下面几点.1. import.2. GetLastBlock的功能.3. 如果有多条区块链,可以选取其中难度最大的一条作为规范的区块链.4. BadHashes 可以手工禁止接受一些区块的hash值.在blocks.go...
  • 本次公开课将从开源项目Hyperledger Fabric基础概念开始,逐步介绍企业级区块链的特点和功能,并使用IBM Blockchain Platform作为媒介,展示如何快速搭建一个联盟链网络,并部署简单的应用。
1 2 3 4 5 ... 20
收藏数 20,967
精华内容 8,386
热门标签
关键字:

blockchain