Truffle contract deployment failed, invalid sender - solidity

I'm trying to deploy a contract to the ropsten testnet using truffle, but I get the following error:
Deploying 'Migrations'
----------------------
Error: *** Deployment Failed ***
"Migrations" -- invalid sender.
at /home/usr/.npm/lib/node_modules/truffle/build/webpack:/packages/deployer/src/deployment.js:365:1
at process._tickCallback (internal/process/next_tick.js:68:7)
Truffle v5.2.5 (core: 5.2.5)
Node v10.19.0
When deploying to ganache locally, it works fine. Also I'm pretty sure my truffle-config.js is correct, it's the same as all the online tutorials, but since I'm here, I guess I'm not completely sure :). The address that hd-wallet is using is also correct (verified with the console.log statement in truffle-config.js) and it has 5 ETH balance, so more than enough. I have 2 migration scripts, it gives exactly the same error with each script.
truffle-config.js:
require("dotenv").config();
const HDWalletProvider = require("#truffle/hdwallet-provider");
module.exports = {
networks: {
ropsten: {
provider: () => {
var provider = new HDWalletProvider({
mnemonic: process.env.MNEMONIC,
providerOrUrl: `https://ropsten.infura.io/v3/${process.env.INFURA_KEY}`,
derivationPath: "m/44'/60'/0'/0/",
addressIndex: 0,
});
console.log(provider.getAddress());
return provider;
},
network_id: 3,
gas: 5500000,
confirmations: 2,
timeoutBlocks: 200,
skipDryRun: true,
},
development: {
host: "127.0.0.1",
port: 7545,
network_id: "*",
},
},
compilers: {
solc: {
version: "0.6.0",
optimizer: {
enabled: true,
runs: 200,
},
},
},
};
1_initial_migration.js:
const Migrations = artifacts.require("Migrations");
module.exports = function (deployer) {
deployer.deploy(Migrations);
};
2_deploy.js:
const Token = artifacts.require("Token");
module.exports = (deployer) => {
deployer.deploy(Token);
};
Token.sol:
//SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Token is ERC20 {
address minter;
// minterChanged event
event minterChanged(address indexed from, address to);
constructor() public payable ERC20("Decentralized Bank Currency", "DCB") {
minter = msg.sender;
}
function transferMinterRole(address bank) public returns(bool) {
require(msg.sender == minter);
minter = bank;
emit minterChanged(msg.sender, minter);
return true;
}
function mint(address account, uint256 amount) public {
require(msg.sender == minter);
_mint(account, amount);
}
}
Escrow.sol:
//SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0 ;
contract Escrow {
address agent;
mapping(address => uint256) public deposits;
modifier onlyAgent() {
require(msg.sender == agent);
_; // return void
}
constructor() public {
// solidity heeft globale var msg
agent = msg.sender;
}
function deposit(address payee) payable public onlyAgent {
uint256 amount = msg.value;
deposits[payee] = deposits[payee] + amount;
}
function withdras(address payable payee) public onlyAgent {
uint256 payment = deposits[payee];
deposits[payee] = 0;
payee.transfer(payment);
}
}

Try a different version #truffle/hdwallet-provider
Works for me with 1.2.3
npm uninstall #truffle/hdwallet-provider
npm install #truffle/hdwallet-provider#1.2.3
With the latest version (1.2.4) there was the same error (invalid sender).

According to my observation, this issue only occurs when you try to deploy any contract on ropsten testnet. If you're deploying with a local node like running with ganache-cli, it functions well even with the latest version (>1.2.3)
The reason here is they change the constructor method to add a chainId parameter to specified which chain you're signing with your transaction.
Solution: Update your code of initializing the HDWalletProvider.
ropsten: {
provider: () =>
new HDWalletProvider({
mnemonic,
providerOrUrl:
'wss://ropsten.infura.io/ws/v3/.....',
chainId: 3,
}),
network_id: 3, // Ropsten's id
gas: 5500000, // Ropsten has a lower block limit than mainnet
confirmations: 0, // # of confs to wait between deployments. (default: 0)
timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
skipDryRun: true, // Skip dry run before migrations? (default: false for public nets )
},
This works fine with me on ropsten

Check this out:
https://github.com/trufflesuite/truffle/issues/3935
Seems that truffle may not be properly eip 155 compliant. A PR was merged to help but I don't think this issue is yet resolved from the HDWallet end.
https://github.com/trufflesuite/truffle/issues/3913
https://github.com/trufflesuite/truffle/pull/3923

I am using #truffle/hdwallet-provider 1.3.0 and still got the same error.
Got it fixed by changing the initialization of HDWalletProvider.
ropsten: {
provider: function () {
return new HDWalletProvider(
{
privateKeys: ["YourPrivateKey"],
providerOrUrl: "https://ropsten.infura.io/v3/InfuraKey",
chainId: 3,
}
)
},
network_id: '3',
}
(Replace YourPrivateKey and InfuraKey with your private key and infura api key)

As an alternative solution, inside truffle-config.js use:
const HDWalletProvider = require('truffle-hdwallet-provider');
instead of
const HDWalletProvider = require('#truffle/hdwallet-provider');
It's just another way of downgrading the #truffle/hdwallet-provider while your package.json can still have:
"dependencies": {
"#truffle/hdwallet-provider": "^1.3.1"
}

Related

How to calculate a smart contract deployment price on RSK?

Say I have an ERC20 smart contract which I'm developing and testing in Hardhat:
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
contract Erc20Token is ERC20, Ownable {
constructor(uint initialSupply) ERC20("ERC20 Token", "ETK") {
ERC20._mint(msg.sender, initialSupply);
}
}
I intend to deploy it to the RSK network with the following Hardhat deploy.js script:
async function deploy() {
try {
const initialSupply = 1e6;
const ERC20TokenFactory = await ethers.getContractFactory('Erc20Token');
const erc20Token = await ERC20TokenFactory.deploy(initialSupply);
await erc20Token.deployed();
console.log(
`ERC20 Token was deployed on ${hre.network.name} with an address: ${erc20Token.address} `,
);
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
}
deploy();
To run this script and deploy my smart contract on RSK mainnet I need to run the following command in terminal:
npx hardhat run scripts/deploy.js --network rskmainnet
However, before deploying the smart contract on a real blockchain, I would really like to know how much this deployment will cost (in EUR)! How to calculate the price of my smart contract deployment transaction on the RSK mainnet, priced in fiat?
For reference, this is the hardhat.config.js file I'm using:
require('#nomiclabs/hardhat-waffle');
const { mnemonic } = require('./.secret.json');
module.exports = {
solidity: '0.8.4',
defaultNetwork: 'rsktestnet',
networks: {
rsktestnet: {
chainId: 31,
url: 'https://public-node.testnet.rsk.co/',
accounts: {
mnemonic,
path: "m/44'/60'/0'/0",
},
},
rskmainnet: {
chainId: 30,
url: 'https://public-node.rsk.co',
accounts: {
mnemonic,
path: "m/44'/60'/0'/0",
},
},
},
};
First you need to estimate the amount of gas which your deploy transaction is going to use. To accomplish this, use ethers.js signer.estimateGas() method.
const deployTx = ERC20TokenFactory.getDeployTransaction(initialSupply);
const estimatedGas = await ERC20TokenFactory.signer.estimateGas(deployTx);
Then you need to know the current gas price in your network:
const gasPrice = await ERC20TokenFactory.signer.getGasPrice();
To get the deployment RBTC price,
multiply gas amount by the gas price:
const deploymentPriceWei = gasPrice.mul(estimatedGas);
const deploymentPriceRBTC =
ethers.utils.formatEther(deploymentPriceWei);
Next you can use the Coingecko API to get current RBTC/EUR rate:
const rbtcEurRate = (
await axios.get('https://api.coingecko.com/api/v3/coins/rootstock')
).data.market_data.current_price.eur;
(Note that CoinGecko uses rootstock to denote the native currency of the RSK network, RBTC.)
And finally, to get the deployment price in EUR, multiply the deployment RBTC price by RBTC/EUR exchange rate:
const deploymentPriceEUR = (deploymentPriceRBTC * rbtcEurRate).toFixed(2);
We can make all of the above repeatable by creating a
hardhat script that combines the above.
To do this create scripts/estimateDeploymentPrice.js,
with the following:
const axios = require('axios').default;
async function estimateDeploymentPrice() {
try {
const initialSupply = 1e6;
const contractFactory = await ethers.getContractFactory('Erc20Token');
const deployTx = contractFactory.getDeployTransaction(initialSupply);
const estimatedGas = await contractFactory.signer.estimateGas(deployTx);
const gasPrice = await contractFactory.signer.getGasPrice();
const deploymentPriceWei = gasPrice.mul(estimatedGas);
const deploymentPriceRBTC = ethers.utils.formatEther(deploymentPriceWei);
const rbtcEurRate = (
await axios.get('https://api.coingecko.com/api/v3/coins/rootstock')
).data.market_data.current_price.eur;
const deploymentPriceEUR = (deploymentPriceRBTC * rbtcEurRate).toFixed(2);
console.log(
`ERC20 token deployment price on ${hre.network.name} is ${deploymentPriceEUR} EUR`,
);
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
}
estimateDeploymentPrice();
Run the script with a command:
npx hardhat run scripts/estimateDeploymentPrice.js --network rskmainnet
(Note that the script needs to be run through hardhat
in order for hre to be injected.)
The script outputs:
ERC20 token deployment price on rskmainnet is 3.34 EUR

Can't deploy smart contract to hardhat network

I set up a project with hardhat for an NFT app. I modify hardhat.config.js like this:
const { ALCHEMY_KEY, ACCOUNT_PRIVATE_KEY } = process.env;
module.exports = {
solidity: "0.8.0",
defaultNetwork: "hardhat",
networks: {
hardhat: {},
rinkeby: {
url: `https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_KEY}`,
accounts: [`0x${ACCOUNT_PRIVATE_KEY}`]
},
// ethereum: {
// chainId: 1,
// url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`,
// accounts: [`0x${ACCOUNT_PRIVATE_KEY}`]
// },
},
}
then I created a deploy script in the scripts folder with the deploy task
// scripts/deploy.js
const { task } = require("hardhat/config");
const { getAccount } = require("./helpers");
task("deploy", "Deploys the TokenV2.sol contract").setAction(async function (taskArguments, hre) {
const tokenFactory = await hre.ethers.getContractFactory("TokenV2", getAccount());
const token = await tokenFactory.deploy();
await token.deployed()
console.log(`Contract deployed to address: ${token.address}`);
});
The problem it's when I run npx hardhat deploy it's shows this error in terminal: Error: unsupported getDefaultProvider network (operation="getDefaultProvider", network="hardhat", code=NETWORK_ERROR, version=providers/5.5.3) What I missed? I will appreciate any help.
I never used defaultNetwork in my works so I just had the following hardhat.config File and had no issues at all:
{
"solidity":"0.8.4",
"networks":{
"rinkeby":{
"url":"`https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_KEY}`",
"accounts":[
"`0x${ACCOUNT_PRIVATE_KEY}`"
]
}
}
}

Error in Remix "Error from IDE : Invalid account selected"

I'm new to Remix and Solidity and don't understand why I recieve error message "Error from IDE : Invalid account selected".
Below line is executed successfully:
await contract.methods.SetMaxSupply("600").send({from: accounts[0]});
Below line results in above mentioned error message:
let supply = await contract.methods.current_supply().call()
Solidity code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
contract Test is Ownable {
uint public max_supply;
function SetMaxSupply(uint amount) public onlyOwner {
max_supply = amount;
}
function current_supply() public view returns(uint) {
return max_supply * 3;
}
}
Remix JS Script:
// Right click on the script name and hit "Run" to execute
(async () => {
try {
console.log('Running deployWithWeb3 script...')
// replace with contract address
const contractAddress = '0xd9145CCE52D386f254917e481eB44e9943F39138'
const contractName = 'Test' // Change this for other contract
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = `browser/contracts/StackOverflow/artifacts/${contractName}.json` // Change this for different path
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
const abi = metadata.abi
// instantiate a new web3 Contract object
let contract = new web3.eth.Contract(abi, contractAddress)
const accounts = await web3.eth.getAccounts()
await contract.methods.SetMaxSupply("600").send({from: accounts[0]});
let supply = await contract.methods.current_supply().call()
console.log(supply)
} catch (e) {
console.log(e.message)
}
})()
Try changing the Account parameter in the Deploy & Run Transaction

UnhandledPromiseRejectionWarning: Error: Returned error: execution reverted

Here's the code I'm running to get the balance of the contract I've previously deployed to Binance Smart Chain:
let Web3 = require('web3');
const fs = require('fs');
let web3 = new Web3('https://data-seed-prebsc-1-s1.binance.org:8545');
const contractAddress = '0x43045f0Cec750eEb70478B023885d1956588438E';
const contractAbi = JSON.parse(fs.readFileSync("scripts/contract_abi.json").toString())
const contract = new web3.eth.Contract(contractAbi, contractAddress);
contract.methods.balanceOf(contractAddress).call().then(result=>console.log(result)).catch(err => console.log(err));
This code throws me the error:
Error: Returned error: execution reverted
at Object.ErrorResponse (/home/zuber/Projects/HelloBSC/HelloCoin/node_modules/web3-core-helpers/lib/errors.js:28:19)
at /home/zuber/Projects/HelloBSC/HelloCoin/node_modules/web3-core-requestmanager/lib/index.js:303:36
at XMLHttpRequest.request.onreadystatechange (/home/zuber/Projects/HelloBSC/HelloCoin/node_modules/web3-providers-http/lib/index.js:98:13)
at XMLHttpRequestEventTarget.dispatchEvent (/home/zuber/Projects/HelloBSC/HelloCoin/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
at XMLHttpRequest._setReadyState (/home/zuber/Projects/HelloBSC/HelloCoin/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
at XMLHttpRequest._onHttpResponseEnd (/home/zuber/Projects/HelloBSC/HelloCoin/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
at IncomingMessage.<anonymous> (/home/zuber/Projects/HelloBSC/HelloCoin/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
at IncomingMessage.emit (events.js:387:35)
at endReadableNT (internal/streams/readable.js:1317:12)
at processTicksAndRejections (internal/process/task_queues.js:82:21) {
data: null}
The contract is copypasted from https://github.com/binance-chain/bsc-genesis-contract/blob/master/contracts/bep20_template/BEP20Token.template (only added onlyOwner modifier to line 332)
Truffle config used to deploy contract to BSC:
const HDWalletProvider = require('#truffle/hdwallet-provider');
const fs = require('fs');
const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = {
networks: {
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 8545, // Standard BSC port (default: none)
network_id: "*", // Any network (default: none)
},
testnet: {
provider: () => new HDWalletProvider(mnemonic, `https://data-seed-prebsc-1-s1.binance.org:8545`),
network_id: 97,
confirmations: 10,
timeoutBlocks: 200,
skipDryRun: true
},
bsc: {
provider: () => new HDWalletProvider(mnemonic, `https://bsc-dataseed1.binance.org`),
network_id: 56,
confirmations: 10,
timeoutBlocks: 200,
skipDryRun: true
},
},
// Set default mocha options here, use special reporters etc.
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: "0.5.16", // A version or constraint - Ex. "^0.5.0"
}
}
}
This is a general error originating from a smart contract, when the contract throws an unhandled exception.
Even though that you didn't post the contract source code, we can get some basic info about its content from the decompiled code.
It shows that there's no balanceOf() (that you're trying to call), and that the fallback() (which is used if you're trying to call an non-existing function) always throws an exception.
From here, the most likely possibility is that you meant to deploy a different contract (that contains the balanceOf() function) but mistakenly deployed this one instead.
Or if you meant to get the BNB balance (not the token balance) of the contract address, you can use the web3 getBalance() method. Example:
const balance = await web3.eth.getBalance(contractAddress);
I was also stuck with the same error and the issue was that I was deploying on the remix local address provided by remix but not with metamask. Hope it help someone.

How to solve the error ""before all" hook: prepare suite:"

When I tested my contract, I got this error ""before all" hook: prepare suite:"
Does anyone know how to solve this error?
This is my dependencies.
"truffle": "5.0.7",
"web3": "1.0.0-beta.46"
npm uninstall -g truffle
npm install -g truffle#5.1.10 (always got me back on track)
Also, this issue occurs when used several test suites that use async test-helpers without await (for example, OpenZeppelin Test Helpers: expectEvent, expectRevert).
Consider example:
contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
contract Test03 {
address public owner;
int32 public id;
event ContractCreated();
constructor() {
owner = msg.sender;
emit ContractCreated();
}
function doSmth(int32 _id) public {
require(id != 0, "id is zero");
id= _id;
}
}
test
const { expectEvent, expectRevert } = require('#openzeppelin/test-helpers');
const TestContract = artifacts.require('Test03');
contract('Test03', function (accounts) {
const [owner] = accounts;
const txParams = { from: owner };
beforeEach(async function () {
this.testContract = await TestContract.new(txParams);
});
describe('construction', function () {
it('initial state', async function () {
expect(await this.testContract.owner()).to.equal(owner);
// !! DONT FORGET await before expectEvent-call <<------------------------------
await expectEvent.inConstruction(this.testContract, 'ContractCreated');
});
});
describe('doSmth', function () {
it('fail when passed zero id', async function () {
// !! DONT FORGET await before expectRevert-call <<------------------------------
await expectRevert(
this.testContract.doSmth(0, txParams),
"id is zero");
});
});
});
package.json
{
..
"devDependencies": {
"#openzeppelin/test-helpers": "^0.5.10"
}
..
}