今天咱们用Python搞点有意思的——用Web3.py库开发一个真正的区块链应用。想象一下,你正在创建一个不会被篡改的投票系统,每个投票记录都永久保存在区块链上,这可比传统数据库酷多了!


先准备好工具箱

安装必要的库:

pip install web3 solcx python-dotenv

solcx是Solidity编译器,python-dotenv用来读取私钥等敏感信息。记得在项目根目录创建.env文件保存你的钱包私钥:

PRIVATE_KEY=你的钱包私钥
INFURA_URL=你的Infura节点URL

温馨提示:千万别把私钥直接写在代码里!新手常犯这个低级错误,分分钟钱包被掏空。


写个智能合约试试手

新建Vote.sol文件,用Solidity语言写投票合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Voting {
    mapping(address => bool) public hasVoted;
    mapping(string => uint) public votesCount;
    string[] public candidates;

    constructor(string[] memory _candidates) {
        candidates = _candidates;
    }

    function vote(string memory candidate) public {
        require(!hasVoted[msg.sender], "Already voted");
        require(isValidCandidate(candidate), "Invalid candidate");
        
        hasVoted[msg.sender] = true;
        votesCount[candidate] += 1;
    }

    function isValidCandidate(string memory candidate) private view returns(bool) {
        for(uint i=0; i<candidates.length; i++) {
            if(keccak256(bytes(candidates[i])) == keccak256(bytes(candidate))) {
                return true;
            }
        }
        return false;
    }
}

这合约做了三件事:初始化候选人列表、防止重复投票、验证候选人有效性。区块链上的代码就像永不休息的公证人,忠实地执行这些规则。


用Python和合约对话

部署合约的Python脚本:

from web3 import Web3
from solcx import compile_standard, install_solc
import json
import os
from dotenv import load_dotenv

load_dotenv()
install_solc('0.8.0')

# 编译合约
with open("Vote.sol", "r") as f:
    contract_source = f.read()

compiled_sol = compile_standard({
    "language": "Solidity",
    "sources": {"Vote.sol": {"content": contract_source}},
    "settings": {"outputSelection": {"*": {"*": ["abi", "evm.bytecode"]}}}
})

# 连接区块链
w3 = Web3(Web3.HTTPProvider(os.getenv("INFURA_URL")))
account = w3.eth.account.from_key(os.getenv("PRIVATE_KEY"))

# 部署合约
contract = w3.eth.contract(
    abi=compiled_sol['contracts']['Vote.sol']['Voting']['abi'],
    bytecode=compiled_sol['contracts']['Vote.sol']['Voting']['evm']['bytecode']['object']
)

tx = contract.constructor(["Alice", "Bob"]).build_transaction({
    'from': account.address,
    'nonce': w3.eth.get_transaction_count(account.address),
    'gas': 1728712,
    'gasPrice': w3.to_wei('21', 'gwei')
})

signed_tx = account.sign_transaction(tx)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"合约地址: {tx_receipt.contractAddress}")

运行后你会得到一个类似0x5B3...的合约地址,这就是你的投票系统在区块链上的身份证号码。


投票功能实现

和合约交互的Python代码:

# 初始化已部署的合约
contract_address = "你的合约地址"
contract = w3.eth.contract(
    address=contract_address,
    abi=compiled_sol['contracts']['Vote.sol']['Voting']['abi']
)

# 执行投票
def cast_vote(candidate):
    tx = contract.functions.vote(candidate).build_transaction({
        'from': account.address,
        'nonce': w3.eth.get_transaction_count(account.address)
    })
    signed_tx = account.sign_transaction(tx)
    return w3.eth.send_raw_transaction(signed_tx.rawTransaction)

# 查询票数
def get_votes(candidate):
    return contract.functions.votesCount(candidate).call()

# 测试投票
cast_vote("Alice")
print(f"Alice得票数: {get_votes('Alice')}")  # 输出1

试试给不存在的候选人投票,你会看到合约像严厉的监考老师一样抛出错误——这就是智能合约的可靠性。


搞个简单的前端

用Flask做个可视化界面(完整版需要处理会话和错误):

from flask import Flask, request
app = Flask(__name__)

@app.route('/vote', methods=['POST'])
def handle_vote():
    candidate = request.form['candidate']
    try:
        cast_vote(candidate)
        return f"成功投给{candidate}!"
    except Exception as e:
        return str(e), 400

@app.route('/results')
def show_results():
    return {
        "Alice": get_votes("Alice"),
        "Bob": get_votes("Bob")
    }

if __name__ == '__main__':
    app.run(port=3000)

现在访问http://localhost:3000/results就能看到实时票数,区块链的数据就像公开的玻璃柜,谁都能查看但无法篡改。


这些坑你别踩

  • • Gas费用估算:用estimate_gas()方法提前计算交易成本,别让用户因为Gas费不足投票失败

  • • 事件监听:合约里可以添加Voted事件,用Web3.py的过滤器实时捕获新投票

  • • 测试网络:先用Rinkeby或Goerli测试网练手,别在主网上烧真金白银

  • • 错误处理:捕获ContractLogicError等异常,给用户友好提示而不是满屏红色错误

现在你手里已经握着进入Web3世界的钥匙了。区块链不是魔法,本质就是代码+密码学+分布式系统,多动手部署几个合约,很快就能找到感觉。下次咱们可以试试给投票系统加上代币激励,让参与者获得投票积分——那才是真正的区块链玩法!

Logo

一站式 AI 云服务平台

更多推荐