Functional Ethereum

Martin Allen & Kristoffer Josefsson, FOAM

May 27, 2018

Ethereum … and Cats

Cryptokitties, what are they?

What are they worth?

Turns out over 12 million dollars!

Ethereum Market Cap

  • Second highest cryptocurrency market cap
  • Doesn’t include the sum of the value of tokens

Kitty Monitor

  • Monitor the sales in real time with the kitty-monitor
  • Backed by purescript-web3

Solidity

  • Javascript like syntax
  • Special blockchain, crypto and signature-recovery primitives
  • Types for EVM primitives such as uint48
  • Interface through ABI

edit on remix

The selector is how we speficy the function to execute

so for GreedyStorage we get

Typesafety (on-chain)

  • Work underway for strongly typed languages targeting EVM
  • Typesafe EVM language wouldn’t necessarily have prevented infamous bugs. We’d need session types or similar.
  • Fundamental problem is call-out from turingcomplete executable to turing complete executable. Type level information not preserved on EVM.

Typesafety (off-chain)

Prevent catastrophes

  • Encoding errors
  • Improper value transfer
  • Function/argument mismatch

Subtle changes leading to broken application code

Architecting an Ethereum App

Auto-generated FFI

  • Ethereum smart contracts expose an interface
  • Example: ERC20 standard

Auto-generated FFI

  • Use the Application Binary Interface (ABI) as a specification

Auto-generated FFI

  • Auto generate purescript or haskell code for FFI

Functional Web3 Libraries

  • purescript-web3: A web3 client library for purescript. Capable of generating client libraries for smart contracts from Solidity ABIs. Integrates with services like Metamask or uPort for in-browser transaction signing. Plays very nicely with Chanterelle.
  • hs-web3: A haskell web3 client library. Also capable of creating client libraries from ABIs using Template Haskell.

Library Layout

  • Low level serialization and RPC layer
    • Solidity types
    • (de)serialization
    • web3 api
  • User Interface and Generator Tool
    • purescript-web3 generator
    • Contract module
    • Methods and Events

Solidity Types

Sized Types

  • Purescript does not as of yet have type level naturals
  • Luckily we don’t need infinitely many

Sized Ints

  • js doesn’t have unbounded integers (doesn’t even have integers!)
  • need something like BigNumber

Length Indexed Vectors

Tuples

  • The EVM is a stack based virtual machine with a maximum depth of 16. Limits the possible tuple sizes.
  • First iteration of purescript-web3 didn’t handle these well.

Basic (De)Serialization

  • All basic Solidity types implement the following type classes for the ABI encoding schema.

Tuples

  • All Solidity functions accept and return tuples.
  • Events are emitted as tuples, though not as straight forward to handle.
  • Encoding and Decoding implemented “generically”.

Generics Primer (Advanced)

  • All “basic” purescript types (i.e. of kind Type) admit a generic decomposition

Generics Primer (Advanced)

  • Compiler implements generic decompositions for us, so we can use them for free.
  • We can inductively build up generic types to have a certain property, such as ABIEncode

Generics

  • enables extremely local reasoning, building up more complicated expressions from smaller ones whose correctness is easier to prove.
  • code utilizing “generics” is extremely reusable.

Web3 API

  • The Web3 API is a set of RPC methods that the ethereum client knows about
  • There are a lot, the type signatures serve as a sort of documentation

Web3 API

  • Implementation of the client portion heavily inspired by the hs-web3 implementation.
  • How easy is it to add new endpoints as they are released?

Pretty easy!

User Interface

You will be able to use purescript-web3 without knowing how it works. This means:

  1. Calling contract methods, listening for events, querying blockchain metadata, full web3 api implementation.
  2. Integrating with metamask.
  3. Easily generate a simple client library for every contract.

Generator - Simple Storage

Simple Storage allows us to change a uint256, query that state, and listen for updates to that state.

Generator - Simple Storage

Here is the client library generated which is generated from the ABI 1

Generator - Benefits

  1. Reduce boiler plate.
  2. You don’t want to access the raw encoders/decoders manually when templating your transactions, laborious and potentially error prone.
  3. The generator is meant to be run as an npm build step - any breaking changes to your contracts will cause compile time errors in your application.
  4. Specially generated types allow for higher levels of abstraction in library.

Generator - How does it work

  • All templated transaction functions are run with the sendTx method:
  • call methods are similar, but with a return type

Generator - Events

  • Events were difficult to find a good solution for due to the Ethereum log structure.
  • All events can be handled with the event method, which similarly defined in hs-web3
  • this looks more complicated than it is.

Events - Example

  • Here’s an example of the event monitor in the example app. It registers a handler and asynchronously polls a filter for the CountSet event, updating the React component’s state.
  • Since the return value of the handler is always ContinueEvent, this poll never terminates.

Live Demo

Local

  1. Setup and ERC20 contract.
  2. Deploy it with hooks for the Indexer.
  3. Make a transaction.
  4. Find it in the API.

Main Net

  1. Submit a request to index the OmiseGo ERC20 token contract.
  2. Find it in the API
Fin

  1. There are a few other boiler plate type declarations that are generated, but this is pretty much it.