±à¼ÍƼö: |
À´Ô´IBM£¬±¾½Ì³Ì½«Ïò¾ßÓÐÈκαà³Ì¼¼ÄÜˮƽµÄ
Python ¿ª·¢ÈËÔ±½éÉÜÇø¿éÁ´¡£Í¨¹ý´ÓÁ㿪ʼʵÏÖÒ»¸ö¹«ÓÐÇø¿éÁ´²¢¹¹½¨Ò»¸ö¼òµ¥Ó¦ÓóÌÐòÀ´ÀûÓÃËü£¬Äú½«Á˽âÇø¿éÁ´µ½µ×ÊÇʲô¡£ |
|
Äú½«Äܹ»Ê¹Óà Flask ΢¿ò¼ÜÎªÇø¿éÁ´µÄ²»Í¬¹¦ÄÜ´´½¨¶Ëµã£¬±ÈÈçÌí¼ÓÊÂÎñ£¬È»ºóÔÚ¶à¸ö»úÆ÷ÉÏÔËÐнű¾À´´´½¨Ò»¸öÈ¥ÖÐÐÄ»¯ÍøÂç¡£Äú»¹½«Á˽âÈçºÎ¹¹½¨Ò»¸ö¼òµ¥µÄÓû§½çÃæ£¬ÒÔ±ãÓëÇø¿éÁ´½øÐн»»¥£¬²¢´æ´¢ÈκÎÓÃÀýµÄÐÅÏ¢£¬±ÈÈç¶ÔµÈÖ§¸¶¡¢ÁÄÌì»òµç×ÓÉÌÎñ¡£
Python ÊÇÒ»ÖÖÈÝÒ×Àí½âµÄ±à³ÌÓïÑÔ£¬ÕâÊÇÎÒÔÚ±¾½Ì³ÌÖÐÑ¡ÔñËüµÄÔÒò¡£Í¨¹ýѧϰ±¾½Ì³Ì£¬Äú½«ÊµÏÖÒ»¸ö¹«ÓÐÇø¿éÁ´²¢Á˽âËüµÄʵ¼ÊÓ¦Óá£GitHub
ÉÏÌṩÁËÒ»¸öÍêÕûµÄÑù±¾Ó¦ÓóÌÐò´úÂ룬¸ÃÓ¦ÓóÌÐòÍêÈ«ÊÇÓà Python ±àдµÄ¡£
»ñÈ¡´úÂë
Ö÷ÒªÂß¼°üº¬ÔÚ views.py ÎļþÖС£ÈÃÎÒÃÇÒ»Æð·ÖÎöһϸÃÂß¼£¬ÒÔ±ãÕæÕýÈ«ÃæÁ˽âÇø¿éÁ´¡£
ǰÌáÌõ¼þ
Python µÄ»ù´¡±à³Ì֪ʶ
Flask ΢¿ò¼Ü£¨ÓÃÓÚ´´½¨Çø¿éÁ´·þÎñÆ÷µÄ¶Ëµã£©
±³¾°
2008 Ä꣬һ¸öÃû½Ð Satoshi Nakamoto µÄÈË£¨»òÕß¿ÉÄÜÊÇÒ»¸öС×飩·¢±íÁËһƪÃûΪ¡¶±ÈÌØ±Ò£ºÒ»ÖֶԵȵç×ÓÏÖ½ðϵͳ¡·µÄ°×ƤÊé¡£¸ÃÎÄÕ½áºÏÁËÃÜÂëѧ¼¼ÊõºÍ¶ÔµÈÍøÂ磬²»ÐèÒªÒÀ¿¿ÖÐÐÄ»¯È¨Íþ»ú¹¹£¨±ÈÈçÒøÐУ©¾ÍÄÜÔÚÈËÃÇÖ®¼äʵÏÖ¸¶¿î¡£±ÈÌØ±ÒÓ¦Ô˶øÉú¡£³ýÁ˱ÈÌØ±ÒÖ®Í⣬ÕâÆªÎÄÕ»¹½éÉÜÁËÒ»ÖÖ´æ´¢Êý¾ÝµÄ·Ö²¼Ê½ÏµÍ³£¨¼´ÏÖÔÚ¹ãΪÈËÖªµÄ¡°Çø¿éÁ´¡±£©£¬¸ÃϵͳµÄÊÊÓ÷¶Î§Ô¶²»Ö»ÊǸ¶¿î»ò¼ÓÃÜ»õ±Ò¡£
´ÓÄÇʱÆð£¬¼¸ºõÿ¸öÐÐÒµ¶¼¶ÔÇø¿éÁ´²úÉúÁËŨºñµÄÐËȤ¡£ÎÞÂÛÊÇÏñ±ÈÌØ±ÒÕâÑùµÄÍêÈ«Êý×Ö»¯µÄ»õ±Ò¡¢ÏñÒÔÌ«·»ÕâÑùµÄ·Ö²¼Ê½¼ÆËã¼¼Êõ£¬»¹ÊÇÏñ
IBM Blockchain Platform Ëù»ùÓÚµÄ Hyperledger Fabric ÕâÑùµÄ¿ªÔ´¿ò¼Ü£¬ÏÖÔÚ¶¼ÒÔÇø¿éÁ´×÷ΪÆä±³ºóµÄ»ù´¡¼¼Êõ¡£
¡°Çø¿éÁ´¡±ÊÇʲô£¿
Çø¿éÁ´ÊÇÒ»ÖÖ´æ´¢Êý×ÖÊý¾ÝµÄ·½Ê½¡£Êý¾Ý¿ÉÒÔÊÇÈκÎÄÚÈÝ¡£¶ÔÓÚ±ÈÌØ±Ò£¬ËüÊÇÊÂÎñ£¨ÔÚÕÊ»§Ö®¼ä×ªÒÆ±ÈÌØ±Ò£©£¬ËüÉõÖÁ¿ÉÒÔÊÇÎļþ£»Õâ¶¼Î޹ؽôÒª¡£Êý¾ÝÊÇÒÔÇø¿éÐÎʽ½øÐд洢µÄ£¬Çø¿éʹÓùþÏ£ÖµÁ´½ÓÔÚÒ»Æð¡£Òò´ËµÃÃû¡°Çø¿éÁ´¡±¡£
Çø¿éÁ´µÄÉñÆæÖ®´¦ÊÇÔÚÆäÖÐÌí¼ÓºÍ´æ´¢´ËÀàÊý¾ÝµÄ·½Ê½£¬¸Ã·½Ê½Ôì¾ÍÁËһЩ·Ç³£ÀíÏëµÄÌØÕ÷£º
ÀúÊ·¼Ç¼ÎÞ·¨¸ü¸Ä
ϵͳÎÞ·¨¹¥ÆÆ
Êý¾ÝµÄ³Ö¾Ã±£´æ
ûÓе¥µã¹ÊÕÏ
ÄÇÃ´Çø¿éÁ´ÈçºÎÄܹ»ÊµÏÖÕâÐ©ÌØÕ÷ÄØ£¿ÎÒÃǽ«Í¨¹ýʵÏÖÒ»¸öÇø¿éÁ´À´ÉîÈëÆÊÎöËü¡£ÈÃÎÒÃÇ¿ªÊ¼°É¡£
¹ØÓÚ¸ÃÓ¦ÓóÌÐò
Ê×Ïȶ¨ÒåÒ»ÏÂÎÒÃǽ«Òª¹¹½¨µÄÓ¦ÓóÌÐòµÄÓÃ;¡£ÎÒÃǵÄÄ¿µÄÊǹ¹½¨Ò»¸öÔÊÐíÓû§¹²ÏíÐÅÏ¢µÄ¼òµ¥ÍøÕ¾¡£ÒòΪÄÚÈݽ«´æ´¢ÔÚÇø¿éÁ´ÖУ¬ËùÒÔËüÎÞ·¨¸ü¸ÄÇÒ»áÓÀÔ¶´æÔÚ¡£
ÎÒÃǽ«²ÉÓÃ×Ô϶øÉϵÄʵÏÖ·½Ê½¡£Ê×Ïȶ¨ÒåÎÒÃǽ«´æ´¢ÔÚÇø¿éÁ´ÖеÄÊý¾ÝµÄ½á¹¹¡£ һƪÌû×Ó£¨ÈκÎÓû§ÔÚÎÒÃǵÄÓ¦ÓóÌÐòÉÏ·¢²¼µÄÒ»ÌõÏûÏ¢£©½«ÓÉ
3 ¸ö»ù±¾ÒªËØÀ´±êʶ£º
.1ÄÚÈÝ
2.×÷Õß
3.ʱ¼ä´Á
½«ÊÂÎñ´æ´¢µ½Çø¿éÖÐ
ÎÒÃǽ«²ÉÓÃÒ»Öֹ㷺ʹÓõĸñʽÀ´½«Êý¾Ý´æ´¢ÔÚÇø¿éÁ´ÖУºJSON¡£ÒÔÏÂÊÇһƪ´æ´¢ÔÚÇø¿éÁ´ÖеÄÌû×ӵĸñʽ£º
{ "author":
"some_author_name", "content":
"Some thoughts that author wants to share",
"timestamp": "The time at
which the content was created"
} |
ÊõÓï¡°Êý¾Ý¡±Í¨³£ÔÚ»¥ÁªÍøÉϱ»¡°ÊÂÎñ¡±Ò»´ÊËùÈ¡´ú¡£ËùÒÔ£¬ÎªÁ˱ÜÃâ»ìÏý²¢±£³ÖÒ»Ö£¬ÎÒÃǽ«Ê¹ÓÃÊõÓï¡°ÊÂÎñ¡±À´±íʾÔÚÎÒÃǵÄʾÀýÓ¦ÓóÌÐòÖз¢²¼µÄÊý¾Ý¡£
ÊÂÎñ±»´ò°üµ½Çø¿éÖС£Ò»¸öÇø¿é¿ÉÒÔ°üº¬Ò»¸ö»òÐí¶à¸öÊÂÎñ¡£°üº¬ÊÂÎñµÄÇø¿éƵ·±µØÉú³É²¢Ìí¼Óµ½Çø¿éÁ´ÖС£ÒòΪ¿ÉÄÜÓжà¸öÇø¿é£¬ËùÒÔÿ¸öÇø¿é¶¼Ó¦ÓÐÒ»¸öΨһ
ID£º
class Block:
def __init__(self, index, transactions, timestamp):
self.index = []
self.transactions = transactions
self.timestamp = timestamp |
ÈÃÇø¿é²»¿É¸ü¸Ä
ÎÒÃÇÏ£Íû¼ì²â³ö¶ÔÇø¿éÄÚ´æ´¢µÄÊý¾ÝµÄÈκδ۸ġ£ÔÚÇø¿éÁ´ÖУ¬ÕâÊÇʹÓÃÒ»¸ö¹þÏ£º¯ÊýÀ´ÊµÏֵġ£
¹þÏ£º¯Êý½ÓÊÜÈκδóСµÄÊý¾Ý²¢Éú³É¹Ì¶¨´óСµÄÊý¾Ý£¬¸Ã½á¹ûͨ³£ÓÃÓÚʶ±ðÊäÈë¡£ÏÂÃæÊÇ Python ÖеÄÒ»¸öʹÓÃ
sha256 ¹þÏ£º¯ÊýµÄʾÀý£º
>>>
from hashlib import sha256
>>> data = "Some variable length
data"
>>> sha256(data).hexdigest()
'b919fbbcae38e2bdaebb6c04ed4098e5c 70563d2dc51e085f784c058ff208516'
>>> sha256(data).hexdigest() # no matter
how many times you run it, the
result is going to be the same 256 character string
'b919fbbcae38e2bdaebb6c04ed4098e5c 70563d2dc51e085f784c058ff208516' |
Ò»¸öÀíÏëµÄ¹þÏ£º¯Êý°üÀ¨ÒÔÏÂÌØÕ÷£º
ËüÓ¦¸ÃºÜÈÝÒ×¼ÆËã¡£
ÄÄÅÂÖ»¸ü¸ÄÊý¾ÝÖеÄÒ»¸ö룬¹þÏ£ÖµÒ²Ó¦¸ÃÍêÈ«·¢Éú±ä»¯¡£
Ó¦¸ÃÎÞ·¨¸ù¾ÝÊä³ö¹þÏ£Öµ²Â³öÊäÈë¡£
ÄúÏÖÔÚÖªµÀ¹þÏ£º¯ÊýÊÇʲôÁ˰ɡ£ÎÒÃǽ«Ã¿¸öÇø¿éµÄ¹þÏ£Öµ¶¼´æ´¢ÔÚ Block ¶ÔÏóÄÚµÄÒ»¸ö×Ö¶ÎÖУ¬Æä×÷ÓÃÀàËÆÓÚËüËù°üº¬µÄÊý¾ÝµÄÊý×ÖÖ¸ÎÆ£º
from hashlib
import sha256
import json
def compute_hash(block): """
A function that creates the hash of the block.
"""
block_string = json.dumps(self.__dict__, sort_keys=True)
return sha256(block_string.encode()).hexdigest() |
±¸×¢£ºÔÚ´ó¶àÊý¼ÓÃÜ»õ±ÒÖУ¬ÉõÖÁ¶ÔÇø¿éÖеĸ÷¸öÊÂÎñÒ²½øÐÐÁ˹þÏ£ÔËË㣬´Ó¶øÐγÉÒ»¿Ã¹þÏ£Ê÷£¨Ò²³ÆÎª¶þ½øÖƹþÏ£Ê÷£©£¬Õâ¿ÃÊ÷µÄ¸ù¿ÉÒÔÓÃ×÷Çø¿éµÄ¹þÏ£Öµ¡£Ëü²»ÊÇÇø¿éÁ´Õý³£ÔË×÷µÄ±ØÒªÌõ¼þ£¬ËùÒÔÎÒÃǽ«Ê¡ÂÔËü£¬ÒÔ±£³Ö´úÂë¼ò½à¡£
Á´½ÓÇø¿é
ÎÒÃÇÒÑÉèÖÃÁËÇø¿é¡£Çø¿éÁ´Ó¦¸ÃÊÇÒ»¸öÇø¿é¼¯ºÏ¡£ÎÒÃÇ¿ÉÒÔ½«ËùÓÐÇø¿é¶¼´æ´¢ÔÚ Python ÁбíÖУ¨µÈЧÓÚÊý×飩¡£µ«Õ⻹²»¹»£¬ÒòΪÈç¹ûÓÐÈ˹ÊÒâÌæ»»Á˼¯ºÏÖеÄÒ»¸öÇø¿é¸ÃÔõô°ì£¿ÓÃÐ޸ĹýµÄÊÂÎñ´´½¨Ò»¸öеÄÇø¿é£¬¼ÆËã¹þÏ£Öµ£¬È»ºóÌæ»»ÈκξÉÇø¿é£¬ÕâÔÚÎÒÃǵĵ±Ç°ÊµÏÖÖв¢²»ÊÇʲôÄÑÊ£¬ÒòΪÎÒÃǻᱣ³ÖÇø¿éµÄ²»¿É¸ü¸ÄÐÔºÍ˳Ðò¡£
ÎÒÃÇÐèÒª²ÉÓÃijÖÖ;¾¶À´È·±£¶Ô¹ýÈ¥µÄÇø¿éµÄÈκθü¸Ä¶¼»áÔì³ÉÕû¸öÁ´µÄʧЧ¡£Ò»ÖÖ·½·¨ÊÇͨ¹ý¹þÏ£Öµ½«Çø¿éÁ´½ÓÆðÀ´¡£Ì¸µ½Á´½Ó£¬ÎÒÃÇÖ¸µÄÊǽ«Ç°Ò»¸öÇø¿éµÄ¹þÏ£Öµ°üº¬ÔÚµ±Ç°Çø¿éÖС£ËùÒÔ£¬Èç¹ûÈκÎÒÔǰµÄÇø¿éµÄÄÚÈÝ·¢Éú¸ü¸Ä£¬¸ÃÇø¿éµÄ¹þÏ£ÖµÒ²»á·¢Éú¸ü¸Ä£¬µ¼ÖÂÓëÏÂÒ»¸öÇø¿éÖеÄ
previous_hash ×ֶβ»Æ¥Åä¡£
ÿ¸öÇø¿é¶¼Í¨¹ý previous_hash ×Ö¶ÎÁ´½Óµ½Ç°Ò»¸öÇø¿é£¬µ«ÊǵÚÒ»¸öÇø¿é¸ÃÈçºÎ´¦Àí£¿µÚÒ»¸öÇø¿é³ÆÎª´´Ê¼Çø¿é£¬´ó¶àÊýÇé¿öÏ£¬ËüÊÇÊÖ¶¯Éú³É»òͨ¹ýijÖÖ¶ÀÌØÂß¼Éú³ÉµÄ¡£ÈÃÎÒÃǽ«
previous_hash ×Ö¶ÎÌí¼Óµ½ Block ÀàÖУ¬²¢ÊµÏÖÎÒÃÇµÄ Blockchain ÀàµÄ³õʼ½á¹¹£¨²Î¼ûÇåµ¥
1£©¡£
Çåµ¥ 1. ÎÒÃÇµÄ Blockchain ÀàµÄ³õʼ½á¹¹
from hashlib
import sha256
import json
import time
class Block:
def__init__(self, index, transactions, timestamp,
previous_hash):
self.index = index
self.transactions = transactions
self.timestamp = timestamp
self.previous_hash = previous_hash
def compute_hash(self):
block_string = json.dumps(self.__dict__, sort_keys=True)
return sha256(block_string.encode()).hexdigest() |
ÕâÊÇÎÒÃÇµÄ Blockchain Àࣺ
class Blockchain:
def __init__(self):
self.unconfirmed_transactions = [] # data yet
to get into blockchain
self.chain = []
self.create_genesis_block()
def create_genesis_block(self): """
A function to generate genesis block and appends
it to
the chain.The block has index 0, previous_hash
as 0, and
a valid hash. """
genesis_block = Block(0, [], time.time(), "0")
genesis_block.hash = genesis_block.compute_hash()
self.chain.append(genesis_block)
@property
def last_block(self):
return self.chain[-1] |
ʵÏÖ¹¤×÷Á¿Ö¤Ã÷Ëã·¨
µ«ÕâÀï´æÔÚÒ»¸öÎÊÌâ¡£Èç¹ûÎÒÃǸü¸Äǰһ¸öÇø¿é£¬ÎÒÃÇ¿ÉÒԷdz£ÇáËɵØÖØÐ¼ÆËãËùÓкóÐøÇø¿éµÄ¹þÏ£Öµ£¬²¢´´½¨Ò»¸ö²»Í¬µÄÓÐÐ§Çø¿éÁ´¡£ÎªÁËÔ¤·ÀÕâÖÖÇé¿ö£¬ÎÒÃDZØÐëÈüÆËã¹þÏ£ÖµµÄÈÎÎñ±äµÃÀ§ÄѺÍËæ»ú»¯¡£
ÒÔÏÂÊÇÎÒÃÇʵÏִ˲Ù×÷µÄ·½Ê½¡£ÎÒÃDz»»á½ÓÊÜÈκÎÇø¿é¹þÏ£Öµ£¬¶øÊǶÔËüÌí¼ÓijÖÖÔ¼Êø¡£ÈÃÎÒÃÇÀ´Ìí¼ÓÒ»ÖÖÔ¼Êø£º¹þÏ£ÖµÓ¦ÒÔÁ½¸öǰµ¼Á㿪ʼ¡£ÁíÍâÎÒÃÇÖªµÀ£¬³ý·Ç¸ü¸ÄÇø¿éµÄÄÚÈÝ£¬·ñÔò¹þÏ£Öµ²»»á·¢Éú¸ü¸Ä¡£
ËùÒÔÎÒÃǽ«ÔÚÇø¿éÖÐÒýÈëÒ»¸ö³ÆÎªËæ»úÊýµÄÐÂ×ֶΡ£Ëæ»úÊý»á²»¶Ï±ä»¯£¬Ö±µ½ÎÒÃÇ»ñµÃÂú×ãÔ¼ÊøÌõ¼þµÄ¹þÏ£Öµ¡£Ç°µ¼ÁãµÄÊýÁ¿£¨ÔÚÎÒÃǵÄÀý×ÓÖÐΪֵ
2£©¾ö¶¨Á˹¤×÷Á¿Ö¤Ã÷Ëã·¨µÄ¡°ÄѶȡ±¡£Äú¿ÉÄÜ»¹×¢Òâµ½£¬ÎÒÃǵŤ×÷Á¿Ö¤Ã÷ºÜÄѼÆË㣬µ«ÔÚÎÒÃÇÈ·¶¨Ëæ»úÊýºóºÜÈÝÒ×ÑéÖ¤£¨¶ÔÓÚÑéÖ¤£¬ÄúÖ»ÐèÒªÔÙ´ÎÔËÐйþÏ£º¯Êý¼´¿É£©£º
class Blockchain:
# difficulty of PoW algorithm
difficulty = 2 """
Previous code contd.. """
def proof_of_work(self, block): """
Function that tries different values of nonce
to get a hash
that satisfies our difficulty criteria. """
block.nonce = 0
computed_hash = block.compute_hash()
while not computed_hash.startswith('0' * Blockchain.difficulty):
block.nonce += 1
computed_hash = block.compute_hash()
return computed_hash |
Çë×¢Ò⣬ûÓÐÃ÷È·µÄÂß¼À´¿ìËÙÈ·¶¨Ëæ»úÊý£»Ö»ÄÜͨ¹ý±©Á¦ÆÆ½â¡£
½«Çø¿éÌí¼Óµ½Á´ÖÐ
Òª½«Çø¿éÌí¼Óµ½Á´ÖУ¬Ê×ÏÈÐèÒªÑéÖ¤ËùÌṩµÄ¹¤×÷Á¿Ö¤Ã÷ÊÇ·ñÕýÈ·£¬ÒÔ¼°ÒªÌí¼ÓµÄÇø¿éµÄ previous_hash
×Ö¶ÎÊÇ·ñÖ¸ÏòÁ´ÖеÄ×îÐÂÇø¿éµÄ¹þÏ£Öµ¡£
ÈÃÎÒÃÇ¿´¿´½«Çø¿éÌí¼Óµ½Á´ÖеĴúÂ룺
class Blockchain:
"""
Previous code contd.. """
def add_block(self, block, proof): """
A function that adds the block to the chain after
verification. """
previous_hash = self.last_block.hash
if previous_hash != block.previous_hash:
return False
if not self.is_valid_proof(block, proof):
return False
block.hash = proof
self.chain.append(block)
return True
def is_valid_proof(self, block, block_hash):
"""
Check if block_hash is valid hash of block and
satisfies
the difficulty criteria. """
return (block_hash.startswith('0' * Blockchain.difficulty)
and
block_hash == block.compute_hash()) |
ÍÚ¿ó
ÊÂÎñ×î³õ´æ´¢ÔÚÒ»¸öδȷÈÏÊÂÎñ³ØÖС£½«Î´È·ÈÏÊÂÎñ·ÅÈëÇø¿éÖв¢¼ÆË㹤×÷Á¿Ö¤Ã÷µÄ¹ý³Ì±»³ÆÎªÇø¿éÍÚ¿ó¡£Ò»µ©ÕÒµ½Âú×ãÎÒÃǵÄÔ¼ÊøÌõ¼þµÄËæ»úÊý£¬ÎÒÃǾͿÉÒÔ˵ÍÚµ½ÁËÒ»¸öÇø¿é£¬Õâ¸öÇø¿é¾Í»á·ÅÈëÇø¿éÁ´ÖС£
ÔÚ´ó¶àÊý¼ÓÃÜ»õ±Ò£¨°üÀ¨±ÈÌØ±Ò£©ÖУ¬×÷Ϊ¶ÔºÄ·ÑËãÁ¦À´¼ÆË㹤×÷Á¿Ö¤Ã÷µÄ½±Àø£¬¿ó¹¤¿ÉÒÔ»ñµÃһЩ¼ÓÃÜ»õ±Ò¡£ÒÔÏÂÊÇÎÒÃǵÄÍÚ¿óº¯ÊýµÄ¸ñʽ£º
class Blockchain:
"""
Previous code contd... """
def add_new_transaction(self, transaction):
self.unconfirmed_transactions.append(transaction)
def mine(self): """
This function serves as an interface to add the
pending
transactions to the blockchain by adding them
to the block
and figuring out Proof of Work. """
if not self.unconfirmed_transactions:
return False
last_block = self.last_block
new_block = Block(index=last_block.index + 1,
transactions=self.unconfirmed_transactions,
timestamp=time.time(),
previous_hash=last_block.hash)
proof = self.proof_of_work(new_block)
self.add_block(new_block, proof)
self.unconfirmed_transactions = []
return new_block.index |
ºÃÁË£¬ÎÒÃǵŤ×÷²î²»¶àÍê³ÉÁË¡£Äú¿ÉÒÔÔÚ GitHub Éϲ鿴½ØÖÁĿǰµÄºÏ²¢´úÂë¡£
´´½¨½Ó¿Ú
ÏÖÔÚΪÎÒÃǵĽڵ㴴½¨½Ó¿Ú£¬ÒÔ±ãÓëÆäËû¶ÔµÈ½ÚµãÒÔ¼°ÎÒÃǽ«Òª¹¹½¨µÄÓ¦ÓóÌÐò½øÐн»»¥¡£ÎÒÃǽ«Ê¹Óà Flask
´´½¨Ò»¸ö REST-API À´ÓëÎÒÃÇµÄ½Úµã½øÐн»»¥¡£ÒÔÏÂÊÇËüµÄ´úÂ룺
from flask import
Flask, request
import requests
app = Flask(__name__)
# the node's copy of blockchain
blockchain = Blockchain() |
ÎÒÃǵÄÓ¦ÓóÌÐòÐèÒªÒ»¸ö¶ËµãÀ´Ìá½»ÐÂÊÂÎñ¡£ÎÒÃǵÄÓ¦ÓóÌÐò½«Ê¹Óô˶˵㽫ÐÂÊý¾Ý£¨Ìû×Ó£©Ìí¼Óµ½Çø¿éÁ´ÖУº
@app.route('/new_transaction',
methods=['POST'])
def new_transaction():
tx_data = request.get_json()
required_fields = ["author", "content"]
for field in required_fields:
if not tx_data.get(field):
return "Invlaid transaction data", 404
tx_data["timestamp"] = time.time()
blockchain.add_new_transaction(tx_data)
return "Success", 201 |
ÏÂÃæÊÇ·µ»Ø½ÚµãµÄÁ´¸±±¾µÄ¶Ëµã¡£ÎÒÃǵÄÓ¦ÓóÌÐò½«Ê¹Óô˶˵ãÀ´²éѯҪÏÔʾµÄËùÓÐÌû×Ó£º
@app.route('/chain',
methods=['GET'])
def get_chain():
chain_data = []
for block in blockchain.chain:
chain_data.append(block.__dict__)
return json.dumps({"length": len(chain_data),
"chain": chain_data}) |
ÏÂÃæÊÇÇëÇó½ÚµãÍÚ¾òδȷÈÏÊÂÎñ£¨Èç¹ûÓУ©µÄ¶Ëµã¡£ÎÒÃǽ«Ê¹Óô˶˵ã´ÓÎÒÃǵÄÓ¦ÓóÌÐò×ÔÉí·¢ÆðÒ»¸öÍÚ¿óÃüÁ
@app.route('/mine',
methods=['GET'])
def mine_unconfirmed_transactions():
result = blockchain.mine()
if not result:
return "No transactions to mine"
return "Block #{} is mined.".format(result)
# endpoint to query unconfirmed transactions
@app.route('/pending_tx')
def get_pending_tx():
return json.dumps(blockchain.unconfirmed_transactions)
app.run(debug=True, port=8000) |
ÏÖÔÚ£¬Äú¿ÉÒÔÌåÑéÒ»ÏÂÎÒÃǵÄÇø¿éÁ´£¬´´½¨Ò»Ð©ÊÂÎñ£¬È»ºóʹÓÃÖîÈç cURL »ò Postman Ö®ÀàµÄ¹¤¾ßÀ´ÍÚ¾òËüÃÇ¡£
½¨Á¢¹²Ê¶ºÍÈ¥ÖÐÐÄ»¯
ĿǰΪֹ£¬ÎÒÃÇʵÏֵĴúÂëÖ»ÄÜÔÚµ¥¸ö¼ÆËã»úÉÏÔËÐС£¼´Ê¹Í¨¹ý¹þÏ£ÖµÁ´½ÓÁËÇø¿é£¬ÎÒÃÇÈÔÈ»²»ÄÜÐÅÈε¥¸öʵÌå¡£ÎÒÃÇÐèÒª¶à¸ö½ÚµãÀ´Î¬»¤ÎÒÃǵÄÇø¿éÁ´¡£
ËùÒÔÈÃÎÒÃÇ´´½¨Ò»¸ö¶Ëµã£¬ÒÔ±ãÈÃÒ»¸ö½ÚµãÁ˽âÍøÂçÖÐµÄÆäËû¶ÔµÈ½Úµã£º
# the address
to other participating members of the network
peers = set()
# endpoint to add new peers to the network.
@app.route('/add_nodes', methods=['POST'])
def register_new_peers():
nodes = request.get_json()
if not nodes:
return "Invalid data", 400
for node in nodes:
peers.add(node)
return "Success", 201 |
Äú¿ÉÄÜÒѾÈÏʶµ½£¬ÔÚ¶à½Úµã·½Ãæ´æÔÚÒ»¸öÎÊÌâ¡£ÓÉÓÚ¹ÊÒâ²Ù×Ý»òÒâÍâµÄÔÒò£¬Ò»Ð©½ÚµãµÄÁ´¸±±¾¿ÉÄÜÓÐËù²»Í¬¡£ÔÚÕâÖÖÇé¿öÏ£¬ÎÒÃÇÐèÒªÉ̶¨²ÉÓÃÁ´µÄij¸ö°æ±¾£¬ÒÔά³ÖÕû¸öϵͳµÄÍêÕûÐÔ¡£ÎÒÃÇÐèÒª´ï³É¹²Ê¶¡£
Ò»ÖÖ¼òµ¥µÄ¹²Ê¶Ëã·¨¿ÉÄÜÊÇ£¬ÔÚÍøÂçÖеIJ»Í¬²ÎÓëÕß¹¹³ÉµÄÁ´³öÏÖ·ÖÆçʱ£¬É̶¨²ÉÓÃ×µÄÓÐЧÁ´¡£Ñ¡Ôñ´Ë·½·¨µÄÀíÓÉÊÇ£¬×µÄÁ´ÊǶÔÒÑÍê³ÉµÄ×î¶à¹¤×÷Á¿µÄÓÐЧ¹ÀË㣺
def consensus():
"""
Our simple consensus algorithm.Èç¹ûÕÒµ½Ò»¸ö¸ü³¤µÄÓÐЧÁ´£¬ÔòÓÃËüÌæ»»ÎÒÃǵÄÁ´¡£
"""
global blockchain
longest_chain = None
current_len = len(blockchain)
for node in peers:
response = requests.get('http://{}/chain'.format(node))
length = response.json()['length']
chain = response.json()['chain']
if length > current_len and blockchain.check_chain_validity(chain):
current_len = length
longest_chain = chain
if longest_chain:
blockchain = longest_chain
return True
return False |
×îºó£¬ÎÒÃÇÐèÒª¿ª·¢Ò»ÖÖ·½·¨£¬ÈÃÈκνڵãÏòÍøÂçÐû²¼ËüÒѾÍÚµ½Ò»¸öÇø¿é£¬ÒÔ±ãÿ¸öÈ˶¼ÄܸüÐÂËûÃǵÄÇø¿éÁ´£¬²¢¼ÌÐøÍÚ¾òÆäËûÊÂÎñ¡£ÆäËû½Úµã¿ÉÒÔÇáËɵØÑéÖ¤¹¤×÷Á¿Ö¤Ã÷£¬²¢½«ËüÌí¼Óµ½¸÷×ÔµÄÁ´ÖУº
# endpoint to
add a block mined by someone else to the node's
chain.
@app.route('/add_block', methods=['POST'])
def validate_and_add_block():
block_data = request.get_json()
block = Block(block_data["index"], block_data["transactions"],
block_data["timestamp", block_data["previous_hash"]])
proof = block_data['hash']
added = blockchain.add_block(block, proof)
if not added:
return "The block was discarded by the node",
400
return "Block added to the chain", 201
def announce_new_block(block):
for peer in peers:
url = "http://{}/add_block".format(peer)
requests.post(url, data=json.dumps(block.__dict__,
sort_keys=True))
|
announce_new_block ·½·¨Ó¦ÔÚ½ÚµãÍÚµ½Ã¿¸öÇø¿éºóµ÷Óã¬ÒÔ±ã¶ÔµÈ½ÚµãÄܽ«¸ÃÇø¿éÌí¼Óµ½×Ô¼ºµÄÁ´ÖС£
¹¹½¨Ó¦ÓóÌÐò
ºÃÁË£¬ºó¶Ë¶¼ÉèÖúÃÁË¡£Äú¿ÉÒÔÔÚ GitHub Éϲ鿴µ½Ä¿Ç°ÎªÖ¹µÄ´úÂë¡£
ÏÖÔÚ£¬ÊÇʱºò´´½¨Ó¦ÓóÌÐòµÄ½Ó¿ÚÁË¡£ÎÒÃÇʹÓÃÁË Jinja2 Ä£°åÀ´³ÊÏÖÍøÒ³ºÍһЩ CSS£¬ÈÃÒ³Ãæ¿´ÆðÀ´ÃÀ¹ÛһЩ¡£
ÎÒÃǵÄÓ¦ÓóÌÐòÐèÒªÁ¬½Óµ½Çø¿éÁ´ÍøÂçÖеÄij¸ö½Úµã£¬ÒÔ±ãץȡÊý¾ÝºÍÌá½»ÐÂÊý¾Ý¡£Ò²¿ÉÄÜ´æÔÚ¶à¸ö½Úµã£º
import datetime
import json
import requests
from flask import render_template, redirect, request
from app import app
.
CONNECTED_NODE_ADDRESS = "http://127.0.0.1:8000"
posts = []
|
fetch_posts º¯Êý´Ó½ÚµãµÄ /chain ¶Ëµã»ñÈ¡Êý¾Ý£¬½âÎö¸ÃÊý¾Ý²¢½«ËüÃÇ´æ´¢ÔÚ±¾µØ¡£
def fetch_posts():
get_chain_address = "{}/chain".format(CONNECTED_NODE_ADDRESS)
response = requests.get(get_chain_address)
if response.status_code == 200:
content = []
chain = json.loads(response.content)
for block in chain["chain"]:
for tx in block["transactions"]:
tx["index"] = block["index"]
tx["hash"] = block["previous_hash"]
content.append(tx)
global posts
posts = sorted(content, key=lambda k: k['timestamp'],
reverse=True) |
¸ÃÓ¦ÓóÌÐòÓÐÒ»¸ö HTML ±íµ¥£¬ÓÃÓÚ½ÓÊÜÓû§ÊäÈ룬ȻºóÏòÒ»¸öÒÑÁ¬½ÓµÄ½Úµã·¢³öÒ»¸ö POST ÇëÇó£¬ÒԱ㽫¸ÃÊÂÎñÌí¼Óµ½Î´È·ÈÏÊÂÎñ³ØÖС£È»ºó£¬Í¨¹ýÍøÂç¶Ô¸ÃÊÂÎñ½øÐÐÍÚ¾ò£¬×îºóÔÚÎÒÃÇË¢ÐÂÍøÕ¾ºóץȡ¸ÃÊÂÎñ£º
@app.route('/submit',
methods=['POST'])
def submit_textarea(): """
Endpoint to create a new transaction via our application.
"""
post_content = request.form["content"]
author = request.form["author"]
post_object = {
'author': author,
'content': post_content,
}
# Submit a transaction
new_tx_address = "{}/new_transaction".format(CONNECTED_NODE_ADDRESS)
requests.post(new_tx_address,
json=post_object,
headers={'Content-type': 'application/json'})
return redirect('/') |
ÔËÐÐÓ¦ÓóÌÐò
´ó¹¦¸æ³É£¡¿ÉÒÔÔÚ GitHub ÉÏÕÒµ½×îÖÕ´úÂë¡£
ÒªÔËÐиÃÓ¦ÓóÌÐò£º
Æô¶¯Ò»¸öÇø¿éÁ´½Úµã·þÎñÆ÷£º
python node_server.py
ÔËÐиÃÓ¦ÓóÌÐò£º
python run_app.py
ÄúÓ¦¸ÃÄÜÔÚ http://localhost:5000 ÉÏ¿´µ½ÕýÔÚÔËÐеÄÓ¦ÓóÌÐò¡£
a.³¢ÊÔ·¢²¼Ò»Ð©Êý¾Ý£¬Äú»á¿´µ½ÀàËÆÏÂͼµÄ½á¹û£º

b.µ¥»÷ Request to mine °´Å¥£¬Äú»á¿´µ½ÀàËÆÏÂͼµÄ½á¹û£º

c.µ¥»÷ Resync °´Å¥£¬Äú»á¿´µ½Ó¦ÓóÌÐòÓëÁ´ÖØÐÂͬ²½£º

ÑéÖ¤ÊÂÎñ
Äú¿ÉÄÜ×¢Òâµ½ÁËÓ¦ÓóÌÐòÖеÄÒ»¸öȱÏÝ£ºÈκÎÈ˶¼Äܸü¸ÄÈκÎÃû³ÆºÍ·¢²¼ÈκÎÄÚÈÝ¡£½â¾ö´ËÎÊÌâµÄÒ»ÖÖ·½·¨ÊÇ£¬Ê¹Óù«Ë½ÃÜÔ¿¼ÓÃÜÀ´´´½¨ÕÊ»§¡£Ã¿¸öÐÂÓû§¶¼ÐèÒªÒ»¸ö¹«Ô¿£¨ÀàËÆÓÚÓû§Ãû£©ºÍ˽Կ£¬²ÅÄÜÔÚÎÒÃǵÄÓ¦ÓóÌÐòÖз¢²¼ÄÚÈÝ¡£ÕâЩÃÜÔ¿¿ÉÒԳ䵱Êý×ÖÇ©Ãû¡£¹«Ô¿Ö»ÄܶÔʹÓÃÏàӦ˽Կ¼ÓÃܵÄÄÚÈݽøÐнâÃÜ¡£ÔÚ½«ÊÂÎñÌí¼Óµ½ÈκÎÇø¿é֮ǰ£¬»áʹÓÃ×÷ÕߵĹ«Ô¿¶ÔÆä½øÐÐÑéÖ¤¡£ÕâÑù£¬ÎÒÃǾÍÖªµÀÊÇËдµÄÕâÌõÏûÏ¢¡£
½áÊøÓï
±¾½Ì³Ì½éÉÜÁ˹«ÓÐÇø¿éÁ´µÄ»ù´¡ÖªÊ¶¡£Èç¹ûÄúÒ»Ö±ÔÚ¸úËæ²Ù×÷£¬ÄÇôÄúÒѾ´ÓÁ㿪ʼʵÏÖÁËÒ»¸öÇø¿éÁ´£¬²¢¹¹½¨ÁËÒ»¸ö¼òµ¥Ó¦ÓóÌÐòÀ´ÔÊÐíÓû§ÔÚ¸ÃÇø¿éÁ´ÉϹ²ÏíÐÅÏ¢¡£
|