Python 实现区块链 Just 模拟

import hashlib
import random
import string
import json
import threading
from decimal import Decimal
from time import time


class MyThread(threading.Thread):

    def __init__(self, target, args=()):
        super(MyThread, self).__init__()
        self.func = target
        self.args = args

    def run(self):
        self.result = self.func(*self.args)

    def get_result(self):
        try:
            return self.result
        except Exception:
            return None


class BlockChain:
    def __init__(self, initialHash):
        # init block chain
        self.chain = []

        # init pitman
        self.pitmen = []
        for i in range(6):
            self.pitmen.append(Pitman)

        # collect mine results
        self.results = []

        # generate GenesisBlock
        self.new_block(initialHash)

    @property
    def last_block(self):
        if len(self.chain):
            return self.chain[-1]
        else:
            return None

    # 随机生成交易记录
    def get_trans(self):
        return json.dumps({
            'sender': ''.join(random.sample(string.ascii_letters + string.digits, 8)),
            'recipient': ''.join(random.sample(string.ascii_letters + string.digits, 8)),
            'amount': random.randrange(1, 10000)
        })

    # 添加区块(包含创世区块、普通区块两种)
    def new_block(self, initialHash=None):
        if initialHash:
            # generate Genesis Block
            block = Block()
            block.index = 0
            block.nonce = random.randrange(0, 99999)
            block.previousHash = '0'
            block.difficulty = 0
            block.transactionData = self.get_trans()
            guess = f'{block.previousHash}{block.nonce}{block.transactionData}'.encode()
            block.hash = hashlib.sha256(guess).hexdigest()
            block.time = time()
            self.chain.append(block)
        else:

            tans_reocrd = self.get_trans()  # 假设这是广播的交易记录
            for i in range(len(self.pitmen)):
                pm = MyThread(target=self.pitmen[i].mine,
                              args=(self.pitmen[i],
                                    len(self.chain),
                                    self.last_block.get_block()['Hash'],
                                    tans_reocrd))
                pm.start()
                pm.join()
                self.results.append(pm.get_result())

            # 这里没有采用通知机制告诉其他矿工停止挖矿,允许它们挖完
            # show all blocks
            print("All blocks generated by pitmen:")
            for result in self.results:
                print(result[0].get_block())

            # 接受最快挖出的区块
            firstblock = self.results[0][0]
            mintime = Decimal(self.results[0][1])
            for i in range(1, len(self.results)):
                if Decimal(self.results[i][1]) < mintime:
                    firstblock = self.results[i][0]
                else:
                    continue
            self.chain.append(firstblock)
            self.results = []

    def show_chain(self):
        print('This is mine first block chain!')
        for block in self.chain:
            print(block.get_block())


class Block:
    def __init__(self):
        self.index = None
        self.time = None
        self.difficulty = None
        self.nonce = None
        self.hash = None
        self.previousHash = None
        self.transactionData = None

    def get_block(self):
        return {
            'Index': self.index,
            'Time': self.time,
            'Difficulty': self.difficulty,
            'Hash': self.hash,
            'Nonce': self.nonce,
            'PreviousHash': self.previousHash,
            'TransactionData': self.transactionData
        }


class Pitman:

    def mine(self, index, previousHash, transactionData):
        beginTime = time()

        block = Block()
        block.index = index
        block.previousHash = previousHash
        block.transactionData = transactionData
        block.difficulty, block.hash, block.nonce = self.generate_hash(previousHash, transactionData)
        block.time = time()
        endTime = time()

        return block, endTime - beginTime

    # 模拟难度较高的 hash 算法,这里认为末尾连续4个0就有效
    @staticmethod
    def generate_hash(previousHash, transactionData):
        difficulty = 0
        nonce = random.randrange(0, 99999)
        guess = f'{previousHash}{nonce}{transactionData}'.encode()
        myhash = hashlib.sha256(guess).hexdigest()
        while myhash[-1:-5:-1] != '0000':
            difficulty += 1
            nonce += difficulty
            guess = f'{previousHash}{nonce}{transactionData}'.encode()
            myhash = hashlib.sha256(guess).hexdigest()
        return difficulty, myhash, nonce


if __name__ == '__main__':
    chain = BlockChain(1)
    length = 5
    for i in range(length):
        chain.new_block()
    chain.show_chain()
All blocks generated by pitmen:
{'Index': 1, 'Time': 1520946890.0671756, 'Difficulty': 46075, 'Hash': 'f4d4a9138fe827d2b4d54a7042a558464b7f41a3859f0a557b849d8308970000', 'Nonce': 1061476520, 'PreviousHash': '573521a64a463f826f44261e46337e256b11c34658a8516534dbbc858f530169', 'TransactionData': '{"sender": "RuJAeWPG", "recipient": "NdIZQoLG", "amount": 852}'}
{'Index': 1, 'Time': 1520946890.1132078, 'Difficulty': 27259, 'Hash': '82997e95b32a4e6634884f4a82b11b9ee6cb1fea9232f1365cff3e0c3bbb0000', 'Nonce': 371608108, 'PreviousHash': '573521a64a463f826f44261e46337e256b11c34658a8516534dbbc858f530169', 'TransactionData': '{"sender": "RuJAeWPG", "recipient": "NdIZQoLG", "amount": 852}'}
{'Index': 1, 'Time': 1520946890.1552513, 'Difficulty': 25203, 'Hash': '3a33bb2100762b3af88e2f7d73ec6079fa960707b441738414c1034cb1a00000', 'Nonce': 317634484, 'PreviousHash': '573521a64a463f826f44261e46337e256b11c34658a8516534dbbc858f530169', 'TransactionData': '{"sender": "RuJAeWPG", "recipient": "NdIZQoLG", "amount": 852}'}
{'Index': 1, 'Time': 1520946890.339387, 'Difficulty': 109752, 'Hash': '89d89e94505d36a96cf285743298997dbbeaa5f92c6ec8f150de646670e80000', 'Nonce': 6022821169, 'PreviousHash': '573521a64a463f826f44261e46337e256b11c34658a8516534dbbc858f530169', 'TransactionData': '{"sender": "RuJAeWPG", "recipient": "NdIZQoLG", "amount": 852}'}
{'Index': 1, 'Time': 1520946890.3774097, 'Difficulty': 22781, 'Hash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'Nonce': 259543941, 'PreviousHash': '573521a64a463f826f44261e46337e256b11c34658a8516534dbbc858f530169', 'TransactionData': '{"sender": "RuJAeWPG", "recipient": "NdIZQoLG", "amount": 852}'}
{'Index': 1, 'Time': 1520946890.508489, 'Difficulty': 77100, 'Hash': '4a768d9b44943ca2d0fc1c95f1dfb79c5eaf5029bc877de100d9572148400000', 'Nonce': 2972250851, 'PreviousHash': '573521a64a463f826f44261e46337e256b11c34658a8516534dbbc858f530169', 'TransactionData': '{"sender": "RuJAeWPG", "recipient": "NdIZQoLG", "amount": 852}'}
All blocks generated by pitmen:
{'Index': 2, 'Time': 1520946890.5325198, 'Difficulty': 14199, 'Hash': 'b9c998b254d69f2f2507ef01756ea391da4cf44df40429bc3328c76b934f0000', 'Nonce': 100849273, 'PreviousHash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'TransactionData': '{"sender": "BEiclDIX", "recipient": "s7wC8uGx", "amount": 2793}'}
{'Index': 2, 'Time': 1520946890.5875456, 'Difficulty': 32647, 'Hash': 'f9431589ceaa5dfa1fae50441cdf408476e5538203e739e7a853dfd412d90000', 'Nonce': 532973064, 'PreviousHash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'TransactionData': '{"sender": "BEiclDIX", "recipient": "s7wC8uGx", "amount": 2793}'}
{'Index': 2, 'Time': 1520946890.694623, 'Difficulty': 64602, 'Hash': '8f90a852a555cca6e92a2344e1ee9be91ceabe696503edeaad4b29b071c00000', 'Nonce': 2086755620, 'PreviousHash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'TransactionData': '{"sender": "BEiclDIX", "recipient": "s7wC8uGx", "amount": 2793}'}
{'Index': 2, 'Time': 1520946890.713637, 'Difficulty': 10647, 'Hash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'Nonce': 56699515, 'PreviousHash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'TransactionData': '{"sender": "BEiclDIX", "recipient": "s7wC8uGx", "amount": 2793}'}
{'Index': 2, 'Time': 1520946890.7506726, 'Difficulty': 22441, 'Hash': 'b23ee841e8975880c535232ace00836cd9d1c9d511e7dfc319271ad5fc6d0000', 'Nonce': 251851011, 'PreviousHash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'TransactionData': '{"sender": "BEiclDIX", "recipient": "s7wC8uGx", "amount": 2793}'}
{'Index': 2, 'Time': 1520946890.7826974, 'Difficulty': 19274, 'Hash': 'af9013b09574c943f962314f52d528bcbc01f399e36d6735299caf41efc20000', 'Nonce': 185769145, 'PreviousHash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'TransactionData': '{"sender": "BEiclDIX", "recipient": "s7wC8uGx", "amount": 2793}'}
All blocks generated by pitmen:
{'Index': 3, 'Time': 1520946890.9648147, 'Difficulty': 105483, 'Hash': '01e8f01e6d02139f3b875062a2351a52ec4ff4074b1fb9650afae28eeb000000', 'Nonce': 5563453473, 'PreviousHash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'TransactionData': '{"sender": "ORMqK4ZI", "recipient": "2W0iOVmA", "amount": 1191}'}
{'Index': 3, 'Time': 1520946891.0788956, 'Difficulty': 66696, 'Hash': '508be0c3b734f015627e6befb71372f0b4a7d1d42a24a63f6a45d33b56d20000', 'Nonce': 2224248128, 'PreviousHash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'TransactionData': '{"sender": "ORMqK4ZI", "recipient": "2W0iOVmA", "amount": 1191}'}
{'Index': 3, 'Time': 1520946891.0798967, 'Difficulty': 926, 'Hash': 'afacb1d649948e8fed9ec247f5374955ebbfc4efa66d2053df240bc70cc50000', 'Nonce': 525105, 'PreviousHash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'TransactionData': '{"sender": "ORMqK4ZI", "recipient": "2W0iOVmA", "amount": 1191}'}
{'Index': 3, 'Time': 1520946891.3671, 'Difficulty': 167675, 'Hash': 'db56b1f223b5a32dbe232bc37fda81c14297ef1a2badb115679d1eaea7260000', 'Nonce': 14057565273, 'PreviousHash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'TransactionData': '{"sender": "ORMqK4ZI", "recipient": "2W0iOVmA", "amount": 1191}'}
{'Index': 3, 'Time': 1520946891.552231, 'Difficulty': 106760, 'Hash': '4fcc9ab1e45e3f92b80bb86afcba489c0fc9a29768c3e06b82bfc8338a1e0000', 'Nonce': 5698952335, 'PreviousHash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'TransactionData': '{"sender": "ORMqK4ZI", "recipient": "2W0iOVmA", "amount": 1191}'}
{'Index': 3, 'Time': 1520946891.6302867, 'Difficulty': 45103, 'Hash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'Nonce': 1017209586, 'PreviousHash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'TransactionData': '{"sender": "ORMqK4ZI", "recipient": "2W0iOVmA", "amount": 1191}'}
All blocks generated by pitmen:
{'Index': 4, 'Time': 1520946891.656305, 'Difficulty': 15247, 'Hash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'Nonce': 116331987, 'PreviousHash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'TransactionData': '{"sender": "BVtcOSnI", "recipient": "PnhZAStw", "amount": 7842}'}
{'Index': 4, 'Time': 1520946892.0025518, 'Difficulty': 196623, 'Hash': 'faa3d5077638742f2b7e1a8c0d23f5d5021da326b12c32a2c570a192d49f0000', 'Nonce': 19330418862, 'PreviousHash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'TransactionData': '{"sender": "BVtcOSnI", "recipient": "PnhZAStw", "amount": 7842}'}
{'Index': 4, 'Time': 1520946892.1907036, 'Difficulty': 110576, 'Hash': '351d628ae66859fb3cc4ad1f2299459affe80c5661c4fe6ce64d023df8df0000', 'Nonce': 6113680764, 'PreviousHash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'TransactionData': '{"sender": "BVtcOSnI", "recipient": "PnhZAStw", "amount": 7842}'}
{'Index': 4, 'Time': 1520946892.330785, 'Difficulty': 81717, 'Hash': 'cc3dccaaca48ad50e359d6d58633175fb132677e23d94cb2058c533832800000', 'Nonce': 3338906778, 'PreviousHash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'TransactionData': '{"sender": "BVtcOSnI", "recipient": "PnhZAStw", "amount": 7842}'}
{'Index': 4, 'Time': 1520946892.390841, 'Difficulty': 34838, 'Hash': 'b3006a5c189d5fe5e9e0f2c856c02ef809bc6a8cfa67cea7767ec6af34fa0000', 'Nonce': 606863416, 'PreviousHash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'TransactionData': '{"sender": "BVtcOSnI", "recipient": "PnhZAStw", "amount": 7842}'}
{'Index': 4, 'Time': 1520946892.5429356, 'Difficulty': 89187, 'Hash': 'c00e711e196f3fde027d60d954c223ab5778549839082326fef5ecd99d7a0000', 'Nonce': 3977304488, 'PreviousHash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'TransactionData': '{"sender": "BVtcOSnI", "recipient": "PnhZAStw", "amount": 7842}'}
All blocks generated by pitmen:
{'Index': 5, 'Time': 1520946892.5739717, 'Difficulty': 18004, 'Hash': '17593a91870fa755c955bfba518081bb9008c4888a40a79ea49287cf047d0000', 'Nonce': 162150579, 'PreviousHash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'TransactionData': '{"sender": "aHUrknDd", "recipient": "QJpM2gVw", "amount": 993}'}
{'Index': 5, 'Time': 1520946892.5919738, 'Difficulty': 9890, 'Hash': 'fe7c4e5b2e4396c8f8a5a0927d81ccccb4b6df5393d72f79c45daa85db550000', 'Nonce': 48948723, 'PreviousHash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'TransactionData': '{"sender": "aHUrknDd", "recipient": "QJpM2gVw", "amount": 993}'}
{'Index': 5, 'Time': 1520946892.70405, 'Difficulty': 44846, 'Hash': 'd2944b0b5a3cb80f40b3bb2120e97456b5e90b23f922b6d7fa87d74a45ff0000', 'Nonce': 1005669926, 'PreviousHash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'TransactionData': '{"sender": "aHUrknDd", "recipient": "QJpM2gVw", "amount": 993}'}
{'Index': 5, 'Time': 1520946892.8521564, 'Difficulty': 78655, 'Hash': '993f330f852dd4bc76cb8d2f308bc1d8e961920ed2950d614ecfc17823380000', 'Nonce': 3093380308, 'PreviousHash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'TransactionData': '{"sender": "aHUrknDd", "recipient": "QJpM2gVw", "amount": 993}'}
{'Index': 5, 'Time': 1520946893.2294347, 'Difficulty': 212275, 'Hash': '8eec8e8d61b167572dcda1341dcfcf11e25311eb4fe006527b9aa3e4b0600000', 'Nonce': 22530540329, 'PreviousHash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'TransactionData': '{"sender": "aHUrknDd", "recipient": "QJpM2gVw", "amount": 993}'}
{'Index': 5, 'Time': 1520946893.3555145, 'Difficulty': 73524, 'Hash': '9bb971c06d46c8e13f15b3c8eb67bba242f1eaae5e6fc3b46f69c860c87a0000', 'Nonce': 2702995520, 'PreviousHash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'TransactionData': '{"sender": "aHUrknDd", "recipient": "QJpM2gVw", "amount": 993}'}
This is mine first block chain!
{'Index': 0, 'Time': 1520946889.9901314, 'Difficulty': 0, 'Hash': '573521a64a463f826f44261e46337e256b11c34658a8516534dbbc858f530169', 'Nonce': 31826, 'PreviousHash': '0', 'TransactionData': '{"sender": "RhdN7Lis", "recipient": "zaU3CQLx", "amount": 3111}'}
{'Index': 1, 'Time': 1520946890.3774097, 'Difficulty': 22781, 'Hash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'Nonce': 259543941, 'PreviousHash': '573521a64a463f826f44261e46337e256b11c34658a8516534dbbc858f530169', 'TransactionData': '{"sender": "RuJAeWPG", "recipient": "NdIZQoLG", "amount": 852}'}
{'Index': 2, 'Time': 1520946890.713637, 'Difficulty': 10647, 'Hash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'Nonce': 56699515, 'PreviousHash': '4a3226377c70b5b8fa3199ad6ddd06ccacb2ad1cc8764443164d374d3a230000', 'TransactionData': '{"sender": "BEiclDIX", "recipient": "s7wC8uGx", "amount": 2793}'}
{'Index': 3, 'Time': 1520946891.6302867, 'Difficulty': 45103, 'Hash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'Nonce': 1017209586, 'PreviousHash': '583860cab5ae3b817568ae714c449be6e7097cbb4fee5367160ef415fed30000', 'TransactionData': '{"sender": "ORMqK4ZI", "recipient": "2W0iOVmA", "amount": 1191}'}
{'Index': 4, 'Time': 1520946891.656305, 'Difficulty': 15247, 'Hash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'Nonce': 116331987, 'PreviousHash': '1a5da6639e2d04160dbdf7cfcf909115d4d2dd9b17161b573e9e1702e24c0000', 'TransactionData': '{"sender": "BVtcOSnI", "recipient": "PnhZAStw", "amount": 7842}'}
{'Index': 5, 'Time': 1520946892.5919738, 'Difficulty': 9890, 'Hash': 'fe7c4e5b2e4396c8f8a5a0927d81ccccb4b6df5393d72f79c45daa85db550000', 'Nonce': 48948723, 'PreviousHash': '3c5e16da37c43e42e1b8aa88e65595940cde28f2be0b22c6dc6b67f280260000', 'TransactionData': '{"sender": "aHUrknDd", "recipient": "QJpM2gVw", "amount": 993}'}

参考实现 http://blog.csdn.net/bmwgaara/article/details/79059007

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值