简单实现区块链

这篇具有很好参考价值的文章主要介绍了简单实现区块链。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、区块链与区块链结构

# Block.py
import hashlib from datetime import datetime class Block: """ 区块链结构: prev_hash: 父区块哈希值 data: 区块内容 timestamp: 区块创建时间 hash: 区块哈希值 """ def __init__(self, data, prev_hash): # 将传入的父区块哈希值和数据保存到变量中 self.prev_hash = prev_hash self.data = data # 获得当前的时间 self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 计算区块哈希值 # 获取哈希对象 message = hashlib.sha256() # 先将数据内容转为字符串并进行编码,再将它们哈希 # 注意:update() 方法现在只接受 bytes 类型的数据,不接收 str 类型 message.update(str(self.prev_hash).encode('utf-8')) message.update(str(self.prev_hash).encode('utf-8')) message.update(str(self.prev_hash).encode('utf-8')) # update() 更新 hash 对象,连续的调用该方法相当于连续的追加更新 # 返回字符串类型的消息摘要 self.hash = message.hexdigest()
# BlockChain.py

from Block import Block
 
 
class BlockChain:
    """
        区块链结构体
            blocks:         包含区块的列表
    """
 
    def __init__(self):
        self.blocks = []
 
    def add_block(self, block):
        """
        添加区块
        :param block:
        :return:
        """
        self.blocks.append(block)
 
 
# 新建区块
genesis_block = Block(data="创世区块", prev_hash="")
new_block1 = Block(data="张三转给李四一个比特币", prev_hash=genesis_block.hash)
new_block2 = Block(data="张三转给王五三个比特币", prev_hash=genesis_block.hash)
 
# 新建一个区块链对象
blockChain = BlockChain()
# 将刚才新建的区块加入区块链
blockChain.add_block(genesis_block)
blockChain.add_block(new_block1)
blockChain.add_block(new_block2)
 
# 打印区块链信息
print("区块链包含区块个数为:%d\n" % len(blockChain.blocks))
blockHeight = 0
for block in blockChain.blocks:
    print(f"本区块高度为:{blockHeight}")
    print(f"父区块哈希:{block.prev_hash}")
    print(f"区块内容:{block.data}")
    print(f"区块哈希:{block.hash}")
    print()
    blockHeight += 1

二、加入工作量证明(POW)

# Block.py

import hashlib
from datetime import datetime
from time import time
 
 
class Block:
    """
        区块链结构:
            prev_hash:      父区块哈希值
            data:           区块内容
            timestamp:      区块创建时间
            hash:           区块哈希值
            nonce:          随机数
    """
    def __init__(self, data, prev_hash):
        # 将传入的父区块哈希值和数据保存到变量中
        self.prev_hash = prev_hash
        self.data = data
 
        # 获得当前的时间
        self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
        # 设置随机数、哈希初始值为 None
        self.nonce = None
        self.hash = None
 
    # 类的 __repr__() 方法定义了实例化对象的输出信息
    def __repr__(self):
        return f"区块内容:{self.data}\n区块哈希值:{self.hash}"
 
 
class ProofOfWork:
    """
        工作量证明:
            block:          区块
            difficulty:     难度值
    """
 
    def __init__(self, block, difficult=5):
        self.block = block
 
        # 定义出块难度,默认为 5,表示有效哈希值以 5 个零开头
        self.difficulty = difficult
 
    def mine(self):
        """
        挖矿函数
        :return:
        """
        i = 0
        prefix = '0' * self.difficulty
 
        while True:
            message = hashlib.sha256()
            message.update(str(self.block.prev_hash).encode('utf-8'))
            message.update(str(self.block.data).encode('utf-8'))
            message.update(str(self.block.timestamp).encode('utf-8'))
            message.update(str(i).encode('utf-8'))
            # digest() 返回摘要,作为二进制数据字符串值
            # hexdigest() 返回摘要,作为十六进制数据字符串值
            digest = message.hexdigest()
            # str.startswith(prefix) 检测字符串是否是以 prefix(字符串)开头,返回布尔值
            if digest.startswith(prefix):
                # 幸运数字
                self.block.nonce = i
                # 区块哈希值为十六进制数据字符串摘要
                self.block.hash = digest
                return self.block
            i += 1
 
    def validate(self):
        """
        验证有效性
        :return:
        """
        message = hashlib.sha256()
        message.update(str(self.block.prev_hash).encode('utf-8'))
        message.update(str(self.block.data).encode('utf-8'))
        message.update(str(self.block.timestamp).encode('utf-8'))
        message.update(str(self.block.nonce).encode('utf-8'))
        digest = message.hexdigest()
 
        prefix = '0' * self.difficulty
        return digest.startswith(prefix)
 
 
# ++++++++测试++++++++
# 定义一个区块
b = Block(data="测试", prev_hash="")
 
# 定义一个工作量证明
w = ProofOfWork(b)
 
# 开始时间
start_time = time()
# 挖矿,并统计函数执行时间
print("+++开始挖矿+++")
valid_block = w.mine()
# 结束时间
end_time = time()
print(f"挖矿花费时间:{end_time - start_time}秒")
 
# 验证区块
print(f"区块哈希值是否符合规则:{w.validate()}")
print(f"区块哈希值为:{b.hash}")
# 更新BlockChain.py

from Block import Block, ProofOfWork
 
 
class BlockChain:
    """
        区块链结构体
            blocks:         包含区块的列表
    """
 
    def __init__(self):
        self.blocks = []
 
    def add_block(self, block):
        """
        添加区块
        :param block:
        :return:
        """
        self.blocks.append(block)
 
 
# 新建一个区块链对象
blockChain = BlockChain()
 
# 新建区块
block1 = Block(data="创世区块", prev_hash="")
w1 = ProofOfWork(block1)
genesis_block = w1.mine()
blockChain.add_block(genesis_block)
 
block2 = Block(data="张三转给李四一个比特币", prev_hash=genesis_block.hash)
w2 = ProofOfWork(block2)
block = w2.mine()
blockChain.add_block(block)
 
block3 = Block(data="张三转给王五三个比特币", prev_hash=block.hash)
w3 = ProofOfWork(block3)
block = w3.mine()
blockChain.add_block(block)
 
# 打印区块链信息
print("区块链包含区块个数为:%d\n" % len(blockChain.blocks))
blockHeight = 0
for block in blockChain.blocks:
    print(f"本区块高度为:{blockHeight}")
    print(f"父区块哈希:{block.prev_hash}")
    print(f"区块内容:{block.data}")
    print(f"区块哈希:{block.hash}")
    print()
    blockHeight += 1

三、实现钱包、账户、交易

# Wallet.py

import base64
import binascii
from hashlib import sha256
# 导入椭圆曲线算法
from ecdsa import SigningKey, SECP256k1, VerifyingKey
 
 
class Wallet:
    """
        钱包
    """
 
    def __init__(self):
        """
            钱包初始化时基于椭圆曲线生成一个唯一的秘钥对,代表区块链上一个唯一的账户
        """
        # 生成私钥
        self._private_key = SigningKey.generate(curve=SECP256k1)
        # 基于私钥生成公钥
        self._public_key = self._private_key.get_verifying_key()
 
    @property
    def address(self):
        """
            这里通过公钥生成地址
        """
        h = sha256(self._public_key.to_pem())
        # 地址先由公钥进行哈希算法,再进行 Base64 计算而成
        return base64.b64encode(h.digest())
 
    @property
    def pubkey(self):
        """
            返回公钥字符串
        """
        return self._public_key.to_pem()
 
    def sign(self, message):
        """
            生成数字签名
        """
        h = sha256(message.encode('utf8'))
        # 利用私钥生成签名
        # 签名生成的是一串二进制字符串,为了便于查看,这里转换为 ASCII 字符串进行输出
        return binascii.hexlify(self._private_key.sign(h.digest()))
 
 
def verify_sign(pubkey, message, signature):
    """
        验证签名
    """
    verifier = VerifyingKey.from_pem(pubkey)
    h = sha256(message.encode('utf8'))
    return verifier.verify(binascii.unhexlify(signature), h.digest())
# Transaction.py

import json
 
 
class Transaction:
    """
        交易的结构
    """
 
    def __init__(self, sender, recipient, amount):
        """
            初始化交易,设置交易的发送方、接收方和交易数量
        """
        # 交易发送者的公钥
        self.pubkey = None
        # 交易的数字签名
        self.signature = None
 
        if isinstance(sender, bytes):
            sender = sender.decode('utf-8')
        self.sender = sender        # 发送方
        if isinstance(recipient, bytes):
            recipient = recipient.decode('utf-8')
        self.recipient = recipient  # 接收方
        self.amount = amount        # 交易数量
 
    def set_sign(self, signature, pubkey):
        """
            为了便于验证这个交易的可靠性,需要发送方输入他的公钥和签名
        """
        self.signature = signature  # 签名
        self.pubkey = pubkey  # 发送方公钥
 
    def __repr__(self):
        """
            交易大致可分为两种,一是挖矿所得,而是转账交易
            挖矿所得无发送方,以此进行区分显示不同内容
        """
        if self.sender:
            s = f"从{self.sender}转自{self.recipient}{self.amount}个加密货币"
        elif self.recipient:
            s = f"{self.recipient}挖矿所得{self.amount}个加密货币"
        else:
            s = "error"
        return s
 
 
class TransactionEncoder(json.JSONEncoder):
    """
        定义Json的编码类,用来序列化Transaction
    """
    def default(self, obj):
        if isinstance(obj, Transaction):
            return obj.__dict__
        else:
            return json.JSONEncoder.default(self, obj)
            # return super(TransactionEncoder, self).default(obj)
# 更新Block.py

import hashlib
import json
from datetime import datetime
from Transaction import Transaction, TransactionEncoder
 
 
class Block:
    """
        区块结构
            prev_hash:      父区块哈希值
            transactions:   交易对
            timestamp:      区块创建时间
            hash:           区块哈希值
            Nonce:          随机数
    """
 
    def __init__(self, transactions, prev_hash):
        # 将传入的父哈希值和数据保存到类变量中
        self.prev_hash = prev_hash
        # 交易列表
        self.transactions = transactions
        # 获取当前时间
        self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
        # 设置Nonce和哈希的初始值为None
        self.nonce = None
        self.hash = None
 
    # 类的 __repr__() 方法定义了实例化对象的输出信息
    def __repr__(self):
        return f"区块内容:{self.transactions}\n区块哈希值:{self.hash}"
 
 
class ProofOfWork:
    """
        工作量证明
            block:          区块
            difficulty:     难度值
    """
 
    def __init__(self, block, miner, difficult=5):
        self.block = block
        self.miner = miner
 
        # 定义工作量难度,默认为5,表示有效的哈希值以5个“0”开头
        self.difficulty = difficult
 
        # 添加挖矿奖励
        self.reward_amount = 1
 
    def mine(self):
        """
            挖矿函数
        """
        i = 0
        prefix = '0' * self.difficulty
 
        # 设置挖矿自动生成交易信息,添加挖矿奖励
        t = Transaction(
            sender="",
            recipient=self.miner.address,
            amount=self.reward_amount,
        )
        sig = self.miner.sign(json.dumps(t, cls=TransactionEncoder))
        t.set_sign(sig, self.miner.pubkey)
        self.block.transactions.append(t)
 
        while True:
            message = hashlib.sha256()
            message.update(str(self.block.prev_hash).encode('utf-8'))
            # 更新区块中的交易数据
            # message.update(str(self.block.data).encode('utf-8'))
            message.update(str(self.block.transactions).encode('utf-8'))
            message.update(str(self.block.timestamp).encode('utf-8'))
            message.update(str(i).encode("utf-8"))
            digest = message.hexdigest()
            if digest.startswith(prefix):
                self.block.nonce = i
                self.block.hash = digest
                return self.block
            i += 1
 
    def validate(self):
        """
            验证有效性
        """
        message = hashlib.sha256()
        message.update(str(self.block.prev_hash).encode('utf-8'))
        # 更新区块中的交易数据
        # message.update(str(self.block.data).encode('utf-8'))
        message.update(json.dumps(self.block.transactions).encode('utf-8'))
        message.update(str(self.block.timestamp).encode('utf-8'))
        message.update(str(self.block.nonce).encode('utf-8'))
        digest = message.hexdigest()
 
        prefix = '0' * self.difficulty
        return digest.startswith(prefix)
# 更新BlockChain.py

from Block import Block, ProofOfWork
from Transaction import Transaction
from Wallet import Wallet, verify_sign
 
 
class BlockChain:
    """
        区块链结构体
            blocks:        包含的区块列表
    """
 
    def __init__(self):
        self.blocks = []
 
    def add_block(self, block):
        """
            添加区块
        """
        self.blocks.append(block)
 
    def print_list(self):
        print(f"区块链包含个数为:{len(self.blocks)}")
        for block in self.blocks:
            height = 0
            print(f"区块链高度为:{height}")
            print(f"父区块为:{block.prev_hash}")
            print(f"区块内容为:{block.transactions}")
            print(f"区块哈希值为:{block.hash}")
            height += 1
            print()
# 追加到BlockChain.py

# 传入用户和区块链,返回用户的“余额”
def get_balance(user, blockchain):
    balance = 0
    for block in blockchain.blocks:
        for t in block.transactions:
            if t.sender == user.address.decode():
                balance -= t.amount
            elif t.recipient == user.address.decode():
                balance += t.amount
    return balance
 
 
# user生成创世区块(新建区块链),并添加到区块链中
def generate_genesis_block(user):
    blockchain = BlockChain()
    new_block = Block(transactions=[], prev_hash="")
    w = ProofOfWork(new_block, user)
    genesis_block = w.mine()
    blockchain.add_block(genesis_block)
    # 返回创世区块
    return blockchain
 
 
# 用户之间进行交易并记入交易列表
def add_transaction(sender, recipient, amount):
    # 新建交易
    new_transaction = Transaction(
        sender=sender.address,
        recipient=recipient.address,
        amount=amount
    )
    # 生成数字签名
    sig = sender.sign(str(new_transaction))
    # 传入付款方的公钥和签名
    new_transaction.set_sign(sig, sender.pubkey)
    return new_transaction
 
 
# 验证交易,若验证成功则加入交易列表
def verify_new_transaction(new_transaction, transactions):
    if verify_sign(new_transaction.pubkey,
                   str(new_transaction),
                   new_transaction.signature
                   ):
        # 验证交易签名没问题,加入交易列表
        print("交易验证成功")
        transactions.append(new_transaction)
    else:
        print("交易验证失败")
 
 
# 矿工将全部验证成功的交易列表打包出块
def generate_block(miner, transactions, blockchain):
    new_block = Block(transactions=transactions,
                      prev_hash=blockchain.blocks[len(blockchain.blocks) - 1].hash)
    print("生成新的区块...")
    # 挖矿
    w = ProofOfWork(new_block, miner)
    block = w.mine()
    print("将新区块添加到区块链中")
    blockchain.add_block(block)
# 测试

# 新建交易列表
transactions = []
 
# 创建 3 个用户
alice = Wallet()
tom = Wallet()
bob = Wallet()
 
print("alice创建创世区块...")
blockchain = generate_genesis_block(alice)
print()
 
print(f"alice 的余额为{get_balance(alice, blockchain)}个比特币")
print(f"tom 的余额为{get_balance(tom, blockchain)}个比特币")
print(f"bob 的余额为{get_balance(bob, blockchain)}个比特币")
print()
 
# 打印区块链信息
blockchain.print_list()
 
print("新增交易:alice 转账 0.5 比特币给 tom")
nt = add_transaction(alice, tom, 0.5)
print()
verify_new_transaction(nt, transactions)
print(f"矿工 bob 将全部验证成功的交易列表打包出块...")
generate_block(bob, transactions, blockchain)
print("添加完成\n")
 
# 打印区块链信息
blockchain.print_list()

结束!文章来源地址https://www.toymoban.com/news/detail-752273.html

到了这里,关于简单实现区块链的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python实现简单的区块链

    运用datetime和hashlib模拟实现区块链 区块函数 包含区块高度标识:blockNo 交易数据:data nonce值 preious_hash:上一个区块哈希 timestamp:当前时间 链函数 分别包括三个方法,添加块的方法、挖矿功能、以及打包交易 添加块的方法: 挖矿功能(采用的是工作量证明共识机制) 打包交

    2024年02月06日
    浏览(29)
  • Java实现一个简单的区块链

    区块链技术是近年来非常热门的话题,它在加密货币、供应链管理、智能合约等领域有着广泛的应用。本文将通过一个具体的Java代码案例,展示如何实现一个简单的区块链。我们将首先展示代码案例,然后逐步解析其中的关键技术和知识点,以便读者能够更好地理解和应用这

    2024年03月22日
    浏览(42)
  • 【Python】实现一个简单的区块链系统

    本文章利用 Python 实现一个简单的功能较为完善的区块链系统(包括区块链结构、账户、钱包、转账),采用的共识机制是 POW。 Block.py  BlockChain.py  测试结果  将工作量证明加入到 Block.py 中 测试结果 更新 BlockChain.py  测试结果  实现钱包、账户、交易功能要先安装非对称加

    2024年02月11日
    浏览(33)
  • 使用python搭建简单的区块链,并实现数据上链

    目录 一、引入库文件 二、编写消息类 三、编写区块类 四、编写区块链 五、编写主函数 六、运行 引入所需的库文件,其中hashlib为核心文件。 通过编写消息类,将消息读入并进行哈希运算,与前面的消息进行连接等操作。 通过编写区块类,使用前一区块的哈希值与时间戳等

    2024年02月12日
    浏览(30)
  • 仅仅用java就能简单实现区块链(BlockChain)

    区块链逻辑:根据所需信息创建一个区块,再利用定义的计算hash值方法,不断进行计算,直到达到想要的结果,再通过层层验证,加入到我们的区块链中。 所谓挖矿,就是进行不断地计算,直到“挖到”,而这步算法我们是借助hash算法完成的。 老实说,“挖矿”这件事本身

    2024年02月02日
    浏览(34)
  • Java实现Tron(波场)区块链的开发实践(一)环境搭建及简单实现

    最近在开发区块链相关项目时,因本人一直使用JAVA做开发语言,但是区块链开发对JAVA语言相对来说不是很友好。在开发过程中遇到很多的问题,甚至通过百度、Google都无法解决,官方文档大部分篇幅在介绍接口相关信息,对Java实现不多。 可是为了赚点钱,也是硬着头皮,经

    2024年04月08日
    浏览(35)
  • 用Java来实现区块链原理并简单模拟开发一个小工具

    前几天心血来潮,用Java模拟实现了一个区块链小工具,该工具是单机版的,没有实现联网功能,属于是单节点的工具,但是对于区块链的核心wk逻辑功能都实现了,如:wk、钱包、转账、记账等功能。界面实现用到了Java的swing包。 下面先看下运行的效果: 主界面: 转账:  

    2024年02月11日
    浏览(31)
  • 创建一个简单的区块链,并使用 Flask 框架提供一个简单的 Web 接口来与区块链交互。

    目录 前言 一、代码展示 二、代码注释 1.简单的区块链模拟实现,这段代码定义了一个简单的区块链类,可以创建一个新的区块链,并能够添加新的区块到链上,同时获取最新的区块信息。这个模拟的区块链可以用于教学或演示区块链的基本概念。 2.这段代码是一个简单的工

    2024年04月14日
    浏览(37)
  • 区块链网络层简单介绍

    区块链网络层主要通过 P2P 技术实现分布式网络的机制,网络层包括 P2P 组网机制、数据传播机制和数据验证机制,因此区块链本质上是一个 P2P 的网络,具备自动组网的机制,节点之间通过维护一个共同的区块链结构来保持通信。 P2P 主要存在四种不同的网络模型,也代表着

    2024年02月03日
    浏览(25)
  • 区块链简单介绍

    区块链的分布式网络是其核心技术之一,它使得整个系统具有高度的安全性、可靠性和可扩展性。具体来说,区块链的分布式网络有以下几个特点: 去中心化:区块链的分布式网络是一个去中心化的网络结构,没有中心化的控制机构,每个节点都是平等的,可以相互通信和交

    2024年02月04日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包