版权声明:Copyright Reserved © 2018-2020 https://blog.csdn.net/lyq13573221675/article/details/84336403
本文是《第二十五篇 墨客区块链(MOAC BlockChain) 母子链架构-如何使用子链原生通证》续篇。
1.部署子链业务逻辑合约
在第二十五篇,已经介绍了怎么使用wallet.moac.io网页版钱包部署子链业务逻辑合约。
在主链使用代码部署智能合约请参考《第八篇 墨客区块链(MOAC BlockChain) 程序猿怎么部署和调用智能合约》。
在子链正常出块后,使用以下代码,直接node运行,可以在子链部署业务逻辑合约。
var Chain3 = require('chain3');
var chain3 = new Chain3(new Chain3.providers.HttpProvider('http://localhost:8545'));
var baseaddr = chain3.mc.accounts[0];
var passwd = "password";
var subchainAddr="0x94949AE4B2b2186fA18703Ef62d3dE5dfB615fD6";
var viaAddr = "0x7610fd66c272332edd59a43460ad24eee1973bfe";
var nonce = 0;
// 部署子链业务逻辑合约
subchaindeploy(subchainAddr,nonce);
// Send Sharding Flag tx example
function sendshardingflagtx(baseaddr,pwd,subchainaddr,amount,code,n)
{
chain3.personal.unlockAccount(baseaddr,pwd,0);
chain3.mc.sendTransaction(
{
from: baseaddr,
value:chain3.toSha(amount,'mc'), //amount是子链原生coin数量,小数点后18位
to: subchainaddr,
gas: '0',
gasPrice: '0',
ShardingFlag: '0x1',
data: code,
nonce: n,
via: viaAddr ,
});
//console.log('sending from:' + src + ' to:' + tgtaddr + ' with data:' + strData);
}
function subchaindeploy(subchainaddr,nonce){
var code="0x6060604052341561000f576000......a943d7837a57451dba695d18a1850029"; //合约bin
code += '000000000000000000000000' + chain3.mc.accounts[0].substr(2, 100);
code += '000000000000000000000000' + chain3.mc.accounts[0].substr(2, 100);
subchaindeploycode(subchainaddr,code,nonce);
}
function subchaindeploycode(subchainaddr,code,nonce)
{
chain3.personal.unlockAccount(baseaddr,pwd,0);
sendshardingflagtx(baseaddr,pwd,subchainaddr,1000000,code,nonce); //1000000就是amount数量,即子链原生coin数量
}
2.ERC20充值的代码实现
在第二十五篇,已经介绍了怎么使用wallet.moac.io网页版钱包授权ERC20和token的充值。
这里,ERC20的Approve和subChainBase的buyMintToken也可以使用以下代码实现:
var baseaddr = mc.accounts[0];
var basename = "123456123456";
subchainAddr="0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05";
subchainABI="[ { \"constant\": true, \"inputs\": [], \"name\":......\"TransferAmount\", \"type\": \"event\" } ]";
var subchainContract=chain3.mc.contract(JSON.parse(subchainABI));
var subchainInstance=subchainContract.at(subchainAddr);
ercAddr="0x0C855a5ED8D86e8F04CfF11b225E3DeD757f2F33";
erc20ABI="[ { \"constant\": true, \"inputs\": [], \"name\":...... \"Approval\", \"type\": \"event\" } ]";
var erc20Contract=chain3.mc.contract(JSON.parse(erc20ABI));
var erc20Instance=erc20Contract.at(subchainAddr);
var via = "0x7610fd66c272332edd59a43460ad24eee1973bfe";
function sendtx(src, tgtaddr, amount, strData) {
chain3.mc.sendTransaction(
{
from: src,
value:chain3.toSha(amount,'mc'),
to: tgtaddr,
gas: "9000000",
gasPrice: chain3.mc.gasPrice,
data: strData
//via:'0x1b9CE7E4f156C1A28f2F1E0e38913a56cD9867'
});
console.log('sending from:' + src + ' to:' + tgtaddr + ' with data:' + strData);
}
//充值
//testApprove_erc20(subchainAddr, 235)
//testBuyMintToken(subchainAddr, 100)
function testBuyMintToken(addr, value){
var data=subchainInstance.buyMintToken.getData(addr, value);
console.log(data);
chain3.personal.unlockAccount(baseaddr,basename,0);
sendtx(baseaddr,subchainAddr,'0',data)
}
// sender approve subchainAddr to get the money
function testApprove_erc20(addr, value){
var data=erc20Instance.approve.getData(addr, value);
console.log(data);
chain3.personal.unlockAccount(baseaddr,basename,0);
sendtx(baseaddr,ercAddr,'0',data)
}
3.查询子链coin的余额
var request = require('request');
var url = "http://127.0.0.1:23456/rpc"; //23456为monitor端口
//查询子链coin的余额
var subChainAddr = "0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05"; //子链合约地址
var sender = "0x7610fD66c272332EDD59A43460AD24eEe1973bfe"; //查询coin的账号地址
var requestData = {"jsonrpc":"2.0","method":"ScsRPCMethod.GetBalance","params":{"SubChainAddr":subChainAddr,"Sender":sender},"id":0};
httprequest(url,requestData);
function httprequest(url,data){
request({
url: url,
method: "POST",
json: true,
body: data,
headers: {
"Content-Type": 'application/json',
"Accept": 'application/json'
}
}, function(error, response, result) {
if (!error && response.statusCode == 200) {
console.log(result) //请求成功的处理逻辑
}
else {
console.log(error) //请求失败的处理逻辑
}
});
};
直接node,输出结果:
4.查询子链scs monitor id
{"jsonrpc":"2.0","method":"ScsRPCMethod.GetScsId","params":{},"id":0};
使用第三节的代码,输出结果:
5.查询Dapp创建者在子链的nonce
{"jsonrpc":"2.0","method":"ScsRPCMethod.GetNonce","params":{"subChainAddr":"0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05","sender":"0x7610fD66c272332EDD59A43460AD24eEe1973bfe"},"id":0}
使用第三节的代码,输出结果:
6.获取子链区块高度
var requestData = {"jsonrpc":"2.0","method":"ScsRPCMethod.GetBlockNumber","params":{"subChainAddr":"0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05"},"id":0};
使用第三节的代码,输出结果:
7.获取子链某一区块信息
{"jsonrpc":"2.0","method":"ScsRPCMethod.GetBlock","params":{"subChainAddr":"0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05","Number":100},"id":0};
使用第三节的代码,输出结果:
8.获取子链智能合约全局变量
{"jsonrpc":"2.0","method":"ScsRPCMethod.GetContractInfo","id":0,
"params":{"subChainAddr":"0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05",
"Request":[{
"Reqtype": 1,
"Storagekey":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5],
"Position":[],
"Structformat":[],
}]
}
}
使用第三节的代码,输出结果:
C:\MyWorkSpace\erc20_transferOnSubchain>node callGetContractInfo.js
{ jsonrpc: '2.0',
id: 0,
result:
{ Balance: 9842,
Nonce: 1,
Root:
'0xad7ee70f35edd4d9d1036a5606059b5b94080dc093297c9f8310103c7a191d44',
CodeHash: 'aHv+BjX3BEYimDk86/AXZF1sxNZIXIpBEHMs0ZwbVYI=',
Code:
'YGBgQFJgBDYQYQHMV2P/////////t1MCql3OEBpvOH0dAAxeh2xleHBlcmltZW50YWz1ADc=',
Storage:
{ '0000000000000000000000000000000000000000000000000000000000000005': '' } } }
C:\MyWorkSpace\erc20_transferOnSubchain>
9.获取子链详细信息
{"jsonrpc":"2.0","method":"ScsRPCMethod.GetSubChainInfo","params":{"subChainAddr":"0xd8A5B206Db885680d7b85480Fb68239FBf0A1a05"},"id":0}
使用第三节的代码,输出结果: