Short answer: you need the ABI in order to call the contract.
Let's talk a bit about how to get it, and then talk about one way you'll still be able to interact with the contract if you don't have it (by writing your own for the part of the contract you need to interact with).
1) Etherscan
Etherscan has something called verified contracts. You can check if the contract you want to interact with is verified by going to the Ropsten Etherscan site and putting in the contract of your address. Scroll down a bit on the Etherscan page for the contract, and there should be a "Contract" tab. If it has a green circle with a checkmark, it's a verified contract. Click on the "Contract" tab, and if you scroll down you should see an option to copy the ABI to your clipboard.
(One little tip: if you are interacting with a token contract, Etherscan often has two separate pages, one for the token, and another for the contract. If you land on a token page and can't find if the contract is verified, on the right-hand side towards the top there should be an option to click through to the contract page, which sometimes helps.)
2) DIY
If you have a Truffle, Hardhat, or similar environment running, and also have access to the source code for the contract you wish to interact with, you can compile the ABI yourself.
Truffle:
truffle compile
The artifacts will be placed in build/contracts
- you'll see a JSON with the name of the contract (as defined inside the contract, not the file name) there.
Hardhat:
npx hardhat compile
The artifacts will be placed in artifacts/
.
note (both Truffle and Hardhat):You may have to select the abi
field of the JSON - the actual JSON contains more than the ABI.
You could also use the solc
compiler to compile the ABI, but it can be much more finnicky to get it working with the right version.
If the contract you are interacting with is from a major developer, you can likely also get it by reaching out on their communication channels.
3) What if I totally can't get the ABI?
The truth is, as Morten pointed out in the comments, that we've been talking about getting the entire ABI up until now. You might not need the whole ABI, in fact, there's a very good chance that you don't. If you are only interacting with some of the functions of a contract, you only need an ABI that has those functions, and can ignore the rest. This means that if you know the name, arguments, and parameters of a function, you have a solution: write your own ABI!
Let's give an example. The ERC20 standard has a function called transfer
:
function transfer(address _to, uint256 _value) public returns (bool success)
Using the ABI JSON standard we can figure out how to construct an ABI object for callig transfer
on an ERC20 contract (that follows the standard) even if we don't have the ABI. It would look something like this:
[
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]
It's impossible to go through all of the different options for all of the different fields, but using this example and the link to the spec, you may be able to create an ABI for functions you are familiar with.