母子链架构不同于比特币、以太坊等单链系统,是基于墨客分片技术构建的多链系统。墨客上的项目都可以基于此架构来构建自己的应用系统(DAPP)。
本文在主链部署标准ERC20合约,通过跨链技术,将主链上的20通证和子链原生通证打通,实现项目方的应用逻辑。
环境:
墨客区块链版本:nuwa1.0.5.win.zip;(mainnet及testnet均使用该版本,本文在testnet进行)
操作系统:64位Windows 10家庭版。
辅助工具:Postman,请读者自行下载安装。
1.准备工作
1.1 启动本地vnode节点
本地vnode节点安装请参考《第三篇 墨客区块链(MOAC BlockChain) 节点安装教程》。
启动命令(mainnet运行时去掉--testnet):
C:\nuwa1.0.5.win\win\vnode>moac --testnet --rpc --rpccorsdomain "http://wallet.moac.io/" --rpcapi="db,mc,net,chain3,personal,vnode,debug,scs"
1.2 部署ERC20标准合约
根据实际情况部署标准合约,请参考《第四篇 墨客区块链(MOAC BlockChain) 部署ERC-20合约》。
因为子链原生coin小数位设为18,建议将标准erc20合约的小数点位数设置为18;
本文档测试中新部署了erc20合约,地址:0x0C855a5ED8D86e8F04CfF11b225E3DeD757f2F33。
1.3 启动三个本地出块SCS和一个monitor
本地SCS节点启动请参考《第六篇 墨客区块链(MOAC BlockChain) 子链搭建教程》第4节。
三个出块SCS启动命令:
C:\nuwa1.0.5.win\win\scs>scsserver
一个monitor启动命令:
D:\nuwa1.0.5.win\win\scs>scsserver --rpc --rpcaddr 0.0.0.0 --rpcport 2345 --rpccorsdomain "*" --verbosity 4
启动后,给每个SCS id发送1moac,用于scs与vnode之间的通讯(gas费用)。
1.4 部署SCS矿池合约
在官方公布SCS矿池合约地址前,需要用户方自己部署该合约。
到官方:https://github.com/MOACChain/moac-core/releases,或者本博客资源下载SubChainProtocolBase.sol合约。
本文档测试中新部署了SubChainProtocolBase合约,地址:0xFe565703cd89514E977041ca8AD33bF090223791。
1.5 将三个scs注册到scs池子合约
仅将出块scs注册到池子,monitor不用注册。
2.部署子链控制合约
2.1 下载子链控制合约
从本博客资源下载SubChainBase_erc20Tansfer.sol合约。
2.2部署合约
该合约“import SubChainProtocolBase.sol”,为了在“http://wallet.moac.io/”方便地部署该合约,可以将这两个合约合并。
选择部署的合约,“Sub chain Base”,主要参数:
- Proto:前面部署的SubChainProtocolBase.sol合约地址,参与子链的scs均为该合约注册的scs;
- Vnode protocol base addr:Vnode proxy地址,有官方提供,测试网0xA0A595CD5dBE0eA08b93d67FA2c873795C5557Ee;
- Erc addr:前面在主链部署的erc 20 合约地址;
- Min:创建子链需要的最少scs数量;
- Max:创建子链需要的最多scs数量;
- Thousandth:scs千分比,这里填写1000;
- Flush round:每次刷新间隔区块个数,比如100。
本文档测试中新部署了SubChainBase_erc20Tansfer合约。
2.3 创建子链
子链控制合约add fund,本例中发送5个moac,用于给scs发放奖励。
操作register open,以让scs过来注册;
scs注册数量合格后,操作register close,开始出块,子链正式建立。
2.4 注册monitor
- Monitor:monitor scs id;
- Link:monitor主机IP + “:” +monitor port;
3.部署子链业务逻辑
3.1 下载子链业务逻辑合约
从本博客资源下载DappBase.sol合约。
3.2部署合约
- INITIAL AMOUNT OF MICROCHAIN DAPP TOKEN:子链coin初始值,也是在子链交易的coin总量,该值不能大于主链部署的erc20的数量(此处建议等于erc20数量,这样全部erc20 token可以在子链交易)。
- MicroChain Base Address :上面部署的SubChainBase_erc20Tansfer合约地址;
- SCS Monitor Address:scs monitor所在的主机IP地址;
- SCS Monitor Port:scs monitor启动时的端口。
至此,子链及业务逻辑部署全部完成。
如果全部过程无误,会在合约的“WATCH MICROCHAIN CONTRACT”显示子链业务逻辑合约图标,点击后显示如下:
- 子链业务逻辑合约地址就是子链控制合约地址;
- 在刷新周期到来后,合约里的moac会减少;
- 显示子链区块高度,以及monitor的address和port信息。
4.coin查询
按照以上步骤部署完成后,可以查询部署状态及coin数量。
本文查询使用postman,详细代码在下篇文档《第二十六篇 墨客区块链(MOAC BlockChain) 母子链架构-子链RPC接口调用》。
用以下命令启动scs monitor:
D:\nuwa1.0.5.win\win\scs>scsserver --rpcdebug --rpcaddr 0.0.0.0 --rpcport 2356 --rpccorsdomain "*" --verbosity 4
4.1查询子链nonce
请注意:本文postman需要Headers下两项配置:
查询子链nonce:
结果是1,证明部署成功;如果是0或者-1,则没有成功。
4.2 查询coin的余额
先查询主账号的balance:
如果部署dapp的时候输入的子链coin原生总量于erc20总量相同,此处所有账号的coin余额都会是0;
此处因为子链coin原生数量比erc20总量少(实际部署中,请设置为相同),因此,主账号里会有coin余额。
再查合约隐藏账号:
到你的scs(或者monitor)的目录下,C:\nuwa1.0.5.win\win\scs35_monitor\_logs,有一个目录文件moac-scs-[time].log。
打开后搜索“created contract address”,如果看到有一条后面跟着有效地址(一串000不是有效地址),如下图:
说明子链业务逻辑合约dapp.sol部署成功,隐含地址:79bceeb5f59a94dce14a19759acbaa31f060dc5b。
拿着这个地址到postman查询余额:
这个隐含地址里有10000个coin,也就是部署dapp合约的时候设置的子链coin总量。
注意:为了让所有erc20 token都可以在子链交易,子链coin总量应该等于erc20总量。
5.将token转换成子链原生通证
5.1 将erc20合约的通证转换成子链的原生通证
调用ERC20合约Approve,给合约地址授权500数量的erc20通证。
授权后,可以在erc20合约看到授权情况:
调用子链控制合约Buy Mint Token,给合约地址授权发送68数量的erc20通证:
5.2 查看转换后原生通证的变化
发送完成后,可以看到授权的500个token已经减少:
此时,需要等待子链刷新,刷新时scs界面类似:
刷新后,查询账号的coin余额:
同时,隐含地址的余额从10000变成9932:
至此,将主链erc20转换成子链coin成功。
6.子链原生coin的交易
用以下命令启动scs monitor:
D:\nuwa1.0.5.win\win\scs>scsserver --rpcdebug --rpcaddr 0.0.0.0 --rpcport 2356 --rpccorsdomain "*" --verbosity 4
6.1 交易子链原生coin
该交易需用代码完成:
var Chain3 = require('chain3');
var chain3 = new Chain3(new Chain3.providers.HttpProvider('http://localhost:8545'));
var subchainAddr = "0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05";
var sender = "0x50463586C483D205F1f15741234F6CD2833e1A59";
var passwd = "123456123456";
var amount = 10;
var nonce = 0; //每个账号在子链有不同的nonce,此处是sender的nonce,请查询后使用
var viaAddr= "0x7610fD66c272332EDD59A43460AD24eEe1973bfe";
var toAddr = "0x247009Fe5Df73abd3Ad89BBd3aFc5F14092F8F61";
subtransfer(sender, passwd, amount, nonce);
function subtransfer(sender, passwd, amount, nonce) //子链coin转账
{
//chain3.personal.unlockAccount(sender, passwd, 0);
chain3.mc.sendTransaction(
{
from: sender, //转出账号地址
value:amount, //转出coin数量
to: subchainAddr,
gas: "0",
gasPrice: "0",
shardingflag: "0x2",
nonce: nonce,
data: toAddr, //转入账号地址
via: viaAddr
});
}
- 只有子链转账的tx交易,shardingflag=0x2;
- 其他子链交易,shardingflag=0x1;
- 主链交易,shardingflag=0x0;
仅需要修改nonce,直接node,执行后,在scs monitor的反映如下:
6.2 查询子链原生coin交易结果
发送2次后,查询该账号的子链nonce:
查询发送账号在子链的coin余额,少了20,正是每次发送10个,发送了2次的结果:
查询接受账号在子链的coin余额:
7.子链coin提现
子链coin提现的代码如下:
var Chain3 = require('chain3');
var chain3 = new Chain3(new Chain3.providers.HttpProvider('http://localhost:8545'));
var subchainAddr = "0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05";
var sender = "0x50463586C483D205F1f15741234F6CD2833e1A59";
var passwd = "123456123456";
var amount = 30;
var nonce = 2;
var viaAddr= "0x7610fD66c272332EDD59A43460AD24eEe1973bfe";
dappredeemFromMicroChain(sender, passwd, amount, nonce);
function dappredeemFromMicroChain(sender, passwd, amount, nonce){
chain3.personal.unlockAccount(sender,passwd,0);
chain3.mc.sendTransaction(
{
from: sender, //提出账号地址
value:amount, //提出token数量
to: subchainAddr,
gas: "0",
gasPrice: "0",
shardingflag: "0x1",
nonce: nonce,
data: '0x89739c5b',
via: viaAddr
});
}
注意代码中nonce的值,执行后在SCS monitor中有交易发生的显示,类似6.1节。
查询账号的coin余额:
提现之前查看token的余额:
刷新之后查看token的余额:
总结本篇:打通母链token与子链原生coin的流程图
如果是一个主链erc20需要在多个子链上运行业务,类似下图:
本文实测中,部署了两个子链,并在每次erc20到coin的映射中使总量一致,就是每个dapp在部署的时候都使用1000000,整个流程能成功并稳定执行。
至此,所有流程结束。
下篇文档,将结合本篇,提供对子链rpc接口调用示例。