7

In a web3 JS dApp (eg.with Metamask),
If I know just the address of a contract and the method name, how can I call that method ?

I don't know the ABI.

1
  • 3
    This can be done if you know the method signature (including the types of the parameters), but not with just the name.
    – user19510
    Nov 24, 2017 at 3:35

2 Answers 2

10

I'm posting a proper answer here - thanks to @smarx, and others off SO who helped lead me to this solution.

The answer

This can be done if you know the method signature (including the types of the parameters), but not with just the name. – @smarx


ERC20 example - show balance of any token

So, for example, an ERC20 compliant token contract will implement a balanceOf() method.
The signature of that method looks like this (see below for how to obtain that) :

var abi = [{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

Now get the contract address of the tokens your are interested in.
As an example, on the Ropsten network there is a Panda Token contract at 0x45135b8ED5f52528175CCC6D7add2228779eDeE0 (donate Ropsten ETH here to receive some Panda Tokens), so you can see your Panda Token balance with the following code (in addition to the abi line above) :

var tokenContractAddress = "0x45135b8ED5f52528175CCC6D7add2228779eDeE0"
var contract = web3.eth.contract( abi ).at( tokenContractAddress )
var account 
web3.eth.getAccounts( (err, ok) => account = ok[0] )
// wait for account to be set ...
contract.balanceOf( account, function(err,ok) { console.log(err,ok.c[0]) } )

How to get the ERC20 balanceOf() signature

To obtain the signature of this method I simply went to Remix, and pasted in the following as the contract (having obtained the function definition from the ERC20 definition):

contract ERC20 {
      function balanceOf(address _owner) constant returns (uint balance);
}

Then to to Compile > Details > INTERFACE - ABI (Copy)

1

If you don't know the ABI or the bytecode (so if you don't have the contract code), you cannot send trasanction(s) or call(s).

But if you know it, in web3js 1.0.0-beta, just do:

contractInstance.methods.getBalance().call(address, function(result){
//do something with the variable
});

Or, for a transaction:

contractInstance.methods.setBalance(address).send({from: someone}, function(hash){
//dosomething
});

Edit for comments: How to create the contractInstance

if (contractInstance == null || contractInstance == 'undefined') {
        console.log("Making a new contract instance");
        var code = fs.readFileSync(solidityFile).toString();
        // Compile the contract code
        var compiledCode = solc.compile(code);
        //Generate the ABI 
        abi = JSON.parse(compiledCode.contracts[':NAMEOFYOUCONTRACT'].interface);
        contractInstance = new web3.eth.Contract(abi, contractAddress);
        console.log("Contract instance created successfully");
4
  • how are you instantiating contractInstance in the sample code in your answer? can it be created without the ABI? Nov 24, 2017 at 1:14
  • I updated the answer. And as I said in it, no, you cannot if you don't have the ABI or the bytecode Nov 24, 2017 at 1:16
  • How does OpenSea call the NFT methods on an ERC-721 contract that has not published the code then?
    – Qwerty
    Jan 16 at 20:12
  • I have not checked that. However, ERC being a standard, one could probably generate the ABI. (pure speculation). Moreover, note that this answer is 5 years old and things may (and probably have) changed). Jan 17 at 7:00

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.