I'm trying to deploy my smart contract to the Ethereum Mainnet using truffle.js. When migrating with a low gas price, the transaction for deploying the contract sometimes takes longer than 750 seconds and causes truffle to timeout.
Is there some way to disable the 750 second timeout when deploying smart contracts (migrating) to the mainnet? I would like to deploy my contract with a low gas price to reduce the cost, and am ok with waiting a long time for the TX to be mined.
Also, if the timeout IS hit and the TX gets mined later, can I still generate the same exact artifact files for the TX? Thanks.
Is there some way to disable the 750 second timeout when deploying smart contracts (migrating) to the mainnet? I would like to deploy my contract with a low gas price to reduce the cost, and am ok with waiting a long time for the TX to be mined.
No. Truffle uses web3 lib with default wait set to 50 blocks. (So it will wait 50 blocks for the tx to be mined before timing out). You can likely get away with increasing this a lot to acheieve what you want--see: https://www.trufflesuite.com/docs/truffle/reference/configuration
However, when the gas price is set very low there is a possibility that it never gets picked up by miners on the network. So without a timeout the process could hang forever.
Also, if the timeout IS hit and the TX gets mined later, can I still generate the same exact artifact files for the TX? Thanks.
I'm not sure what you mean here. The artifact files are generated after a contract is compiled. Maybe you are referring to getting the transaction hash? It is always best to check a service like etherscan or trueblocks for the state of your transaction.
Related
Gas costs for even a simple contract deployment are astronomical. If I spin up my own node and connect directly to it can I deploy on that node and avoid the gas fees?
Can I avoid gas fees by running my own Ethereum node?
Simple answer: No.
A node accepts the transaction, stores it in its mempool, and relays it to other nodes so that they can also store it in their mempool. There's nothing related to gas costs at this point.
Theoretically you could deploy a contract for "free" by running your own miner. But that's impossible without professional hardware costing very large amounts - many times more expensive than what you'd save on the gas fees.
However, in a block that you mined, you could include a transaction deploying a contract with 0 gas price. This sometimes happens - miners do occasionally put their own 0-priced transactions in their own blocks. But apart from that, no miner would accept your transaction with 0 gas price (or any transaction priced lower than the current market rate), as that wouldn't be profitable for them.
I deployed my smart contract(ERC-721) on truffle (Rinkeby | Ropsten | local node) and again on Remix and I keep getting an average cost of 0.0165 ether. This gas fee seems unrealistic to me, even though my contract is pretty simple.
I finally tried deploying to MAINNET using Truffle and the transactions stopped due to a low gas value. I switched over to REMIX and the new total gas fee is 0.65 ($2500) ether.
Is this a realistic amount to deploy a smart contract? or do I need to change some setting on remix?
Do the testnet's give a good representation of what gas fee will cost on mainnet ?
The amount of gas used from gas limit, not the gas price is going to be consistent between mainnet and testnets as the gas used from gas limit represents the amount of work that needs to be done to process the transaction logic in the EVM. Gas price (how much you pay for a unit of gas used) fluctuates as it is dependent on market economics/game theory, which is going to be very different on a test network vs live network.
References
https://ethereum.org/en/developers/docs/gas/
I am developing a smart contract and I recently updated Hardhat to 2.6.x, which has london hardfork as default network settings. My issue is that gas used by my transaction increased by more than 50% in most cases. When I switch back to berlin hardfork, the cost is "correct" again.
Can somebody explain me why? Is there some updated opcode gas cost list? Or did gas cost for storing / loading values from storage increased? I am failing in finding the source of the increase.
I read EIP-1559, but there is no much information about opcode updates, just gas price and model of a base fee burning, which should not increase transaction gas usage imo.
I use ethers and property gasUsed on transaction receipt to get used gas.
It looks like EIP-3529 is the reason of the increase. EIP-3529 is reducing gas refunds and for one NFT transfers its ~20k gas increase because while transferring NFT you set storage of previous owner and (in some cases) his balance to 0, which are refunded less after london hardfork. Unfortunate.
I'm working on sending transactions from one address to another on the goerli testnet and all transactions so far are not confirming. They have been staying in a pending state: https://goerli.etherscan.io/tx/0x056187763bac9adc8696fa0554c26b2f0e8ac48601dd4e5f03a30536d6597bf0
Did I do something wrong? I see the transaction in the etherscan.io/tx, but do I need some sort of callback handler?
Is this because there are not enough miners on the goerli testnet? Is Kovan the best testnet for ethereum dapp/smart contract development where transactions are being confirmed more often?
Any help is appreciated.
The linked transaction offers gas price of 0.000000002 Gwei (which is 2 wei). Usual current gas price on the Goerli network is 2 Gwei (1 billion times larger).
So it just seems that your sending script incorrectly calculates the decimals for the gas price.
Most miners order transactions by the gas price. So if there were more miners or less pending transactions, there would be a higher probability of this transaction making it to the block. But in the current situation, you need to raise the gas price of your transaction in order to compete with the other pending transactions.
If you want to replace the gas price on this particular transaction, you can send a new one with the same nonce but higher gas fee.
This is the code that I'm using to send signed transactions to mainnet programmatically:
import Web3 from 'web3'
import EthereumTx from 'ethereumjs-tx'
const web3 = new Web3(new Web3.providers.HttpProvider(INFURA_URL))
const Contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS)
const createItem = (name, price, nonce, callback) => {
console.log(`Nonce: ${nonce}. Create an Item with Name: ${name}, Price: ${price}`)
const data = Contract.methods.createItem(name, price).encodeABI()
const tx = new EthereumTx({
nonce: nonce,
gasPrice: web3.utils.toHex(web3.utils.toWei('4', 'gwei')),
gasLimit: 400000,
to: CONTRACT_ADDRESS,
value: 0,
data: data,
})
tx.sign(new Buffer(MAINNET_PRIVATE_KEY, 'hex'))
const raw = '0x' + tx.serialize().toString('hex')
web3.eth.sendSignedTransaction(raw, callback)
}
export default createItem
I have to mass create (i.e. populate) items in my contract, and I want to do it programatically. However, while the code works well in ropsten, it fails to send all the transactions in mainnet; it only sends the first few transactions and doesn't send the rest. The errors are not helpful because this error is usually guaranteed to occur:
Unhandled rejection Error: Transaction was not mined within 50 blocks, please make sure your transaction was properly sent. Be aware that it might still be mined!
I wonder how other people do when they have to send a lot of transactions to Ethereum mainnet today. Is there anything I'm doing wrong?
You basically cannot reliably do what you guys are trying to do. Here's a set of problems that arises:
Transactions only succeed in nonce order. If an early nonce is pending (or worse, went missing), the other transaction will pend until the early nonce has been consumed (or it gets removed from the mempool).
There's no hard rule for when a transaction will drop from the mempool. This is scary when you've made a nonce error or an intermediary nonce has not reached the network for some reason because you don't know what is going to happen when you finally post that nonce.
Many transactions with the same nonce can be sent. They are very likely to be selected by gas price (because miners are incentivized to do exactly that). One useful trick when something strange has happened is to clear out your nonces by sending a bunch of high gas price, zero value transactions. You might call this an increment method. Remember this comes with a cost.
A lot of tools do one of two things to handle nonces: a live read from getTransactionCount() or a read from getTransactionCount() followed by incrementing for each additional transaction you send. Neither of these work reliably: for the first, transactions are sometimes pending but not visible in the pool yet. This seems to especially happen if gas price is below safemin, but I'm not entirely sure what is happening here. For the second, if any other system sends a transaction with the same address, it will not work.
So, how do we work around this?
A smart contract is a straightforward way to reduce a transaction from many sender nonces to few sender nonces. Write a contract that sends all your different transactions, then send the budget to that contract. This is a relatively high cost (in terms of time/effort/expertise) way to solve the problem.
Just do it anyway, batch style. When I've had to send many transactions manually, I've batched them in to sets of 10 or so and gone for it. Incrementing the nonce manually each time (because the transaction is usually not on the network yet) and then waiting sufficiently long for all the transactions to confirm. Don't rely on pending transactions on Etherscan or similar to determine whether this is working, as things often vanish unpredictably from this level. Never reuse a nonce for a different transaction that isn't a 0ing high gas transaction - you will screw it up and you'll end up sending the same transaction twice by mistake.
Serialize. One-by-one you post a transaction, wait for it to confirm, increment your nonce. This is probably the best of the easy-to-implement automated solutions. It will not fail. It might buffer forever if you have a constant stream of transactions. It also assures you can never have more than one transaction per block, limiting your throughput to 4 a minute or so.
Fire and retry. This is a little sketchy because it involves reusing nonces for different transactions. Send all (or some large batch) of your transactions to the network. If any fail, restart from the failure nonce and send again. There's possibly a more intelligent solution where you just try to swap out the missing nonce. You'll need to be very careful you never send a transaction that is secretly in the pending-but-not-visible pool.
New address for every transaction. A buffering step of distributing funds to your own addresses ensures you never screw it up for other people. It does double your transaction time and cost though.
I think some variant of fire and retry is what most of the big services (like pools and exchanges) do. Some of these can be improved by splitting the budget over a few addresses as available (reducing the collision frequency).