This error suggests that whatever account you are using to send the transaction from does not have enough ether in it. Though you don't have to post the answers to these, you need to know the answers to help debug this:
- Exactly what account is this being sent from?
- Exactly what is the balance of that account, on the network this transaction is being sent to?
- What gas limit am I sending with?
- What gas price am I sending with?
- How much ether am I including as part of this transaction?
(your answer for #3)*(your answer for #4) + (your answer for #5) needs to be less than (your answer for #2). Is it? The error indicates it is not, so figure out which of these values is not as you expect.
Most likely, it's #2 and you don't have enough ether in the account you're trying to send from.
Keep in mind that if you bought/acquired Ether on the main Ethereum chain, or used the faucet to get some on Rinkeby, it doesn't matter on Ropsten. You could try the Ropsten faucet here to boost your balance a bit. You can check your balance on Ropsten by searching the address here.
There is different way to send transactions to a smart contract through node:
(1) A client signs a transaction with his account (private key) and send it to the node. Then the node only broadcasts it to the network.
Transaction fees are paid by the client.
(2) A client sends a clear transaction (no signature) and ask the node to sign and broadcast the transaction with one of the account managed by this node. That's the all concept of personal unlocked account
which should be used only for personal use or testing.
Transaction fees are paid by the node.
By doing this (below), you basically create an account directly on the node (2)
NewAccountIdentifier newAccountIdentifier = admin.personalNewAccount(key).send();
String address = newAccountIdentifier.getAccountId();
If you want to create and manage an account only on the client (java program), you would have to do this:
ECKeyPair keyPair = Keys.createEcKeyPair();
Credentials credentials = Credentials.create(privateKey);
In web3j you have the concept of TransactionManager
responsible of executing the transactions and you have different type of TransactionManager:
RawTransactionManager
can sign and send transaction (1)
ReadonlyTransactionManager
can only read data (no transaction)
ClientTransactionManager
can only send a clear transaction to the node and let the node sign it (2)
When you load the contract like you did UsersContract userContract = UsersContract.load(address, admin, credential, ...)
, behind the scene, Web3J instantiate a RawTransactionManager
which will sign the transaction (using the credentials
- private key) before sending it to the node.
UsersContract userContract = UsersContract.load("0xc85e6e4b979d05a9b5adbac3e0e7d68b632460d1", admin, credentials, new BigInteger("240000"), new BigInteger("2400000"));
But in your case, you actually need a ClientTransactionManager
, so you can directly pass it to the UsersContract.load(...)
method like this
ClientTransactionManager transactionManager = new ClientTransactionManager(web3j, newAccountIdentifier.getAccountId());
UsersContract userContract = UsersContract.load("0xc85e6e4b979d05a9b5adbac3e0e7d68b632460d1", admin, transactionManager, new BigInteger("240000"), new BigInteger("2400000"));
Best Answer
It seems it was a problem with amount of ETHER.
When I changed Convert.Unit.ETHER to Convert.Unit.WEI it solved the problem