Skip to content

Instantly share code, notes, and snippets.

Last active Sep 11, 2018
What would you like to do?
Scala code making use of rchain project resources to generate Rholang that performs transfers
import coop.rchain.casper.genesis.contracts.{Rev, Wallet}
import coop.rchain.casper.util.rholang.InterpreterUtil.mkTerm
import coop.rchain.casper.util.rholang.RuntimeManager
import coop.rchain.crypto.codec.Base16
import coop.rchain.crypto.hash.Blake2b256
import coop.rchain.crypto.signatures.Ed25519
import coop.rchain.rholang.interpreter.Runtime
import coop.rchain.shared.PathOps.RichPath
import java.nio.file.Files
import Wallet._
object RChainWalletTransfers {
//give a simple address for a wallet
def depositAddress(wallet: Wallet): String = "0x" + rhoPublicName(wallet).split(':').last.dropRight(1)
//generate the rholang code for accepting purses at an address
def depositForwarder(wallet: Wallet): String = {
val address = depositAddress(wallet)
contract @"$address"(@purse) = {
new purseAmountCh, return(`rho:io:stdout`) in {
@(purse, "getBalance")!(*purseAmountCh) |
for(@wallet <- ${rhoPublicName(wallet)}; @amount <- purseAmountCh) {
@(wallet, "deposit")!(amount, purse, *return)
//generate rholang code for transferring rev between wallets
def transfer(from: Wallet, to: Wallet, amount: Int, nonce: Int, sk: Array[Byte])(implicit rm: RuntimeManager): String = {
val destName = depositAddress(to)
val sigData = rm.captureResults(rm.emptyStateHash, mkTerm(s""" @"__SCALA__"!([$nonce, $amount, "$destName"].toByteArray()) """).right.get).head.exprs.head.getGByteArray
val sig = Base16.encode(Ed25519.sign(Blake2b256.hash(sigData.toByteArray), sk))
for(@wallet <- ${rhoPublicName(from)}) {
new status(`rho:io:stdout`) in {
@(wallet, "transfer")!($amount, $nonce, "$sig", "$destName", *status)
def writeToFile(code: String, name: String): Unit = {
val out = new PrintWriter(s"./$name.rho")
def main(args: Array[String]): Unit = {
//main method to actually generate the rholang code
val runtimeDir = Files.createTempDirectory("casper-rholang-interpreter-")
val runtime = Runtime.create(runtimeDir, 1024L * 1024 * 10)
implicit val runtimeManager = RuntimeManager.fromRuntime(runtime)
val n: Int = args.head.toInt //number of wallets to make
val (sks, pks) = (1 to n).map(_ => Ed25519.newKeyPair).unzip
val wallets = => Wallet("ed25519", Base16.encode(pk), 100))
val rev = new Rev[Wallet](Wallet.rhoCode, wallets)
val depositForwarders =
val transfers = { //set up transfers between wallets; could be modified to do more txns
val wsks = {
case ((from, sk), to) => transfer(from, to, 11, 0, sk)
//Note that this generated code assumes NonNegativeNumber.rho, MakeMint.rho and BasicWallet.rho
//are already deployed. This is is the case for node instances because those contracts are in
//the genesis block.
val walletSeupCode = (rev.code +: depositForwarders).mkString(" |\n")
val transferCode = transfers.mkString(" |\n")
writeToFile(walletSeupCode, "walletSeup")
writeToFile(transferCode, "transfers")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment