Skip to content

Instantly share code, notes, and snippets.

@greenhat
Last active January 23, 2020 07:47
Show Gist options
  • Save greenhat/a32a61798782e7dc0bdecc10602d35db to your computer and use it in GitHub Desktop.
Save greenhat/a32a61798782e7dc0bdecc10602d35db to your computer and use it in GitHub Desktop.
ErgoScala teaser

I want to share with you a glimpse of the new contract development workflow that we’ve been working on for some time. The idea is to provide the following abilities to the contract developers:

1. Write a contract in Scala subset(ErgoScala) Here is a buyer’s contract from assets atomic exchange example:

def buyer(ctx: Context,
            deadline: Int,
            tokenId: Coll[Byte],
            tokenAmount: Long,
            pkA: SigmaProp): SigmaProp = {
            
    import ctx._
    (HEIGHT > deadline && pkA) ||
      {
        val tokens = OUTPUTS(0).tokens
        val tokenDataCorrect = tokens.nonEmpty &&
          tokens(0)._1 == tokenId &&
          tokens(0)._2 >= tokenAmount

        val knownId = OUTPUTS(0).R4[Coll[Byte]].get == SELF.id
        tokenDataCorrect &&
          OUTPUTS(0).propositionBytes == pkA.propBytes &&
          knownId
      }
  }

source

2. Prove it’s properties (formal verification) using Stainless. Here are three proven properties of the buyer contract proofs

3. Compile the contract to ErgoTree and executable Scala func. With the following call:

def buyerContractInstance(deadline: Int,
                            tokenId: Coll[Byte],
                            tokenAmount: Long,
                            pkA: SigmaProp): ErgoContract =
    ErgoContractCompiler.compile { context: Context =>
      buyer(context: Context, deadline: Int, tokenId: Coll[Byte], tokenAmount: Long, pkA: SigmaProp)
    }

  val ergoContract = buyerContractInstance(10000, Coll[Byte](...), 100, SigmaProp.fromBytes(...))

ergoContract.tree gives you ErgoTree of the buyer contract instance with passed parameters inlined. You can serialize it to bytes and use in a box. ergoContract.scalaFunc gives you a function with signature Context => SigmaProp with compiled buyer contract instance where passed parameters are inlined. You can call it in tests passing any suitable context (height, in and out boxes, etc.).

And all this is available inside your favorite Scala IDE.

4. Use compiled contracts and ErgoTrees from Appkit The ergoContract variable can be made available in an application written using Appkit. To achieve that the module with verified contracts should be added to Appkit application as a dependency. Then instead of writing

.contract(ctx.compileContract(
   ConstantsBuilder.create()
   .item("deadline", 1000)
   .item("tokenId", Coll[Byte](...))
   .item("tokenAmount", 100)
   .item("pkA", SigmaProp.fromBytes(...))
   .build(),
   "{ body of the contract }"))

You can write something like .contract(ergoContract.ergoTree(10000, Coll[Byte](...), 100, SigmaProp.fromBytes(...)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment