通过deepseek生成的简单区块链代码(已调试)
deepseek最近大火,自己通过deepseek生成一段简单的区块链代码,并且调试成功。通过python语言编写,希望能帮助想了解区块链底层逻辑的朋友们。
deepseek最近大火,自己通过deepseek生成一段简单的区块链代码,并且调试成功。通过python语言编写,希望能帮助想了解区块链底层逻辑的朋友们。
由于是简易区块链,所以有几点不足,实际区块链需要以下增强:
1、网络通信(P2P网络)2、UTXO模型改进 3、更复杂的安全机制 4、交易手续费机制 5、更高效的数据存储 5、智能合约支持
后续会完善代码,完善后会继续更新。废话不多说,上代码:
import hashlib
import json
from time import time
from typing import List, Dict
from ecdsa import SigningKey, VerifyingKey, NIST256p
#定义交易的类
class Transaction:
def __init__(self, sender: str, recipient: str, amount: float):
self.sender = sender # 发送者地址
self.recipient = recipient# 接收者地址
self.amount = amount # 转账金额
self.signature = None # 数字签名后的信息
def sign(self, private_key: SigningKey):
#"""用私钥对交易进行签名 (通过椭圆签名算法ecdsa)"""
tx_data = self._serialize() #_serialize() 方法将当前对象的状态信息序列化,存储在tx_data中
self.signature = private_key.sign(tx_data.encode()) #tx_data是要被签名的数据,通过私钥private_key生成数字签名后的信息存储在signature
def is_valid(self) -> bool: #-> bool::这是类型提示的一部分,用于指示该方法返回一个布尔值
#"""验证交易签名有效性"""
if self.sender == "0": # 没有发送者,则为系统奖励交易
return True
tx_data = self._serialize() #_serialize() 方法将当前对象的状态信息序列化,存储在tx_data中
vk = VerifyingKey.from_string(bytes.fromhex(self.sender), curve=NIST256p) #创建验证密钥
try:
#第一个参数是签名(self.signature),这是要验证的数据的数字签名。
#第二个参数是已编码的数据(tx_data.encode()),这是原始数据,其完整性或真实性需要通过签名来验证。
#如果返回 True,则表示签名有效,即数据未被篡改且确实由声称的签名者签名
return vk.verify(self.signature, tx_data.encode())
except:
return False
def _serialize(self) -> str:
#"""序列化交易数据(排除签名)"""
return json.dumps({
"sender": self.sender,
"recipient": self.recipient,
"amount": self.amount
}, sort_keys=True) #json.dumps() 函数是用来将 Python 对象编码成 JSON 字符串,sort 参数指出需要排序
#定义区块
class Block:
def __init__(self, index: int, transactions: List[Transaction], previous_hash: str):
self.index = index # 区块高度
self.timestamp = time() # 时间戳
self.transactions = transactions # 交易列表
self.previous_hash = previous_hash # 前区块哈希
# 工作量证明随机数 每次都是通过改变nonce这个值让工作量证明每次哈希值的计算的值不一样
# 但是确认nonce后,用确认的区块进行哈希运算,得到的就是一个确定的哈希值,可以用于验证区块完整性和不可篡改性
self.nonce = 0
self.hash = self.calculate_hash() # 当前哈希
def calculate_hash(self) -> str:
#"""计算区块哈希值"""
#transactions 获取每个 Transaction 实例的属性字典
#注意,每次都是通过改变nonce这个值让工作量证明每次哈希值的计算的值不一样
bytes_data=b'{"index": self.index,"timestamp": self.timestamp,"transactions": [tx.__dict__ for tx in self.transactions], "previous_hash": self.previous_hash,"nonce": self.nonce }'
str_data=bytes_data.decode('utf-8')
block_data = json.dumps(str_data, sort_keys=True).encode()
return hashlib.sha256(block_data).hexdigest() #生成sha-256算法的哈希值并转化成十六进制表示形式的字符串
#定义区块链
class Blockchain:
def __init__(self):
self.chain: List[Block] = [] #初始化区块链列表
self.pending_transactions: List[Transaction] = [] #初始化待处理交易列表
self.mining_reward = 20 # 挖矿奖励
self.difficulty = 1 # 挖矿难度(哈希前导零数量)
# 创建创世块
self.create_genesis_block()
#定义创世区块函数
def create_genesis_block(self):
genesis_block = Block(0, [], "0")
genesis_block.hash = genesis_block.calculate_hash() #生成哈希值
self.chain.append(genesis_block) #将创世区块加入区块链列表
def add_transaction(self, transaction: Transaction):
#"""添加新交易到待处理交易池"""
if not transaction.is_valid(): #验证交易签名有效性
raise ValueError("Invalid transaction signature")
self.pending_transactions.append(transaction) #添加交易到待处理交易池
def mine_pending_transactions(self, miner_address: str):
#"""挖矿打包交易"""
#block= Block(0, [], "0")
#block.index=len(self.chain)
#block.transactions=self.pending_transactions
#block.previous_hash=self.get_last_block().hash
block = Block(
len(self.chain),
self.pending_transactions,
self.get_last_block().hash
)
# 工作量证明 用新区块计算哈希值,到前面有难度值个0为止,作为新区块的哈希值
while not block.hash.startswith('0' * self.difficulty):
block.nonce += 1
block.hash = block.calculate_hash()
print(f"Block mined: {block.hash}")
self.chain.append(block) #将新的块加入链中
self.pending_transactions.append(Transaction("0", miner_address, self.mining_reward)) #加入新的交易,为奖励mining_reward个金额,sender为0表示为奖励金额
def get_balance(self, address: str) -> float:
#"""获取地址余额"""
balance = 0.0
#遍历所有区块的交易链,计算指定地址的余额
for block in self.chain:
for tx in block.transactions:
if tx.sender == address:
balance -= tx.amount
if tx.recipient == address:
balance += tx.amount
return balance
def get_last_block(self) -> Block:
#"""获取最新区块"""
return self.chain[-1]
def is_chain_valid(self) -> bool:
#"""验证区块链完整性"""
for i in range(1, len(self.chain)):
current = self.chain[i]
previous = self.chain[i-1]
#如果现在区块的哈希值不等于区块哈希运算后的值,说明本区块被篡改
if current.hash != current.calculate_hash():
return False
#如果现在区块记录的之前区块的哈希值不等于区块链上之前区块的哈希值,说明区块被篡改
if current.previous_hash != previous.hash:
return False
#遍历现在区块的交易链,验证每个交易的签名有效性
for tx in current.transactions:
if not tx.is_valid():
return False
return True
#定义钱包
class Wallet:
#初始化钱包字段:
# private_key:私钥 利用椭圆算法ecdsa库生成私钥,该私钥可以用于生成公钥
# public_keyi:公钥 通过生成的私钥生成公钥
# 加密数据时使用公钥,解密数据时使用私钥
# address :地址 将公钥通过处理后,再生成地址
# 在比特币等区块链中,通常需要将公钥通过SHA-256哈希和RIPEMD-160哈希处理后,再通过Base58Check编码来生成地址,这里是简单处理转换为十六进制字符串
def __init__(self):
self.private_key = SigningKey.generate(curve=NIST256p)
self.public_key = self.private_key.get_verifying_key()
self.address = self.public_key.to_string().hex()
def send_money(self, recipient: str, amount: float) -> Transaction:
#"""创建并签名交易"""
tx = Transaction(self.address, recipient, amount)
tx.sign(self.private_key)
return tx #返回交易信息
# 使用示例
if __name__ == "__main__":
# 初始化区块链和钱包
blockchain = Blockchain()
wallet1 = Wallet()
wallet2 = Wallet()
print(f"Wallet 1 地址: {wallet1.address}")
print(f"Wallet 2 地址: {wallet2.address}")
# 创建并提交交易
tx = wallet1.send_money(wallet2.address, 5)
blockchain.add_transaction(tx)
# 挖矿打包交易
print("开始挖矿...")
blockchain.mine_pending_transactions(wallet1.address)
print(f"Wallet1 余额: {blockchain.get_balance(wallet1.address)}")
print(f"Wallet2 余额: {blockchain.get_balance(wallet2.address)}")
# 验证区块链
print(f"区块链是否有效? {'是' if blockchain.is_chain_valid() else '否'}")
更多推荐
所有评论(0)