搭建以太坊私有链与Chainlink本地节点

本地私有链搭建

在搭建私有链之前需要安装geth

Version: 1.10.1-stable  //我的geth版本

创建文件夹

创建如下的文件目录

/myChain
├── chainlink
└── localChain
    ├── node1

创建账户

在node1下输入命令创建账户,输入并记住密码

sudo geth --datadir ./ account new   //账户用于后面填入初始以太的账户

调用puppeth

创建私有链创世纪文件,配置方法可参考如下

  • 要选择Clique - proof-of-authority配置创建POA链
  • 要设置Which accounts should be pre-funded? (advisable at least one)填入上面创建的账户地址用于设置初始的以太
  • Which accounts are allowed to seal? (mandatory at least one)设置初始的挖矿账户,依旧填入上面创建的账户
+-----------------------------------------------------------+
| Welcome to puppeth, your Ethereum private network manager |
|                                                           |
| This tool lets you create a new Ethereum network down to  |
| the genesis block, bootnodes, miners and ethstats servers |
| without the hassle that it would normally entail.         |
|                                                           |
| Puppeth uses SSH to dial in to remote servers, and builds |
| its network components out of Docker containers using the |
| docker-compose toolset.                                   |
+-----------------------------------------------------------+

Please specify a network name to administer (no spaces, hyphens or capital letters please)
> testChain
ERROR[04-09|13:47:08.779] I also like to live dangerously, still no spaces, hyphens or capital letters 
> testchain

Sweet, you can set this via --network=testchain next time!

INFO [04-09|13:47:19.771] Administering Ethereum network           name=testchain
WARN [04-09|13:47:19.771] No previous configurations found         path=/root/.puppeth/testchain

What would you like to do? (default = stats)
 1. Show network stats
 2. Configure new genesis
 3. Track new remote server
 4. Deploy network components
> 2

What would you like to do? (default = create)
 1. Create new genesis from scratch
 2. Import already existing genesis
> 1

Which consensus engine to use? (default = clique)
 1. Ethash - proof-of-work
 2. Clique - proof-of-authority
> 2

How many seconds should blocks take? (default = 15)
> 5 

Which accounts are allowed to seal? (mandatory at least one)
> 0x24829d5D928c9f1aE2B8eFC13a24C42b6EB1846D
> 0x

Which accounts should be pre-funded? (advisable at least one)
> 0x24829d5D928c9f1aE2B8eFC13a24C42b6EB1846D
> 0x

Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)
> 

Specify your chain/network ID if you want an explicit one (default = random)
> 
INFO [04-09|13:49:02.108] Configured new genesis block 

What would you like to do? (default = stats)
 1. Show network stats
 2. Manage existing genesis
 3. Track new remote server
 4. Deploy network components
> 2

 1. Modify existing configurations
 2. Export genesis configurations
 3. Remove genesis configuration
> 2

Which folder to save the genesis specs into? (default = current)
  Will create testchain.json, testchain-aleth.json, testchain-harmony.json, testchain-parity.json
> testchain
INFO [04-09|13:49:30.973] Saved native genesis chain spec          path=testchain.json/testchain.json
ERROR[04-09|13:49:30.973] Failed to create Aleth chain spec        err="unsupported consensus engine"
ERROR[04-09|13:49:30.973] Failed to create Parity chain spec       err="unsupported consensus engine"
INFO [04-09|13:49:30.975] Saved genesis chain spec                 client=harmony path=testchain.json/testchain-harmony.json

What would you like to do? (default = stats)
 1. Show network stats
 2. Manage existing genesis
 3. Track new remote server
 4. Deploy network components
> ^C

完成上面的步骤后,可以得到testchain.json这个文件,这就是创建私有链所需要的创世纪文件

初始化私有链

在node1下初始化

sudo geth --datadir ./ init testchain.json 

配置成功如下

INFO [04-09|14:04:53.526] Maximum peer count                       ETH=50 LES=0 total=50
INFO [04-09|14:04:53.526] Smartcard socket not found, disabling    err="stat /run/pcscd/pcscd.comm: no such file or directory"
INFO [04-09|14:04:53.527] Set global gas cap                       cap=25000000
INFO [04-09|14:04:53.527] Allocated cache and file handles         database=/myChain/localChain/run/geth/chaindata cache=16.00MiB handles=16
INFO [04-09|14:04:53.534] Writing custom genesis block 
INFO [04-09|14:04:53.563] Persisted trie from memory database      nodes=355 size=50.43KiB time=2.522668ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [04-09|14:04:53.564] Successfully wrote genesis state         database=chaindata                              hash="7304a9…c1e849"
INFO [04-09|14:04:53.564] Allocated cache and file handles         database=/myChain/localChain/run/geth/lightchaindata cache=16.00MiB handles=16
INFO [04-09|14:04:53.568] Writing custom genesis block 
INFO [04-09|14:04:53.582] Persisted trie from memory database      nodes=355 size=50.43KiB time=2.078084ms gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [04-09|14:04:53.583] Successfully wrote genesis state         database=lightchaindata                         hash="7304a9…c1e849"

启动geth

sudo geth --datadir ./ --networkid 47505  --allow-insecure-unlock console

此处的47505是创建puppeth创世纪块中可以自己指定也可随机生成的,若是随机生成需要在testchain.json中查看networkid

到此为止,私有链就创建完毕了,下一步搭建在本地的chainlink节点

Chainlink节点

需要安装DockerPostgreSQL

Docker version 20.10.5, build 55c4c88   //我的docker版本
psql (PostgreSQL) 12.6 (Ubuntu 12.6-0ubuntu0.20.04.1)  // 我的psql版本

配置PostgreSQL

安装PostgreSQL可参考这篇教程
按照这篇教程的步骤一步步完成即可
需要注意的是一下两个报错

报错一
在创建完成my_user后试图连接会报错如下
psql: FATAL: Peer authentication failed for user "my_user"
参考这篇教程需要改的文件的部分内容要改成如下形式,要不然还是会报错

# Database administrative login by Unix domain socket
local   all             postgres                                md5

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            md5

(我记得要改的内容只有第一行的md5和第二行的trust?)
报错二
在调用连接数据库中,会提示不存在数据
解决方式可参考这篇博客
输入CREATE DATABASE chainlink WITH OWNER my_user ENCODING 'UTF8';可解决
结果如下

                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-------------+----------+----------+-------------+-------------+-----------------------
 chainlink | my_user  | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 

现在我们的PostgreSQL也已经配置完毕

搭建chainlink节点

搭建过程可参考这篇博客

部署LinkToken合约

首先需要在已经建立好的私有链上部署LinkToken.sol合约
以如下方式启动geth

sudo geth --datadir ./ -networkid 47505 --rpc --ws --rpcaddr "0.0.0.0" --rpcport 80 --allow-insecure-unlock console

启动的 --rpc --ws 为必须
--rpcaddr "0.0.0.0" 与 --rpcport 80 视配置要求决定
在这里插入图片描述
将合约部署在私链上如下,利用transfer函数可以进行转LINK币操作

配置文件

搭建chainlink节点
首先在我们的chainlink目录下

mkdir .chainlink
cd .chainlink
vim .env

填入如下参数

ROOT=/chainlink
LOG_LEVEL=debug
ETH_CHAIN_ID=47505			// 你的ChainID
MIN_OUTGOING_CONFIRMATIONS=0
MIN_INCOMING_CONFIRMATIONS=0
LINK_CONTRACT_ADDRESS=0xC64E8Ae217d72cd8cFdf321Db81227E0e05C9661  //部署LinkToken合约地址
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
ALLOW_ORIGINS=*
ETH_URL=ws://localhost:8546		// RPC接口地址
DATABASE_URL=postgresql://my_user:123@localhost:5432/chainlink?sslmode=disable  
DATABASE_TIMEOUT=0

DATABASE_URL 需要注意的要点是

  • my_user 是数据库的用户名,即创建数据库时你自己创建的用户
  • 123是创建数据库的密码
  • localhost:5432是psql的端口地址 (好像是
  • chainnlink是你创建的database的名字

启动chainlink

.chainlink下输入

docker run --net host  -p 6688:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink local n

提示输入密码、邮箱、邮箱密码后,即可进入
在这里插入图片描述
浏览器输入你的ip:6688即可进入chainlink控制台
在这里插入图片描述
到此为止,我们的本地私有链的chainlink节点已经部署完毕啦!

特别鸣谢硕宝的友情支持(

—————————————————————————————
2021年 7月更新

现在我们已经完成了在本地私有链搭建了chainlink节点
下一步,我们就要用chainlink获取链下的数据啦在这里插入代码片

Chainlink操作

在chainlink节点的搭建过程中,我们已经部署好了LinkToken合约
下一步我们将部署Oracle合约

部署Oracle合约

pragma solidity 0.4.24;

import "https://raw.githubusercontent.com/smartcontractkit/chainlink/develop/contracts/src/v0.4/Oracle.sol";

在remix solidityIDE下部署,官网给出的链接有可能访问不了,可以去github找源码自己部署
这里给出的是能够访问的Oracle合约
部署Oracle 合约时,需要传入LinkToken合约的地址

Oracle 调用函数setFulfillmentPermissment

在Oracle合约中,传入chainlink节点的地址、true对节点进行授权

创建Job

EthByte32(Get)

{
    
     
  "name": "Get > Bytes32",
  "initiators": [
    {
    
    
      "type": "runlog",
      "params": {
    
    
        "address": "YOUR_ORACLE_CONTRACT_ADDRESS"
      }
    }
  ],
  "tasks": [
    {
    
    
      "type": "httpget"
    },
    {
    
    
      "type": "jsonparse"
    },
    {
    
    
      "type": "ethbytes32"
    },
    {
    
    
      "type": "ethtx"
    }
  ]
}

Job中的YOUR_ORACLE_CONTRACT_ADDRESS合约要换成Oracle合约地址

向Chainlink节点转入一定的ETH

chainlink节点地址在,chainlink Dash Board中的配置界面中可以找到
在高版本的Chainlink客户端,配置界面隐藏这一信息,但在启动Chainlink节点后也可以找到地址

部署用户合约

pragma solidity 0.4.24;

import "https://github.com/smartcontractkit/chainlink/evm-contracts/src/v0.4/ChainlinkClient.sol";


contract GetTemperature is ChainlinkClient {
    
    
  LinkTokenInterface internal LinkToken;

    
  //string constant url = "https://www.random.org/integers/?num=1&min=1&max=6&col=1&base=10&format=plain&rnd=new";
  string constant url = "https://api.seniverse.com/v3/weather/now.json?key=S9g8Ize9pNyUZ_BOP&location=shanghai&language=zh-Hans&unit=c";
  address constant oracleAddress = 0xa6126AD8B8307C6e1b668F486BEA155e814FA22d;
  bytes32 constant JobId = "d91130d49daf46aaa591bcbce6d59b72";
  address constant linkAddress = 0x9E05B78ea853a4B093694645561c4BFc953A6f62;
  
  constructor() public {
    
    
    setChainlinkToken(linkAddress);
    setChainlinkOracle(oracleAddress);
    LinkToken = LinkTokenInterface(linkAddress);
  }

  string public temperature;

  function getData() public {
    
    
    
    // 发起Chainlink请求
    requestTemperature(JobId);

  }


  function requestTemperature(bytes32 _jobId) public returns (bytes32 requestId) {
    
    
      
    Chainlink.Request memory req = buildChainlinkRequest(_jobId, this, this.fulfillTemperature.selector);

    req.add("get", url);
    req.add("path", "results.0.now.temperature");

    requestId = sendChainlinkRequest(req, 1 * LINK);

    return requestId;
  }


  function fulfillTemperature(bytes32 _requestId, bytes32 _temp)
    public recordChainlinkFulfillment(_requestId)
  {
    
    
    temperature = bytes32ToString(_temp);
    //data = _temp;
  }
  
  
  function bytes32ToString(bytes32 x) private pure returns (string) {
    
    
    bytes memory bytesString = new bytes(32);
    uint charCount = 0;
    for (uint j = 0; j < 32; j++) {
    
    
        byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
        if (char != 0) {
    
    
            bytesString[charCount] = char;
            charCount++;
        }
    }
    bytes memory bytesStringTrimmed = new bytes(charCount);
    for (j = 0; j < charCount; j++) {
    
    
        bytesStringTrimmed[j] = bytesString[j];
    }
    return string(bytesStringTrimmed);
}
  
}

猜你喜欢

转载自blog.csdn.net/qq_45469783/article/details/115548635