点击围观!腾讯 TAPD 助力金融行业研发提效、敏捷转型最佳实践! 了解详情
写点什么

使用 Python 实现一个“智能区块链”

  • 2020-12-03
  • 本文字数:12406 字

    阅读完需:约 41 分钟

使用Python实现一个“智能区块链”

本文最初发布于 Medium 网站,经原作者授权由 InfoQ 中文站翻译并分享。

前言


在本文中,我们将使用 Python 语言实现一个简单朴素的“智能区块链”,并和一个区块链做对比。我们希望通过这种方式,帮助开发人员和区块链社区更清楚地了解并接纳这种技术的主要概念和优势。常见的“智能区块链”网络中有一个区块生产者智能合约(BPSC)。为了在网络中成功交易,发送者必须先将加密货币转移到(BPSC)钱包,然后(BPSC)立即将相同的加密货币自动发送到最终接收者的钱包。这个看似简单的任务可以准确地保存(BPSC)智能合约中所有成功交易的数据,并确保数据不受篡改。本文由 Somayeh Gholami 和 Mehran Kazeminia 于 2020 年 4 月撰写。


开始之前的准备工作


如果你不熟悉“智能区块链”,并且还没有阅读过我们以前写的关于这种技术的文章,那么可以在下面这篇文章中大致了解一下。本文的实现过程中也会给出必要的解释。


https://hackernoon.com/what-is-smart-blockchain-4b134275e90f


我们假设读者熟悉 Python 语言并理解区块链、哈希等技术概念。因此为了简化篇幅,我们将重点放在了“智能区块链”的特性上。当然,如果你忘记了一些区块链的概念,则可以参考以下文章。在这篇文章中,作者使用 Python 实现了一个完整的区块链。我们还使用他的想法和代码来实现了“智能区块链”,这样就能方便地对比“智能区块链”和区块链了。


https://hackernoon.com/learn-blockchains-by-building-one-117428612f46


我们的 Python 版本是 Python 3.7,使用 Spyder-Anaconda3 作为 IDE。你可以使用自己喜欢的 IDE,例如 PyCharm 等。当然,Jupyter Notebook 之类并不适合这一用例。我们还将使用 Postman,但你也可以使用 cURL


通过编程了解“智能区块链”的功能


首先,我们来创建一个名为 Smart_Blockchain 的类。这个类的构造方法现在会创建两个空列表,一个用于存储交易(transaction),另一个用于存储区块(block)的链。在这个类的构造方法中,我们还编写了用于创建初始的创世块(genesis block)的代码。现在我们需要完成以下四种方法:


new_block、new_transaction、last_block、hash


但是,“智能区块链”中没有共识问题,也没有工作量证明(POW)机制或权益证明(POS)机制之类的东西。换句话说,没必要像比特币和以太坊网络那样生成单一区块的几个替代方案,让矿工花费数十亿美元和惊人的功耗来选择有效且正确的区块。以下代码就是根据这些特性来编写的。


import hashlibimport jsonfrom time import timeclass Smart_Blockchain:    def __init__(self):        self.current_transactions = []        self.chain = []        # Create the genesis block        self.new_block(previous_hash='1')    def new_block(self, previous_hash):        """        Create a new Block in the Smart Blockchain        :param previous_hash: Hash of previous Block        :return: New Block        """        block = {            'index': len(self.chain) + 1,            'timestamp': time(),            'transactions': self.current_transactions,            '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
def new_transaction(self, sender, amount, recipient): """ Creates a new transaction to go into the next mined Block :param sender: Address of the Sender :param amount_send: The amount sent by the sender :param bpsc: Address of the Smart contract (bpsc) :param amount_bpsc: The amount received by bpsc (Transaction fees) :param recipient: Address of the Recipient :param amount_receive: The amount received by the recipient :return: The index of the Block that will hold this transaction """ self.current_transactions.append({ 'sender': sender, 'amount_send': amount, 'bpsc': 'bpsc_wallet_address', # Block Producer Smart Contract (bpsc) 'amount_bpsc': amount * 0.00005, # Transaction fees 'recipient': recipient, 'amount_receive': amount * 0.99995, }) return self.last_block['index'] + 1 @property def last_block(self): return self.chain[-1]
@staticmethod def hash(block): """ Creates a SHA-256 hash of a Block :param block: Block """ # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
复制代码


在以上代码中,没有证明变量或随机数,也不需要区块奖励。因为如前所述,“智能区块链”没有共识可言。甚至交易费也可能为零。但是,为了避免垃圾邮件之类的目的,我们可以假定每笔交易的总费用为 0.00005。这笔小额款项存储在(BPSC)智能合约中,交易的总成本可用于开发等工作,甚至可以烧掉以产生通缩。通缩是维持和增强货币以及加密货币价值的最有效方法之一。我们现在正在使用 Flask 框架,这样就可以通过基于 HTTP 协议平台的请求来与“智能区块链”通信。为此我们创建以下三种方法:


/transactions/new


  • 请求建立一个新的交易并将其添加到一个块中


/mine


  • 要求我们的服务器挖掘一个新块


/chain


  • 请求返回完整的块列表


import hashlibimport jsonfrom time import timefrom urllib.parse import urlparsefrom flask import Flask, jsonify, request
class Smart_Blockchain: # .....# .....# ..... # Instantiate the Nodeapp = Flask(__name__)# Instantiate the Smart_Blockchainblockchain = Smart_Blockchain()
@app.route('/mine', methods=['GET'])def mine(): last_block = blockchain.last_block # Forge the new Block by adding it to the chain previous_hash = blockchain.hash(last_block) block = blockchain.new_block(previous_hash) response = { 'message': "New Block Forged", 'index': block['index'], 'transactions': block['transactions'], 'previous_hash': block['previous_hash'], } return jsonify(response), 200
@app.route('/transactions/new', methods=['POST'])def new_transaction(): values = request.get_json() # Check that the required fields are in the POST'ed data required = ['sender', 'amount', 'recipient'] if not all(k in values for k in required): return 'Missing values', 400 # Create a new Transaction index = blockchain.new_transaction(values['sender'], values['amount'], values['recipient']) response = {'message': f'Transaction will be added to Block {index}'} return jsonify(response), 201
@app.route('/chain', methods=['GET'])def full_chain(): response = { 'chain': blockchain.chain, 'length': len(blockchain.chain), } return jsonify(response), 200
if __name__ == '__main__': from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument('-p', '--port', default=5000, type=int, help='port to listen on') args = parser.parse_args() port = args.port app.run(host='0.0.0.0', port=port)
复制代码


根据以上代码,服务器将在端口 5000 上启动。当然,另一种方法是导入 sys 并对最后一部分代码进行以下更改。这样,你就可以在每次运行时指定所需的端口。


import sys      .....      if __name__ == '__main__':    app.run(host='0.0.0.0', port=sys.argv[1])      
复制代码


现在,我们将代码的两个主要部分串联起来。你可以在这里下载本文的所有代码。这时,我们的文件名为bpsc101.py。在下一步中我们将运行服务器。我们还使用 Postman 连接到网络上的新 API。将 POST 交易请求发送到下列服务器地址后,我们将开始与新 API 通信:


http://localhost:5000/transactions/new


这个交易的信息必须在“Body”部分中输入,并且显然,我们选择“raw”,然后是“JSON”。



在上面的示例中,我们想将一百万个代币(例如 Aka 代币)从一个钱包发送给(带特定地址的)另一个人。为此,我们将代币和对这个交易的请求发送到服务器(其充当区块生产者智能合约)。如你所见,服务器的响应将这个交易添加到第二个块中,因为创世块已经在代码中定义过了。


现在,我们发送一个 GET 挖掘请求到服务器地址:


http://localhost:5000/mine


这将创建下一个块。每个块的内容包括所有已执行的交易和未完成的交易,例如在这里,创建的第二个块仅包含一个交易。



根据上图,作为交易费的五十个代币保留在(BPSC)钱包中,其余代币由(BPSC)发送给最终接收者。当然,如前所述,交易费用将被烧掉或花费在网络开发等任务上。但是,我们尚未对这些金额的支出类型建模。现在,我们知道链服务器中必须有两个块。要查看当前链,我们发送一个 GET 链请求到服务器地址:


http://localhost:5000/chain



为了进一步的测试,你可以发送新的交易请求,并且每次发送少量交易请求后,你都可以发送一个挖掘请求。即使不做交易,你也可以挖一个空块。同时,链请求可随时为你确定链的状态。


“智能区块链”的去中心化网络


像区块链这样的“智能区块链”网络是去中心化的。因此我们需要为每个节点实现一种方法,告知它们旁边有哪些节点,并保留那些节点的列表。为此我们使用 set(),这样每个节点仅记录一次。我们还创建以下方法来接受 URL 形式的新节点列表:


/nodes/register


import hashlibimport jsonfrom time import timefrom urllib.parse import urlparsefrom flask import Flask, jsonify, requestclass Smart_Blockchain:    def __init__(self):        self.current_transactions = []        self.chain = []        self.nodes = set()        # Create the genesis block        self.new_block(previous_hash='1')                    def register_node(self, address):        """        Add a new node to the list of nodes        :param address: Address of node. Eg. 'http://192.168.0.5:5000'        """        parsed_url = urlparse(address)        if parsed_url.netloc:            self.nodes.add(parsed_url.netloc)        elif parsed_url.path:            # Accepts an URL without scheme like '192.168.0.5:5000'.            self.nodes.add(parsed_url.path)        else:            raise ValueError('Invalid URL')

.......
@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
if __name__ == '__main__': from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument('-p', '--port', default=5000, type=int, help='port to listen on') args = parser.parse_args() port = args.port app.run(host='0.0.0.0', port=port)
复制代码


请记住,在“智能区块链”中,只有(BPSC)的区块生产者智能合约可以创建或挖掘新区块。但网络的其余节点只能将请求发送到(BPSC),并通过该请求接收最新的链。因此,我们需要实现来自(BPSC)的节点请求以返回最新链。为此我们创建以下方法:/smart/chain


import hashlibimport jsonfrom time import timefrom urllib.parse import urlparseimport requestsfrom flask import Flask, jsonify, request
class Smart_Blockchain: def __init__(self): self.current_transactions = [] self.chain = [] self.nodes = set() # Create the genesis block self.new_block(previous_hash='1') def smart_chain(self): """ All nodes can receive the smart_chain """ schain = None response = requests.get(f'http://127.0.0.1:5000/chain') if response.status_code == 200: chain = response.json()['chain'] schain = chain # Replace our chain if schain: self.chain = schain return True return False

....... @app.route('/smart/chain', methods=['GET'])def smart_chain(): replaced = blockchain.smart_chain() if replaced: response = { 'message': 'Smart chain update by bpsc', 'smart chain': blockchain.chain, 'length': len(blockchain.chain) } else: response = { 'message': 'Unsuccessful: Please try again', 'old chain': blockchain.chain, 'length': len(blockchain.chain) } return jsonify(response), 200
if __name__ == '__main__': from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument('-p', '--port', default=5000, type=int, help='port to listen on') args = parser.parse_args() port = args.port app.run(host='0.0.0.0', port=port)
复制代码


如前所述,在这个示例中,我们要在端口 5000 上启动服务器(充当区块生产者智能合约)。根据上述代码,网络中的其他任何节点都可以向(BPSC)发送请求,并收到最新链。第 26 行上的命令“requests”执行相同的操作。换句话说,根据一个请求,由(BPSC)创建的最新链将替换该节点的链。下面我们还需要把目前为止的各段代码组合起来。但如果我们要测试/nodes/register 方法和/smart/chain 方法,则需要在网络中有其他节点。这意味着我们要么使用多台计算机,要么在同一台计算机上定义不同的端口。我们选择第二种方式,在同一台计算机上创建端口号为 5001 和 5002 的另外两个节点。但主要问题是,除了负责交易、挖掘区块并为特定代币(例如 Aka 代币)创建链的(BPSC)之外,其余节点应该无法执行这些活动。当然这很简单,我们只需要从其他节点中删除一些代码即可,例如挖掘能力等。现在我们的文件名是bpsc102.py


为此我们创建了以下文件:nodes_v1_5001.pynodes_v1_5002.py。请单击它们查看详细更改。这些文件与原始的 bpsc102.py 相比仅删除了部分代码,并且未添加任何内容。当然,端口号也已更改。


如果你出于任何原因使用了 VPN,则必须在后续测试中将其关闭。请在单独的控制台上运行所有三个文件,并创建三个节点。这意味着我们将同时拥有以下节点:


http://localhost:5000


  • 充当智能合约(BPSC)。


http://localhost:5001


  • 网络的一个节点,充当代币发送者。


http://localhost:5002


  • 网络的一个节点,充当代币接收者。


测试时,我们首先发送两个连续的 POST 请求,以将端口号为 5001 的节点通知给网络上的邻居节点,并存储这些节点的列表:


http://localhost:5001/nodes/register


这意味着,第一个“节点”:[“http://127.0.0.1:5000”](BPSC)和第二个“节点”:[“http://127.0.0.1:5002“](另一个节点)存储在了上述列表中。



现在我们要测试/smart/chain 方法。但在这个测试之前,我们最好至少发送一个交易请求,然后再向(BPSC)发送一个挖掘请求。这将在(BPSC)中保存一个带有两个块的链。





现在,我们将后续请求(GET 类型)发送到端口号为 5001 的节点地址:


http://localhost:5001/smart/chain


这样,具有端口 5001 的节点将接收来自(BPSC)的最新链,节点的链替换为(BPSC)创建的最新链。



这样,在“智能区块链”中,尽管所有节点都无法生成区块链,但所有节点都可以通过(BPSC)交易并从(BPSC)接收最新链。另外,作为去中心化网络,节点之间可以相互通信,网络节点甚至可以通过数十个(BPSC)的服务获益,因为假定每个(BPSC)都专用于一种代币。


去中心化网络上的数十个“智能区块链”


为了解释清楚这个主题,我们最好为网络节点实现第二条链。通过这种模式,你能在每个节点上存储数十个并行的链。


import hashlibimport jsonfrom time import timefrom urllib.parse import urlparseimport requestsfrom flask import Flask, jsonify, request
class Smart_Blockchain: def __init__(self): self.current_information = [] self.chain = [] self.chain2 = [] self.nodes = set() # Create the genesis block self.new_block(previous_hash='1') def register_node(self, address): """ Add a new node to the list of nodes :param address: Address of node. Eg. 'http://192.168.0.5:5000' """ parsed_url = urlparse(address) if parsed_url.netloc: self.nodes.add(parsed_url.netloc) elif parsed_url.path: # Accepts an URL without scheme like '192.168.0.5:5000'. self.nodes.add(parsed_url.path) else: raise ValueError('Invalid URL')
def smart_chain(self): """ All nodes can receive the smart_chain """ schain = None response = requests.get(f'http://127.0.0.1:5000/chain') if response.status_code == 200: chain = response.json()['chain'] schain = chain # Replace our chain if schain: self.chain = schain return True return False
def new_block(self, previous_hash): """ Create a new Block in the Smart Blockchain :param previous_hash: Hash of previous Block :return: New Block """ block = { 'index2': len(self.chain2) + 1, 'timestamp': time(), 'information': self.current_information, 'previous_hash': previous_hash or self.hash(self.chain2[-1]), } # Reset the current list of transactions self.current_information = [] self.chain2.append(block) return block def new_information(self, information): """ Creates a new information :param information: Your information :return: The index of the Block that will hold this information """ self.current_information.append({'information': information })
return self.last_block['index2'] + 1
@property def last_block(self): return self.chain2[-1]
@staticmethod def hash(block): """ Creates a SHA-256 hash of a Block :param block: Block """ # 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() # Instantiate the Nodeapp = Flask(__name__)# Instantiate the Smart_Blockchainblockchain = Smart_Blockchain()
@app.route('/mine', methods=['GET'])def mine(): last_block = blockchain.last_block # Forge the new Block by adding it to the chain previous_hash = blockchain.hash(last_block) block = blockchain.new_block(previous_hash) response = { 'message': "New Block Forged", 'index2': block['index2'], 'information': block['information'], 'previous_hash': block['previous_hash'], } return jsonify(response), 200
@app.route('/information/new', methods=['POST'])def new_information(): values = request.get_json() # Check that the required fields are in the POST'ed data required = ['information'] if not all(k in values for k in required): return 'Missing values', 400 # Create a new information index = blockchain.new_information(values['information']) response = {'message': f'information will be added to Block {index}'} return jsonify(response), 201
@app.route('/chain2', methods=['GET'])def full_chain2(): response = { 'chain2': blockchain.chain2, 'length': len(blockchain.chain2), } return jsonify(response), 200
@app.route('/chain', methods=['GET'])def full_chain(): response = { 'chain': blockchain.chain, 'length': len(blockchain.chain), } return jsonify(response), 200
@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('/smart/chain', methods=['GET'])def smart_chain(): replaced = blockchain.smart_chain() if replaced: response = { 'message': 'Smart chain update by bpsc', 'smart chain': blockchain.chain, 'length': len(blockchain.chain) } else: response = { 'message': 'Unsuccessful: Please try again', 'old chain': blockchain.chain, 'length': len(blockchain.chain) } return jsonify(response), 200
if __name__ == '__main__': from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument('-p', '--port', default=5001, type=int, help='port to listen on') args = parser.parse_args() port = args.port app.run(host='0.0.0.0', port=port)
复制代码


仔细查看以上代码,可以发现两个并行且独立的区块链存储在一个节点上。当然,其中一个是先前的“智能区块链”,另一个是已添加到先前代码中以存储个人数据的简单区块链。当然,第二个区块链可以是“智能区块链”,并且节点能够以相同的方式使用数十个(BPSC)服务(这些服务可以是存储在各自独立的区块链中针对不同代币的交易服务,等等。)为了创建第二个链,我们将两个列表添加到先前的列表中。第 12 行用于存储数据,第 14 行用于存储区块链。你可以自行检查其余的更改。我们根据上述代码创建了nodes_v2_5001.pynodes_v2_5002.py文件。请同时运行这两个文件和bpsc102.py文件以执行以下测试。


现在我们要测试/chain2 方法。nodes_v2_5001.py 文件表示一个端口号为 5001 的节点。我们向该节点发送了一个存储个人数据的请求。当然,我们知道最早创建的是初始块或称创世块,所以服务器会将数据添加到第二个块。然后,我们发送对同一节点的挖掘请求。这将创建下一个块(第二个链上的第二个块)。


http://localhost:5001/information/new


http://localhost:5001/mine


我们将后续类型为 GET 的请求发送到同一节点:


http://localhost:5001/chain2


通过这个测试,我们可以确保两个块都位于服务器的第二个链中,并且第二个链与第一个链没有关系。





为了确保第二条链不会干扰“智能区块链”的功能,我们将重复之前对“智能区块链”的测试。也就是说,我们首先测试所有三个节点的/nodes/register 方法。然后,从扮演(BPSC)角色的节点上,我们请求几个交易和多个挖掘:


http://localhost:5000/transactions/new


http://localhost:5000/mine


最后,我们将后续类型为 GET 的请求发送到端口号为 5001 的节点地址:


http://localhost:5001/smart/chain




如你在图中所见,由(BPSC)创建的最新链代替了该节点的主链(第一条链)。最后我们得出结论,“智能区块链”和该节点中存储的第二条链各自完全独立。


在“智能区块链”中计划和调度挖矿,及生产区块的操作


当一个智能合约在区块链网络上注册后,它就会永远存在下去。也就是说,只要这个区块链网络还在正常工作,任何人(甚至是智能合约的编写者和拥有者)都无法对合约的初始内容做任何改动。区块生产者智能合约(BPSC)的情况也是一样的。因此从一开始,挖矿作业(生产区块)的时间就应在代码中明确实现。否则,(BPSC)就必须等待挖掘请求才能挖掘新块。


有三种方法可以为挖矿作业(生产区块)规划一个(BPSC)智能合约:


  • A:根据时间,例如每秒或每分钟构建一个新块。

  • B:基于交易数;例如,每十笔交易或一百笔交易之后。

  • C:方法 A 和 B 的组合;例如,十秒钟或十笔交易之后,先到先得。


我们这里只实现一种方法的一个示例。例如,假设在每个交易之后,(BPSC)都会创建一个新块。因此每个块仅包含一个交易。




..........

@app.route('/transactions/new', methods=['POST'])def new_transaction(): values = request.get_json() # Check that the required fields are in the POST'ed data required = ['sender', 'amount', 'recipient'] if not all(k in values for k in required): return 'Missing values', 400 # Create a new Transaction index = blockchain.new_transaction(values['sender'], values['amount'], values['recipient']) response = {'message': f'Transaction will be added to Block {index}'} last_block = blockchain.last_block # Forge the new Block by adding it to the chain previous_hash = blockchain.hash(last_block) block = blockchain.new_block(previous_hash) response = { 'message': "New Block Forged", 'index': block['index'], 'transactions': block['transactions'], 'previous_hash': block['previous_hash'], } return jsonify(response), 201

..........
复制代码


如你所见,这里只更改了/transactions/new 方法,在方法末尾添加了/mine 的代码。我们从中创建了bpsc103.py文件。你可以运行该文件并使用 Postman 执行所需的测试。在这种情况下,如果你将之后的请求发送到服务器:


http://localhost:5000/transactions/new


(BPSC)会立即进行交易,同时挖掘一个块并将其添加到链中。


现在,如果你决定将挖掘请求发送到服务器:


http://localhost:5000/mine


就只会挖一个空块,因为没有任何交易。


总结和结论


为了模拟(BPSC)区块生产者智能合约,我们设定了端口号为 5000 的节点,并实现了以下三个文件:


  • bpsc101.py:这个版本不是最终版本,不能与其他节点交互。

  • bpsc102.py:这是最终版本,并且所有场景都针对该版本做了测试。我们测试了交易请求、挖掘请求、发送其他节点的最新链的请求,等等。

  • bpsc103.py:这个版本也是最终版本,但我们在之前的版本基础上添加了新功能。具体来说,(BPSC)需要在每次交易后创建一个新块并将该块添加到链中。


端口 5001 和 5002 表示其他网络节点。为了模拟这些节点,我们实现了以下两个版本:


nodes_v1_5001.py 和 nodes_v1_5002.py


  • 这个版本基于“智能区块链”技术和最终版本。尽管这些节点无法生产区块,但它们可以通过(BPSC)交易,也可以从(BPSC)接收最新链。


nodes_v2_5001.py 和 nodes_v2_5002.py


  • 它们也是最终版本,但我们在之前版本的基础上添加了新功能,在代码中添加了一个简单的区块链(用于存储个人数据)。


至此代码就写完了。你还可以在单机或多台机器上做更多测试。但请记住,无论是针对区块链还是“智能区块链”的 Python 模拟,通常都不会包含所有必要的控件和操作。在本文中就没有涉及某些控件。例如,对钱包的必要控件就没提。如果(BPSC)处于任何原因未能将代币发送给最终接收者,我们会希望将所有代币返回给发送者,但这里也没有实现。在实际工作中不应忽略这些控件。大多数智能合约均以特定的高级语言编写。例如,以太坊区块链中的智能合约通常以 Solidity 语言编写。还好,使用 Solidity 实现这种类型的控件比 Python 更容易。


最后提一下


在本文和之前的一些文章中,我们已经证明矿工、区块生产者及其活动不是区块链技术的固有组成部分。当然,用智能合约代替矿工和区块生产者是一个新的,有争议的想法,并且存在很多反对声音和阻碍。但是从长远来看,维持现状是不可能的。实际上,比特币的工作量证明机制(POW)陷入了僵局。所有矿工都在提高他们的处理能力以相互竞争,结果消耗相当于一个一千万人口国家的年消费量的电力。这不公平。



剑桥比特币电力消耗指数


如果你对这个主题感兴趣,可以阅读我们之前关于“智能区块链”以及比特币问题的文章。


另外,如果你有任何疑问或在本文中看到任何歧义或错误,请告知我们。


Somayyeh Gholami


Mehran Kazeminia


原文链接:


Implementing a “Smart Blockchain” with Pyth


2020-12-03 15:242615

评论

发布
暂无评论
发现更多内容

图解网络:什么是热备份路由器协议HSRP?

wljslmz

网络技术 路由协议 7月月更 热备份路由器协议 HSRP

如何远程办公更有效率 | 社区征文

宇宙之一粟

效率 居家办公 初夏征文

浅谈一篇优质的小红书文案需要具备什么

石头IT视角

JDBC 进阶

武师叔

7月月更

如何有效远程办公之我见 | 社区征文

踏雪痕

远程办公 居家办公 初夏征文

资深开发人员告诉你,怎样编写出优秀的代码?

雨果

程序员 软件 开发者 代码

分布式系统:what、why、how

javaadu

分布式系统

毕业设计:设计秒杀电商系统

jiaoxn

「架构实战营」

【Python技能树共建】Beautiful Soup

梦想橡皮擦

Python 7月月更

设计电商秒杀系统

Jadedev

「架构实战营」

一个漂亮的API文档生成工具

为自己带盐

7月月更

NFT新的契机,多媒体NFT聚合平台OKALEIDO即将上线

威廉META

牛客java选择题每日打卡Day5

京与旧铺

7月月更

NFT新的契机,多媒体NFT聚合平台OKALEIDO即将上线

石头财经

线程常用的方法

zarmnosaj

7月月更

毕业总结

michael

架构实战营 #架构实战营 「架构实战营」

分布式CAP理论

源字节1号

软件开发 后端开发

封装Ajax

Jason199

ajax 7月月更

透过JVM-SANDBOX源码,了解字节码增强技术原理

柠檬汁Code(binbin0325)

互联网架构 源码剖析 字节码增强 源码解读 Java’

【安全攻防】序列化与反序列,你了解多少?

网络安全学海

黑客 网络安全 安全 信息安全 渗透测试

疫情远程办公经验分享| 社区征文

乌龟哥哥

7月月更

架构训练毕业设计+总结

小马

#架构训练营

架构实战营 - 第 6 期 模块九之毕业设计

乐邦

「架构实战营」

leetcode 121 Best Time to Buy and Sell Stock 买卖股票的最佳时机(简单)

okokabcd

LeetCode 动态规划 算法与数据结构

Java多线程案例之单例模式(懒汉,饿汉,枚举)

未见花闻

7月月更

疫情来袭--远程办公之思考|社区征文

桑榆

初夏征文

Go 语言入门很简单:Go 实现凯撒密码

宇宙之一粟

密码学 Go 语言 7月月更

【愚公系列】2022年7月 Go教学课程 002-Go语言环境安装

愚公搬代码

7月月更

毕业设计项目

michael

架构实战营 #架构实战营 「架构实战营」

程序员远程办公喜忧参半| 社区征文

乌龟哥哥

7月月更

使用Python实现一个“智能区块链”_区块链_Somayyeh Gholami_InfoQ精选文章