如何在ethers.rs中部署合约时设置Gas参数?
如何在ethers-rs中为合约部署设置Gas参数?
针对你遇到的问题,直接链式调用gas_price/gas_limit不生效,大概率是因为单位错误或者未明确指定交易类型(EIP-1559 vs Legacy),下面给出具体的解决方法:
核心问题分析
你之前的写法中gas_price(10000000)数值过小,仅为0.01 Gwei,远低于Polygon/BSC网络的最低要求,导致交易无法被打包;另外ethers-rs默认优先使用EIP-1559交易,此时gas_price参数会被忽略,需要显式指定使用Legacy交易。
正确实现方式
1. 显式指定Legacy交易(适配Polygon/BSC)
对于Polygon、BSC这类仍广泛支持Legacy交易的网络,需要先调用legacy()方法,再设置Gas参数:
// 无构造参数的情况 factory.deploy(())? .legacy() // 强制使用Legacy交易类型 .gas_price(U256::from(30000000000)) // 30 Gwei(单位为Wei,1Gwei=10^9 Wei) .gas_limit(U256::from(2000000)) // 部署合约的典型Gas上限 .send() .await?
2. 适配EIP-1559交易(可选)
如果目标网络支持EIP-1559,可使用max_fee_per_gas和max_priority_fee_per_gas替代gas_price:
factory.deploy(())? .max_fee_per_gas(U256::from(35000000000)) // 最大总费用35 Gwei .max_priority_fee_per_gas(U256::from(2000000000)) // 优先费用2 Gwei .gas_limit(U256::from(2000000)) .send() .await?
3. 改造你的部署函数(支持多网络自动适配)
修改_deploy_contract函数,加入根据网络自动配置Gas参数的逻辑,同时支持自定义参数:
use ethers::types::{Address, Token, U256}; use ethers::contract::ContractFactory; use std::result::Result; // 定义Gas配置结构体,支持自定义参数 #[derive(Clone, Default)] struct GasConfig { gas_price: Option<U256>, gas_limit: Option<U256>, max_fee_per_gas: Option<U256>, max_priority_fee_per_gas: Option<U256>, } async fn _deploy_contract( network: &str, contract_path: &str, constructor_args: Option<Vec<Token>>, custom_gas_config: Option<GasConfig>, ) -> Result<Address, Box<dyn std::error::Error>> { let (client, abi, bytecode) = init(&contract_path, &network)?; let factory = ContractFactory::new(abi, bytecode.into(), client); // 处理构造参数,生成DeployBuilder let mut deploy_builder = match constructor_args { Some(args) => match args.len() { 1 => factory.deploy(args[0].clone())?, 4 => { let args_tuple = ( args[0].clone(), args[1].clone(), args[2].clone(), args[3].clone(), ); factory.deploy(args_tuple)? } _ => panic!("Incorrect number of arguments!"), }, None => factory.deploy(())?, }; // 应用Gas配置:优先使用自定义参数,否则根据网络设置默认值 let gas_config = custom_gas_config.unwrap_or_default(); if network == "polygon" || network == "bsc" { // 默认使用Legacy交易 deploy_builder = deploy_builder.legacy(); // 设置Gas价格(默认30 Gwei) let gas_price = gas_config.gas_price.unwrap_or(U256::from(30000000000)); deploy_builder = deploy_builder.gas_price(gas_price); // 设置Gas上限(默认200万) let gas_limit = gas_config.gas_limit.unwrap_or(U256::from(2000000)); deploy_builder = deploy_builder.gas_limit(gas_limit); } else { // 以太坊网络使用客户端自动估算的参数,也可覆盖 if let Some(gp) = gas_config.gas_price { deploy_builder = deploy_builder.gas_price(gp); } if let Some(gl) = gas_config.gas_limit { deploy_builder = deploy_builder.gas_limit(gl); } } // 发送部署交易 let contract = deploy_builder.send().await?; Ok(contract.address()) }
关键注意事项
- 单位转换:所有Gas价格参数的单位是Wei,务必注意Gwei与Wei的转换(1 Gwei = 10^9 Wei)
- 交易类型:ethers-rs默认使用EIP-1559交易,此时
gas_price参数会被忽略,必须调用legacy()才能生效 - Gas上限:部署合约的Gas上限建议设置在200万-500万之间,可根据合约复杂度调整
内容的提问来源于stack exchange,提问作者sh3ifu
相关产品推荐
相关产品推荐

