声明:本文旨在传递更多市场信息,不构成任何投资建议。文章仅代表作者观点,不代表火星财经官方立场。
边肖:记得要集中注意力。
“了解工作量证明”
工作量证明算法(PoW)是一种在区块链创建或挖掘新块的方法。
PoW的目标是找到可以解决问题的数字。从计算机的角度来看,这个数字必须既难找到又容易核实。这是工作量证明的核心思想。
我们将看一个非常简单的例子来帮助你深入理解一个整数x乘以另一个y的散列必须表示为一个以0结尾的函数:
hash(x * y)=ac23dc.0
对于这个例子,我们设x=5,代码如下:
从hashlib导入sha256
x=5
y=0 #我们还不知道y应该是多少.
而sha 256(f“{ x * y }”。编码)。hexdigest[-1]!=\'0\':
y=1
打印(f \'解是y={y} \')
运行代码后的结果是y=21(生成的哈希以0结尾)
哈希(5 * 21)=1253e9373e.5e3600155e860
在比特币中,工作量证明算法被称为Hashcash。这与我们刚刚运行的基本示例代码没有太大区别。这是矿工们竞相创造新区块的算法。通常,难度由字符串中搜索的字符数决定。通过在交易中获得btc,矿工解决问题获得奖励,全网可以轻松验证他们的答案。
让我们为我们在上一篇文章中构建的区块链实现一个类似的算法,例如:找到一个数P,当这个数与前一个块的答案进行哈希运算时,将产生一个带有四个前导零的哈希值。
导入hashlib
导入json
从时间导入时间
从uuid导入uuid4
类区块链(对象):
.
def工作证明(自我证明,最后证明):
\'\'\'
简单的工作证明算法:
-找到一个数字p \',使得hash(pp \')包含4个前导零,其中p是前一个p \'
- p是以前的证明,p \'是新的证明
:param last_proof:
:返回:
\'\'\'
证明=0
而self.valid_proof(last_proof,proof)为False:
证明=1
退货证明
@静态方法
def valid_proof(最后的证明,证明):
\'\'\'
验证证明: hash(last _ Proof,proof)是否包含4个前导零?
:param last_proof:
:参数证明:
:返回:
\'\'\'
guess=f“{ last _ proof } { proof }”。编码
guess _ hash=hashlib . sha 256(guess)。己糖文摘
return guess _ hash[:4]==\' 0000 \'
为了调整算法的难度,我们可以修改前导零的数量。但是四个就够了。你会发现加一个前导零会大大缩短求答案所需的时间。
第二步:通过API与区块链交互
我们将使用Python Flask框架。这是一个微型框架,可以很容易地将端点映射到Python函数。这允许我们使用HTTP请求通过网络与我们的区块链进行对话。
让我们先创建三个方法:
#创建块的新事务。
/交易/新建
#告诉我们的服务器挖掘一个新的块。
/我的
#返回完整的区块链
/链
导入hashlib
导入json
从textwrap导入数据
从时间导入时间
从uuid导入uuid4
从烧瓶进口烧瓶
类区块链(对象):
.
#实例化节点
app=Flask(__name__)
#为此节点生成一个全局唯一的地址
node_identifier=str(uuid4)。替换(\'-\',\'\')
#实例化区块链
区块链=区块链
@app.route(\'/mine \',methods=[\'GET\'])
def mine:
返回“我们将开采一个新区块”
@app.route(\'/transactions/new \',methods=[\'POST\'])
定义新交易:
返回“我们将添加新交易”
@app.route(\'/chain \',methods=[\'GET\'])
定义完整_链:
响应={
chain\': blockchain.chain,
长度\' : len(blockchain.chain),
}
返回jsonify(响应),200
if __name__==\'__main__\':
app.run(主机=\'0.0.0.0 \',端口=5000)
为了便于理解,我再补充一些上面代码的简要中文注释:
第15行:实例化我们的节点
第18行:为我们的节点创建一个随机名称
第21行:实例化我们的区块链类
第2426行:创建/我的,这是一个得到请求
第2830行:创建/事务/新(这是邮政请求),因为我们将向其发送数据
第3238行:创建/chain,返回完整的区块链
第40-41行:在端口5000上运行
以下是用户发送交易请求到服务器的示例代码:
{
发件人\' : \'我地址:
收件人\' : \'别人地址:
金额\' : 5
}
由于我们已经有了用于将事务添加到块中的类方法,因此其余操作很容易。让我们编写添加交易的功能:
导入摘要算法
导入数据
从时间导入时间
从全局唯一识别导入uuid4
从烧瓶导入烧瓶,jsonify,请求
.
@app.route(\'/transactions/new \',methods=[\'POST\'])
定义新交易:
values=request.get_json
#检查必填字段是否在发布的数据中
必填=[\'发件人\',\'收件人\',\'金额]
如果不是全部(k的k值是必需的):
返回\'缺失值\',400
#创建新交易
指数=区块链。新交易(值[\'发送方\'],值[\'接收方\'],值[\'金额\'])
response={\'message\': f \'事务将被添加到块{index}\'}
返回jsonify(响应),201
最后,我们挖矿只需要做三件事:
1、计算工作量证明
2、通过添加一笔交易来奖励矿工(也就是我们)
3、将新块添加到链中
导入摘要算法
导入数据
从时间导入时间
从全局唯一识别导入uuid4
从烧瓶导入烧瓶,jsonify,请求
.
@app.route(\'/mine \',methods=[\'GET\'])
def mine:
#我们运行工作证明算法来获得下一个证明.
最后一个街区=区块链。最后一块
last_proof=last_block[\'proof\']
证明=区块链。工作证明
#我们必须得到找到证据的奖励。
#发送者是\"0 \",表示该节点已经挖掘了新硬币。
blockchain.new_transaction(
发件人=\'0 \',
收件人=节点标识符,
金额=1,
)
#通过添加到链中来锻造新块
上一个哈希=区块链。哈希(最后一个块)
街区=区块链。new _ block(证明,以前的散列)
响应={
消息\' : \'新块被伪造,
索引\' :块[\'索引\'],
交易\' :块[\'交易\'],
证明\' :块[\'证明\'],
previous_hash\':块[\'previous_hash\'],
}
返回jsonify(响应),200
请注意,已开采区块的接收者是我们节点的地址。
而且,我们在这里所做的大部分工作只是与区块链类上的方法进行交互。