13

I want to call the methods with metamask of this simple contract:

contract AssetPrices {
  mapping (uint => uint) public prices;
  uint public data;

  function EnterPrice(uint _time, uint _price){
  prices[_time] = _price;
  }

  function GetPrice(uint _time) returns (uint){
  data = prices[_time];
  return data;
  }

}

The contract is deployed at address 0xd884b7b7d6e21798814f218f2daa1054cff33ee5

The index.html file is:

<!DOCTYPE html>
<html>
<head>
</head>
<body class="container">
  <h1>A Simple METAMASK controlled contract</h1>
</body>
<script src="https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script>
$(document).ready(function() {
window.addEventListener('load', function() {
  // Check if Web3 has been injected by the browser:
  if (typeof web3 !== 'undefined') {
    // You have a web3 browser! Continue below!
    startApp(web3);
  } else {
    alert("no web3 detected");
  }
})
function startApp(web3) {
  web3.eth.defaultAccount = web3.eth.accounts[0];
  abi= JSON.parse('[{"constant":false,"inputs":[{"name":"_time","type":"uint256"},{"name":"_price","type":"uint256"}],"name":"EnterPrice","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"data","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_time","type":"uint256"}],"name":"GetPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"prices","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"}]');
  PriceContract = web3.eth.contract(abi);
  ContractInstance = PriceContract.at('0xd884b7b7d6e21798814f218f2daa1054cff33ee5');
  // Enter new price
  ContractInstance.EnterPrice(25,150, {from: web3.eth.accounts[0]});
  // Get the price you entered
  x = ContractInstance.GetPrice(25, {from: web3.eth.accounts[0]});
}
})
</script>
</html>

However when I serve the page I get the following error:

Uncaught Error: invalid address

    at inputAddressFormatter (https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js:3920:11)
    at inputTransactionFormatter (https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js:3746:20)
    at https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js:5005:28
    at Array.map (native)
    at Method.formatInput (https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js:5004:32)
    at Method.toPayload (https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js:5030:23)
    at Eth.send [as sendTransaction] (https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js:5055:30)
    at SolidityFunction.sendTransaction (https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js:4121:26)
    at SolidityFunction.execute (https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js:4207:37)
    at startApp (http://127.0.0.1:8000/:27:20)
  • I have a similar problem and doesn't exist a lot information about the invalid address errors. The only what i found is the web3.eth.accounts "solution", but this doens't work for me, cause metamask put the correct account with injected web3. Maybe somethign like this can help you, if you found the answer write here again ^^ – Gawey Jul 6 '17 at 9:33
  • Try to set default account and send transaction in callback from web3.eth.getAccounts(function(err, accounts) {...}. Maybe, it'll help. – Viktor Baranov Jul 8 '17 at 19:48
12

I had the same problem when testing the contract from 'geth console'.

I found out the problem was not having set the default account. You have to assign a default account and unlock it, like this:

web3.eth.defaultAccount = web3.eth.accounts[0]
personal.unlockAccount(web3.eth.defaultAccount)
contractObj = web3.eth.contract(contractABI).at(contractAddr)
contractObj.method(args...)

I guess the contract uses the default account to pay the gas used by the contract.

  • 1
    This worked perfectly. But I am still baffled as to why would I need to unlock the account to get the encoded ABI of a method even before I call it. Any info on this? – Shashikant Soni Jul 20 '18 at 11:20
6
PriceContract.web3.eth.defaultAccount=PriceContract.web3.eth.coinbase

You need to set the default account of the contract too. or if contractinstance is what you use to call the functions

Contractinstance.web3.eth.defaultAccount=Contractinstance.web3.eth.coinbase
3

One reason this error can be thrown is if the web3.eth.accounts array is empty, which happens if the user has not signed in to MetaMask.

  • The array is not empty - it has exactly one account – gpanterov Jul 6 '17 at 0:32
1

Update from January 2019:

The Invalid address error can also happen if you haven't called window.ethereum.enable(); yet.

0

web3.eth.defaultAccount = web3.eth.accounts[0]; console.log(web3.eth.defaultAccount) This prints the address fine.

but... var address = web3.eth.defaultAccount

When i pass the address or web3.eth.defaultAccount into a smart contract method, it gives invalid address.

I want to know if anyone faced similar issue and how to go about solving this invalid address in the smartcontract methods.

0

Have a same problem. Firefox has installed Metamask and web3 variable is already setted, but on DOMContentLoaded time web3.eth.accounts[0] is empty. My solution was

  if (web3.eth.accounts.length === 0){
    var fckdFirefox = setInterval(() => {
      if (web3.eth.accounts.length > 0) {
        web3.eth.defaultAccount = web3.eth.accounts[0]
        window.contract = web3.eth.contract(bsABI).at(bsAddress)
        clearInterval(fckdFirefox)
      }
      else {
       console.log(Date.now(),  " WTF?");
      }
    }, 100)
  }

Output is

  1557269408292  WTF? main.js:30
  1557269408391  WTF? main.js:30
  1557269408493  WTF? main.js:30
  1557269408593  WTF? main.js:30
  1557269408693  WTF? main.js:30
  1557269408794  WTF? main.js:30

E.g. web3.eth.accounts assigned after ~600ms

0

The call to web3.eth.accounts does not return a list of accounts, as per the docs:

enter image description here

Fetch the active user account like so:

var userAccount = null;
web3.eth.getAccounts(async function(error, accounts) {

        if (error == null && accounts.length > 0) {
          userAccount = accounts[0];
        }
-1

add window.ethereum.enable(); in the your html file.

-2

Try using either constant or payable modifier.

function GetPrice(uint _time) constant returns (uint) {...}
// or
function GetPrice(uint _time) payable returns (uint) {...}

Since GetPrice doesn't change a state, probably best to use constant so you don't have to pay a gas cost.

But, if you want to test integration with metamask, you can try payable and see if you get metamask to popup with the gas price of the transaction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.