Skip to content

Metaprogramming for Ethereum Smart Contracts expressed in Scala's Type System

Notifications You must be signed in to change notification settings

fluencelabs/hackethberlin

Repository files navigation

Crotalinae

Metaprogramming for Ethereum Smart Contracts expressed in Scala's Type System.

  • Unlock Smart Contracts adoption with a JVM-based language: code them from Scala or in Scala
  • Smart Contracts code generator is itself a strictly typed program
  • Write a Contract using structs and definitions of Crotalinae DSL, and if it compiles, you're safe
  • Export Smart Contract in Vyper as a single plaintext and check it visually if needed
  • (WIP) Code directly in Scala: Scala source code is translated to Crotalinae DSL using macros

Tech dive

Scala language is a functional programming language for JVM.

We've noticed that we may generate Smart Contracts in a functional way: function definition is a profunctor (Intuitively it is a bifunctor where the first argument is contravariant and the second argument is covariant.), arguments and structs are products, and so on.

Scala's strictly typed product exists in form of a shapeless heterogenous list. As arguments or contract data may be referenced by name, we also use Record pattern and reflect these names in the type system.

To go beyond the data and function definitions, we use Free Monad from a category theory library for Scala named Cats. It lets us represent stateful computations as data, and run them.

Running, in our case, means code generation. It is done with a natural transformation from Crotalinae DSL into a Writer Monad, which is then converted to a text.

Contracts are exported in Vyper language. It's simple, very readable and comprehensive, and we really like it! However, it lacks tools for code reuse: you often need to copy-paste where, say in Solidity, you may call a function from a library. With Crotalinae you still have Vyper sources at the end, but may take advantages of the functional composition to re-use code in different contracts instead of copy-pasting it.

Example

This crazy Scala code:

  val f = `@public` @:
    sumArgs.funcDef("sumSome", uint256) { args 
    for {
      c  'c :=: `++`(args.ref('a), args.ref('b))
      d  'd :=: `++`(args.ref('b), c)
      _  d :=: c
      sum  `++`(args.ref('a), d).toReturn
    } yield sum
  }
  
  println(f.toVyper)

Compiles into this:

@public
def sumSome(a: uint256, b: uint256) -> uint256:
  c = a + b
  d = b + c
  d = c
  return a + d

The more sophisticated Auction example is deployed on Rinkeby. Also, you may try it out in scastie. Hooray!

Future plans

Of course, building EVM code from Vyper, from Scala DSL, using Free Monads and Shapeless Records, is not enough.

So we're working on Macro Programming support as well, so you can write your contracts in a less crazy, more usual Scala and still get all safety advantages. It will add one more layer of Scala code: Scala -> Scala AST (macro) -> Crotalinae DSL -> Vyper.

So stay tuned!

About

Metaprogramming for Ethereum Smart Contracts expressed in Scala's Type System

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages