Web3.js

This will be a fairly brief write-up, introducing Web3 ahead of my next DApp tutorial series.

To kick this article off, I first have to reaffirm, for those that aren’t aware, I am not, and never have been, a lover of JavaScript. While my cool friends were off learning Node, and for some reason moving a scripting language to the backend, I was learning C and Go, Erlang and Distributed Systems.

For years, I harboured a deep hatred of JS, and actively whinged about it at every opportunity I got; being forced to use it in my daily work life. Now however, I do have to say; over the last few years I have softened to JS, and I am much more comfortable in my own skin when having to use it.

It goes without saying, the entire web is JS. Look around you - JS. View the source of this article - JS files. Look at your own app’s dependencies - JS.

JavaScript, specifically Node, really is in everything we use, and that now also applies to our wonderful world of Cryptocurrencies.

As I mentioned briefly in my last article, my next article series is going to be about building your first DApp – from start to finish. Inevitably, the frontend of our DApp needs to be able to communicate with the Ethereum Network. This is where Web3.js comes into the mix. Web3.js is a collection of APIs allowing us such functionality as: Reading & Writing data from Smart Contracts, sending and receiving Ether, encrypting / decrypting wallets & data, and a whole bunch of other stuff too. Basically, most of the backend functionality available on the Ethereum Network natively becomes available for use in the browser.

This is how the web3.js library talks to the Ethereum Network:

Web3 JS Diagram
Image credit: iotbl

So, now that the basics are covered, let’s go over installing and using the web3.js library.

Installing Web3

Installing web3.js is as simple as:

npm install web3

One thing worth noting here; is that (coming from an anti-js background), I kept getting a cannot find web3 module error when trying to import web3 into a Node console. If you, like me, aren’t a big js fan, this can be solved by first running the npm init command to ensure there is a package.json file in the cwd, and then you can run npm install web3, and it will work fine. (I realise this is basic stuff – but actually for someone who’s tried to avoid Node at all costs, it was initially confusing enough to have to search online.)

I am working from a Mac here, but if you are working from Windows, the install process can be exactly the same, assuming you do have Node & NPM installed.

So, with web3.js installed, let’s do some basic interactions with the Ethereum Network, and dive on in!

Communicating with the Ethereum Network

Wallet Interaction

For this article, we’re going to use Ganache, for simplicity, as our local Blockchain. By using Ganache, we can spin up a local Ethereum node, without having to write a single line of code!

(Yes, I realise that rhymes. No, I didn’t realise until my second proof-read through of this article!)

In fact, though, Embark already has Ganache inbuilt, so we could also simply run:

embark simulator

Anyway, to install Ganache head over to this page and click on the executable there. If you so choose; there is also a Ganache CLI available you can install by running:

npm install -g ganache-cli

Running the Ganache CLI will give you the same functionality as the desktop client; in essence giving us a multitude of ETH-loaded wallets that we can build contracts around / interact with.

Ganache CLI

Rather brilliantly; we now have a local Ethereum Node running that we can start using the Web3 client to interact with. In another Terminal tab, open up a node instance from the same working directory we ran the npm init command from earlier.

Now, in our interactive Node console, run:

var Web3 = require('web3');
var web3 = new Web3('http://localhost:8545');

Something to note here, is that I’m calling new Web3 with an http protocol, but the WebSocket protocol is also commonly used:

var web3 = new Web3(Web3.givenProvider || new Web3.providers.WebsocketProvider('ws://remotenode.com:8546'));

To test and ensure the connection, you can get a list of the accounts made available in Ganache by running:

web3.eth.getAccounts().then(console.log);

Which should give you an output like the following:

> [ '0x7689cF9F90FAad61B8a3c9b1b2A5b4580B37358b',
'0x852e9a9db77a4e6169e175cDBb33dBE350150A8e',
'0x946700a1a4f30Dfe80307C91B6DaF1cCa2d09401',
'0x7d356aF02A87147D3ce5F9ACA716a78f70aF7616',
'0x88A116a16e4c8838F575a0e7a72eE27C7B073263',
'0x655317701Fcf3b310F492cB801C8D23f8c6fb556',
'0x16D305e72aFb0DDa1dB1830F8a98D5cD5337882E',
'0x9099bb4Af9CE5734E7a7e62f817e833fcFFaaF32',
'0x2ec4CC6700d0424A78a9B9Fc2ecBaeFc162313F1',
'0x1BC51a0edEC9FdEA3B14748e9209F4bF8Fe024b5' ]

If you want to check the balance of an individual account from the above list, you can do so by running:

const account1 = "0x7689cF9F90FAad61B8a3c9b1b2A5b4580B37358b";

web3.eth.getBalance(account1)
.then(console.log);

Which will output:

> 100000000000000000000

Contract Interaction

As above; interacting with our individual accounts through web3.js is cool, but not nearly the extent to which the library works. Let’s now take a brief look at the more important functionality; of interacting with Smart Contracts through web3.js.

The first thing we need to do, is to create a new Smart Contract, which we can do with the new web3.eth.Contract command.

Before we call the new command, we need to assign our json interface for the contract’s ABI:

const abi = [{"type":"function", "name":"foo", "inputs": [{"name":"a","type":"uint256"}], "outputs": [{"name":"b","type":"address"}] },{ "type":"event", "name":"Event", "inputs": [{"name":"a","type":"uint256","indexed":true},{"name":"b","type":"bytes32","indexed":false}], }]

The json interface is a JSON object describing the Application Binary Interface (ABI) for our Smart Contract. Using this JSON interface; web3.js is able to create a JavaScript object representing our Smart Contract and its methods & events, using the web3.eth.Contract functionality.

Note, the above JSON interface / ABI is taken directly from the Web3 docs.

Now that we have our json interface defined, we can create our new contract instance:

var myContract = new web3.eth.Contract(abi, '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe');

(The from address is the address of the already deployed contract instance that we’re aiming to talk to.)

You could then set the Smart Contract’s data and other options, and then deploy your Contract with something like the following:

myContract.options.data = '0x12345...';

myContract.deploy({
arguments: [123, 'My String']
})
.send({
from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
gas: 1500000,
gasPrice: '30000000000000'
})
.then(function(newContractInstance){
console.log(newContractInstance.options.address) // instance with the new contract address
});

The above examples aren’t supposed to be perfect continuous code, and should definitely not be copy/pasted into a production project, but they are there to show off roughly how Web.js works, and give an overview of interacting with the 2 main pieces of functionality, as I see them – Wallets and Contracts.

In my next tutorial series, we will be utilising Embark, and therefore we’ll be diving deeper into web3.js, and showing off much more of its potential.

Web.js in Other Languages

Naturally the whole idea behind this article was to show off communication with the Ethereum Network through a JavaScript frontend. However, there are also many other libraries, in pretty much every language, available to do the same:

Nim - nim-web3
Crystal - web3.cr
Ruby - web3-eth gem
Elixir - ethereumex
Python - Web3.py
Haskell - hs-web3
Java - web3j
Scala - web3j-scala
Purescript - purescript-web3
PHP - web3.php

Beyond Web3

As stated at the opening of this article, we’ve barely even scratched the surface of web.js capabilities. But I do hope that you now have a better understanding of what Web3 stands for.

Personally, I am very much looking forward to diving on in to my next DApp tutorial series, to utilise and demonstrate the Ethereum Network to its fullest.

As always, if you have any questions regarding Web3, how Status utilises Web3, or if you have comments on this article, feel free to reach out to me at [email protected].

Thanks again for reading, and check back for my DApp tutorial series, starting later this week!

- @rbin