web3: 1.0.0-beta.30 and 1.0.0-beta.31
ethermint: 0.5.3-b72a1eef
go-ethereum: 1.6.7-stable
When sending a transaction, and setting the gasPrice to 0, the gasPrice is ignored and the default gas price is used instead. Other values (1, 2, 1000000, ...) work. This happens when deploying a contract (as shown below in the example code) and also when sending a transaction on an existing contract.
In web3 0.20.6, setting the gasPrice to 0 works fine.
Setting the gasPrice to 0 is useful for private, permissioned networks (e.g. ethermint).
Example code:
const solc = require('solc');
const Eth = require('web3-eth');
const eth = new Eth(Eth.givenProvider || "http://localhost:8545");
const input = `
contract A {
uint public x;
function A(uint _x) {
x = x;
}
}
`
console.log("compiling...");
const output = solc.compile(input);
console.log("done");
const compiled = output.contracts[":A"];
const contract = new eth.Contract(JSON.parse(compiled.interface));
let account;
let deploy;
eth.personal.getAccounts()
.then(accounts => {
account = accounts[0];
console.log("using account " + account)
return eth.personal.unlockAccount(account, "1234")
})
.then(() => {
console.log("unlocked account. estimating gas...");
deploy = contract.deploy({
data: '0x'+compiled.bytecode,
arguments: [123]
});
return deploy.estimateGas({from: account})
})
.then(gasEstimate => {
console.log("gasEstimate = " + gasEstimate + ", now deploying...");
return deploy.send({
from: account,
gas: gasEstimate,
gasPrice: 0 // <------------------------------------- this has no effect
})
.once('transactionHash', hash => {
console.log("transaction hash: " + hash);
eth.getTransaction(hash)
.then(transaction => console.log("gasPrice was: " + transaction.gasPrice));
})
})
.then(() => console.log("done"))
.catch(err => console.log(err.stack))
Output:
compiling...
done
using account 0x7eFf122b94897EA5b0E2A9abf47B86337FAfebdC
unlocked account. estimating gas...
gasEstimate = 116392, now deploying...
hash: 0x247100d4d1bf75042fdf94a3744ce095a71060b4192b52161b9e761fbe348d68
gasPrice was: 18000000000
done
I discovered that the following _does_ work, instead of:
gasPrice: 0, use gasPrice: '0'
Probably there's a test somewhere if (gasPrice) to check if gasPrice was set.
Not sure if this behavior (having to pass '0' as a string but being able to pass 5 as an integer) is acceptable.
Can confirm this bug still exists in 1.0.0-beta.33. And can be mitigated with @joeriexelmans's answer above.
EDIT: Also can confirm it exists in 1.0.0-beta.36.
This should be solved with the PR #2000
Most helpful comment
I discovered that the following _does_ work, instead of:
gasPrice: 0, usegasPrice: '0'Probably there's a test somewhere
if (gasPrice)to check if gasPrice was set.Not sure if this behavior (having to pass
'0'as a string but being able to pass5as an integer) is acceptable.