3.1 XuperUnion的编译
3.1.1 准备环境
3.1.2 编译步骤
- 使用git下载源码到本地
- git clone xchain地址
- 执行命令
cd github.com/xuperchain/xuperunion
make
- 得到产出xchain和xchain-cli
3.2 单节点网络
3.2.1 启动单节点模拟的测试网络
3.2.1.1 获取编译产出
在当前目录下:主要获取目录为data, logs, conf, plugins, 二进制文件为xchain,xchain-cli,wasm2c
3.2.1.2 建立目录
目录名 | 功能 | 备注 |
---|---|---|
node/ | 根节点目录 | |
——-/conf | xchain.yaml:xchain服务的配置信息,plugins.conf: 插件的配置信息 | 防止冲突,部署时根据需要修改端口号 |
——-/data | 数据的存放目录,创世块信息,以及共识和合约的样例 | |
——-/——-/blockchain | 账本目录 | |
——-/——-/keys | 此节点的地址,唯一性 | |
——-/——-/netkeys | 此节点的网络标识ID,唯一性 | |
——-/——-/config | 创始的共识采用tdpos模式,指定单一地址有权利出块 | |
——-/logs | 程序日志目录 | |
——-/plugins | so的存放目录 | |
——-/xchain | 服务的二进制文件 | |
——-/xchain-cli | 客户端工具 | |
——-/wasm2c | wasm工具 |
3.2.1.3 创建链
# 创建xuper链
./xchain-cli createChain
3.2.1.3 启动服务
# 启动服务节点
nohup ./xchain &
3.2.2 观察区块
# check服务运行状况
./xchain-cli status -H 127.0.0.1:37101
3.2.3 测试基本功能
3.2.3.1 创建新账户
# 创建普通用户, 包含地址,公钥,私钥
./xchain-cli account newkeys --output data/accounts/bob
# 在bob目录下会看到文件address,publickey,privatekey生成
# 创建合约账户
## 通用方式
./xchain-cli account new --desc account.des
其中,account.des内容如下
{
"module_name": "xkernel",
"method_name": "NewAccount",
"args" : {
"account_name": "1111111111111111", //说明:16位数字组成的字符串
"acl": "{\"pm\": {\"rule\": 1,\"acceptValue\": 0.6},\"aksWeight\": {\"AK1\": 0.3,\"AK2\": 0.3}}"
}
}
## 简易方式
./xchain-cli account new --account 1111111111111111 // 说明:16位数字组成的字符串
3.2.3.2 查余额
./xchain-cli account balance --keys data/accounts/bob -H 127.0.0.1:37101
3.2.3.3 转账
# --keys 从此地址 转给 --to地址 --amount 钱
./xchain-cli transfer --to czojZcZ6cHSiDVJ4jFoZMB1PjKnfUiuFQ --amount 10 --keys data/keys/ -H 127.0.0.1:37101
3.2.3.4 查询交易信息
# 查询上一步生成的txid的交易信息
./xchain-cli tx query cbbda2606837c950160e99480049e2aec3e60689a280b68a2d253fdd8a6ce931 -H 127.0.0.1:37101
3.2.3.5 查询block信息
# 可查询上一步交易所在的block id信息
./xchain-cli block 0354240c8335e10d8b48d76c0584e29ab604cfdb7b421d973f01a2a49bb67fee -H 127.0.0.1:37101
3.2.3.6 发起多重签名交易
# generate raw tx
### data/acl/addrs维护好涉及到操作权限的所有的address信息,默认从此地址文件读取,可用参数指定自己文件。此操作会默认产生一个tx.out文件,供后续命令使用。这里所有地址为需要多方的所有参与者的地址以及一些需要授权的地址
addrs文件中,格式为每行一个address,例如
YDYBchKWXpG7HSkHy4YoyzTJnd3hTFBgG
ZAmWoJViiNn5pKz32m2MVgmPnSpgLia7z
## 某个address发起
./xchain-cli multisig gen --to YDYBchKWXpG7HSkHy4YoyzTJnd3hTFBgG --amount 100 --desc contract.desc -H 127.0.0.1:37101
## 从账户发起
./xchain-cli multisig gen --to YDYBchKWXpG7HSkHy4YoyzTJnd3hTFBgG --amount 100 --desc contract.desc -H 127.0.0.1:37101 --from XC11111111111111@xuper
# 各方在签名之前可以check 原始交易是否ok,查看visual.out
./xchain-cli multisig check --input tx.out --output visual.out
# 各方签名生成签名文件
./xchain-cli multisig sign --keys data/account/bob --output bob.sign
# 组装成带有签名的完整tx,并更新账本,同时发送到周边节点 eg. 第一个参数是发起者的签名文件,第二个参数是需要所有方的签名文件,均为逗号分割
./xchain-cli multisig send --tx tx.out a.sign,b.sign c.sign,d.sign
3.2.4 常见问题
- tdpos默认共识,xuper.json文件如下:
详情内容介绍请见3.5.2{
"version" : "1"
, "predistribution":[
{
"address" : "dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN"
, "quota" : "100000000000000000000"
}
]
, "maxblocksize" : "128"
, "award" : "1000000"
, "decimals" : "8"
, "award_decay": {
"height_gap": 31536000,
"ratio": 1
}, "genesis_consensus":{
"name": "tdpos",
"config": {
"timestamp": "1556444792000000000",
"proposer_num":"1",
"period":"3000",
"alternate_interval":"3000",
"term_interval":"6000",
"block_num":"20",
"vote_unit_price":"1",
"init_proposer": {
"1":["dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN"]
}
}
}
}
- single共识介绍
{
"version" : "1"
, "predistribution":[
{
"address" : "dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN" // 创世块生产者地址
, "quota" : "100000000000000000000" // 初始货币量
}
]
, "maxblocksize" : "128"
, "award" : "428100000000" // 挖块奖励
, "decimals" : "8"
, "award_decay": { // 挖块奖励衰减
"height_gap": 31536000,
"ratio": 1
},"genesis_consensus":{
"name": "single", // 共识机制
"config": {
"miner":"dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN", // 矿工地址
"period": "3000" // 块生产间隔
}
}
}
3.3 账号与权限管理
3.3.1 创建合约账号
3.3.1.1 快速创建一个合约账号
./xchain-cli account new —account 1111111111111111
3.3.1.2 按照json文件创建一个合约账号
./xchain-cli account new —desc account.jsonaccount.json模版如下:
{
"module_name": "xkernel",
"method_name": "NewAccount",
"args" : {
"account_name": "1111111111111111",
"acl": "{\"pm\": {\"rule\": 1,\"acceptValue\": 0.6},\"aksWeight\": {\"AK1\": 0.5,\"AK2\": 0.5}}"
}
}
3.3.2 管理合约账号/合约方法ACL
3.3.2.1 重新设置一个账号/合约方法的ACL
走multisig命令
step1:准备好ACL的json文件,该json文件中有新的ACL配置,文件名记为acl_new.json
step2:针对acl_new.json生成原始交易
先查看合约账号余额是否充足: ./xchain-cli account balance XC1111111111111111@xuper
如果不足,可以把当前个人账户(data/keys/address)的资产转移一些给合约账户
./xchain-cli multisig gen --desc acl_new.json --from XC1111111111111111@xuper
step3:使用旧有的acl权限模型对新生成的原始交易做签名(假设旧有的权限模型的成员包括bob和alice)
./xchain-cli multisig sign --keys data/account/bob --output bob.sign
./xchain-cli multisig sign --keys data/account/alice --output alice.sign
step4:将签名后的交易post出去
./xchain-cli multisig send --tx tx.out bob.sign,alice.sign bob.sign,alice.sign
3.3.2.2 查询一个账号的Acl
./xchain-cli acl query —account XC1111111111111111@xuper
3.3.2.3 查询一个合约方法的Acl
./xchain-cli acl query —contract contractName —method methodName
3.3.3 常见问题
3.3.3.1 创建合约账户,重置合约账户/合约方法的ACL时,配置文件的案例:
a.创建合约账号,配置文件案例如下:
{
"module_name": "xkernel",
"method_name": "NewAccount",
"args" : {
"account_name": "1111111111111111",
"acl": "{\"pm\": {\"rule\": 1,\"acceptValue\": 0.6},\"aksWeight\": {\"AK1\": 0.5,\"AK2\": 0.5}}"
}
}
b.重置合约账户的ACL,配置文件案例如下:
{
"module_name": "xkernel",
"method_name": "SetAccountAcl",
"args" : {
"account_name": "XC1111111111111111@xuper",
"acl": "{\"pm\": {\"rule\": 1,\"acceptValue\": 0.6},\"aksWeight\": {\"AK1\": 0.5,\"AK2\": 0.5}}"
}
}
c.重置合约方法的ACL,配置文件案例如下:
{
"module_name": "xkernel",
"method_name": "SetMethodAcl",
"args" : {
"contract_name": "math",
"method_name": "transfer",
"acl": "{\"pm\": {\"rule\": 1,\"acceptValue\": 0.6},\"aksWeight\": {\"AK1\": 0.5,\"AK2\": 0.5}}"
}
}
3.4 智能合约开发
3.4.1 编写合约
参考源码样例contractsdk/cpp/example/counter.cc contractsdk/go/example/counter/counter.go主要实现一个struct的任意方法,来实现自己的逻辑
3.4.2 wasm合约
3.4.2.1 部署合约
3.4.2.1.1 编译
注意合约编译环境与源码编译环境一致
#c++语言的智能合约
# 依赖docker环境
cd contractsdk/cpp
sh build.sh
到当前目录build里,将编译好的合约二进制counter.wasm,重新命名为counter,放到某个目录node/data/下,这是随意的。
涉及到合约操作会消耗资源,需要通过--fee
参数指定为该transaction付出的资源量,在一开始不确定需要花费多少资源时,可以先不加参数—fee, 预执行会提示需要消耗的资源数值,第二次再指定>=要消耗的资源数值的数量即可。
3.4.2.1.2 部署
合约在使用前,所使用的账号一定要提前储备资金
# 便捷方式
## 账户下权限AK是自己,提前创建好账号,并保证账号下有足够资源余额
查看合约账号资源余额是否充足: ./xchain-cli account balance XC1111111111111111@xuper
如果不足,可以把当前个人账户(data/keys/address)的资产转移一些给合约账户:
./xchain-cli transfer --to XC1111111111111111@xuper --amount 100000
# c语言合约
./xchain-cli wasm deploy --account XC1111111111111111@xuper --cname counter -H localhost:37101 data/counter -a '{"creator":"xchain"}'
# 多重签名场景
## 提前维护好data/acl/addrs 需要的合作的地址
# c语言合约
./xchain-cli wasm deploy --account XC1111111111111111@xuper --cname counter -H localhost:37101 -m data/counter -a '{"creator":"xchain"}'
## 后续参看3.2.3.6多重签名交易的后续check,sign,send场景
3.4.2.2 调用合约
# --method 是指合约样例里方法
# c++合约
./xchain-cli wasm query -a '{"key":"counter"}' --method get -H localhost:37101 counter
# 便捷方式
# c++合约
./xchain-cli wasm invoke -a '{"key":"counter"}' --method increase -H localhost:37101 counter
# 多重签名场景
# 参考部署多重签名场景
./xchain-cli wasm invoke -a '{"key":"counter"}' --method increase -H localhost:37101 counter -m
### go语言部分
# 编译
#go语言的智能合约,在当前写的智能合约目录下
GOOS=js GOARCH=wasm go build
# 便捷方式
./xchain-cli wasm deploy --account XC1111111111111111@xuper --cname counter -H localhost:37101 -a '{"creator":"xchain"}' data/counter --runtime go
# 多重签名
./xchain-cli wasm deploy --account XC1111111111111111@xuper --cname counter -H localhost:37801 -m -a '{"creator":"xchain"}' data/counter
./xchain-cli wasm query -a '{"key":"counter"}' --method get -H localhost:37101 counter
./xchain-cli wasm invoke -a '{"key":"counter"}' --method increase -H localhost:37101 counter
3.4.3 访问权限管理
合约方法的ACL控制参看3.3.3设置合约方法权限样例
3.5 多节点网络搭建
在阅读本节前,请先阅读3.2节“单节点网络”。3.2 节中介绍了创建单节点网络的创建,在该基础上,搭建一个SINGLE共识的多节点网络,其他节点只要新增p2p网络 bootNodes 配置即可。如果你想搭建一个TDPoS共识的链,仅需要修改创世块参数中 “genesis_consensus” 配置参数即可。下面将详细介绍相关操作步骤。
3.5.1 p2p网络配置
- 假设搭建3个节点的网络,在单节点的基础上再新增两个节点node2和node3;
创建node2和node3的部署路径,并按照3.2.1.2 建立每个节点自己的部署目录;
注意:由于每个节点在网络中有自己唯一的身份,所以node2 和node3 需要重置自己的身份信息,
主要包括2个步骤:
1 创建节点私钥
./xchain-cli account newkeys -f
2 创建节点netUrl
./xchain-cli netURL gen
查询node节点的netUrl,会得到节点netUrl
./xchain-cli netUrl get -H 127.0.0.1:37101
- 在node2和node3的p2pv2配置中的bootNodes增加node的netUrl,如下所示:
p2pV2:
// port是节点p2p网络监听的端口,如果在一台机器上部署注意端口配置不要冲突,node配置的是47101,node2和node3可以分别设置为47102和47103
port: 47102
// 节点加入网络所连接的种子节点的链接信息,
bootNodes:
- "/ip4/127.0.0.1/tcp/47101/p2p/QmVxeNubpg1ZQjQT8W5yZC9fD7ZB1ViArwvyGUB53sqf8e"
- 设置node2和node3节点RPC服务暴露的端口
// port是节点启动时RPC服务监听的端口,如果在一台机器上部署注意端口配置不要冲突,node配置的是 :37101,node2和node3可以分别设置为 :37102和 :37103
tcpServer:
port: :37102
- 启动node2和node3,check服务是否正常:
若节点高度一致,则网络启动成功。./xchain-cli status -H 127.0.0.1:37102
./xchain-cli status -H 127.0.0.1:37103
3.5.2 搭建TDPoS共识网络
3.5.1 是搭建一个SINGLE共识的多节点网络。网络中的矿工节点是node。XuperUnion系统支持可插拔共识,通过修改创世块的参数,可以创建一个TDPoS链。下面创世块配置和单节点创世块配置的区别在于创世共识参数genesis_consensus
的config
配置,各个配置参数详解配置说明如下所示:
{
"version" : "1"
, "predistribution":[
{
"address" : "mahtKhdV5SZP4FveEBzX7j6FgUGfBS9om"
, "quota" : "100000000000000000000"
}
]
, "maxblocksize" : "128"
, "award" : "1000000"
, "decimals" : "8"
, "award_decay": {
"height_gap": 31536000,
"ratio": 1
}, "genesis_consensus":{
"name": "tdpos",
"config": {
"timestamp": "1548123921000000000", // tdpos共识初始时间,声明tdpos共识的起始时间戳,建议设置为一个刚过去不旧的时间戳
"proposer_num":"3",// 每一轮选举出的矿工数,如果某一轮的投票不足以选出足够的矿工数则默认复用前一轮的矿工
"period":"3000",// 每个矿工连续出块的出块间隔
"alternate_interval":"6000",// 每一轮内切换矿工时的时间间隔,需要为period的整数倍
"term_interval":"9000", // 切换轮时的出块间隔,即下一轮第一个矿工出第一个块距离上一轮矿工出最后一个块的时间间隔,需要为period的整数配
"block_num":"200",// 每一轮内每个矿工轮值任期内连续出块的个数
"vote_unit_price":"1",// 为被提名的候选人投票时,每一票单价,即一票等于多少Xuper
// 指定第一轮初始矿工,矿工个数需要符合proposer_num指定的个数,所指定的初始矿工需要在网络中存在,不然系统轮到该节点出块时会没有节点出块
"init_proposer": {
"1":["RU7Qv3CrecW5waKc1ZWYnEuTdJNjHc43u","XpQXiBNo1eHRQpD9UbzBisTPXojpyzkxn","SDCBba3GVYU7s2VYQVrhMGLet6bobNzbM"]
}
}
}
}
修改完创世块参数后,删除./data/blockchain下的内容,3个节点全部重新创建链:
./xchain-cli createChain
先启动node,再启动node2和node3,至此TDPoS共识的集群启动成功。
3.5.3 提名候选人
./xchain-cli transfer --to=dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN --name=$chain --desc=./nominate.json --amount=11000002266 --frozen=-1 -H=$host
nominate.json
{
"module": "tdpos",
"method": "nominate_candidate",
"args": {
"candidate": "提名address"
}
}
3.5.4 投票
./xchain-cli transfer --to=dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN --desc=./vote.json --amount=$ballots --frozen=-1 --name=$chain -H=$host
vote.json
{
"module": "tdpos",
"method": "vote",
"args" : {
"candidates":["提名过的address"]
}
}
3.5.5 撤销提名 && 撤销投票
./xchain-cli transfer --to Y4TmpfV4pvhYT5W17J7TqHSLo6cqq23x3 --desc=./revoke_demo.json --amount=1
revoke_demo.json
{
"module":"proposal",
"method": "Thaw",
"args" : {
"txid":"02cd75a721f2589a3ff6768b49650b46fa0b042f970df935b4d28a15aa19e49a" // 提名或者投票时的txid,发起的交易的input需只有一个,且address与提名或者投票时需要相同
}
}
3.5.6 TDPOS结果查询
./xchain-cli tdpos -h
提示如下所示:
1.查询候选人信息
./xchain-cli tdpos query-candidates --name=$chain -H=$host
2.查看某一轮的出块顺序
./xchain-cli tdpos query-checkResult -t=30 --name=$chain -H=$host
3.查询提名信息:某地址发起提名的记录
./xchain-cli tdpos query-nominate-records --name=$chain -H=$host -a=dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN
4.被提名查询:某个候选人被提名的记录
./xchain-cli tdpos query-nominee-record --name=$chain -H=$host -a=TyYCWDJ1pyV8fA3VyPenCdFdcPmHnwMhx
5.某选民的有效投票记录
./xchain-cli tdpos query-vote-records --name=$chain -H=$host -a=dpzuVdosQrF2kmzumhVeFQZa1aYcdgFpN
6.某候选人被投票记录
./xchain-cli tdpos query-voted-records --name=$chain -H=$host -a=TyYCWDJ1pyV8fA3VyPenCdFdcPmHnwMhx
3.5.7 常见问题
- 端口冲突:注意如果在一台机器上部署3个节点,各个节点的RPC监听端口以及p2p监听端口都需要设置地不相同,避免冲突;
- 节点公私钥和节点netUrl冲突:注意网络中不同节点 ./data/keys下的文件和./data/netkeys下的内容都不一样,这两个文件夹是节点在网络中的唯一标识,每个节点需要独自生成,否则网络启动异常。
- 启动时链接bootNodes节点失败:注意要先将bootNodes节点启动,再起动其他节点,否则会加入网络失败而启动失败。
- The gas you cousume is: XXXX, You need add fee. 通过加
--fee XXXX
参数附加资源