Inspiration

We code in Scala and love Functional Programming, exceptionally the craziest and the least practical parts of it.

So we decided to do an impossible thing on a hackathon, that we would never try at work: implement EVM in the Scala's type system!

Well, EVM compiler is too hard to code in a day, so we took Vyper language as an assembly instead. So it's like on the early ages of Javascript translators when CoffeeScript appeared to fix some of the language problems.

What it does

It lets to code Smart Contracts with Scala DSL.

All the language constructs are type safe, reusable and composable. So, one can use the same ProductType for function arguments, struct definition, and Contract's data representation. The same holds for the parts of a function body: it's expressed with a Free Monad, so you can assign chunks of code to variables and then reuse them.

Resulting Smart Contract is exported as Vyper plaintext.

How we built it

We began by noticing that, even if it's impractical to employ functional patterns in a smart contract directly, we can work with the code structures as they were functional programming primitives. So, a function definition in a Smart Contract is a profunctor, from a domain expressed as a product to a codomain, also expressed somehow.

Sounds wonderfully crazy, isn't it?

Challenges we ran into

We took shapeless' Heterogenous Lists, and Records (Labelled Generics), and Free Monads in a single new project. The type system is very strict, types are so complex that IDE can't derive them, and it often refuses to compile.

We haven't tried Labelled Generics before.

We haven't known about Vyper and learned it during the hackathon after failed with Solidity.

Also, we've tried to use Scala Macro to convert raw scala code to a smart contract (we've never used macro programming before), but yet it fails (my teammates are still trying hard while I'm typing these words).

One of the particular complex problems was a problem of type-safe function call definitions. As a function domain is expressed as a Product (Heterogenous List with types labeled with argument names on type level), we had to find a way to remove the argument name tags from the types. Hell, it's even complex to say.

Accomplishments that we're proud of

It compiles. And it's deployed.

We were able to generate a working example with Auction smart contract, deploy it to Rinkeby, in a day.

We haven't dropped any important type-level constraint. No Any types around! So it's really safe.

It runs in Scastie, so you can code Crotalinae DSL in the browser!

What we learned

Vyper language is really awesome!

And Heterogenous Lists are really weird in complex scenarios.

What's next for Crotalinae

  • Macro support :)
  • Better language coverage
  • Implement best practices, like safe math

It could be really useful for generating smart contracts from Scala code. It's possible that we will use it, or some of the approaches, in Fluence later.

Built With

Share this project:

Updates