RChain Blog

RChain Powerbox 汇总

愁虫

愁虫

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`

stdoutstdoutAck 为例简单介绍使用方法,其它三个类似。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 用于生成多重签名钱包,我们会专门写文章介绍这部分代码,多重签名钱包智能合约的代码:

https://github.com/rchain/rchain/blob/d581015a2ed5c81aa92f1f31e8efcef14e0c4fff/casper/src/main/resources/MultiSigRevVault.rho

第四类,权限相关
包括以下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情况也比较复杂,我们专门准备一篇文章讲解。

https://github.com/rchain/rchain/blob/0a6ffe0826e56707d32b6b7348b3d29c345692ed/casper/src/main/resources/Either.rho

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微信,拉你入群。非开发者请勿加,会有一轮测试,通过者方可入群。

Leave a Reply

Your email address will not be published. Required fields are marked *