async function balanceOf(owner) {
const res = await myToken.call("balanceOf", [owner])
const balance = res.outputs[0]
console.log(`balance:`, balance.toNumber())
}
The arguments to balanceOf are passed in as an array.
Send VS Call
Confusingly, there are two ways to invoke a method: send and call. These two names are inherited from Ethereum. A more descriptive way to name them is perhaps to call send "commit" and call "query".
call (or "query"): executes contract code on your own local hyrad node as a "simulation", returning results, but not changing the blockchain. This is free.
send (or "commit"): creates an actual transaction that would execute code globally on the network, changing the blockchain. This costs gas.
Next, we are going to mint some new tokens using hydrajs. And because minting token changes the blockchain, we'll use send.
Mint Tokens With Send
The mint command creates new tokens by using send to create a new transaction. Then it waits for that transaction to confirm:
node index.js transfer \
qdgznat81MfTHZUrQrLZDZteAx212X4Wjj \
9d748f98e65c6875dbed7bfb6ffbeca426ff9cc6 \
100
transfer tx: a1ba017b3974b98bf9c8edc824c3abc0ce17678a14e7cfac94b5900a290bdd07
✔ confirm transfer
Note that we MUST specify the senderAddress using base58 address format. We'll fix this in the future.
We can then verify that 9d74...9cc6 had indeed received the tokens:
The CappedToken contract defines a few events. The Transfer event is emitted whenever fund is moved from one account to another (also when minting new tokens). The Transfer event:
event Transfer(
address indexed from,
address indexed to,
uint256 value
);
Let's use qtumjs to subscribe to the stream of contract events, so we can react in a timely manner when a transfer occurs. The code:
async function streamEvents() {
console.log("Subscribed to contract events")
console.log("Ctrl-C to terminate events subscription")
myToken.onLog((entry) => {
console.log(entry)
}, { minconf: 1 })
}
Let's see it in action. Launch the events subscriber:
node index.js events
Subscribed to contract events
Ctrl-C to terminate events subscription
The program hangs there waiting for new events. In another terminal, mint more tokens:
node index.js mint dcd32b87270aeb980333213da2549c9907e09e94 10000
mint tx: c0e3007178a1b9e05b33e770f7a0e7d084f2d06732658524be042dc0e9864cc4
Wait for a bit for confirmations. In the events terminal, you should see both Mint and Transfer events printed out:
If you are running your own hydrad node instead of the provided docker image, you'll need to enable -logevents for events logging to work.
Conclusion
In this chapter we've developed a simple NodeJS CLI tool to interact with an HRC20 contract.
hydrajs is a Promise-based API. Use async/await to write clean asynchronous code.
call is like "query", send is like "commit".
Use senderAddress to in call or send to specify the msg.owner.
Now that you know how to use hydrajs, you are ready to build a DApp, and be on your way to fame and riches!
For modern JavaScript development, you really owe it to yourself to try . hydrachainjs comes with static type definitions for its API, and with VSCode you get some of the most useful IDE features (e.g. type-accurate autocomplete) without the UX bloat:
It is recommended to try too. JavaScript is in fact an extremely powerful language. TypeScript is the sobered-up version, yet retaining the same dynamism and expressivity that JavaScript developers love.
Or yarn install if you prefer that. See:
See an example file
myToken.call("totalSupply") returns a , and await is a syntatic sugar to that waits for the asynchronous computation, then returns the result.
Solidity numbers (int, uint, etc.) are represented in JavaScript using .
The type definition for :
As we've learned in , HYDRA doesn't really have the idea of an "account". The msg.sender is the address of whatever UTXO that was used to pay for the transaction.
In the above code, the third argument of send allows you to specify the msg.sender. Remember to this address with UTXOs.