21026 large

020 孤荷凌寒从零开始学区块链第 20 天逐过程分析区块链每一步的执行情况

941xue · 于 发布 · 92 次阅读

孤荷凌寒自学python第106天认识区块链020
【主要内容】
今天继续分析从github上获取的开源代码怎么实现简单区块链的入门知识,共用时间25分钟。
(此外整理作笔记花费了约60分钟)
详细学习过程见文末学习过程屏幕录像。
今天主要继续分析前天断点调试后得到的变量中间值,进而反推执行过程,以注释之前还不理解 的代码部分,发现我学习的难点还在于 密码学部分。

【学习笔记】
一、没有完成理解的私钥签名算法部分:
源代码如下:
def sign_transaction(self):
"""
Sign transaction with private key
"""
ls=binascii.unhexlify(self.sender_private_key)
'''
与hexlify()方法相反,
unhdexlify()方法,
将一个用ascii(其实这里也可能原本是Unicode编码)编码表示 的字符串(我估计此处不一定是byte字符串)
表示为,用十六进制(即字符串本身内容用\x转义表示编码)编码的byte字符串。
此时ls的值是:
b'0\x82\x02]\x02\x01\x00\x02\x81\x81\x00\xbac\xd7\x02\xfc~\x02\xc3\x85sL\xb3\x84n]\x8ds\x19\xab97\xe3\xb5a\r$\xd0\x93\xb0\xd1t\xe4\xe5\xde!\xfe\x9a\x15\xfbagw \x04u\x1b\x13u^\xc6l\xf4\x84\xad\x07\xcb\x12\xf9o\x0c\xea\xa7b\xbaC\xfb\x05H\x86\xad\xd8~\x8a\xc6\xe6\x11\x173\xb3\xa1\xaeY\x91CW\xaeK\xf0\xef\x81\x9d0\x92O\x01\xd5T\xc1p\x0fe>\xa9Q\x12\x07\xb00\xe4OMhKY\xfe\\xe4Dx\x84Q\xacKH\xd4\x1d\xdd\xf3\x02\x03\x01\x00\x01\x02\x81\x80\x18~\xe8\x92\x0e\xe6\xec\xac\x0f\x8c\xd0\xa6\xc3\x1f\xd2\x11\xb5\xef\xc8\xad\xf3gl\xbd\xfd\x81:\x1c>\xdf\xb82 \xf7\xa9\x96\x11\x142\x7f\xeb\x8a\xfc\xaa\xfbL\xfa^\xe3K\x0cs\xa7]\xdf\xd5u\x8c\x9f\xb0\xf3 \xa9J\xbc~\xcbA{\xd0\x11+8?\xb1\x96I*5\xc9\x11@\x86$\x90\xce\xaf\xfa\xbf\xc4\xfc6\xb4r*\xf3P\x857\xd2\xdcl\\x84\xe1\xb14\xea\x88\x8e\xb8\x04\xa4d?3B\xa6\xaf\xa2Y^\xe0\xce@\x89\x02A\x00\xd8.x\xbbE\xd4\x97\x9c\xc8z\xcd\xf3\xaa\x18*\xf1k\r\x80\x18\xff\xfb\xca\xdf$6^\xe4\xff\x84w\x93\xb9W<\x13et\xee\xba\xeeM{\xc6\xfc^\x97\n\xbf~\xe6C;\x05\xa3\x9bO\x05_;F]\xa0\r\x02A\x00\xdc\xb8\x9e\x82\xf6\x08\xf8\xaf\xba:\xe3/\x1c\x98\xbdz(\xdfi\xe7\xb3\xb8;\xac|\xa0>\xf4\xda\xef\xda\x18@T\xab\x832W\xf94\x88T\xb22]\xc4\x9e\xabH\x86\x0b\xbd-A\xfc\x97bD\xb0d\xa2\xab\xf5\xff\x02A\x00\xd4\x0e\xe9\xf1R3\x931\x81[-q\xaa\xd5\xa02F\xff\xec;\x19\xc7\xc5\x9e\x93\xe8\x1d\xb7\xe6\x89\xeb\xbee\xdd\x93\x99\xb798\x00\xf8G\xdbv;\x13\x12x\xc1\x95\xda\x8b\xf2v\xba\xa1[\xa7z^+\xcd%u\x02A\x00\x8dv\x19\xc9\x8f\x8crn\x95\xe9\xf5\xff\x14\xd1\xe3\xe6nY\xba\x13\x91@\xcb\xa6!\xfd\xc6;\xc22%R\x93\xb0pxV\x84\xc1\xa8d\x93\xfb\xdd\x81\xf1iL\x17\xe0)\x97\xe6p\xbbE\xfe\xeaM/B~\xf9\xdb\x02@4.o4\xd4(\xb7C\x8d\xa3\x0f\xe0\x80\xcc\xd8\x14\x03\xc2\xf9\xa8A1B\xcb\xe1p\x8bk:\xfe\x0fE\xe6@\x19/\x0f\xbc\x86\xd1\xda-\xc4\x04\xca\xaf\x7f\x923\x1fJz\x02kD\x02*\xf7&\xbe9!\xa5\xf9'
'''
private_key = RSA.importKey(ls) #对发送者的私钥进行处理
#RSA.importKey方法导入标准格式编码的RSA密钥(公共或私有半密钥【什么叫私有半密钥,这是机器 翻译的。】)。
'''
现在private_key的值的描述如下:
RsaKey(n=130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171, e=65537, d=17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041, p=11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197, q=11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143, u=8769754763737200992798546201632006230482985591385219415794498461221610682090347455858465717896322624555845424913806144911132535297210576548414324318453089)
_d:Integer(17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041)
_e:Integer(65537)
_n:Integer(130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171)
_p:Integer(11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197)
_q:Integer(11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143)
_u:Integer(8769754763737200992798546201632006230482985591385219415794498461221610682090347455858465717896322624555845424913806144911132535297210576548414324318453089)
d:17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041
e:65537
n:130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171
p:11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197
q:11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143
u:8769754763737200992798546201632006230482
'''

signer = PKCS1_v1_5.new(private_key) #通过发送者的私钥来计算出发送者要添加到改善信息中的私钥的数字签名信息
#--这儿使用了Crypto.Signature子库中的一种填充方法:PKCS1_v1_5(另有一种填充方法:PKCS1_OAEP)
#通过PKCS1_v1_5.new方法将发送者的私钥填充为(此处应当是签名)
#此处 原来的 Private_key被进行了处理,得到一个可以签名的对象:signer
'''
现在signer的值的描述如下 :(此时是不是已经完成了签名?)

key:RsaKey(n=130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171, e=65537, d=17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041, p=11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197, q=11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143, u=876975476373720099279854620163200623048298559138521941579449846...
_verify:<bound method PKCS115
SigScheme.verify of >
verify:<bound method _pycrypto_verify of <
'''

ls2=str(self.to_dict()).encode('utf8') #把当前的交易信息先字符串化然后转换为utf8编码
'''
ls2中现在包含了本次交易信息的全部内容,并以utf8格式编码,内容如下:

key:RsaKey(n=130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171, e=65537, d=17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041, p=11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197, q=11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143, u=876975476373720099279854620163200623048298559138521941579449846...
_verify:>
verify: 感觉为什么会是一样的?有没有可能在前天逐步调试时复制出错?
'''
h = SHA.new(ls2)
'''
现在h值的描述如下:

_state:<Crypto.Util.
raw_api.SmartPointer object at 0x000001DFFE82C128>
block_size:64
digest_size:20
oid:'1.3.14.3.2.26'
'''
ls3=binascii.hexlify(signer.sign(h))
'''
signer是前面得到的可以执行的签名对象。
执行sign()方法将新的一个hash值h与私钥混合得到签名后的字符串?
signer.sign(h)这才是在执行真正的签名过程?
binascii.hexlify()方法将此结果转换成ascii编码的byteE字符中
现在的ls3是用ascii编码的byte字符串,所以下一句又将其还原为unicode编码的
结果如下:
b'1d2358b76ba1eeeef12efefee609626e985880b76be7044ca0dc8ad5563408d330ddbb37d6d864184657f61bd8b336ff6ac87c1b602907c624fcebc8f2837cdf15c723d7dbbb102c5bbe61c822b9f2d8ec622743d6bac46d623ad8aa7f78cd55d22127312b4d758656ee86506e0fcdf13b4c2c7dda34e954efc18bd84f95ee06'
'''
ls4=ls3.decode('ascii')
'''
现在ls4的结果 :
'1d2358b76ba1eeeef12efefee609626e985880b76be7044ca0dc8ad5563408d330ddbb37d6d864184657f61bd8b336ff6ac87c1b602907c624fcebc8f2837cdf15c723d7dbbb102c5bbe61c822b9f2d8ec622743d6bac46d623ad8aa7f78cd55d22127312b4d758656ee86506e0fcdf13b4c2c7dda34e954efc18bd84f95ee06'
'''
return ls4 #这是添加有签名信息的要广播给区块链网络的信息

然后此部分算法得到的结果会在发送者(一个节点的使用者)发送交易请求信息时作为交易信息的字典的:'signature' 对应的key的值被发送出去。
当然由于我缺少基本的密码学知识,所以这部分还没有完全理解。恳请高手指导。

根据以上代码——
我目前所知的使用发送者私钥签名的流程如下:
第一步:对发送者的私钥进行处理,这使用了RSA.importKey()方法,但我不知道具体做了什么。
第二步:通过发送者私钥得到一个signer对象(这个对象我也不甚了了),使用了
PKCS1_v1_5.new(private_key)方法进行填充。
第三步:把完整的交易信息先转换成字符串,然后使用SHA.new()方法生成一个新的hash字符串(我不确定是不是字符串,研究不够透彻)。
第四步:使用前面的signer对象的sign()方法来将新的hash字符串混合(这就是签名的过程?)
第五步:转换编码后,得到签名信息。

三、对【blockchain_client.py】页面的补充注释:
【blockchain_client.py】客户端页面

   '''
title           : blockchain_client.py
description     : A blockchain client implemenation, with the following features
                  - Wallets generation using Public/Private key encryption (based on RSA algorithm)
                  - Generation of transactions with RSA encryption      
author          : Adil Moujahid
date_created    : 20180212
date_modified   : 20180309
version         : 0.3
usage           : python blockchain_client.py
                  python blockchain_client.py -p 8080
                  python blockchain_client.py --port 8080
python_version  : 3.6.1
Comments        : Wallet generation and transaction signature is based on [1]
References      : [1] https://github.com/julienr/ipynb_playground/blob/master/bitcoin/dumbcoin/dumbcoin.ipynb
'''

from collections import OrderedDict

import binascii

import Crypto
import Crypto.Random
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5

import requests
from flask import Flask, jsonify, request, render_template

class Transaction:

    def __init__(self, sender_address, sender_private_key, recipient_address, value):
        self.sender_address = sender_address
        self.sender_private_key = sender_private_key
        self.recipient_address = recipient_address
        self.value = value

    def __getattr__(self, attr):
        return self.data[attr]

    def to_dict(self):
        return OrderedDict({'sender_address': self.sender_address,
                            'recipient_address': self.recipient_address,
                            'value': self.value})

    def sign_transaction(self):
        """
        Sign transaction with private key
        """
        ls=binascii.unhexlify(self.sender_private_key)
        '''
        与hexlify()方法相反,
        unhdexlify()方法,
        将一个用ascii(其实这里也可能原本是Unicode编码)编码表示 的字符串(我估计此处不一定是byte字符串)
        表示为,用十六进制(即字符串本身内容用\x转义表示编码)编码的byte字符串。
        此时ls的值是:
        b'0\x82\x02]\x02\x01\x00\x02\x81\x81\x00\xbac\xd7\x02\xfc~\x02\xc3\x85sL\xb3\x84n]\x8ds\x19\xab97\xe3\xb5a\r$\xd0\x93\xb0\xd1t\xe4\xe5\xde!\xfe\x9a\x15\xfbagw \x04u\x1b\x13u^\xc6l\xf4\x84\xad\x07\xcb\x12\xf9o\x0c\xea\xa7b\xbaC\xfb\x05H\x86\xad\xd8~\x8a\xc6\xe6\x11\x173\xb3\xa1\xaeY\x91CW\xaeK\xf0\xef\x81\x9d0\x92O\x01\xd5T\xc1p\x0fe>\xa9Q\x12\x07\xb00\xe4OMhKY\xfe\\\xe4Dx\x84Q\xacKH\xd4\x1d\xdd\xf3\x02\x03\x01\x00\x01\x02\x81\x80\x18~\xe8\x92\x0e\xe6\xec\xac\x0f\x8c\xd0\xa6\xc3\x1f\xd2\x11\xb5\xef\xc8\xad\xf3gl\xbd\xfd\x81:\x1c>\xdf\xb82 \xf7\xa9\x96\x11`\x142\x7f\xeb\x8a\xfc\xaa\xfbL\xfa^\xe3K\x0cs\xa7]\xdf\xd5u\x8c\x9f\xb0\xf3 \xa9J\xbc~\xcbA{\xd0\x11+8?\xb1\x96I*5\xc9\x11@\x86$\x90\xce\xaf\xfa\xbf\xc4`\xfc6\xb4r*\xf3P\x857\xd2\xdcl\\\x84\xe1\xb14\xea\x88\x8e\xb8\x04\xa4d?3B\xa6\xaf\xa2Y^\xe0\xce@\x89\x02A\x00\xd8.x\xbbE\xd4\x97\x9c\xc8z\xcd\xf3\xaa\x18*\xf1k\r\x80\x18\xff\xfb\xca\xdf$6^\xe4\xff\x84w\x93\xb9W<\x13et\xee\xba\xeeM{\xc6\xfc^\x97\n\xbf~\xe6C;\x05\xa3\x9bO\x05_;F]\xa0\r\x02A\x00\xdc\xb8\x9e\x82\xf6\x08\xf8\xaf\xba:\xe3/\x1c\x98\xbdz(\xdfi\xe7\xb3\xb8;\xac|\xa0>\xf4\xda\xef\xda\x18@T\xab\x832W\xf94\x88T\xb22]\xc4\x9e\xabH\x86\x0b\xbd-A\xfc\x97bD\xb0d\xa2\xab\xf5\xff\x02A\x00\xd4\x0e\xe9\xf1R3\x931\x81[-q\xaa\xd5\xa02F\xff\xec;\x19\xc7\xc5\x9e\x93\xe8\x1d\xb7\xe6\x89\xeb\xbee\xdd\x93\x99\xb798\x00\xf8G\xdbv;\x13\x12x\xc1\x95\xda\x8b\xf2v\xba\xa1[\xa7z^+\xcd%u\x02A\x00\x8dv\x19\xc9\x8f\x8crn\x95\xe9\xf5\xff\x14\xd1\xe3\xe6nY\xba\x13\x91@\xcb\xa6!\xfd\xc6;\xc22%R\x93\xb0pxV\x84\xc1\xa8d\x93\xfb\xdd\x81\xf1iL\x17\xe0)\x97\xe6p\xbbE\xfe\xeaM/B~\xf9\xdb\x02@4.o4\xd4(\xb7C\x8d\xa3\x0f\xe0\x80\xcc\xd8\x14\x03\xc2\xf9\xa8A1B\xcb\xe1p\x8bk:\xfe\x0fE\xe6@\x19/\x0f\xbc\x86\xd1\xda-\xc4\x04\xca\xaf\x7f\x923\x1fJz\x02kD\x02*\xf7&\xbe9!\xa5\xf9'
        '''
        private_key = RSA.importKey(ls) #对发送者的私钥进行处理
        #RSA.importKey方法导入标准格式编码的RSA密钥(公共或私有半密钥【什么叫私有半密钥,这是机器 翻译的。】)。
        '''
        现在private_key的值的描述如下:
        RsaKey(n=130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171, e=65537, d=17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041, p=11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197, q=11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143, u=8769754763737200992798546201632006230482985591385219415794498461221610682090347455858465717896322624555845424913806144911132535297210576548414324318453089)
        _d:Integer(17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041)
        _e:Integer(65537)
        _n:Integer(130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171)
        _p:Integer(11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197)
        _q:Integer(11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143)
        _u:Integer(8769754763737200992798546201632006230482985591385219415794498461221610682090347455858465717896322624555845424913806144911132535297210576548414324318453089)
        d:17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041
        e:65537
        n:130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171
        p:11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197
        q:11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143
        u:8769754763737200992798546201632006230482
        '''

        signer = PKCS1_v1_5.new(private_key) #通过发送者的私钥来计算出发送者要添加到改善信息中的私钥的数字签名信息
        #--这儿使用了Crypto.Signature子库中的一种填充方法:PKCS1_v1_5(另有一种填充方法:PKCS1_OAEP)
        #通过PKCS1_v1_5.new方法将发送者的私钥填充为(此处应当是签名)
        #此处 原来的 Private_key被进行了处理,得到一个可以签名的对象:signer
        '''
        现在signer的值的描述如下 :(此时是不是已经完成了签名?)
        <Crypto.Signature.pkcs1_15.PKCS115_SigScheme object at 0x000001DFFFBB5898>
        _key:RsaKey(n=130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171, e=65537, d=17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041, p=11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197, q=11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143, u=876975476373720099279854620163200623048298559138521941579449846...
        _verify:<bound method PKCS115_SigScheme.verify of <Crypto.Signature.pkcs1_15.PKCS115_SigScheme object at 0x000001DFFFBB5898>>
        verify:<bound method _pycrypto_verify of <
        ''' 

        ls2=str(self.to_dict()).encode('utf8') #把当前的交易信息先字符串化然后转换为utf8编码
        '''
        ls2中现在包含了本次交易信息的全部内容,并以utf8格式编码,内容如下:
        <Crypto.Signature.pkcs1_15.PKCS115_SigScheme object at 0x000001DFFFBB5898>
        _key:RsaKey(n=130887508839744775363828489292492942444463434346971086658287181395248393849272716452901010865933107018951332471959936992676702744651630598299834435409087847044817115913438678900174924682299501670221020517043795850861688069799360443152949010476579188812260442594535889700621204848910086446699487189153307549171, e=65537, d=17201490969020885152030986744529681146133688756434715800049246888891380689134167063015341052966749328688036171643360808671810438983848731909554511072805795649945207662156234769699660635030358600038497835440405622733641149446902066966647182765150369696363815548406661407019882811271534070582519070030369276041, p=11322345423620747756358608825813006396534468076628379449281718497918962244676729732525986825607491134689178650194810855403918488894622671601159574317277197, q=11560105609098132329937153390284829548701209459314037867607446378353402816362871241978872702637539563535884720320614616368699804388342805715787783993030143, u=876975476373720099279854620163200623048298559138521941579449846...
        _verify:<bound method PKCS115_SigScheme.verify of <Crypto.Signature.pkcs1_15.PKCS115_SigScheme object at 0x000001DFFFBB5898>>
        verify:<bound method _pycrypto_verify of <
        感觉为什么会是一样的?有没有可能在前天逐步调试时复制出错?
        '''
        h = SHA.new(ls2)
        '''
        现在h值的描述如下:
        <Crypto.Hash.SHA1.SHA1Hash object at 0x000001DFFDD483C8>
        _state:<Crypto.Util._raw_api.SmartPointer object at 0x000001DFFE82C128>
        block_size:64
        digest_size:20
        oid:'1.3.14.3.2.26'
        '''
        ls3=binascii.hexlify(signer.sign(h))
        '''
        signer是前面得到的可以执行的签名对象。
        执行sign()方法将新的一个hash值h与私钥混合得到签名后的字符串?
        signer.sign(h)这才是在执行真正的签名过程?
        binascii.hexlify()方法将此结果转换成ascii编码的byteE字符中
        现在的ls3是用ascii编码的byte字符串,所以下一句又将其还原为unicode编码的
        结果如下:
        b'1d2358b76ba1eeeef12efefee609626e985880b76be7044ca0dc8ad5563408d330ddbb37d6d864184657f61bd8b336ff6ac87c1b602907c624fcebc8f2837cdf15c723d7dbbb102c5bbe61c822b9f2d8ec622743d6bac46d623ad8aa7f78cd55d22127312b4d758656ee86506e0fcdf13b4c2c7dda34e954efc18bd84f95ee06'
        '''
        ls4=ls3.decode('ascii')
        '''
        现在ls4的结果 :
        '1d2358b76ba1eeeef12efefee609626e985880b76be7044ca0dc8ad5563408d330ddbb37d6d864184657f61bd8b336ff6ac87c1b602907c624fcebc8f2837cdf15c723d7dbbb102c5bbe61c822b9f2d8ec622743d6bac46d623ad8aa7f78cd55d22127312b4d758656ee86506e0fcdf13b4c2c7dda34e954efc18bd84f95ee06'
        '''
        return ls4 #这是添加有签名信息的要广播给区块链网络的信息


app = Flask(__name__)

@app.route('/') #这儿将index.html文件的展示目录指定为虚拟web服务器的根目录
def index():
    return render_template('./index.html')

@app.route('/make/transaction') #这儿将make_transaction.html文件的展示目录指定为虚拟web服务器的make一级目录下的transaction子目录
def make_transaction():
    return render_template('./make_transaction.html')

@app.route('/view/transactions') #这儿将view_transactions.html文件的展示目录指定为虚拟web服务器的view一级目录下的transactions子目录
def view_transaction():
    return render_template('./view_transactions.html')

@app.route('/wallet/new', methods=['GET'])
def new_wallet():
    random_gen = Crypto.Random.new().read #得到随机字符串
    '''
    Crypto.Random.new().read调用了系统 os.urandom()函数,其解释如下:
    来自博文:https://blog.csdn.net/a19990412/article/details/80934268
    os.urandom(n)函数在python官方文档中做出了这样的解释
    函数定位: Return a string of n random bytes suitable for cryptographic use. 
    意思就是,返回一个有n个byte那么长的一个string,然后很适合用于加密。
    然后这个函数,在文档中,被归结于os这个库的Miscellaneous Functions,意思是不同种类的函数(也可以说是混种函数) 
    原因是: This function returns random bytes from an OS-specific randomness source. (函数返回的随机字节是根据不同的操作系统特定的随机函数资源。即,这个函数是调用OS内部自带的随机函数的。有特异性)
    然后一开始的那个 u 其实我是以为是uniform(表示正态分布的),后来我发现文档中有这样的一句:The returned data should be unpredictable enough for cryptographic applications。 
    注意到这个 unpredictable, 再结合之前所说的根据os底层来实现的,所以,u 应该是表示难以预料的意思。
    '''
    private_key = RSA.generate(1024, random_gen) #从随机字符串生成私钥
    public_key = private_key.publickey() #从私钥生成对应成对的公钥(即公钥和私钥之间是有对应关系的)
    ls=private_key.exportKey(format='DER')
    '''
    执行exportkey算法后,编码变成了byte字符串,
    bytes字符串的组成形式,必须是十六进制数,或者ASCII字符:
    此时是用 十六进 制来表示字符串的,因为\x这个转义字符转义的就是十六进制编码
    b'0\x82\x02]\x02\x01\x00\x02\x81\x81\x00\xbac\xd7\x02\xfc~\x02\xc3\x85sL\xb3\x84n]\x8ds\x19\xab97\xe3\xb5a\r$\xd0\x93\xb0\xd1t\xe4\xe5\xde!\xfe\x9a\x15\xfbagw \x04u\x1b\x13u^\xc6l\xf4\x84\xad\x07\xcb\x12\xf9o\x0c\xea\xa7b\xbaC\xfb\x05H\x86\xad\xd8~\x8a\xc6\xe6\x11\x173\xb3\xa1\xaeY\x91CW\xaeK\xf0\xef\x81\x9d0\x92O\x01\xd5T\xc1p\x0fe>\xa9Q\x12\x07\xb00\xe4OMhKY\xfe\\\xe4Dx\x84Q\xacKH\xd4\x1d\xdd\xf3\x02\x03\x01\x00\x01\x02\x81\x80\x18~\xe8\x92\x0e\xe6\xec\xac\x0f\x8c\xd0\xa6\xc3\x1f\xd2\x11\xb5\xef\xc8\xad\xf3gl\xbd\xfd\x81:\x1c>\xdf\xb82 \xf7\xa9\x96\x11`\x142\x7f\xeb\x8a\xfc\xaa\xfbL\xfa^\xe3K\x0cs\xa7]\xdf\xd5u\x8c\x9f\xb0\xf3 \xa9J\xbc~\xcbA{\xd0\x11+8?\xb1\x96I*5\xc9\x11@\x86$\x90\xce\xaf\xfa\xbf\xc4`\xfc6\xb4r*\xf3P\x857\xd2\xdcl\\\x84\xe1\xb14\xea\x88\x8e\xb8\x04\xa4d?3B\xa6\xaf\xa2Y^\xe0\xce@\x89\x02A\x00\xd8.x\xbbE\xd4\x97\x9c\xc8z\xcd\xf3\xaa\x18*\xf1k\r\x80\x18\xff\xfb\xca\xdf$6^\xe4\xff\x84w\x93\xb9W<\x13et\xee\xba\xeeM{\xc6\xfc^\x97\n\xbf~\xe6C;\x05\xa3\x9bO\x05_;F]\xa0\r\x02A\x00\xdc\xb8\x9e\x82\xf6\x08\xf8\xaf\xba:\xe3/\x1c\x98\xbdz(\xdfi\xe7\xb3\xb8;\xac|\xa0>\xf4\xda\xef\xda\x18@T\xab\x832W\xf94\x88T\xb22]\xc4\x9e\xabH\x86\x0b\xbd-A\xfc\x97bD\xb0d\xa2\xab\xf5\xff\x02A\x00\xd4\x0e\xe9\xf1R3\x931\x81[-q\xaa\xd5\xa02F\xff\xec;\x19\xc7\xc5\x9e\x93\xe8\x1d\xb7\xe6\x89\xeb\xbee\xdd\x93\x99\xb798\x00\xf8G\xdbv;\x13\x12x\xc1\x95\xda\x8b\xf2v\xba\xa1[\xa7z^+\xcd%u\x02A\x00\x8dv\x19\xc9\x8f\x8crn\x95\xe9\xf5\xff\x14\xd1\xe3\xe6nY\xba\x13\x91@\xcb\xa6!\xfd\xc6;\xc22%R\x93\xb0pxV\x84\xc1\xa8d\x93\xfb\xdd\x81\xf1iL\x17\xe0)\x97\xe6p\xbbE\xfe\xeaM/B~\xf9\xdb\x02@4.o4\xd4(\xb7C\x8d\xa3\x0f\xe0\x80\xcc\xd8\x14\x03\xc2\xf9\xa8A1B\xcb\xe1p\x8bk:\xfe\x0fE\xe6@\x19/\x0f\xbc\x86\xd1\xda-\xc4\x04\xca\xaf\x7f\x923\x1fJz\x02kD\x02*\xf7&\xbe9!\xa5\xf9'
    '''
    ls2=binascii.hexlify(ls)
    '''
    hexlify()方法将上面用十六进制表示的字符编码,又换成了用ASCII字符表示的字符编码,仍然是byte字符串
    结果如下:
    b'3082025d02010002818100ba63d702fc7e02c385734cb3846e5d8d7319ab3937e3b5610d24d093b0d174e4e5de21fe9a15fb6167772004751b13755ec66cf484ad07cb12f96f0ceaa762ba43fb054886add87e8ac6e6111733b3a1ae59914357ae4bf0ef819d30924f01d554c1700f653ea9511207b030e44f4d684b59fe5ce444788451ac4b48d41dddf30203010001028180187ee8920ee6ecac0f8cd0a6c31fd211b5efc8adf3676cbdfd813a1c3edfb83220f7a996116014327feb8afcaafb4cfa5ee34b0c73a75ddfd5758c9fb0f320a94abc7ecb417bd0112b383fb196492a35c91140862490ceaffabfc460fc36b4722af3508537d2dc6c5c84e1b134ea888eb804a4643f3342a6afa2595ee0ce4089024100d82e78bb45d4979cc87acdf3aa182af16b0d8018fffbcadf24365ee4ff847793b9573c136574eebaee4d7bc6fc5e970abf7ee6433b05a39b4f055f3b465da00d024100dcb89e82f608f8afba3ae32f1c98bd7a28df69e7b3b83bac7ca03ef4daefda184054ab833257f9348854b2325dc49eab48860bbd2d41fc976244b064a2abf5ff024100d40ee9f152339331815b2d71aad5a03246ffec3b19c7c59e93e81db7e689ebbe65dd9399b7393800f847db763b131278c195da8bf276baa15ba77a5e2bcd25750241008d7619c98f8c726e95e9f5ff14d1e3e66e59ba139140cba621fdc63bc232255293b070785684c1a86493fbdd81f1694c17e02997e670bb45feea4d2f427ef9db0240342e6f34d428b7438da30fe080ccd81403c2f9a8413142cbe1708b6b3afe0f45e640192f0fbc86d1da2dc404caaf7f92331f4a7a026b44022af726be3921a5f9'
    '''
    ls3=ls2.decode('ascii')
    '''
    参见博文:https://blog.csdn.net/qq_40134903/article/details/80710882
    decode(原字符串编码格式描述)
    是将字符串从字符串的原编码格式转换成 unicode 编码。
    在ls2.decode('ascii')这一句中,是将字符串ls2从ascii编码格式转换为:unicode编码。
    现在ls3的值如下:(不再是byte字符串)
    '3082025d02010002818100ba63d702fc7e02c385734cb3846e5d8d7319ab3937e3b5610d24d093b0d174e4e5de21fe9a15fb6167772004751b13755ec66cf484ad07cb12f96f0ceaa762ba43fb054886add87e8ac6e6111733b3a1ae59914357ae4bf0ef819d30924f01d554c1700f653ea9511207b030e44f4d684b59fe5ce444788451ac4b48d41dddf30203010001028180187ee8920ee6ecac0f8cd0a6c31fd211b5efc8adf3676cbdfd813a1c3edfb83220f7a996116014327feb8afcaafb4cfa5ee34b0c73a75ddfd5758c9fb0f320a94abc7ecb417bd0112b383fb196492a35c91140862490ceaffabfc460fc36b4722af3508537d2dc6c5c84e1b134ea888eb804a4643f3342a6afa2595ee0ce4089024100d82e78bb45d4979cc87acdf3aa182af16b0d8018fffbcadf24365ee4ff847793b9573c136574eebaee4d7bc6fc5e970abf7ee6433b05a39b4f055f3b465da00d024100dcb89e82f608f8afba3ae32f1c98bd7a28df69e7b3b83bac7ca03ef4daefda184054ab833257f9348854b2325dc49eab48860bbd2d41fc976244b064a2abf5ff024100d40ee9f152339331815b2d71aad5a03246ffec3b19c7c59e93e81db7e689ebbe65dd9399b7393800f847db763b131278c195da8bf276baa15ba77a5e2bcd25750241008d7619c98f8c726e95e9f5ff14d1e3e66e59ba139140cba621fdc63bc232255293b070785684c1a86493fbdd81f1694c17e02997e670bb45feea4d2f427ef9db0240342e6f34d428b7438da30fe080ccd81403c2f9a8413142cbe1708b6b3afe0f45e640192f0fbc86d1da2dc404caaf7f92331f4a7a026b44022af726be3921a5f9'
    这时目测与byte字符串的内容本身没有区别。
    '''

    #----------------------

    ls4=public_key.exportKey(format='DER')
    ls5=binascii.hexlify(ls4)
    ls6=ls5.decode('ascii')

    response = {
        'private_key': ls3,
        'public_key': ls6
    }

    return jsonify(response), 200

@app.route('/generate/transaction', methods=['POST'])
def generate_transaction():

    sender_address = request.form['sender_address'] #从客户端post过来的参数中,获取发送者用户公钥
    sender_private_key = request.form['sender_private_key'] #从客户端post过来的参数中,获取发送者用户私钥
    recipient_address = request.form['recipient_address'] #从客户端post过来的参数中,获取接收者用户公钥
    value = request.form['amount']  #从客户端post过来的参数中,获取本次交易要发送的代币数量

    #下一行代码生成一个transaction类的实例 对象 
    transaction = Transaction(sender_address, sender_private_key, recipient_address, value)

    response = {'transaction': transaction.to_dict(), 'signature': transaction.sign_transaction()}
        # 将广播一次交易的所有信息(发送者私钥除外)封装为字典      #这是添加发送者的私钥的签名信息

    return jsonify(response), 200

if __name__ == '__main__':
    from argparse import ArgumentParser

    parser = ArgumentParser()
    parser.add_argument('-p', '--port', default=80, type=int, help='port to listen on')
    args = parser.parse_args()
    port = args.port

    app.run(host='127.0.0.1', port=port)

【学习后记】
我想说密码学才是人类最伟大的壮举,简直搞得人云里雾里~~~~
进而我又想到,既然密码学可以弄得如此庞杂,那么根据宇宙信息理论,整个宇宙会不会只是一个加密的信息存储器呢?这其中的万事万物都是加密后的信息的一部分,甚至其实现在这些信息还在不停地被运算着呢?

github: https://github.com/lhghroom/Self-learning-blockchain-from-scratch
原文地址:http://www.941xue.com/content.aspx?id=1372

【欢迎大家加入[就是要学]社群】
如今,这个世界的变化与科技的发展就像一个机器猛兽,它跑得越来越快,跑得越来越快,在我们身后追赶着我们。
很多人很早就放弃了成长,也就放弃了继续奔跑,多数人保持终身不变的样子,原地不动,成为那猛兽的肚中餐——当然那也不错,在猛兽的逼迫下,机械的重复着自我感觉还良好地稳定工作与生活——而且多半感觉不到这有什么不正常的地方,因为在猛兽肚子里的是大多数人,就好像大多数人都在一个大坑里,也就感觉不出来这是一个大坑了,反而坑外的世界显得有些不大正常。
为什么我们不要做坑里的大多数人?
因为真正的人生,应当有百万种可能 ;因为真正的一生可以有好多辈子组成,每一辈子都可以做自己喜欢的事情;因为真正的人生,应当有无数种可以选择的权利,而不是总觉得自己别无选择。因为我们要成为一九法则中为数不多的那个一;因为我们要成为自己人生的导演而不是被迫成为别人安排的戏目中的演员。
【请注意】
就是要学社群并不会告诉你怎样一夜暴富!也不会告诉你怎样不经努力就实现梦想!
【请注意】
就是要学社群并没有任何可以应付未来一切变化的独门绝技,也没有值得吹嘘的所谓价值连城的成功学方法论!
【请注意】
社群只会互相帮助,让每个人都看清自己在哪儿,自己是怎样的,重新看见心中的梦想,唤醒各自内心中的那个英雄,然后勇往直前,成为自己想要成为的样子!
期待与你并肩奔赴未来!
www.941xue.com
QQ群:646854445 (【就是要学】终身成长)

【同步语音笔记】
https://www.ximalaya.com/keji/19103006/261545259

【学习过程屏幕录屏】
https://www.bilibili.com/video/av92691917/

  • 暂无回复。