Smart contracts are the main feature that distinguishes Ethereum from Bitcoin. A smart contract is a program running on the Ethereum network, and it can access the blockchain data.
You write smart contracts in the Solidity programming language. Like Java, Solidity gets compiled to a bytecode that runs in a virtual machine. In this case, it's called the Ethereum Virtual Machine, or EVM for short.
To interact with a smart contract from JavaScript, you need three things:
In the last lesson, you learned, every EOA and smart contract has an address; this is how you find the contract on the blockchain.
const address = "0x25ed58c027921E14D86380eA2646E3a1B5C55A8b"
To figure out what functions a contract has to offer, you need an Application Binary Interface, or short ABI, a list of function signatures of functions you want to call later. Ethers.js uses the ABI to determine what arguments a function expects and what values it returned when it finished its work.
When using Ethers.js, you can define the ABI as an array of strings, where the strings are Solidity function signatures, just like you would write them in the Solidity programming language.
Here is an example of an ABI for one function:
const abi = [ "function ownerOf(uint256 tokenId) external view returns (address owner)", ]
Functions get defined with the function
keyword followed by a name and then the
arguments in paratheses. Solidity is statically typed and doesn't support floating points but
integer types of different sizes.
In the example above the function takes one argument of type uint256
and it's named
tokenId
.
The external
keyword is an access modifier that marks the function as callable from
outside of the contract.
The view
keyword is crucial too because it tells the EVM that the function won't
modify any on-chain state; it will just read it. view
enables you to call the
function without having a wallet because the Ethereum RPC you use can read all data from its local
copy of the blockchain.
The returns
keyword tells you what you get back when you call the function. In this
case, it's the owner's address of a token.
The next step is to create a new contract instance and call the ownerOf
function
defined by the ABI!
Try it yourself in the editor!
const smartContract = new ethers.Contract( contractAddress, contractAbi, provider, ) const owner = await smartContract.ownerOf(2) print(owner)
The owner of the contract, like everything on the blockchain, is located at an address, and this is just what the function returned. The address could point to another contract that created our contract, as so called factory contract. The address could also point to an EOA, which is the case in this example.
This lesson taught you about smart contract interaction. How to find them on the blockchain with the help of a provider and an address and how to call its functions with an ABI.
An ABI is just an array of strings, these strings are function signatures like you would write them in Solidity, the programming language powering Ethereum.
If you found these addresses a bit cumbersome to work with, I have good news for you. The next lesson is about the blockchain equivalent of DNS: The Etherum Name Service.