You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中通过web3.py与Metamask实现以太坊合约交易

解决方案

首先明确:后端(Django视图)无法直接触发浏览器端的Metamask签名请求,因为Metamask是运行在浏览器中的扩展,只能由前端JavaScript代码调用。你需要调整实现逻辑,采用「前端处理签名+后端辅助验证」的模式,具体步骤如下:

核心实现步骤

  • 步骤1:后端准备合约关键数据
    在Django视图中,提前准备好合约的ABI、合约地址、参与彩票所需的固定参数(比如彩票金额),将这些数据传递给前端模板。示例代码:

    # Django视图函数
    from django.shortcuts import render
    
    def lottery_participate(request):
        contract_address = "0xD5d56C139848A0E55DC5C616D04a0CeD98D8BeA3"
        # 简化的合约ABI(仅保留参与函数)
        contract_abi = [
            {
                "inputs": [],
                "name": "enterLottery",
                "outputs": [],
                "stateMutability": "payable",
                "type": "function"
            }
        ]
        lottery_entry_amount = "0.01"  # 参与彩票所需ETH金额(测试网)
        return render(request, 'participate.html', {
            'contract_address': contract_address,
            'contract_abi': contract_abi,
            'entry_amount': lottery_entry_amount
        })
    
  • 步骤2:前端JavaScript处理交易签名与发送
    在前端模板中,编写JS代码监听「参与彩票」按钮的点击事件,通过Metamask的eth_requestAccounts获取用户账户,然后构造交易并调用Metamask请求签名:

    // 前端JS代码
    document.getElementById('join-lottery-btn').addEventListener('click', async () => {
        if (typeof window.ethereum !== 'undefined') {
            try {
                // 确保用户已连接钱包
                const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
                const web3 = new Web3(window.ethereum);
                
                // 从后端获取的合约数据
                const contractAddress = "{{ contract_address }}";
                const contractAbi = JSON.parse('{{ contract_abi|escapejs }}');
                const entryAmount = web3.utils.toWei("{{ entry_amount }}", 'ether');
                
                // 初始化合约实例
                const lotteryContract = new web3.eth.Contract(contractAbi, contractAddress);
                
                // 构造交易并请求签名
                const txResponse = await lotteryContract.methods.enterLottery().send({
                    from: accounts[0],
                    value: entryAmount
                });
                
                // 交易发送成功后,可将txHash发送给后端记录
                fetch('/record-transaction/', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRFToken': getCSRFToken()  // Django的CSRF令牌
                    },
                    body: JSON.stringify({ tx_hash: txResponse.transactionHash })
                });
                
                alert('参与成功!交易哈希:' + txResponse.transactionHash);
            } catch (error) {
                console.error('交易失败:', error);
                alert('交易失败,请检查钱包设置');
            }
        } else {
            alert('请安装Metamask钱包');
        }
    });
    
    // 获取Django CSRF令牌的辅助函数
    function getCSRFToken() {
        return document.querySelector('[name=csrfmiddlewaretoken]').value;
    }
    
  • 步骤3:后端验证交易状态(可选)
    如果需要后端确认用户参与成功,可以在接收交易哈希的视图中,使用web3.py查询链上交易状态:

    # Django接收交易哈希的视图
    from django.http import JsonResponse
    from web3 import Web3
    
    def record_transaction(request):
        if request.method == 'POST':
            tx_hash = request.POST.get('tx_hash')
            w3 = Web3(Web3.HTTPProvider('https://sepolia.infura.io/v3/YOUR_INFURA_KEY'))
            tx_receipt = w3.eth.get_transaction_receipt(tx_hash)
            
            if tx_receipt.status == 1:
                # 交易成功,可更新数据库记录用户参与状态
                return JsonResponse({'status': 'success', 'message': '交易已确认'})
            else:
                return JsonResponse({'status': 'failed', 'message': '交易执行失败'})
        return JsonResponse({'status': 'error', 'message': '无效请求'})
    

关键注意事项

  • 确保前端引入web3.js库(可以通过CDN加载:<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>)
  • 处理Metamask的网络切换问题,确保用户当前连接的是Sepolia测试网
  • 后端不要存储用户的私钥或签名信息,所有签名操作必须由前端Metamask完成

内容的提问来源于stack exchange,提问作者Nilesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:35:20