節點扮演的角色是在鏈下世界和區塊鏈之間的中間件。本文將逐步講解如何在 18.04的系統中,基于環境搭建節點。
自己搭建節點比較方便測試各類節點的任務,可以在搭建的節點上添加多個job對外提供服務,同時通過搭建節點,能夠更加深刻的了解的基本數據請求模型。
運營節點相關
在節點自帶的適配里,不能直接處理需要驗證的API數據,如果想通過含驗證(密鑰,API Key等,我們會在外部適配器章節討論這個場景)的API提供數據,我們就需要添加外部適配器(在節點上建立橋指向外部適配器)通過節點連接數據。
硬件要求
對節點的硬件要求是比較輕量的,唯一比較重的地方在于需要一個區塊鏈全節點連接ieee9節點使用說明,但如果使用第三方服務(如,推薦自己搭建節點采用這種方式),則最少只需要1GB的內存和10GB的硬盤,在實測中,如果節點服務器只有1GB內存,則實際能用于節點的將不足1GB,將無法開啟節點,所以,至少要2GB內存,需要考慮到服務器還有其他進程在運行。
該節點將在Kovan測試網環境下部署,如LINK代幣地址用的是Kovan網絡上部署的合約。
安裝步驟--基于方式步驟1:安裝
更加詳細步驟可參考:///how-to--and-use--on--18-04
或者按照官方文檔的步驟:
curl -sSL https://get.docker.com/ | sh
sudo usermod -aG docker $USER // 執行這一行,可以不用通過sudo docker執行
exit
# log in again
注意,如果通過其他方式安裝完,但執行命令需要用sudo權限,可以執行:sudo -aG $USER,將當前用戶添加到組中。
驗證是否正確安裝
docker run hello-world
如果本地沒有鏡像,這會拉取鏡像,并開啟容器,從而測試是否能正常工作。
步驟2:創建安裝項目
我們假定節點在當前主目錄下保存相關文件,創建一個隱藏文件夾:
mkdir ~/.chainlink-kovan
步驟3:配置文件
執行:
echo "ROOT=/chainlink
LOG_LEVEL=debug
ETH_CHAIN_ID=42
MIN_OUTGOING_CONFIRMATIONS=2
LINK_CONTRACT_ADDRESS=0xa36085F69e2889c224210F603D836748e7dC0088
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
GAS_UPDATER_ENABLED=true
ALLOW_ORIGINS=*" > ~/.chainlink-kovan/.env
或者直接在創建的目錄下,新建一個.env文件,將如下內容寫入:
ROOT=/chainlink
LOG_LEVEL=debug
ETH_CHAIN_ID=42
MIN_OUTGOING_CONFIRMATIONS=2
LINK_CONTRACT_ADDRESS=0xa36085F69e2889c224210F603D836748e7dC0088
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
GAS_UPDATER_ENABLED=true

ALLOW_ORIGINS=*
其中,88是LINK代幣()在Kovan網絡上的合約地址。
步驟4:設置以太坊網絡連接
本文采用第三方的節點服務,使用的是提供的連接服務。可以訪問申請連接地址,在節點配置這里,需要的是的配置鏈接,形如:wss://kovan..io/ws/v3/
注:請使用自己的鏈接。
現在將其配置到.env文件中。
執行:
echo "ETH_URL=wss://kovan.infura.io/ws/v3/afc48dd54b2b408aa43e79ce09c5d1f5 >> ~/.chainlink-kovan/.env
現在的環境配置文件內容為:
ROOT=/chainlink
LOG_LEVEL=debug
ETH_CHAIN_ID=42
MIN_OUTGOING_CONFIRMATIONS=2
LINK_CONTRACT_ADDRESS=0xa36085F69e2889c224210F603D836748e7dC0088
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
GAS_UPDATER_ENABLED=true
ALLOW_ORIGINS=*
ETH_URL=wss://kovan.infura.io/ws/v3/afc48dd54b2b408aa43e79ce09c5d1f5
步驟5:設置數據庫
我們在容器中開啟數據庫,這也是官方支持的數據庫。
開啟新的容器并拉取數據庫鏡像
執行如下命令:
docker container run -d --name=pg -p 5432:5432 -e POSTGRES_PASSWORD=keepitsecret -e PGDATA=/pgdata -v /pgdata:/pgdata postgres:latest
使得宿主機器端口和容器端口映射關系為:5432->5432,并設定數據庫的密碼,同時我們會在宿主機器的目錄:/掛載容器數據(在容器內操作,可以直接在宿主機器中查看文件),并拉取的最新鏡像。
查看容器跑起來之后的數據,查看/目錄(和容器內相同):
linknode@chainlinkhost:/pgdata$ ls
base pg_hba.conf pg_notify pg_stat pg_twophase postgresql.auto.conf
global pg_ident.conf pg_replslot pg_stat_tmp PG_VERSION postgresql.conf
pg_commit_ts pg_logical pg_serial pg_subtrans pg_wal postmaster.opts
pg_dynshmem pg_multixact pg_snapshots pg_tblspc pg_xact postmaster.pid
**
測試數據庫的連接:
linknode@chainlinkhost:~$ telnet localhost 5432
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
通過查看5432端口是否正常連接來判斷容器是否正常通信。
連接數據庫
docker container exec -it pg psql -U postgres
注意前面開啟容器啟動數據庫時,設定的容器名是pg,現在開啟容器并進入到數據庫的命令行界面,默認有一個用戶名:,本地機器無需密碼即可訪問。
基本命令:
\l --列出數據庫
\c chainlinkdb --連接到指定的數據庫
\q --退出psql
創建數據庫
基本指令:
create database chainlinkdb;
具體執行:
linknode@chainlinkhost:~$ docker container exec -it pg psql -U postgres
psql (13.2 (Debian 13.2-1.pgdg100+1))
Type "help" for help.
postgres=# create database chainlinkdb;
CREATE DATABASE
postgres=#
現在關于數據庫的信息差不多準備完畢,基本信息如下:
設置節點環境變量中的數據庫字段
echo "DATABASE_URL=postgresql://postgres:keepitsecret@8.136.156.151:5432/chainlinkdb" >> ~/.chainlink-kovan/.env
步驟6:運行節點
現在可以開始運行節點了。
執行:
docker run -p 6688:6688 -v ~/.chainlink-kovan:/chainlink -it --env-file=.env smartcontract/chainlink:0.9.4 local n
注意端口映射關系。
這里選擇的鏡像的版本是0.9.4,可以選擇其他版本或者最新版本)。
通常,這時候都會遇到一個問題: to lock ORM: pq: SSL is not on the
解決方法是修改配置文件中的字段:
DATABASE_URL=postgresql://postgres:keepitsecret@8.136.156.151:5432/chainlinkdb?sslmode=disable
末尾添加:?=即可。
如果出現類似:
2021-03-13T10:23:03Z [ERROR] unable to lock ORM: dial tcp 8.136.156.151:5432: connect: connection timed out logger/default.go:155 stacktrace=github.com/smartcontractkit/chainlink/core/logger.Errorf
可以判斷一下是否服務器的安全組沒有添加允許訪問服務器的端口的權限,這個錯誤可能是因為服務器端口沒有在安全組進行配置。
現在是5432端口,后面需要從瀏覽器端能訪問ieee9節點使用說明,需要打開6688端口。
最終可行的配置方案為:
ROOT=/chainlink
LOG_LEVEL=debug
ETH_CHAIN_ID=42
MIN_OUTGOING_CONFIRMATIONS=2
LINK_CONTRACT_ADDRESS=0xa36085F69e2889c224210F603D836748e7dC0088
CHAINLINK_TLS_PORT=0

SECURE_COOKIES=false
GAS_UPDATER_ENABLED=true
ALLOW_ORIGINS=*
ETH_URL=wss://kovan.infura.io/ws/v3/afc48dd54b2b408aa43e79ce09c5d1f5
DATABASE_URL=postgresql://postgres:keepitsecret@8.136.156.151:5432/chainlinkdb?sslmode=disable
DATABASE_TIMEOUT=0
注意添加,且中用的是IP地址,服務器的防火墻添加5432和6688端口的訪問規則。
再次執行:
docker run -p 6688:6688 -v ~/.chainlink-kovan:/chainlink -it --env-file=.env smartcontract/chainlink:0.9.4 local n
首次執行成功時,需要輸入新的密碼并確認密碼,這個密碼會用于錢包密碼,用于解鎖文件,然后我們需要輸入郵件和密碼,這會用于從界面登錄節點管理界面。
訪問::6688/
輸入剛剛配置的郵箱地址和密碼即可進入。
并且可在配置頁查看到關于節點的信息。
至此,鏈下節點部分就運行起來了。
下面我們將進行屬于此節點的預言機合約的部署。
預言機合約部署鏈上交易 & 鏈下數據部署合約的步驟
在Remix上,新建一個合約,命名為.sol:
pragma solidity 0.6.6;
import "https://github.com/smartcontractkit/chainlink/evm-contracts/src/v0.6/Oracle.sol";
在Remix中導入和在中導入是不同的。
這樣就可以直接部署此合約了。
部署合約的賬戶需要有一定的ETH作為gas費支出,同時領取一定的LINK測試代幣(節點暫時不需要,為了后續的節點調用,可以先準備領取一些代幣)。
constructor(address _link)
public
Ownable()
{
LinkToken = LinkTokenInterface(_link); // external but already deployed and unalterable
}
注意部署時候,需要傳入LINK代幣合約的地址
Kovan上LINK代幣合約地址是:88
部署完成后,得到合約的地址:31
將節點的賬戶地址添加到合約中
設置格式:sion(87, true)
這里預言機合約地址填寫自己實際部署上去的即可,實際本文用的是: 31
使用節點添加job
{
"name": "Get > Bytes32",
"initiators": [
{
"type": "runlog",
"params": { "address": "0xa04803C3cbd890083D668e7fc3cE44863ff9df31" }
}
],
"tasks": [
{ "type": "httpget" }, { "type": "jsonparse" }, { "type": "ethbytes32" }, { "type": "ethtx" }
]
}
其中,觸發器字段中的字段是合約字段,觸發器監聽此預言機合約的事件,來觸發下面tasks的執行。 創建的jobId為:
該job的主頁:8.136.156.151:6688/jobs/ 現在準備讓這個job發揮作用,為合約提供服務,可以賺取LINK代幣。
添加消費者合約
這個合約主要是基本模型的左側合約的子合約(參考基本請求模型章節),調用預言機的服務。調用一次至少消耗1LINK。
消費者合約代碼:
pragma solidity ^0.6.0;
import "https://raw.githubusercontent.com/smartcontractkit/chainlink/develop/evm-contracts/src/v0.6/ChainlinkClient.sol";
// 消費者合約need to deposit LINK
contract APIConsumer is ChainlinkClient {
uint256 public ethereumPrice;
address private oracle;
bytes32 private jobId;
uint256 private fee;
constructor() public {
setPublicChainlinkToken();
oracle = 0xa04803C3cbd890083D668e7fc3cE44863ff9df31; // oracle address
jobId = "9a0e3a132a6847b9bf6aa856b17a2ab9"; // jobId
// Minimal Oracle Fee,Check out Configuration-> MINIMUM_CONTRACT_PAYMENT
fee = 1 * 10 ** 18; // 1 LINK
}
function requestEthereumPrice() public returns (bytes32 requestId)
{

Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
// 設置所要請求的API地址,HttpGet
request.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
// API返回結果的解析路徑,JsonParse
request.add("path", "USD");
// 為去除小數點將結果乘以的倍數
request.addInt("times", 100);
// 發送請求
return sendChainlinkRequestTo(oracle, request, fee);
}
function fulfill(bytes32 _requestId, uint256 _price) public recordChainlinkFulfillment(_requestId)
{
ethereumPrice = _price;
}
}
部署此合約,并記錄部署的合約地址:6E
為了能調用預言機服務,需要向此合約充值LINK代幣。
在這個消費者合約的代碼中,我們會調用函數向預言機合約發送請求,等到鏈下數據準備完畢,預言機合約會回調函數,這個也是需要我們在此消費者合約中提前準備好的,預言機通過調用此函數將獲取到的數據傳遞到本合約中的狀態變量,這里是。
但是在調用時,跟蹤節點job運行狀態會發現下面的錯誤,這是一個經典的錯誤,預言機節點會卡在:
原因:沒有給的節點賬戶充ETH,它沒有足夠的ETH支付gas費用,預言機節點需要調用合約的函數,需要支付gas費。
充值ETH完成后,可以看到job順利運行。
通過這個步驟,也能間接看出,job運行是可以被暫停的,在tasks字段中定義的適配器的執行是按照順序來的,在客戶端合約構建請求時,添加參數可以是無序的,因為數據會以字典的形式存儲到參數字段,每一個適配器所需要的參數字段是不同的。且每種適配器有自己的使用范圍和場景。
取回預言機合約中的LINK代幣
取回合約中獲得的代幣,雖然代幣是節點提供提供服務,但是消費者合約支付的LINK是要給到合約的。
如果是通過Remix部署的預言機合約,則直接調用函數取回即可。
function withdraw(address _recipient, uint256 _amount)
external
override(OracleInterface, WithdrawalInterface)
onlyOwner
hasAvailableFunds(_amount)
{
withdrawableTokens = withdrawableTokens.sub(_amount);
assert(LinkToken.transfer(_recipient, _amount));
}
需要指定接收人地址以及要取回的數量。
END.