Zhuang's Diary

言之有物,持之以恒

文档链接=>https://hyperledger.github.io/burrow/

github链接=>https://github.com/hyperledger/burrow/

Burrow是一个权限控制较为严格、以太坊EVM和WASM虚拟机支持、运行于Tendermint共识之上的区块链客户端。其主要由Monax贡献,并由Monax 和英特尔赞助。

其强调的设计理念包括:

  1. 防篡改的Merkle状态—Tamper-resistant merkle state
  2. PoS支持
  3. 链上治理原生支持
  4. 以太坊账户一览
  5. 可以根据每个帐户设置代码执行权限
  6. 事件流支持
  7. 智能合约事件弹出至SQL表记录
  8. GRPC和Protobuf支持
  9. Javascript SDK支持,客户端库可以生成代码来访问合约,生成的代码是静态的Typescript对象
  10. Keys服务,提供代理签名服务器
  11. Web3 RPC,兼容Ethereum主网的开发工具,如 Truffle、 Metamask、Remix

Burrow应用于多个区块链生产项目

初始化Burrow节点

https://github.com/hyperledger/burrow/下载可执行文件,本文以 ubuntu 环境为例。

1
./burrow spec -f2 -p2 | ./burrow configure --curve-type secp256k1 -s- --pool --separate-genesis-doc=genesis.json

./burrow spec 建立一个GenesisSpec作为GenesisDoc和configure命令的模板,f2是指2个full-accounts,p2是指2个participant-accounts。

--curve-type secp256k1 是指定加密曲线的类型。

./burrow configure -s- 通过使用GenesisDoc或GenesisSpec,创建密钥并创建配置文档。--pool 为名为burrowNNN.toml的所有共识节点(validators)编写配置文件。--separate-genesis-doc 将genesis文档投送至 JSON或者TOML文件。

  • validator-accounts 共识的参与者,需要抵押一部分资金

  • root-accounts 根账户

  • developer-accounts 开发者,功能很多和全节点很像

  • participant-accounts 参与者

  • full-accounts 全功能

启动Burrow节点

1
2
3
4
5
6
7
8
➜  script ./burrow start --config=burrow000.toml &
./burrow start --config=burrow001.toml &
./burrow start --config=burrow002.toml &
./burrow start --config=burrow003.toml &
[5] 12458
[6] 12459
[7] 12460
[8] 12464

网页端访问RPC服务

http://127.0.0.1:26759/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Available endpoints:
//127.0.0.1:26759/account_stats
//127.0.0.1:26759/accounts
//127.0.0.1:26759/chain_id
//127.0.0.1:26759/consensus
//127.0.0.1:26759/genesis
//127.0.0.1:26759/network
//127.0.0.1:26759/network/registry
//127.0.0.1:26759/validators

Endpoints that require arguments:
//127.0.0.1:26759/account?address=_
//127.0.0.1:26759/account_human?address=_
//127.0.0.1:26759/block?height=_
//127.0.0.1:26759/blocks?minHeight=_&maxHeight=_
//127.0.0.1:26759/dump_storage?address=_
//127.0.0.1:26759/name?name=_
//127.0.0.1:26759/names?regex=_
//127.0.0.1:26759/status?block_time_within=_&block_seen_time_within=_
//127.0.0.1:26759/storage?address=_&key=_
//127.0.0.1:26759/unconfirmed_txs?maxTxs=_

Kuboard 是 Kubernetes 的一款图形化管理界面。参考如下链接:https://kuboard.cn/install/install-dashboard.html 安装kuboard

  1. kuboard 首页

  1. Deployment 视图页面

体验结论:

  1. kuboard 比 Kubernetes Dashboard(Kubernetes 的官方 Web UI)要友好许多,并且 Kubernetes Dashboard 需要在操作机中具备 Kubectl;
  2. wayne 对用户的权限管理会优秀一些。但是经过docker-compose实验,启动为dev版本,未成功打开页面
  3. rancherhttps://github.com/rancher/)Rancher为您提供“Kubernetes即服务(Kubernetes-as-a-Service)”。在国内北京、上海、深圳、沈阳均有办公地点,汉语支持较好。推荐使用。

SeaweedFS 是开源的,简单的,高伸缩性的分布式文件系统。SeaweedFS 作为支持全 POSIX 文件系统语义替代,Seaweed-FS 选择仅实现 key-file 的映射,类似 “NoSQL”,也可以说是 “NoFS”。

SeaweedFS 仅花费 40 字节的硬盘来存储每个文件的元数据。

GlusterFS, Ceph相比较

System File Meta File Content Read POSIX REST API Optimized for small files
SeaweedFS lookup volume id, cacheable O(1) disk seek Yes Yes
SeaweedFS Filer Linearly Scalable, Customizable O(1) disk seek FUSE Yes Yes
GlusterFS hashing FUSE, NFS
Ceph hashing + rules FUSE Yes
MooseFS in memory FUSE No

体验seaweedfs

参考==>https://hub.docker.com/r/chrislusf/seaweedfs

  1. 拉取 docker-compose 文件,wget https://raw.githubusercontent.com/chrislusf/seaweedfs/master/docker/seaweedfs-compose.yml
  2. 启动,docker-compose -f seaweedfs-compose.yml -p seaweedfs up

参考 => https://github.com/chrislusf/seaweedfs/wiki/Volume-Server-API

1
2
3
4
5
6
➜  seaweedfs: curl http://localhost:9333/dir/assign
{"fid":"7,01248b7b86","url":"172.18.0.3:8080","publicUrl":"172.18.0.3:8080","count":1}%
➜ seaweedfs: curl -F file=@/home/will/documents/zaq12wsxcde3--de4064dc15870163a9aab589a1ccf7900dd68ef4 http://127.0.0.1:8080/7,01248b7b86
{"name":"zaq12wsxcde3--de4064dc15870163a9aab589a1ccf7900dd68ef4","size":489,"eTag":"468de108"}%
➜ seaweedfs: curl http://localhost:9333/dir/lookup\?volumeId\=7
{"volumeId":"7","locations":[{"url":"172.18.0.3:8080","publicUrl":"172.18.0.3:8080"}]}%
  1. curl http://localhost:9333/dir/assign 获取fid
  2. curl -F file=@/home/will/documents/zaq12wsxcde3--de4064dc15870163a9aab589a1ccf7900dd68ef4 http://127.0.0.1:8080/7,01248b7b86 上传文件
  3. curl http://localhost:9333/dir/lookup\?volumeId\=7 查询
  4. 在浏览器中打开 http://172.18.0.3:8080/7,01248b7b86,查看文档
  5. master 的url:http://127.0.0.1:9333/
  6. volume的url:http://172.18.0.3:8080/ui/index.html

Chainlink是一个去中心化的预言机,但是你同样可以在私有环境中使用Chainlink,让它成为一个为私有链或联盟链服务的中心化的预言机系统。只要你的私有链环境支持完整的EVM环境,就可以利用Chainlink的开源实现,为自己的系统搭建一个具有广泛适配能力的预言机系统。

准备工作

私有链/联盟链(需支持EVM,开放WebSocket端口)

由于目前Chainlink的合约系统都是在以太坊网络上的虚拟环境中运行的,所以需要您的私有链/联盟链支持EVM环境以及Solidity合约编程语言。

用于部署合约的账户,账户需持有足够数量的Native Token(原生代币)

一般来说,向区块链提交事务,不管是创建合约还是普通转账,都需要事务发起账户提供一定的手续费,所以需要一个持有原生代币的账户,用于部署合约和节点提交事务。如果您的私有链提交事务不需要手续费,那仅需要一个账户就可以。(具体请根据您的私有链的配置操作)

一台服务器用于部署Chainlink节点

Chainlink节点相当于区块链在真实世界中的代理,它可以接收链上的数据请求,并获取到链上所需要的数据,通过事务提交给链上。所以需要一台服务器来建立Chainlink节点服务,服务器配置不需要很高,但是需要和私有链环境保持良好的网络通讯。

之前的Chainlink节点版本默认使用Sqlite作为存储数据库,但是随着功能越来越完善,性能要求也越来越高,从0.8.0版本起,Chainlink节点要求必须使用postgres作为存储数据库,所以我们需要搭建一个postgres数据库。这个数据库可以和节点位于同一台服务器上,也可以位于不同的服务器上。您也可以同时搭建两个数据库作为备份。

(可选)准备truffle suite和npm或WebIDE Remix等开发部署工具

您可以选择Chainlink提供的truffle box来编写和部署测试合约

1
truffle unbox smartcontractkit/box

也可以在已有的项目中添加Chainlink开发库

1
2
truffle init
npm install @chainlink/contracts --save

同样的,您也可以使用可视化的Web IDE Remix来进行开发,使用起来更加方便,也无需配置本地开发环境。在使用Remix时,可以搭配MetaMask来进行转账和事务操作。

https://remix.ethereum.org

https://metamask.io

实施步骤

0.搭建 EVM 私链

LinkToken.sol

所有Chainlink的功能实现和数据流转都是围绕LINK token来实现的。这里的remix中默认是https url,如果访问vmware中的linux server,建议在remix中使用 http url

img

2.部署Chainlink节点

2.1 安装docker、postgres (建议postgres也在docker中安装)

2.2 创建环境变量配置文件

1
2
3
mkdir ~/.chainlink
cd ~/.chainlink
vim .env
1
2
3
4
5
6
7
8
9
10
11
12
ROOT=/chainlink
LOG_LEVEL=debug
ETH_CHAIN_ID=1337
MIN_OUTGOING_CONFIRMATIONS=0
MIN_INCOMING_CONFIRMATIONS=0
LINK_CONTRACT_ADDRESS=0x9E05B78ea853a4B093694645561c4BFc953A6f62
CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
ALLOW_ORIGINS=*
ETH_URL=ws://localhost:8546
DATABASE_URL=postgresql://postgres:123456@localhost:5432/chainlink?sslmode=disable
DATABASE_TIMEOUT=0

其中ETH_URL是私有链的RPC接口,必须是WebSocket接口,可以是ws也可以是wss

LINK_CONTRACT_ADDRESS 是刚刚部署的Link token 地址。

2.3 通过docker启动

1
2
3
4
5
cd ~/.chainlink
# 启动postgres
docker run --name postgres_chainlink -e POSTGRES_PASSWORD=123456 -v /home/will/documents/chainlink:/var/lib/postgresql/data -p 5432:5432 -d postgres:11.5-alpine
# 启动chainlink节点
docker run --net host -p 6688:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink:0.7.8 local n

其中--net host 是为了让通过docker启动的Chainlink节点可以访问到宿主记得网络,否则上面配置文件中的localhost都是不可访问的。也可以通过其他更加安全的docker网络配置完成同样功能。

0.7.8是Chainlink的release版本号,不写的话默认是latest。

2.4 记录节点管理密码

首次启动成功后,首先会要求输入一个密码,这个密码是Chainlink节点账户的私钥密码,可以用来控制Chainlink节点账户,必须牢记,否则节点账户所持有的资金无法取出。

然后会要求输入一对用户名和密码,这是Chainlink管理界面的的用户名和密码,在通过 http: //chainlink_ip:6688 访问管理端界面时会要求输入这对用户名和密码。

img

2.5 创建Job

https://docs.chain.link/docs/fulfilling-requests#section-add-jobs-to-the-node

创建不同数据类型的 Job

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"initiators": [
{
"type": "runlog"
}
],
"tasks": [
{
"type": "httpget"
},
{
"type": "jsonparse"
},
{
"type": "ethbytes32"
},
{
"type": "ethtx"
}
]
}

2.6 向Chainlink节点(ACCOUNT_ADDRESS)转入一定数量的Native token用于提交事务

比如:如果是以太坊公网,需要转入ETH,以作为交易的gas费用。

节点地址可以在管理页面的configure页面下找到,账户资金仅用于提交transaction。

3.部署oracle contract

1
2
3
pragma solidity 0.4.24;

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

调用合约中的setFulfillPermission方法,传递参数为(ACCOUNT_ADDRESS,true),ACCOUNT_ADDRESS是ChainLink Operator。

4.编写部署用户合约

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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);
}

}

其中 linkAddress、OracleAddress、JobId 需要根据上面的配置结果填写,或作为参数在调用时传入。

向部署好的用户合约地址转入Link token,用户在发起请求是支付给节点的费用。上述部署的Link Token为18位精度,建议使用 transfer 方法转移 Link token 2000,000000000000000000

发起请求获取数据,使用getData方法获取天气数据。

image

准备虚拟服务器

  1. 在vmware上安装centos7.7 server

  2. vmware工具栏,虚拟机->管理->克隆,制作k8s-master

  3. vmware工具栏,虚拟机->管理->克隆,制作k8s-worker01

  4. vmware工具栏,虚拟机->管理->克隆,制作k8s-worker02

  5. 于k8s-master内,/etc/sysconfig/network-scripts/ifcfg-ens33,将server编辑为静态ip,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #######################################
    ### depends on vm network settings ####
    #######################################
    BOOTPROTO=static
    IPADDR=192.168.180.10
    NETMASK=255.255.255.0
    GATEWAY=192.168.180.2
    DNS1=192.168.180.2
    ONBOOT=yes

    其中,192.168.180.2来自vmware工具栏,编辑->虚拟网络编辑器->NAT设置->子网IP

    重启server网卡如下:

    1
    2
    nmcli c reload ens33
    nmcli c up ens33

    从windows登录k8s-master,登录IP为192.168.180.10

  6. 于k8s-worker01内,/etc/sysconfig/network-scripts,将server编辑为静态ip,IPADDR=192.168.180.11

    重启server网卡如上

  7. 于k8s-worker01内,/etc/sysconfig/network-scripts,将server编辑为静态ip,IPADDR=192.168.180.12

    重启server网卡如上

  8. optional,检查vmware,编辑->虚拟网络编辑器 中的VMnet8的连通状态,如果有需要,在windows10->设置->更改适配器选项,重新启动VMnet8网卡

从winscp端登录:

最后,按照 kuboard -> 安装 -> 安装 kubernetes 手册完成kubernetes安装。