Tutorial Part 5: Work with Contracts
Contract API basically comes in three pieces:
- there is inspection of the contract state through calling constant functions.
- there's state-changing transactions like transferring tokens to a counter-party.
- there's event reception and reporting that (usually) happen when such a state change occurs
As of version v1.0.4 of @parity/light.js
, the library only supports the two first functionalities. Let's see how they work. But before that, let's create a contract object.
Our first contract
Let's deal with the ERC20 contract, which is quite possible the most famous contract. We'll use the GavCoin
contract, a test ERC20 contract deployed on Kovan at the address 0x4733659a5cB7896A65c918Add6f59C5148FB5ffa
.
The ABI of a classic ERC20 can be found in a lot of places, for example within the @parity/contracts
npm module.
So let's instantiate a contract object:
import erc20Abi from '@parity/contracts/lib/abi/eip20';
import { makeContract } from '@parity/light.js';
const gavcoinContract = makeContract(
'0x4733659a5cB7896A65c918Add6f59C5148FB5ffa',
erc20Abi
);
And done! gavcoinContract
is now a javascript object, where all the keys are the functions in the contract with a $
sign at the end:
{
abi: {...}, // @parity/abi Abi object, only needed for advanced usage
address: '0x4733659a5cB7896A65c918Add6f59C5148FB5ffa',
allowance$(): ...,
approve$(): ...,
balanceOf$(): ...,
contractObject: {...}, // @parity/api Contract object, only needed for advanced usage
totalSupply$(): ...,
transfer$(): ...,
transferFrom$(): ...
}
The functions defined in the ABI are defined in this object too. We won't go into details about the abi
and contractObject
fields, but have a look at @parity/abi
and @parity/api
respectively if interested.
Calling constant functions
In the ERC20 ABI, the balanceOf
function is a constant function, which means that it doesn't modify the Ethereum state. Calling such a function with return a RpcObservable that will update when the token balance of a account changes.
gavcoinContract
.balanceOf$('0x407d73d8a49eeb85d32cf465507dd71d507100c1')
.subscribe(balance => console.log('balance', balance));
See this snippet in action: https://codesandbox.io/s/mq8rwkqzxp.
Calling state-changing function
The usage is exactly the same as with constant functions, but the returned RpcObservable is the same as the one returned by post$
(see previous chapter).
gavcoinContract
.transfer$(
[
'0x407d73d8a49eeb85d32cf465507dd71d507100c1', // The "to" address
new BigNumber(2.01) // The amount to transfer
],
// This 2nd argument is an options object containing the following fields:
{
from: "0x...",
passphrase: "mypassphrase",
gasPrice: ...
}
)
.subscribe(transfer => console.log('transfer$', transfer));
// Logs:
// transfer$ { signed: '0x123...ff' }
// transfer$ { sent: '0x456...ff' }
// transfer$ { confirmed: {/* receipt object */} }