Chainlink on Docker: Part 1
Tags: chainlink, docker, web3, beginners
Published: 2023-06-29 06:34:50

Adding off-chain data to a Blockchain network is not a straightforward process. For a Blockchain network to achieve Byzantine Fault tolerance, all the nodes or peer nodes in the network must unanimously agree on the state of the blockchain, also known as the world state. This means that the ledger, which contains the complete history of transactions, must always be consistent and verifiable by all nodes. No node can add a transaction to the ledger without the agreement of other peer nodes. To ensure resilience, every peer node maintains a copy of the ledger. Therefore, even if a particular node becomes unavailable due to network issues or malicious attacks, other nodes can continue to operate within the blockchain network and handle requests. If a compromised node tries to rejoin the network, it may need to be in-line with the blockchain rules (or policies) or be removed from the network through voting, especially if it continues to introduce conflicting transactions that deviate from the overall world state. In Blockchain, the principle of quorum rules applies, where the majority consensus is crucial, and mechanisms are in place to prevent a central entity from validating every transaction of each node.

In my own opinion, [Chainlink](https://docs.chain.link/) seems to be the leading oracle that allows integration of data that is considered off-chain to the Blockchain network. With the consistent trend of Web3 and Generative AI it is important to know what Chainlink is. What is the role of Chainlink in various use cases such as  Decentralized Finance, Non-Fungible Tokens (NFTs), Music and Gaming. In a overly simplified way, basically, an oracle or mainly a "decentralised oracle network" (DON) allows `off-chain` data to be integrated to a Blockchain network such as Ethereum Mainnet or the Testnets such as Sepolia. 

The aim of this article is to cover the steps that one would  follow when configuring a Chainlink node locally via Docker. Please use the [link](https://docs.chain.link/chainlink-nodes/resources/requirements) for the hardware requirements if you aim to set this up within your own machine. The steps  are as follows for this article:

- PostgreSQL database setup
- Details on setting up an Alchemy or Infura free account for Sepolia, getting the API KEY.
- Configure an Testnet environment via docker for Sepolia as well.
- Attempt to fulfil requests with the Chainlink node through a Smart contract written in Solidity.
- Validation of transactions via [Etherscan](https://sepolia.etherscan.io/contractsVerified).

### Setting up PostgreSQL

You can pull an existing docker for PostgreSQL and setup the following commands to create a database user, password and the database where Chainlink will create the relational databases of what store Chainlink events, transactions and events.

```
docker run --name cl-postgres -v $HOME/.chainlink-sepolia/db:/var/lib/postgresql/data -e POSTGRES_PASSWORD=myPostgresPW -d -p 5432:5432 postgres:11.12
```
Once the above has been ran, you need to create the USER and database.
```
sudo docker exec -it cl-postgres psql -U postgres -c "CREATE USER $USERNAME WITH PASSWORD '$PASSWORD';"

sudo docker exec -it cl-postgres psql -U postgres -c "CREATE DATABASE "chainlink_sepoliadb";"

sudo docker exec -it cl-postgres psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE "chainlink_sepoliadb" TO $USERNAME;"
```

The above is crucial as these PostgreSQL will be the database where the tables for Chainlink node are stored.

You can use the following ways to test if the PostgreSQL database is up and running
- if you have `psql` CLI within your local machine, you can run the command `psql postgresql://$USER:$PASSWORD@localhost:5432/chainlink_sepoliadb?sslmode=disable` to see if you get logged in to the PostgreSQL shell where the database is the `chainlink_sepolia` as mentioned within the command. For an example, see this command below:

```
~/.chainlink-sepolia$ psql postgresql://$USER:$PASSWORD@localhost:5432/chainlink_sepoliadb?sslmode=disable
psql (14.8 (Ubuntu 14.8-0ubuntu0.22.04.1))
Type "help" for help.

chainlink_sepoliadb=> 
```
- Or you can use [pgAdmin](https://hub.docker.com/r/dpage/pgadmin4/) in order to connect to your `localhost` on port `5432` as it was exposed via Docker commands. You can do administrator related tasks on the database via this tool.

### Signup for Alchemy Sepolia Testnet. 

You need to get the Websocket URL of your Alchemy application. The `.env` file for the Chainlink node will need the Websocket URL one can always use HTTPS URL to interact with blockchain network however for the Chainlink setup, you need Websocket URL.

### Setting up the Testnet client.

This is up to you. However, in this tutorial we are using the Sepolia Geth client. Using the free faucets to fund this type of testnet for fake currency seems to be currently supported as Goerli is deprecated. You can do the configuration for Goerli but the tutorial on [official documentation](https://docs.chain.link/chainlink-nodes/v1/running-a-chainlink-node) places Sepolia network forward and regards Goerli deprecated and might have potential issues when setting up. One suggestion, is to run the commands that produce constant logs via the Unix `screen` command so that they execute in the background of each terminal. 

As we did for PostgreSQL, you can configure the [Geth client](https://docs.chain.link/chainlink-nodes/resources/run-an-ethereum-client) for Sepolia using the following steps:

- `docker pull ethereum/client-go:latest`
- `mkdir ~/.geth-sepolia`
- `docker run --name eth -p 8546:8546 -v ~/.geth-sepolia:/geth -it \
ethereum/client-go --sepolia --ws --ipcdisable \
--ws.addr 0.0.0.0 --ws.origins="*" --datadir /geth`

If the container was stopped for any reason, you can restart it with the following command
```
sudo docker start -i eth
```
You can detach from the running client by using the commands `Ctrl + P, Ctrl + Q` as we do not want to stop it. Chainlink requires this container on running status in order to connect to it.

### Setting up the Chainlink node

Once you have the docker up and running for PostgreSQL, Sepolia testnet and you have setup the hidden files `.api` file API KEY for Infura/Alchemy, .password file for your Chainlink UI and a `.env` file within a hidden directory `.chainlink-sepolia`. The .env will contain all your underlying network configurations such as the ChainID for the Testnet and the LINK address to use for your chainlink node. It might look like the following:

```
LOG_LEVEL=debug
ROOT=/chainlink
ETH_CHAIN_ID=11155111
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
CHAINLINK_DEV=true
LINK_CONTRACT_ADDRESS=0x779877A7B0D9E8603169DdbD7836e478b4624789
ALLOW_ORIGINS=*
MIN_INCOMING_CONFIRMATIONS=1
ETH_URL=wss://eth-sepolia.g.alchemy.com/v2/RTDG...
DATABASE_URL=postgresql://$USER:$PASSWORD@localhost:5432/chainlink_sepoliadb?sslmode=disable

```
You need to make sure that you do not commit the above file to Github or any version control service. You start the chainlink node by running the following command.

```
sudo docker run --name chainlink_sepolia \ 
     --network host -p 6688:6688 \
     -v $HOME/.chainlink-sepolia:/chainlink \
     -it --env-file=$HOME/.chainlink-sepolia/.env \ 
      smartcontract/chainlink:1.1.0 local n -p \
      /chainlink/.password -a /chainlink/.api
```
This generates logs and push to a local folder in the same hidden directoty called, `log.jsonl`.

Once the docker containers are up and running, you can visit the URL `http://localhost:6688` and you should be able to see the Chainlink UI tool. This is where you should locate the Chainlink key, along with the Job UI console where you would define your HTTP request syntax using TOML.

### Setup a Smart contract within Solidity for a basic HTTP request (will be included in **Part 2**):

This section will be in **part 2** of this article. I will discuss the underlying smart contract that is responsible for reaching out an world-wide web service (via HTTPs) to fetch `off-chain`. Further I aim to discuss how Chainlink works with the `on-chain` smart contracts to make sure the blockchain network remains deterministic. This part would also involve setting up a frontend for the project and cover security best practices.

_Please note that the suggestions made here are purely from my understanding of the Chainlink software and can be corrected where misleading or false. The purpose is to learn and grow in the space of Web3, so comments are welcome for improvements._