2. What is SCaml
Yet another compiler from OCaml to Michelson.
“Smart Contract Abstract Machine Language”
For Smart contracts
Strict Subset of OCaml
Small (7500 loc.).
3. Strict Subset of OCaml
Valid SCaml program is valid OCaml program.
No special features for smart contracts.
Some OCaml features are disabled:
No recursion
No polymoprhism
No ML functors
No objects
No mutability
4. Small
Built over OCaml’s compilerlibs:
Reusing OCaml’s parser and type-checker.
SCaml compiles OCaml’s typed AST to Michelson.
The first version was in 3000 loc written in 5 days.
6. Benefit of being Strict Subset
OCaml programmers can use SCaml immediately.
Newbies can learn SCaml via OCaml tutorial.
Many OCaml eco-system tools can be used for free:
Menhir, Tuareg, indender, reformatter
Dune (build system)
PPX, P4, ReasonML
7. Possibilities of being Strict Subset
Simluation in native code
Native compilation with simulated primitives:
dApp development in one language
Contracts: to Michelson by SCaml
UI: to JS by JSOO
Server: to native by OCaml
Certification in Coq and F*
11. Entry points with [@entry]
Allowed only in the last linked module:
let [@entry] f param storage = ...
val f : param_ty
> storage_ty
> SCaml.operation list * storage_ty
13. Numeralic types int, nat, tz
Int (12)
Nat 42
Tz 1.23 (in tez, not micro tez)
with monomorphic operators: (+), (+^),(+$)
14. Options, Lists, Sets, Maps
Some 1
[ Int 1; Int 2; Int 3 ]
Set [ Nat 1; Nat 2; Nat 3 ]
Map [ (Int 1, "one"), (Int 2, "two") ]
Set and Map only take constants for now.
15. Blockchain related constants
In style of a constructor + a string constant:
Key_hash "tz1KqTpEZ7Yob7QbPE4Hy4.."
Signature "edsigtteMcYkviZ3rTaM6N7DW.."
Timestamp "20190911T08:30:23Z"
16. Pairs, Sums, Variants, and Records
Compiled down to pairs and sums.
Using right balanced tree,
with optimization for nullary variants (like OCaml)
17. Full pattern match
Nested patterns
Or patterns
Guards
Non-exhaustive check
TODO: Pattern match heuristics for
efficiency
19. Exceptions
User definable
Reported as (Pair "Module.My_error" 1)
in Michelson.
Exception is not catchable.
(* module.ml *)
exception My_error of int
raise (My_error (Int 1))
20. SCaml specific errors
Error number to indicate the nature:
Easy to distinguish OCaml errors and SCaml ones.
[ESCaml000] SCaml does not support objects
22. Surprises on closures
Michelson closure must be packable.
Its environment cannot carry unpackables:
Operations, Contracts, and BigMaps.
SCaml functions (except entry points) cannot have
free variables of unpackable types:
Error: [ESCaml400] Function body cannot have
a free variable occurrence `x` with
unpackable type.
23. Surprises on closures: Example
ops is a free in fun c > ...
and its type is unpackable operation list
List.fold_left (fun ops > fun c >
Operation.transfer_tokens () (Tz 1.) c
:: ops)
[] contracts
Error: [ESCaml400] Function body cannot have
a free variable occurrence `ops` with
unpackable type.
24. Surprises on closures: Mitigation
Use uncurried version:
List.fold_left' (fun (ops, c) >
Operation.transfer_tokens () (Tz 1.0) c
:: ops)
([], contracts)
28. SCaml in Dune
Almost unable to use scamlc in Dune build system.
Dune is not forgiving once you step away from the
standard OCaml development.
29. SCaml in Dune: scaml.ppx
SCaml compiler integrated into OCaml PPX.
Allows SCaml compilation in Dune workflow:
SCaml code is pre-compiled and embeded in OCaml object files.
OCaml executable to link SCaml code and emit Michelson.
module Contract = struct
[@@@SCaml] (* Smart contract part *)
let [@entry] default () _ = ...
end
let () = SCamlc.Ppx.emit ~outputprefix:"out"
30. SCaml in Dune: scaml.ppx
OCaml code now can have SCaml code inside:
structures tagged with [@@@SCaml].
Possibilities:
Test code in OCaml
Simulation driver in OCaml
Sharing server side and client code
31. SCaml errors in Merlin
scaml.ppx makes Merlin browsable SCaml specific
errors on the fly.
32. SCaml with Reason
ReasonML is just another syntax of OCaml.
ReasonML to SCaml to Michelson almost for free.
33. Candies
Not quite useful to me but some people love:
TrySCaml (compiling SCaml compiler to JS)
SCaml Blocky (using OCaml Blocky)
35. Interop between Camls with typerep
ppx_typerep_conv: embed type def info in OCaml.
type t = Foo of int | Bar
[@@deriving typerep]
module Smart_contract = struct
[@@@SCaml]
let [@entry] default () _ =
[], Foo (Int 42)
end
36. Interop between Camls with typerep
SCaml to Michelson:
Michelson to SCaml:
SCaml type to Michelson type in OCaml:
SCamlc.Typerep.to_micehlson typerep_of_t
(Foo (Int 42))
SCamlc.Typerep.of_micheline typerep_of_t
"{ Right 42 }"
SCamlc.Typerep.to_michelson_type
typerep_of_t
37. Typesafe pack/unpack simulation
Original pack/unpack cannot be simulated:
Extend with typerep:
OCaml can pack’/unpack’ type-safely.
SCaml ignores typerep arguments.
Obj.pack : 'a > bytes
Obj.unpack : bytes > 'a option
pack' : 'a typerep > 'a > bytes
unpack' : 'a typerep > bytes > 'a option
38. Simulation
SCaml.ml: OCaml simualtion of SCaml primitives.
Things to do:
Blockchain state
Semantics of operations
Globals (NOW, AMOUNT, etc)
Must be done
41. Compilation path
Parsing by OCaml parser
Typing by OCaml type checker
Unifying types for entry points and storage
Translation to an IL, pure monomorhpic core ML
(Code with unsupported language features are rejected.)
Optimization
Compilation to Michelson
42. Unifying types for entry points and
storage
Frees us from writing type constraits around
[@entry].
43. Translation to an intermediate language
Convert to IML, an almost pure core ML:
Rejects unsupported OCaml features
Disintegrate OCaml types to binary type combinations
(pairs/sums)
Pattern match compilation
45. Compilation to Michelson
Compilation keeps the SCaml typing environment
and Michelson stack isomorphic.
This makes algorithm simple but stack tends deeper
and deeper.
Some efforts required