Web3 Tutorial

Web3.js

Documentation

Web3 Areas

The web3-eth is for the Ethereum blockchain and smart contracts
The web3-shh is for the whisper protocol to communicate p2p and broadcast
The web3-bzz is for the swarm protocol, the decentralized file storage
The web3-utils contains useful helper functions for DApp developers.

Installing Web3

Use npm :

npm install web3

Steps in interacting with your contract

Creating the Web3 Object

// in node.js use: const Web3 = require('web3');

// use the given Provider, e.g in the browser with Metamask, or instantiate a new websocket provider
const web3 = new Web3(Web3.givenProvider || 'ws://localhost:8546', null, {});

// or
const web3 = new Web3(Web3.givenProvider || new Web3.providers.WebsocketProvider('ws://localhost:8546'), null, {});

// Using the IPC provider in node.js
const net = require('net');

const web3 = new Web3('/Users/myuser/Library/Ethereum/geth.ipc', net, {}); // mac os path
// or
const web3 = new Web3(new Web3.providers.IpcProvider('/Users/myuser/Library/Ethereum/geth.ipc', net, {})); // mac os path
// on windows the path is: '\\\\.\\pipe\\geth.ipc'
// on linux the path is: '/users/myuser/.ethereum/geth.ipc'

Creating Contract Objects

See https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html

Format is

new web3.eth.Contract(jsonInterface, address, options)

e.g.

const myContract = new web3.eth.Contract([...], '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe', {
});

Using Truffle Artifacts

import metaCoinArtifact from "../../build/contracts/MetaCoin.json";

Contract Methods

View Functions

myContract.methods.myMethod([param1[, param2[, 
...]]]).call(transactionObject, blockNumber, callback])

e.g.

// using the promise
myContract.methods.myMethod(123).call({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'})
.then((result) => {
    ...
});

State changing functions

myContract.methods.myMethod([param1[, param2[, 
...]]]).send(options[, callback])

e.g.

// using the promise
myContract.methods.myMethod(123).send({from: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'})
.then((receipt) => {
    // receipt can also be a new contract instance, when coming from a "contract.deploy({...}).send()"
});

Handling Events


myContract.events.MyEvent([options][, callback])

Example
myContract.events.MyEvent({
  filter: {myIndexedParam: [20,23], myOtherIndexedParam: '0x123456789...'}, 
    fromBlock: 0
}, (error, event) => { console.log(event); })
.on('data', (event) => {
    console.log(event); // same results as the optional callback above
})
.on('changed', (event) => {
    // remove event from local database
})
.on('error', console.error);

Truffle Example

import Web3 from "web3";
import metaCoinArtifact from "../../build/contracts/MetaCoin.json";

const App = {
  web3: null,
  account: null,
  meta: null,

  start: async function() {
    const { web3 } = this;

    try {
      // get contract instance
      const networkId = await web3.eth.net.getId();
      const deployedNetwork = metaCoinArtifact.networks[networkId];
      this.meta = new web3.eth.Contract(
        metaCoinArtifact.abi,
        deployedNetwork.address,
      );

      // get accounts
      const accounts = await web3.eth.getAccounts();
      this.account = accounts[0];

      this.refreshBalance();
    } catch (error) {
      console.error("Could not connect to contract or chain.");
    }
  },

  refreshBalance: async function() {
    const { getBalance } = this.meta.methods;
    const balance = await getBalance(this.account).call();

    const balanceElement = document.getElementsByClassName("balance")[0];
    balanceElement.innerHTML = balance;
  },

  sendCoin: async function() {
    const amount = parseInt(document.getElementById("amount").value);
    const receiver = document.getElementById("receiver").value;

    this.setStatus("Initiating transaction... (please wait)");

    const { sendCoin } = this.meta.methods;
    await sendCoin(receiver, amount).send({ from: this.account });

    this.setStatus("Transaction complete!");
    this.refreshBalance();
  },

  setStatus: function(message) {
    const status = document.getElementById("status");
    status.innerHTML = message;
  },
};

window.App = App;

window.addEventListener("load", function() {
  if (window.ethereum) {
    // use MetaMask's provider
    App.web3 = new Web3(window.ethereum);
    window.ethereum.enable(); // get permission to access accounts
  } else {
    console.warn(
      "No web3 detected. Falling back to http://127.0.0.1:9545. You should remove this fallback when you deploy live",
    );
    // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
    App.web3 = new Web3(
      new Web3.providers.HttpProvider("http://127.0.0.1:9545"),
    );
  }

  App.start();
});