Chainlink节点部署教程
本文主要参考Chainlink官方文档(https://docs.chain.link/docs/running-a-chainlink-node)编写,如果您可以阅读英文,推荐您直接阅读官方文档。
安装必须组件
服务器环境Ubuntu1804,我们以Ropsten测试网为例,以太坊主网的搭建只需修改相关配置选项即可。
Docker 安装参考文档
https://docs.docker.com/engine/install/ubuntu/
将当前用户添加至docker用户组
sudo usermod -aG docker $USER
exit
# 重新登录
PostgresSQL
Chainlink Node在0.8版本之后将PostgresSQL作为唯一的存储选项。PostgresSQL数据库可以是自己搭建的,也可以是云服务商提供的,只要可以提供数据库的访问接口即可。
本地安装参考:
https://www.postgresql.org/download/linux/ubuntu/
以太坊客户端
Chainlink节点通过与以太坊客户端节点连接,通过连接的以太坊客户端来获取链上的用户预言机请求,通过提交交易将获取到的数据写入到链上。所以Chainlink节点必须要依靠一个以太坊客户端节点才能发挥作用。您可以自己搭建以太坊客户端节点,也可以选择以太坊RPC服务提供方的服务,只需要一个WebSocket链接提供给Chainlink节点即可。
Chainlink的文档中(https://docs.chain.link/docs/run-an-ethereum-client)提供了搭建本地以太坊客户端节点的方法,也提供了几个外部以太坊API服务供您选择。由于以太坊客户端节点对硬件要求比较高,本文中我们选择infura提供的免费API来作为Chainlink节点的以太坊客户端选择。
部署Chainlink节点
创建Chainlink目录
Ropsten: mkdir ~/.chainlink-ropsten
配置环境变量
Ropsten:
echo "ROOT=/chainlink
LOG_LEVEL=debug
ETH_CHAIN_ID=3
MIN_OUTGOING_CONFIRMATIONS=2
LINK_CONTRACT_ADDRESS=0x20fE562d797A42Dcb3399062AE9546cd06f63280
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
GAS_UPDATER_ENABLED=true
ALLOW_ORIGINS=*
ETH_URL=wss://ropsten.infura.io/ws/v3/<your-api-key>
DATABASE_URL=postgresql://postgres:password@localhost:5432/postgres
DATABASE_TIMEOUT=0" > ~/.chainlink-ropsten/.env
MIN_OUTGOING_CONFIRMATIONS
: 节点发出交易所需要的最小确认块数,在达到最小确认块数之前,同一个run不会开始下一个任务。如果不设置,默认值为12。
LINK_CONTRACT_ADDRESS
: LINK token的发行地址,这里有测试网和主网的LINK发行地址,您可以根据自己的网络进行配置。如果不进行配置,默认是主网的LINK发行地址。
GAS_UPDATER_ENABLED
: 如果设置为true,节点会在提交事务失败时提高gas费用重新提交。默认为false。
ETH_URL
: 以太坊客户端WebSocket RPC接口地址。您可以选择自建以太坊客户端,也可以选择第三方服务,只要提供WebSocket协议的RPC接口地址即可。
DATABASE_URL
: Chainlink节点需要使用PostgresSQL数据库来进行一些数据的持久化存储。同样您可以选择自建数据库或使用第三方数据库服务,只需要提供数据库地址可以让节点读写数据即可。
DATABASE_TIMEOUT
:数据库连接超时等待时间。默认500ms。
启动节点
cd ~/.chainlink-ropsten && docker run -p 6688:6688 -v ~/.chainlink-ropsten:/chainlink -it --env-file=.env smartcontract/chainlink local n
首次启动会首先要求管理员输入一个密码,这个密码是节点账户的keystore密码,这个密码必须牢记,丢失的话没有办法找回,并且私钥所管理的资金也会丢失。每次启动都会要求管理员输入这个密码,以解锁keystore。节点需要通过keystore的私钥来签署交易,提交到区块链上。
接下来还会要求节点管理员输入一对邮箱账户和密码,用于登录节点管理页面。
测试节点
登录浏览器管理页面
浏览器中打开ip:6688地址,就能看到Chainlink节点管理页面的登录入口。用我们在启动节点时填入的邮箱账户和密码,就可以登录到管理界面中了。
我们先去到**Configuration
** 标签页,会发现有一个ACCOUNT_ADDRESS
字段,这个address就是我们在首次启动节点时候设置keystore密码的私钥所对应的地址,在节点提供服务之前,需要向这个地址转入ETH,用于提交交易。
由于我们使用的是Ropsten测试网络,所以我们可以把这个地址复制到Ropsten faucet中,获取测试ETH。如果您是服务于以太主网上的应用,需要您想这个账户地址手动转入ETH。
创建oracle合约
Oracle合约是Chainlink节点在区块链上的桥头堡,它与用户合约直接进行沟通,接收用户的预言机请求,将请求结果通过用户注册的回调函数,写入到用户的合约中。
Oracle合约无需自己编写,我们直接部署Chainlink开源的Oracle合约代码即可。如果用remix部署,只需新建一个包含下面两行代码的文件即可:
pragma solidity 0.6.6;
import "https://github.com/smartcontractkit/chainlink/evm-contracts/src/v0.6/Oracle.sol";
需要注意的是,oracle合约会暂时接受用户发起Chainlink请求是所支付的LINK费用,所以请务必妥善保存合约owner的私钥。
部署好Oracle合约之后,需要将开放权限给节点的地址,允许节点可以提交事务。
创建Jobs
按照文档中的例子,在节点中添加Job(作业)。
打开节点管理界面的Jobs标签页,点击New Job添加新的Job,将每个类型的Job的JSON拷贝到文本框中,用刚刚部署好的Oracle合约地址,替换JSON中的YOUR_ORACLE_CONTRACT_ADDRESS
字段。每创建成功一个Job,都会生成一个Job ID,在Jobs标签页可以找到所有的Jobs。
测试节点可用性
接下来我们测试一下我们部署的Chainlink服务的可用性。
pragma solidity ^0.6.0;
import "https://raw.githubusercontent.com/smartcontractkit/chainlink/develop/evm-contracts/src/v0.6/ChainlinkClient.sol";
contract APIConsumer is ChainlinkClient {
uint256 public ethereumPrice;
address private oracle;
bytes32 private jobId;
uint256 private fee;
constructor() public {
setPublicChainlinkToken();
// 填入我们刚刚部署好的oracle地址
oracle = 0x5F66a231a29CE1513dc6c16407fDCe9D0aEE2cB0;
// 填入我们刚刚创建的地址
jobId = "4b9b6e7d89154a8d855affed3985aafd";
// 支付给Oracle的最小费用,可用在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地址
request.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
// API返回结果的解析路径
request.add("path", "USD");
// 为去除小数点将结果乘以的倍数
request.addInt("times", 100);
// 发送请求
return sendChainlinkRequestTo(oracle, request, fee);
}
function fulfill(bytes32 _requestId, uint256 _price) public recordChainlinkFulfillment(_requestId)
{
ethereumPrice = _price;
}
}
部署好用户合约之后,向用户合约转入LINK,调用requestEthereumPrice
方法,就可以测试我们的Chainlink预言机节点是否可以正常工作啦。