写点什么

Python 与区块链:构建简单的加密货币钱包

  • 2024-08-21
    湖南
  • 本文字数:6498 字

    阅读完需:约 21 分钟

加密货币钱包是与区块链技术互动的关键工具之一。它们不仅存储用户的加密资产,还负责管理密钥对、生成交易、以及与区块链网络进行交互。本文章将介绍如何使用 Python 构建一个简单的加密货币钱包。我们将重点讨论钱包的基本结构、密钥生成、地址生成以及交易的创建和签名。

钱包的基本结构

一个加密货币钱包通常包含以下几个主要部分:

  • 密钥对生成:生成公钥和私钥对。

  • 地址生成:从公钥生成钱包地址。

  • 交易创建和签名:生成交易数据并用私钥进行签名。

  • 与区块链交互:将交易发送到区块链网络。

环境准备

首先,确保你已经安装了必要的 Python 库:

pip install ecdsa hashlib base58 requests
复制代码


密钥对生成


密钥对的生成是钱包创建的核心部分。我们将使用 ecdsa 库来生成一个基于椭圆曲线加密算法(ECDSA)的密钥对。

from ecdsa import SECP256k1, SigningKeyimport hashlibimport base58
# 生成私钥def generate_private_key(): return SigningKey.generate(curve=SECP256k1)
# 从私钥生成公钥def get_public_key(private_key): return private_key.get_verifying_key()
# 从公钥生成地址def get_address(public_key): public_key_bytes = public_key.to_string() sha256 = hashlib.sha256(public_key_bytes).digest() ripemd160 = hashlib.new('ripemd160', sha256).digest() address = b'\x00' + ripemd160 # 以太坊地址前缀(0x00) checksum = hashlib.sha256(hashlib.sha256(address).digest()).digest()[:4] address += checksum return base58.b58encode(address).decode()
private_key = generate_private_key()public_key = get_public_key(private_key)address = get_address(public_key)
print(f"Private Key: {private_key.to_string().hex()}")print(f"Public Key: {public_key.to_string().hex()}")print(f"Address: {address}")
复制代码

交易创建和签名

生成交易并用私钥签名是钱包的关键功能之一。以下示例演示了如何创建一个简单的交易并使用 ECDSA 签名。

import jsonimport requests
# 创建交易def create_transaction(from_address, to_address, amount, private_key): transaction = { "from": from_address, "to": to_address, "amount": amount, } transaction_json = json.dumps(transaction, sort_keys=True).encode() signature = private_key.sign(transaction_json) return transaction, signature.hex()
# 验证交易签名def verify_transaction(transaction, signature, public_key): transaction_json = json.dumps(transaction, sort_keys=True).encode() return public_key.verify(bytes.fromhex(signature), transaction_json)
from_address = address # 示例中的发送地址to_address = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa" # 示例中的接收地址amount = 0.1 # 示例中的交易金额
transaction, signature = create_transaction(from_address, to_address, amount, private_key)print(f"Transaction: {transaction}")print(f"Signature: {signature}")
# 验证签名public_key = get_public_key(private_key)is_valid = verify_transaction(transaction, signature, public_key)print(f"Signature Valid: {is_valid}")
复制代码

与区块链交互

为了将交易发送到区块链网络,我们可以使用 requests 库与区块链 API 进行交互。这里假设你使用的是一个支持交易广播的区块链 API(如 Bitcoin 或 Ethereum 的 API)。

def broadcast_transaction(transaction):    url = "https://blockchain-api.example.com/broadcast"  # 替换为实际的区块链API地址    response = requests.post(url, json=transaction)    return response.json()
# 广播交易response = broadcast_transaction(transaction)print(f"Broadcast Response: {response}")
复制代码

私钥的安全存储

在加密货币钱包中,私钥的安全性至关重要。私钥一旦泄露,恶意用户即可轻松转移你的资产。因此,必须采取适当的措施来保护私钥。


以下是几种常见的私钥存储方式:

  1. 本地文件加密:将私钥存储在本地文件中,并使用对称加密算法(如 AES)对文件进行加密。

  2. 硬件钱包:将私钥存储在专门的硬件设备中,如 Ledger 或 Trezor,这些设备通常具有强大的安全措施来防止私钥泄露。

  3. 分层确定性钱包(HD Wallet):通过一个种子短语生成多个私钥,这样可以在需要时恢复钱包。

代码示例:私钥的本地加密存储

我们可以使用 Python 的 cryptography 库来加密和解密私钥文件。

pip install cryptography
复制代码


from cryptography.fernet import Fernet
# 生成密钥并加密私钥def encrypt_private_key(private_key): key = Fernet.generate_key() cipher = Fernet(key) encrypted_private_key = cipher.encrypt(private_key.to_string()) # 存储加密的私钥和密钥 with open("encrypted_private_key.bin", "wb") as f: f.write(encrypted_private_key) with open("secret.key", "wb") as f: f.write(key)
# 解密私钥def decrypt_private_key(): with open("secret.key", "rb") as f: key = f.read() cipher = Fernet(key) with open("encrypted_private_key.bin", "rb") as f: encrypted_private_key = f.read() decrypted_private_key = cipher.decrypt(encrypted_private_key) return SigningKey.from_string(decrypted_private_key, curve=SECP256k1)
# 加密存储私钥encrypt_private_key(private_key)
# 解密并恢复私钥restored_private_key = decrypt_private_key()print(f"Restored Private Key: {restored_private_key.to_string().hex()}")
复制代码

多重签名交易

多重签名(Multisig)是一种增强钱包安全性的方法,它要求多个私钥签署交易才能执行。这在需要多方共同管理资产时特别有用,如企业账户或联合账户。

代码示例:多重签名交易

以下是如何使用 Python 创建一个简单的多重签名交易。

from ecdsa import BadSignatureError
# 创建多重签名交易def create_multisig_transaction(from_address, to_address, amount, private_keys): transaction = { "from": from_address, "to": to_address, "amount": amount, } transaction_json = json.dumps(transaction, sort_keys=True).encode() signatures = [] for key in private_keys: signatures.append(key.sign(transaction_json).hex()) return transaction, signatures
# 验证多重签名交易def verify_multisig_transaction(transaction, signatures, public_keys): transaction_json = json.dumps(transaction, sort_keys=True).encode() for i, signature in enumerate(signatures): try: if not public_keys[i].verify(bytes.fromhex(signature), transaction_json): return False except BadSignatureError: return False return True
# 示例:创建和验证多重签名交易private_key1 = generate_private_key()private_key2 = generate_private_key()public_key1 = get_public_key(private_key1)public_key2 = get_public_key(private_key2)
from_address = address # 示例中的发送地址to_address = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa" # 示例中的接收地址amount = 0.1 # 示例中的交易金额
transaction, signatures = create_multisig_transaction(from_address, to_address, amount, [private_key1, private_key2])is_valid = verify_multisig_transaction(transaction, signatures, [public_key1, public_key2])print(f"Multisig Transaction Valid: {is_valid}")
复制代码

钱包备份与恢复


备份钱包数据对于加密货币用户来说至关重要。如果设备丢失或损坏,用户仍然可以通过备份恢复访问其资产。

代码示例:钱包数据的备份与恢复

我们可以将私钥和其他重要数据以加密的形式进行备份。

import json
# 创建钱包备份def backup_wallet(private_key, public_key, address): wallet_data = { "private_key": private_key.to_string().hex(), "public_key": public_key.to_string().hex(), "address": address, } with open("wallet_backup.json", "w") as f: json.dump(wallet_data, f)
# 从备份中恢复钱包def restore_wallet_from_backup(file_path): with open(file_path, "r") as f: wallet_data = json.load(f) restored_private_key = SigningKey.from_string(bytes.fromhex(wallet_data["private_key"]), curve=SECP256k1) restored_public_key = get_public_key(restored_private_key) restored_address = wallet_data["address"] return restored_private_key, restored_public_key, restored_address
# 备份钱包backup_wallet(private_key, public_key, address)
# 恢复钱包restored_private_key, restored_public_key, restored_address = restore_wallet_from_backup("wallet_backup.json")print(f"Restored Address: {restored_address}")
复制代码

高级交易功能的实现

在实际应用中,钱包不仅仅用于简单的发送和接收加密货币。高级交易功能,如智能合约交互和复杂交易类型,在许多应用场景中都非常重要。接下来,我们将探讨如何在 Python 钱包中实现这些功能。

智能合约交互

智能合约是自动执行合约条款的代码,部署在区块链上。通过智能合约,用户可以实现去中心化的应用(DApps),如去中心化交易所(DEX)、借贷平台、NFT 市场等。我们将使用以太坊的智能合约作为示例,演示如何与智能合约进行交互。

代码示例:与以太坊智能合约交互

为了与以太坊智能合约交互,我们需要使用 web3.py 库:

pip install web3
复制代码

以下是如何使用 Python 与以太坊智能合约交互的基本步骤:

from web3 import Web3
# 连接到以太坊网络(这里使用Infura的Ropsten测试网节点)w3 = Web3(Web3.HTTPProvider('https://ropsten.infura.io/v3/YOUR_INFURA_PROJECT_ID'))
# 检查连接状态if not w3.isConnected(): raise Exception("Failed to connect to the Ethereum network")
# 合约地址和ABIcontract_address = '0xYourContractAddress'contract_abi = [...] # 合约的ABI定义
# 创建合约实例contract = w3.eth.contract(address=contract_address, abi=contract_abi)
# 读取合约状态(调用无状态变化的函数)result = contract.functions.someViewFunction().call()print(f"Contract state: {result}")
# 发送交易(调用改变合约状态的函数)transaction = contract.functions.someStateChangingFunction().buildTransaction
复制代码

与以太坊智能合约交互

在继续之前,你需要确保有一个有效的以太坊节点可以连接到主网或测试网。可以使用服务提供商如 Infura,或者直接运行一个本地的以太坊节点。

代码示例:与以太坊智能合约交互

首先,安装 web3.py 库:

pip install web3
复制代码

以下是如何使用 Python 与以太坊智能合约进行交互的基本步骤:

from web3 import Web3
# 连接到以太坊网络(这里使用Infura的Ropsten测试网节点)infura_url = "https://ropsten.infura.io/v3/YOUR_INFURA_PROJECT_ID"web3 = Web3(Web3.HTTPProvider(infura_url))
# 检查连接是否成功if web3.isConnected(): print("Connected to Ethereum network")else: print("Failed to connect")
# 合约的ABI(应用二进制接口)和合约地址contract_abi = [ # 合约的ABI在合约部署时生成]contract_address = "0xYourContractAddress"
# 创建合约对象contract = web3.eth.contract(address=contract_address, abi=contract_abi)
# 调用合约的一个只读方法def call_contract_method(method_name, *args): method = getattr(contract.functions, method_name) result = method(*args).call() return result
# 示例:调用智能合约中的一个方法result = call_contract_method("balanceOf", "0xAddressOfAccount")print(f"Account Balance: {result}")
# 发送交易调用合约方法def send_contract_transaction(private_key, method_name, *args): method = getattr(contract.functions, method_name) transaction = method(*args).buildTransaction({ 'chainId': 3, # Ropsten网络的链ID 'gas': 2000000, 'gasPrice': web3.toWei('50', 'gwei'), 'nonce': web3.eth.getTransactionCount(web3.eth.default_account), })
# 使用私钥签署交易 signed_txn = web3.eth.account.sign_transaction(transaction, private_key) # 发送交易 txn_hash = web3.eth.sendRawTransaction(signed_txn.rawTransaction) print(f"Transaction Hash: {web3.toHex(txn_hash)}")
# 示例:发送一个调用合约方法的交易private_key = "YourPrivateKey"send_contract_transaction(private_key, "transfer", "0xRecipientAddress", 100)
复制代码

创建自定义代币(ERC-20 Token)

你还可以使用智能合约来创建自定义的代币(Token)。最常见的标准是以太坊上的 ERC-20 标准,它定义了代币的基本功能和接口。

代码示例:部署 ERC-20 智能合约

在此示例中,我们将部署一个简单的 ERC-20 代币合约:

// SPDX-License-Identifier: MITpragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 { constructor(uint256 initialSupply) ERC20("MyToken", "MTK") { _mint(msg.sender, initialSupply); }}
复制代码

要部署该智能合约,可以使用以下 Python 脚本:

from solcx import compile_sourcefrom web3 import Web3
# Solidity源代码contract_source_code = '''// 这里粘贴你的Solidity合约代码'''
# 编译合约compiled_sol = compile_source(contract_source_code)contract_interface = compiled_sol['<stdin>:MyToken']
# 连接到以太坊网络infura_url = "https://ropsten.infura.io/v3/YOUR_INFURA_PROJECT_ID"web3 = Web3(Web3.HTTPProvider(infura_url))
# 设置默认账户(合约的部署者)web3.eth.default_account = web3.eth.account.privateKeyToAccount("YourPrivateKey")
# 创建合约对象MyToken = web3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
# 部署合约tx_hash = MyToken.constructor(1000000 * 10**18).transact()tx_receipt = web3.eth.waitForTransactionReceipt(tx_hash)
print(f"Contract Deployed At: {tx_receipt.contractAddress}")
复制代码

扩展功能

随着技术的进步,你可以扩展钱包的功能以满足特定需求。以下是一些建议:

  • 多币种支持:扩展钱包以支持比特币、以太坊、BNB、Cardano 等多种加密货币。

  • 去中心化身份验证:集成去中心化身份(DID)系统,提升用户的隐私与安全性。

  • 智能合约创建和管理:不仅限于调用智能合约,还可以允许用户创建、部署和管理智能合约。

  • NFT 支持:随着 NFT(非同质化代币)的流行,钱包还可以增加对 NFT 的管理功能,包括查看、转移和出售 NFT。

  • 跨链交易:实现跨不同区块链网络的交易功能,如使用跨链桥(Cross-chain Bridge)技术。

总结

本文详细介绍了如何使用 Python 构建一个简单的加密货币钱包,包括生成地址、私钥管理、多重签名交易、与智能合约交互等功能。这些基础功能构成了钱包应用的核心,同时也为后续的功能扩展提供了坚实的基础。


区块链技术和加密货币仍在快速发展,不断涌现出新的应用场景和技术挑战。作为开发者,掌握钱包开发的基础知识将使你能够更好地适应和应对这些挑战,参与到更复杂、更创新的区块链项目中。


作者:我是杰尼

链接:https://juejin.cn/post/7401327691893293082

用户头像

欢迎关注,一起学习,一起交流,一起进步 2020-06-14 加入

公众号:做梦都在改BUG

评论

发布
暂无评论
Python与区块链:构建简单的加密货币钱包_Python_我再BUG界嘎嘎乱杀_InfoQ写作社区