Authenticating on the Blockchain with Hydro & Web3.js

Rachel Lee
Hydrogen
Published in
4 min readAug 23, 2018

Introduction

Today, we will use web3.js (Ethereum JavaScript API) to authenticate on the public blockchain via the Hydro Server-side Raindrop smart contract, using the Server-side Raindrop API. To interact with Ethereum smart contracts, you can use popular sites such as Ethereum Wallet, MyEtherWallet, and MyCrypto, or interface programmatically with libraries like web3.js, as we will describe in this article. Check out the full code for our sample app here!

Process Overview

Here are the steps for implementing the Server-side Raindrop API to authenticate via the blockchain. Step 4, specifically, is where we use web3.js to programmatically interact with the smart contract, outside of the purview of the Raindrop API.

  1. Get an access token with the OAuth API
  2. Whitelist an Ethereum address with the Raindrop API
  3. Request a challenge with the Raindrop API
  4. Execute an authentication transaction via the Server-side Raindrop smart contract
  5. Validate the authentication attempt with the Raindrop API

Setting Up the Environment

Before we start, make sure you have Node.js installed on your machine. You can find details to our server setup in the sample app which is built on node v10.4.1, npm 6.1.0, and web3.js 1.0.0-beta.35.

Let’s dive into the code! First, we initialize our Node/Express server.

const express = require('express');
const cors = require('cors');
const app = express();
const morgan = require('morgan');
const chalk = require('chalk');
const bodyParser = require('body-parser');
const request = require('request-promise');
const path = require('path');
const nodeModulesPath = path.join(__dirname, '../node_modules');
app.use(cors());
app.use(morgan('dev'));
app.use(express.static(nodeModulesPath));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//we can execute our logic here!
function main() {
...}//global error handling
app.use(function (err, req, res, next) {
});//our server listens on port 3000
app.listen(3000, function() {
main();
});

As part of the setup, we also create a web3 instance by passing in the Ethereum network provider. We use the Rinkeby testnet in this example, so that we don’t have to run our own Ethereum node in order to interact with the smart contract.

const Web3 = require('web3');
const web3 = new Web3('wss://rinkeby.infura.io/ws');

Now, we create an instance of the contract using the interface.json which contains an ABI (Application Binary Interface), or what is simply a JSON representation of our contract.

const contractAddress = '0x4959c7f62051D6b2ed6EaeD3AAeE1F961B145F20';
const abi = require('../interface.json');
const HydroContract = new web3.eth.Contract(abi, contractAddress);

We can carry out the following steps inside the main function in the initial code block.

Step 1: Get an access token with the OAuth API

Let’s call the OAuth API given the client_id and client_secret credentials. Developers can get access to these credentials when registered on the Hydrogen platform.

const auth = new Buffer.from(`${client_id}:${client_secret}`).toString('base64')

We’ll use the header 'Authorization': `Basic ${auth}`. Here is an example of a curl request below.

curl -X POST https://sandbox.hydrogenplatform.com/authorization/v1/oauth/token?grant_type=client_credentials \   
-H "Authorization: Basic aHlkcm9nZW5faWQ6aHlkcm9nZW5fc2VjcmV0"

We receive an access_token from the API response, which we save into a variable as shown below.

let access_token = '<OAuth Token>';

Step 2: Whitelist an Ethereum address with the Raindrop API

Next, we create an Ethereum account using web3, which provides us the address and the privateKey to our account.

let account = web3.eth.accounts.create();
let { address, privateKey } = account;

As a one-time step, let’s whitelist the Ethereum address with the Raindrop API. This may take ~30 seconds, as it saves the address on the blockchain and thus propagates a state change on the Ethereum network. We’ll use the header 'Authorization': `Bearer ${access_token}` this time. Here is an example of a curl request below.

curl -X POST -H "Authorization: Bearer ac6b8213-2a77-4ecc-89fd-68c9f2aff256" \      
-H "Content-Type: application/json"
-H \
-d '{ "address": "0xWY81621928g5454415154354ac82cd2F266181G7" }' "https://sandbox.hydrogenplatform.com/hydro/v1/whitelist"

We receive a hydro_address_id from the API response, which we save into a variable as shown below.

let hydro_address_id = '<hydro_address_id>';

Step 3: Request a challenge with the Raindrop API

Next, we request challenge details via the Raindrop API — these are the transactional parameters we will have to satisfy on-chain in order to authenticate. This returns values for amount, challenge, and partner_id. Let’s also save these into variables.

let amount = '<amount>';
let challenge = '<challenge>';
let partner_id = '<partner_id>';

Step 4: Execute an authentication transaction via the Server-side Raindrop smart contract

Now, given all the information we have so far, we can authenticate via our smart contract on the blockchain by calling the authenticate smart contract method! Below is a code snippet for a performRaindrop function which calls on the sendSignedTransaction utility function to execute the transaction.

Step 5: Validate the authentication attempt with the Raindrop API

Finally, we check if the transaction has been successfully performed on the blockchain by making another request to the Raindrop API. Here is an example of a curl request below.

curl -X GET -H "Authorization: Bearer ac6b8213-2a77-4ecc-89fd-68c9f2aff256" \   "https://api.hydrogenplatform.com/hydro/v1/authenticate?hydro_address_id=cbcd0758-1314-11e8-b642-0ed5f89f718b"

If all went well, we should receive a 200 status code along with metadata such as authentication_id in the response. This metadata can be used in any private systems that could benefit from a layer of public authentication on the blockchain.

Thanks for reading! If you have any questions or feedback, please feel free to write comments below.

Resources

Find Sample app with web3.js here: https://github.com/hydrogen-dev/Hydro-Auth

Find Hydro Raindrop API documentation here: https://www.hydrogenplatform.com/docs/hydro/v1/#Raindrop

Find instructions for calling the Hydro Raindrop contract here: https://www.hydrogenplatform.com/docs/hydro/v1/#Smart-Contract

Request Sandbox API credentials here: https://www.hydrogenplatform.com

--

--