当前位置: 首页 > 科技 > 区块链 > 区块链研究实验室|通过使用Python构建区块链学习区块链

区块链研究实验室|通过使用Python构建区块链学习区块链

天乐
2020-12-29 08:54:42 第一视角

在开始构建之前,您需要了解区块链的基础知识。

区块链是可以用来记录数据的系统。例如这意味着可以在正规银行进行转账,但也可以包含所有权合约、协议、个人信息或其他数据。

区块链的特殊之处在于,无需中央授权就可以实现。 无法通过破坏一个中心点来伪造记录数据。区块链最著名的实现是比特币。

本教程是供具有一点Python知识的绝对初学者使用的,让我们开始吧!

要求

确保您已安装最新版本的Python。 另外,您需要安装两个称为Flask和Requests的Python库:

对于这些请求,我建议下载Postman。

入门

创建一个新的Python文件。我称它为app.py。首先我们应该创建一个Blockchain类:

创建构造函数时,我们添加一个空列表来存储链:

def __init__(self):

self.chain = []

现在,我们需要创建一个列表来存储我们的交易,因此我们的Blockchain类现在看起来像这样:

class Blockchain(object):

def __init__(self):

self.chain = []

self.current_transactions = []

为了用数据填充这些列表,我们创建了两个方法(addBlock()和addTransaction()):

def addBlock(self):

pass

def addTransaction(self):

pass

这些函数目前无法执行任何操作,但是我们在后面将进行数据填充。

为了以安全的方式存储数据,我们对数据进行哈希处理。 创建一个hash()方法。 这是一种静态方法,因此不要忘记添加@staticmethod:

@staticmethod

def hash(block):

pass

最后,创建一个lastBlock()方法:

@property

def lastBlock(self):

pass

创建一个区块

现在我们需要考虑如何显示块。 首先它需要一个index和timestamp。 我敢打赌,您会明白的,但是证明呢? 那是什么? 最好的解释方法是稍后再做。

我们的区块还需要一个transactions和一个previous_hash,它是前一个块的哈希。

创建新事务

为了创建一个新的事务,我们创建了addTransaction()方法。 现在让我们用代码填充它。

首先,我们应该传入一些参数(self、sender、receiver、amount):

现在,我们将新交易添加到我们的交易列表中:

self.current_transactions.append({

'sender': sender,

'recipient': recipient,

'amount': amount,

})

最后,此方法需要返回事务的索引:

这使得方法如下所示:

def addTransaction(self, sender, recipient, amount):

self.current_transactions.append({

'sender': sender,

'recipient': recipient,

'amount': amount,

})

return self.last_block['index'] + 1

创建一个新区块

在开始创建新区块之前,需要在构造函数中创建一个核心去块:

然后我们可以填写addBlock()方法:

def addBlock(self, proof, previous_hash=None):

block = {

'index': len(self.chain) + 1,

'timestamp': time(),

'transactions': self.current_transactions,

'proof': proof,

'previous_hash': previous_hash or self.hash(self.chain[-1]),

}

self.current_transactions = []

self.chain.append(block)

return block

如您所见,我们需要创建hash()方法以使其工作:

@staticmethod

def hash(block):

block_string = json.dumps(block, sort_keys=True).encode()

return hashlib.sha256(block_string).hexdigest()

哈希很简单。 基本上它是编码一个字符串。 然后,我们需要另一个方法,那就是lastBlock()方法:

@property

def last_block(self):

return self.chain[-1]

什么是证明?

工作量证明是一种旨在抵抗网络攻击(例如DDoS攻击)的协议。 工作量证明是Cynthia Dwork和Moni Naor最初于1993年发布的想法。

该协议是密集计算形式(也称为挖掘)的要求,必须执行密集计算形式才能在区块链上创建新的一组不信任交易。

为了验证这些交易,矿工们必须解决一个数学难题。第一个解决这个问题的矿工将获得奖励(以新的加密货币)。已验证的交易存储在公共区块链中。这个谜题对每一个新的方块都有点困难。这就是为什么矿工们必须提高工作效率。

如何实施PoW

现在,让我们通过以下难题将其实现到我们的blockChain中:

找出一个数字x。 当使用上一个区块的解决方案进行哈希处理时,会生成带有两个前导0的哈希值。

为此,我们首先添加以下模块:

import hashlib

import json

from time import time

from uuid import uuid4

并创建两个新方法:

和:

@staticmethod

def valid_proof(last_proof, proof):

填写如下:

使用Flask服务我们的API

创建一个区块链很有趣,但是现在我们要使用它,Python有一个完美的模块来创建API:Flask。 让我们添加一些基本的Flask代码:

from flask import Flask

app = Flask(__name__)

node_identifier = str(uuid4()).replace('-', '')

blockchain = Blockchain()

@app.route('/mine', methods=['GET'])

def mine():

return "Mining a new Block"

@app.route('/transactions/new', methods=['POST'])

def new_transaction():

return "Adding 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)

新交易

API的新交易端点将如下所示,并且由于我们已经创建了类似的方法,因此非常简单:

@app.route('/transactions/new', methods=['POST'])

def newTransaction():

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 '}

return jsonify(response), 201

挖矿

挖矿是我们需要在其工作之前添加一点代码的地方。需要做几件事:

证明

矿工奖励

新区块+将其添加到链中

@app.route('/mine', methods=['GET'])

def mine():

last_block = blockchain.last_block

last_proof = last_block['proof']

proof = blockchain.proof_of_work(last_proof)

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 Created",

'index': block['index'],

'transactions': block['transactions'],

'proof': block['proof'],

'previous_hash': block['previous_hash'],

}

return jsonify(response), 200

运行我们的BlockChain API

让我们尝试通过打开Python程序来运行API:

$ python app.py

$ Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

您可以使用Postman或Curl挖掘块:

$ curl -X POST -H "Content-Type: application/json" -d '{

"sender": "d4ee26eee15148ee92c6cd394edd974e",

"recipient": "address2",

"amount": 5

}' "http://localhost:5000/transactions/new"

要检查挖掘了多少区块,请转到http://localhost5000/chain,将显示一个JSON格式的链:

{

"chain": [

{

"index": 1,

"previous_hash": 1,

"proof": 100,

"timestamp": 1606910340,

"transactions": []

},

}

以下是完整代码:

import requests

from time import time

import hashlib

import json

from flask import Flask

from time import time

from uuid import uuid4

class Blockchain(object):

app = Flask(__name__)

node_identifier = str(uuid4()).replace('-', '')

blockchain = Blockchain()

@app.route('/mine', methods=['GET'])

def mine():

last_block = blockchain.last_block

last_proof = last_block['proof']

proof = blockchain.proof_of_work(last_proof)

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

@app.route('/transactions/new', methods=['POST'])

def newTransaction():

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 '}

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__':

app.run(host='0.0.0.0', port=5000)

def __init__(self):

self.chain = []

self.current_transactions = []

def proof_of_work(self, last_proof):

proof =

while self.valid_proof(last_proof, proof) is False:

proof += 1

return proof

@staticmethod

def valid_proof(last_proof, proof):

guess = f''.encode()

guess_hash = hashlib.sha256(guess).hexdigest()

return guess_hash[:4] == "0000"

def addBlock(self, proof, previous_hash=None):

block = {

'index': len(self.chain) + 1,

'timestamp': time(),

'transactions': self.current_transactions,

'proof': proof,

'previous_hash': previous_hash or self.hash(self.chain[-1]),

}

self.current_transactions = []

self.chain.append(block)

return block

def addTransaction(self, sender, recipient, amount):

self.current_transactions.append({

'sender': sender,

'recipient': recipient,

'amount': amount,

})

return self.last_block['index'] + 1

@staticmethod

def hash(block):

block_string = json.dumps(block, sort_keys=True).encode()

return hashlib.sha256(block_string).hexdigest()

@property

def last_block(self):

return self.chain[-1]

提示:支持键盘“← →”键翻页
为你推荐
加载更多
意见反馈
返回顶部