RandDrop应用链的部署、强随机数的合约调用
V刘晨曦
发表于 2023-1-15 10:53:15
1427
0
0
RandDrop 应用链是指采用 BLS 签名,支持多合约部署的 MOAC 应用链。 RandDrop 目前还在测试阶段,将会支持两种原子跨链交换,完成母链原生通证或者 ERC20 通证和应用链原生通证之间的互换。& T) s7 ^3 b4 O% Y$ Y% P, C
RandDrop 共识0 O e6 k" G6 T
共识算法作为区块链系统的核心技术,决定了整个系统的性能和可扩展性,一直是当前区块链关键技术研究的重点。 目前最新的共识机制研究中有很多对于 PoS 和 PBFT 的改进,尤其是使用随机数算法来提高共识的效率和增加参与共识的节点数目。: c& n1 S# j' e* j
RandDrop 采用 BLS 签名,从共识层支持多个节点的签名片段进行合并得到阈值签名,以此为基础产生随机数。随机数可以在 RandDrop 的智能合约里面直接调用。RandDrop 随机数的优点是可以杜绝单个节点对最终签名的可操作性,更加安全可靠。同时,RandDrop 的信息量是 O(n),比其他类似的随机数区块链具有较大的优势。
RandDrop 应用链的验证过程由支持 RandDrop 应用链的客户端(SCS)完成,ProcWind 和 RandDrop 的 SCS 节点不能混用。+ ]9 ^) j9 Z4 E2 Z) c5 h3 B
应用链本身是以智能合约的方式部署到 MOAC 平台上,其共识方式、节点组成和业务逻辑都在应用链合约中定义。
应用链节点控制合约(ScsProtocolBase),用于定义 SCS 节点共识方式和如何包括 SCS 节点矿工加入应用链;
可验证秘密共享(VssBase)合约,构造函数需要提供 1个 threshold 参数,该参数表示阈值签名的阈值。部署后,记录下 vssbase 合约的部署地址 vssbaseAddress;
应用链逻辑控制合约(AppChainBase):用于应用链控制逻辑,应用链生成前和生成后的一系列控制逻辑;
应用链合约控制(DappBase):用于控制合约在应用链上的部署,一条应用链可以部署多个合约;目前有两类控制合约,一类是仅允许应用链的部署帐号,即拥有者(owner)在应用链上部署合约,而另一类则没有这个限制;, E- c6 f- y5 e, Q% B7 l% J( q
应用链 DAPP 智能合约:用于部署应用链业务逻辑的合约,每个应用链可以部署多个 DAPP 合约;
与 ProcWind 不同的是,在部署完 VssBase 和 RandDropChainBase 的合约后,需要在基础链上,调用 VssBase 合约的 setCaller 方法, 传入之前的 RandDrop 合约地址 subchainbaseAddress。 此方法调用后,保证了 VssBase 合约的部分关键函数只能由 subchainbase 合约调用,而无法由外部普通账户调用。
RandDrop 中随机数的使用
RandDrop 应用链可以产生随机数。随机数可以在 RandDrop 的智能合约里面直接调用。
pragma solidity ^0.4.8;
contract precompileBLS {' w- R9 ?* b3 O1 }! q
function f() public returns(bytes32);
}4 \" n+ |$ J8 q8 }, q
contract Lottery {
mapping (uint8 => address[]) playersByNumber ;
address owner;" w/ z Q4 p' E z
enum LotteryState { Accepting, Finished }
LotteryState state;" u3 ^' K2 w& S( ]) e$ A; U
function Lottery() public {
owner = msg.sender;
state = LotteryState.Accepting;( H' S/ `! B$ R
}% X: }% T! r! _/ ?" I4 X* o
function enter(uint8 number) public payable {
require(number
function determineWinner() public {
require(msg.sender == owner);
state = LotteryState.Finished;
uint8 winningNumber = random();
distributeFunds(winningNumber);
}0 p, x, U: v: e7 |8 v; J- H
function resetLotteryState() public {8 y7 D0 Q2 e* H7 v- x3 C
require(msg.sender == owner);
state = LotteryState.Accepting;9 V0 P, ?: `/ C. T. h) X
}
function distributeFunds(uint8 winningNumber) private returns(uint256) {# L6 L0 M% n" s4 n L+ h$ ~/ @
uint256 winnerCount = playersByNumber[winningNumber].length;* B8 }# Y8 B3 Y8 J8 s8 b
uint256 balanceToDistribute = this.balance/(2*winnerCount);# D; F; }5 [: m6 t/ l
for (uint i = 0; i
return this.balance;: y; X- G0 ], H: p4 x
}
function random() private view returns (uint8) {% X* j" x$ ^5 ?7 C
precompileBLS bls = precompileBLS(0x20); k8 a' |+ t6 [
// get the 256-bit random number
bytes32 r = bls.f();0 q2 \8 W6 T; V7 R+ E0 S
// return its first 8 bits, range from 0-255
return uint8(r[0]);! y: [! M# S& h8 J
}
}
RandDrop 验证节点! m/ S/ c& i7 j9 }
RandDrop 节点客户端与 ProcWind 不同,称智能合约服务器 Smart Contract Server(SCS-VSS) 是支持 BLS 共识的节点软件。 SCS-VSS 也通过 VNODE 代理节点接入 MOAC 母链,每个运行的 SCS 可以支持多条应用链,也可以动态接入不同 VNODE。 目前有两种应用链客户端,分别支持对应的应用链 ProcWind 和 RandDrop。
当前,按在应用链中的功能分,有如下几种 SCS 节点类型:) Z$ l% q) S3 I- e+ ?
参与业务逻辑的 SCS4 Q% Y* e* A/ F& l) X6 ^
用于业务监控的 SCS. t$ N2 v1 W+ q+ I- H' N5 y
准备参与业务逻辑的 SCS
节点的操作可以参考:
SCS 节点快速启动指南
RandDrop 通证
RandDrop 应用链也支持应用链上的原生通证(TOKEN),其发行方式是在应用链合约中设定,这点和 ProcWind 相同, 详细介绍请参考: RandDrop 应用链的部署
关于 RandDrop 上通证的转移,也是采用 shardingFlag=2 的方式,例子如下:$ I3 _0 p9 d1 C/ K( E
//Example to transfer the AppChain tokens* j; v3 Y/ r: g9 Y
function sendAppChainToken(baseaddr,basepsd,appchainaddr,amount,code,sf,n)
{+ ^! g7 h5 \, E+ W
//unlock the
chain3.personal.unlockAccount(baseaddr,basepsd,0);- o/ q, Q/ Q- v1 _
//transfer the appchain token8 [% _2 V1 [2 F& G( f5 |; _
chain3.mc.sendTransaction(0 S, F1 L c' x% c9 F
{
from: baseaddr,
value:chain3.toSha(amount,‘mc’), // note this value is the appchain token value, not mc3 [: B0 u- S& L& x" y! q+ K
to: appchainaddr,4 k( e$ N Y. |+ b" l) c' X
gas: ‘0’,//‘200000’,
gasPrice: ‘0’,//chain3.mc.gasPrice,$ M/ p) {$ a3 k d9 [
ShardingFlag: sf,$ l4 {) E% C% _. y
data: code,4 Z4 ~0 j6 K( g0 @% ?6 q
nonce: n,
via:via,4 g6 h" s7 M# {& m. |& z! j4 K
});
console.log('sending from:' + baseaddr + ' to:' + appchainaddr + ' with nonce:' + n);
}
// Call the function to transafer3 L- {% N8 l# J
var amount = 1;4 o7 x# W) A7 m1 W6 f
//函数输入参数说明
//baseaddr:转出地址4 m4 r/ H/ {( D/ A
//basepsd:转出地址的密码
//appchainaddr:应用链地址
//amount:转账金额
//receive: 转入的地址/ M$ ?. H# Y/ i5 a, H
//‘0x2’: shardingFlag 设为2为应用链原生货币转换1 P/ {5 ^" U8 c* a; P6 p
//n: 转出地址的nonce
sendAppChainToken(baseaddr,basename,appchainaddr,amount,receive,‘0x2’,n)
RandDrop 跨链
应用链通证可以和母链的原生货币或者 ERC20 代币直接进行兑换,只需要部署不同的应用链合约并执行相应功能调用即可完成。 具有与母链原生货币(moac)进行跨链交换功能合约的名称为 ASM(Atomic Swap of Moac)。 具有与母链 ERC20 代币进行跨链交换功能合约的名称为 AST(Atomic Swap of Token)。 具体做法可以参考:
ProcWind 跨链指南5 Q. w' D" n+ c8 N
RandDrop 应用链的参数和设置
目前采用 RandDrop 共识的应用也分为两种:ASM 和 AST。 在 MOAC 发布的目录可以看到合约内容,主要的不同是需要加入 VssBase.sol 的部署地址。6 A7 L, l/ m0 `7 ]! H7 | P3 [
ASM 的合约构建函数为:
function ChainBaseASM(& M/ m0 m$ N8 \3 P# Y
address scsPoolAddr,
address vnodeProtocolBaseAddr,
uint min, e2 L5 U e6 I" M; h
uint max,' y! J/ A1 H- u* ]3 M2 P
uint thousandth,! `4 `; {4 E7 k+ t1 j( S
uint flushRound,
uint256 tokensupply," v8 R0 _% W; {
uint256 exchangerate,
address vssBaseAddr
)5 c, W& F7 E! L' t
其中的参数含义为: `* c! O; G1 Q
address scsPoolAddr - SCS 节点池地址;! ]8 L* q# Y+ X* w
address vnodeProtocolBaseAddr - Vnode 节点池合约地址;/ S+ n/ |2 {' T9 b, T, s/ f
uint min - 应用链需要 SCS 的最小数量,需要从如下值中选择:1,3,5,7;
uint max - 应用链需要 SCS 的最大数量,需要从如下值中选择:11,21,31,51,99
uint thousandth - 控制选择 scs 的概率,建议设为 1,对于大型应用链节点池才有效;5 v0 E! b, s/ N
uint flushRound - 应用链刷新周期 单位是主链 block 生成对应数量的时间,当前的取值范围是 40-99;* W% `+ a+ u7 r) `) ]. d7 m. y
uint256 tokensupply - 应用链的原生货币数量;
uint256 exchangerate - 应用链原生货币和母链 moac 的兑换比例;
address vssBaseAddr - VSSBase 的部署地址;
注意,这里输入参数 tokensupply 和应用链的 BALANCE 相对映, BALANCE = tokensupply * 1e18 例如,tokensupply = 1000,结果的 BALANCE 应该是 10 的 21 次方。! x6 Z# U" y: q2 @( |0 H4 o
AST 的合约构建函数为:
function ChainBaseAST() M( Z5 ]4 H) j) L6 O
address scsPoolAddr,$ k7 ?! G+ R* @; I, ~ g
address vnodeProtocolBaseAddr,5 ?, g3 s9 D) \; T
address ercAddr,9 h. V" U% v5 e/ g/ [. G% P
uint ercRate,
uint min,7 M# b; {3 w+ | @! d
uint max,
uint thousandth,: i* y# C) b; ^, o
uint flushRound,
uint256 exchangerate,7 P2 c! `( v) N9 G9 \/ m0 w
address vssBaseAddr
)
其中的参数含义为:* S8 X7 O9 l* ]1 j$ ^
address proto - SCS 节点池地址;+ u4 A/ x" q, ^* M
address vnodeProtocolBaseAddr - Vnode 节点池合约地址;+ y- p" S5 C% s4 D/ b
address ercAddr - 基础链 ERC20 合约地址;
uint ercRate - 应用链原生货币和基础链 ERC20 token 的兑换比例;
uint min - 应用链需要 SCS 的最小数量,需要从如下值中选择:1,3,5,7;
uint max - 应用链需要 SCS 的最大数量,需要从如下值中选择:11,21,31,51,99
uint thousandth - 控制选择 scs 的概率,建议设为 1,对于大型应用链节点池才有效;' V! H5 j7 c4 _0 d9 O% R- O
uint flushRound - 应用链刷新周期 单位是主链 block 生成对应数量的时间,当前的取值范围是 40-99;" [# i0 o$ Q* h- e0 X4 h
uint256 exchangerate - 应用链原生货币和母链 moac 的兑换比例;; Z7 ^5 z ]4 @% M5 `4 Y" F0 @
address vssBaseAddr - VSSBase 的部署地址;
注意,AST 应用链的 BALANCE 不能设定,而是由 ERC20 token 里面 totalSupply 所决定的, BALANCE = tokenSupply * ERCRate * (10 ** (ERCDecimals));
成为第一个吐槽的人