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

使用web3.py的send_raw_transaction方法发送交易失败求助

Ganache + web3.py 转账报错:exceeds block gas limit 解决办法

我在测试web3.py的send_raw_transaction方法,试图将ETH从一个账户转到另一个账户,用Ganache做测试环境。严格按照web3文档步骤操作,但每次都报错,问题出在send_raw_transaction调用上。

原代码

from web3 import Web3
from web3.middleware import geth_poa_middleware
import json

# GANACHE. TESTING TRANSACTIONS
ganache_url = "http://127.0.0.1:7545"
w3 = Web3(Web3.HTTPProvider(ganache_url))

# accs and keys
account_1 = "0x72e94DaE4d186639B9Bb2baA89caa4Da5f931231"
account_2 = "0xaB2fF898c56a43f56845180081A0C467f2640332"
privatekey_1 = "0x5af8420db3d42b3fc14a13f64dd8dd490783746fdea406ac68afc9b3b9e51132"

# getting eth balance
balance_gwei = w3.eth.get_balance(account_1)
k = 10 ** 18
balance_eth = balance_gwei/k

nonce = w3.eth.get_transaction_count(account_1)

tx = {
    "nonce": nonce,
    "to":   account_2,
    "value":    w3.to_wei(1, "ether"),
    "gas":  20000000000,
    "gasPrice": w3.to_wei("50", "gwei"),
}


print(balance_eth)
signed_tx = w3.eth.account.sign_transaction(tx, privatekey_1)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
print(balance_eth)

终端错误输出

(venv) PS C:\Users\Kirill\Desktop\PYTHON\CRYPTO_PAYMENTS_PYTHON> python main.py

100.0
Traceback (most recent call last):
  File "C:\Users\Kirill\Desktop\PYTHON\CRYPTO_PAYMENTS_PYTHON\main.py", line 34, in <module>
    tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Kirill\Desktop\PYTHON\CRYPTO_PAYMENTS_PYTHON\venv\Lib\site-packages\web3\eth\eth.py", line 396, in send_raw_transaction
    return self._send_raw_transaction(transaction)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Kirill\Desktop\PYTHON\CRYPTO_PAYMENTS_PYTHON\venv\Lib\site-packages\web3\module.py", line 75, in caller
    result = w3.manager.request_blocking(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Kirill\Desktop\PYTHON\CRYPTO_PAYMENTS_PYTHON\venv\Lib\site-packages\web3\manager.py", line 330, in request_blocking
    return self.formatted_response(
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Kirill\Desktop\PYTHON\CRYPTO_PAYMENTS_PYTHON\venv\Lib\site-packages\web3\manager.py", line 293, in formatted_response
    raise ValueError(error)
ValueError: {'message': 'exceeds block gas limit', 'stack': 'Error: exceeds block gas limit\n    at TransactionPool.<anonymous> (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:120454)\n    at TransactionPool.prepareTransaction (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:120796)\n    at TransactionManager.add (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:138284)\n    at Blockchain.queueTransaction (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:70776)\n    at EthereumApi.eth_sendRawTransaction (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:88213)\n    at EthereumApi.n.value (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:238968)\n    at Object.execute (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:165607)\n    at RequestCoordinator.<anonymous> (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:165421)\n    at C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:165687)\n    at new Promise (<anonymous>)', 'code': -32000}

问题分析

错误信息明确指出exceeds block gas limit(超出区块gas限制),问题出在你设置的gas参数上:代码里写的20000000000远大于Ganache默认的区块gas限制(通常是6721975左右),而且普通ETH转账只需要固定的21000 gas。

修复后的代码

方法1:手动设置正确的gas值

把gas改成21000即可:

from web3 import Web3
from web3.middleware import geth_poa_middleware
import json

# GANACHE. TESTING TRANSACTIONS
ganache_url = "http://127.0.0.1:7545"
w3 = Web3(Web3.HTTPProvider(ganache_url))

# accs and keys
account_1 = "0x72e94DaE4d186639B9Bb2baA89caa4Da5f931231"
account_2 = "0xaB2fF898c56a43f56845180081A0C467f2640332"
privatekey_1 = "0x5af8420db3d42b3fc14a13f64dd8dd490783746fdea406ac68afc9b3b9e51132"

# getting eth balance
balance_gwei = w3.eth.get_balance(account_1)
k = 10 ** 18
balance_eth = balance_gwei/k

nonce = w3.eth.get_transaction_count(account_1)

tx = {
    "nonce": nonce,
    "to":   account_2,
    "value":    w3.to_wei(1, "ether"),
    "gas":  21000,  # 普通ETH转账固定需要21000 gas
    "gasPrice": w3.to_wei("50", "gwei"),
}


print(balance_eth)
signed_tx = w3.eth.account.sign_transaction(tx, privatekey_1)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
print(f"交易哈希: {w3.to_hex(tx_hash)}")
# 查询转账后余额
new_balance = w3.eth.get_balance(account_1)/k
print(f"转账后余额: {new_balance}")

方法2:自动估算gas(更推荐)

用w3.eth.estimate_gas()方法自动计算当前交易需要的gas,避免手动设置错误:

from web3 import Web3
from web3.middleware import geth_poa_middleware
import json

# GANACHE. TESTING TRANSACTIONS
ganache_url = "http://127.0.0.1:7545"
w3 = Web3(Web3.HTTPProvider(ganache_url))

# accs and keys
account_1 = "0x72e94DaE4d186639B9Bb2baA89caa4Da5f931231"
account_2 = "0xaB2fF898c56a43f56845180081A0C467f2640332"
privatekey_1 = "0x5af8420db3d42b3fc14a13f64dd8dd490783746fdea406ac68afc9b3b9e51132"

# getting eth balance
balance_gwei = w3.eth.get_balance(account_1)
k = 10 ** 18
balance_eth = balance_gwei/k

nonce = w3.eth.get_transaction_count(account_1)

# 先构造不带gas的交易对象
tx = {
    "nonce": nonce,
    "to":   account_2,
    "value":    w3.to_wei(1, "ether"),
    "gasPrice": w3.to_wei("50", "gwei"),
}

# 自动估算gas
tx["gas"] = w3.eth.estimate_gas(tx)

print(balance_eth)
signed_tx = w3.eth.account.sign_transaction(tx, privatekey_1)
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
print(f"交易哈希: {w3.to_hex(tx_hash)}")
# 查询转账后余额
new_balance = w3.eth.get_balance(account_1)/k
print(f"转账后余额: {new_balance}")

说明

  • 普通ETH转账(仅转ETH,不调用合约)的gas消耗是固定21000,这是以太坊网络的规则。
  • 如果你调用智能合约,gas消耗会根据合约执行的代码逻辑变化,此时必须用estimate_gas来计算。
  • Ganache的区块gas限制可以在设置里调整,但没必要为了一个普通转账修改,用正确的gas值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:29:54