
Powerbox 是RChain系统级的channel,通过Powerbox,Rholang智能合约开发者可以调用系统资源。Powerbox层位于系统物理资源和Rholang代码之间,用于处理磁盘IO和网络等请求,对RSpace的访问请求也要通过Powerbox层。
Powerbox 模式是从 Object Capability (“OCaps”) Security Model 借鉴过来的,Powerbox 作为权限转移的仲裁者, 将多样化的权限管理集于一身。 当子系统需要新的权限时,由Powerbox决定是否授予。
本文整理了29个Powerbox,方便开发者调用,如有遗漏请指出。
第一类,屏幕IO相关
包括以下5个:
`rho:io:stdout`
`rho:io:stdlog`
`rho:io:stdoutAck`
`rho:io:stderr`
`rho:io:stderrAck`
以 stdout
和 stdoutAck
为例简单介绍使用方法,其它三个类似。stdout
向屏幕输出;stdoutAck
向屏幕输出的同时产生一个确认信号,用以触发其它事件。
new myAckChannel,
stdout(`rho:io:stdout`),
stdoutAck(`rho:io:stdoutAck`) in {
stdoutAck!("Print some words.", *myAckChannel)|
for (acknowledgement <- myAckChannel) {
stdout!("Received an acknowledgement.")
}
}
第二类,deploy相关
包括以下5个:
`rho:rchain:deployId`
`rho:rchain:deployerId`
`rho:rchain:deployerId:ops`
`rho:block:data`
`rho:deploy:params`
在部署智能合约和出块的过程中,智能合约可以从系统得到相应信息。
rho:rchain:deployId
能够返回当前部署的智能合约的deployId.
new deployId(`rho:rchain:deployId`),
stdout(`rho:io:stdout`)
in {
stdout!(*deployId)
}
rho:rchain:deployerId
能够返回当前智能合约的部署者的deployerId.
new deployerId(`rho:rchain:deployerId`),
stdout(`rho:io:stdout`)
in {
stdout!(*deployerId)
}
rho:rchain:deployerId:ops
接收一个deployerId, 返回部署者的公钥。下面的例子返回了当前智能合约部署者对应的REV钱包地址。
new RevAddress(`rho:rev:address`), DeployerIdOps(`rho:rchain:deployerId:ops`),
deployerId(`rho:rchain:deployerId`), stdout(`rho:io:stdout`),
revAddrCh, deployerPubKeyBytesCh
in {
DeployerIdOps!("pubKeyBytes", *deployerId, *deployerPubKeyBytesCh) |
for (@deployerPubKeyBytes <- deployerPubKeyBytesCh) {
RevAddress!("fromPublicKey", deployerPubKeyBytes, *revAddrCh) |
for (@deployerRevAddress <- revAddrCh) {
stdout!(deployerRevAddress)
}
}
}
rho:block:data
能够返回当前智能合约部署的区块的BlockNumber, 时间戳和deployerId.
new retCh, getBlockData(`rho:block:data`), stdout(`rho:io:stdout`) in {
getBlockData!(*retCh) |
for (@blockNumber, @timestamp, @sender <- retCh) {
stdout!((blockNumber, timestamp, sender))
}
}
rho:deploy:params
该参数曾用于PoS.rhox的某个版本,现已去掉,期待能发现相关资料。
第三类,货币相关
包括以下4个:
`rho:rchain:makeMint`
`rho:rchain:revVault`
`rho:rev:address`
`rho:rchain:multiSigRevVault`
REV与ETH不同的地方在于,ETH是以太坊上原生的coin,而在RChain上没有coin,REV是通过智能合约的方式生成的,应该称为Token。 REV的好处是与其它RChain主网上的Token拥有相同的业务逻辑,通过智能合约可以进行互操作,而ETH就没有这个能力。这也是为什么以太坊上会存在WETH这样的Token.
rho:rchain:makeMint
这个智能合约可以帮你铸造Token,REV就是通过这个智能合约铸造的。
new MakeMintCh, stdout(`rho:io:stdout`),
rl(`rho:registry:lookup`)
in {
rl!(`rho:rchain:makeMint`, *MakeMintCh) |
for (@(_, MakeMint) <- MakeMintCh){
new mintCh in {
@MakeMint!(*mintCh) |
for (mint <- mintCh) {
new purseCh in {
mint!("makePurse", 9999999999999, *purseCh) |
for (purse <- purseCh) {
stdout!(*purse)
}
}
}
}
}
}
想要了解Vault和Purse的基本概念可以看这里:https://rchain.atlassian.net/wiki/spaces/CORE/pages/652640311/Wallet+proposal+Note+we+decided+to+rename+terms+such+that+wallet+is+not+used+for+on-chain+components
注:REV可精确到小数点后8位。REV在链上只能以整数表示,REV余额要除以10^8。
rho:rchain:revVault
与REV的智能合约互动,发起创建新钱包,转账等活动。
下面的代码用于查询钱包地址余额。
new
rl(`rho:registry:lookup`), RevVaultCh,
vaultCh, balanceCh,
stdout(`rho:io:stdout`)
in {
rl!(`rho:rchain:revVault`, *RevVaultCh) |
for (@(_, RevVault) <- RevVaultCh) {
match "%REV_ADDR" {
revAddress => {
stdout!(("Accessing vault at RevAddress", revAddress)) |
@RevVault!("findOrCreate", revAddress, *vaultCh) |
for (@(true, vault) <- vaultCh) {
@vault!("balance", *balanceCh) |
for (@balance <- balanceCh) {
stdout!(("Balance is", balance))
}
}
}
}
}
}
其它诸如转账等操作,详细信息可参考https://github.com/rchain/rchain/blob/0a6ffe0826e56707d32b6b7348b3d29c345692ed/casper/src/main/resources/RevVault.rho
rho:rev:address
可以从公钥和Unforgeable name两种形式生成REV地址。
new a, RevAddress(`rho:rev:address`), revAddr1Ch, revAddr2Ch,
stdout(`rho:io:stdout`) in {
RevAddress!("fromUnforgeable", *a, *revAddr1Ch) |
RevAddress!("fromPublicKey", "xxx", *revAddr2Ch) |
for (@unforgeableRevAddress <- revAddr1Ch) {
stdout!(("Rev address from Unforgeable name: ", unforgeableRevAddress))
}|
for (@deployerRevAddress <- revAddr2Ch) {
stdout!(("Rev address from pub key: ", deployerRevAddress))
}
}
rho:rchain:multiSigRevVault
用于生成多重签名钱包,我们会专门写文章介绍这部分代码,多重签名钱包智能合约的代码:
第四类,权限相关
包括以下3个:
`rho:rchain:authKey`
`sys:authToken:ops`
`rho:rchain:pos`
rho:rchain:authKey
AuthKey用于创建一个授权token,AuthKey提供make和check两个方法,make方法将unforgeable name配制成“shape”,以保证不会泄漏unforgeable name。
我们会专门写一篇文章讲解AuthKey。
AuthKey的代码:https://github.com/rchain/rchain/blob/d0a3dd737828eca8ec9320b7d590d5421567879f/casper/src/main/resources/AuthKey.rho
sys:authToken:ops
这个应用是在PoS.rhox的代码里发现的,应该是用于检查是否是来自系统的调用。请参见:
https://github.com/rchain/rchain/blob/0a6ffe0826e56707d32b6b7348b3d29c345692ed/casper/src/main/resources/PoS.rhox
...
sysAuthTokenOps!("check", sysAuthToken, *isValidTokenCh) |
for (@isValid <- isValidTokenCh) {
if (isValid) {
...
}
...
rho:rchain:pos
对PoS智能合约进行调用,
下面这个例子来自于https://github.com/rchain/rchain/blob/e70f4c1d3660b155718a9d084993f25a64c9a76a/rholang/examples/bond/bond.rho 成功完成一次Validator的绑定:
new retCh, PoSCh, rl(`rho:registry:lookup`), stdout(`rho:io:stdout`) in {
stdout!("About to lookup pos contract...") |
rl!(`rho:rchain:pos`, *PoSCh) |
for(@(_, PoS) <- PoSCh) {
stdout!("About to bond...") |
new deployerId(`rho:rchain:deployerId`) in {
@PoS!("bond", *deployerId, 100, *retCh) |
for ( @(true, message) <- retCh) {
stdout!("Successfully bonded!")
}
}
}
}
第五类,数据结构类
包括以下4个:
#`rho:lang:either`
#`rho:lang:listOps`
#`rho:lang:nonNegativeNumber`
#`rho:lang:treeHashMap`
rho:lang:either
Either是借鉴自scala的数据类型,适用于可能会出现两种结果的场景。有Left, Right两个子类型。Eitehr情况也比较复杂,我们专门准备一篇文章讲解。
rho:lang:listOps
用于链上的数组操作
https://github.com/rchain/rchain/blob/582247cf1e2e4c93f8bae59cb040168ae2c38021/casper/src/main/resources/ListOps.rho
rho:lang:nonNegativeNumber
用于非负数的加法和乘法,防止overflow
rho:lang:treeHashMap
TreeHashMap也是借鉴于scala的一个数据类型,用于提高链上数据插入或查询的速度。我们专门做准备一篇文章介绍TreeHashMap。TreeHashMapr的相关代码:https://github.com/rchain/rchain/blob/582247cf1e2e4c93f8bae59cb040168ae2c38021/casper/src/main/resources/TreeHashMap.rho
第六类,注册相关
包括以下4个:
`rho:registry:insertArbitrary`
`rho:registry:insertSigned:secp256k1`
`rho:registry:lookup`
`rho:registry:ops`
rho:registry:insertArbitrary
下面例子在链上注册newContract:
new newContract, uriChan,
insertArbitrary(`rho:registry:insertArbitrary`),
stdout(`rho:io:stdout`)
in {
contract newContract(@a) = {
...
}|
insertArbitrary!(bundle+{*newContract} , *uriChan) |
for(@uri <- uriChan) {
stdout!(uri)
}
}
rho:registry:lookup
下面例子从链上找到newContract的合约并触发:
new newContractCh,
rl(`rho:registry:lookup`),
stdout(`rho:io:stdout`)
in {
rl!(`rho:id:xxx`, *newContractCh) |
for (newContract <- newContractCh) {
newContract!("123")
}
}
rho:registry:ops
下面的例子是用字符串生成rho:id :
new registryOps(`rho:registry:ops`), retCh,
stdout(`rho:io:stdout`)
in {
registryOps!("buildUri", "foo".toByteArray(), *retCh) |
for (@ret <- retCh){
stdout!(ret)
}
}
第七类,测试相关
包括以下4个:
`rho:test:deploy:set`
`rho:test:assertAck`
`rho:test:testSuiteCompleted`
`rho:test:deployerId:make`
测试类我们一般用不到,找机会再介绍。
欢迎关注 “Rholang中文社区” 公众号
欢迎开发者加入 “RChain开发者” 微信群。加群请加lowbird微信,拉你入群。非开发者请勿加,会有一轮测试,通过者方可入群。