What’s New in SnarkyJS: June 2023

Refactor the SnarkyJS code base, improved error messages, and a new interface for ZkPrograms

Barrie Byron
o1Labs

--

This month in SnarkyJS lands in the midst of a deep refactor of the SnarkyJS code base: core modules such as Field and Circuit were rewritten in TypeScript (replacing the previous OCaml implementations). Future releases will include a refactor of other modules like Bool and Group.

For SnarkyJS users, refactors are expected to go by smoothly and largely unnoticed, with the occasional happy surprise such as bug fixes and small improvements. The end result will be a code base that is more maintainable for core developers and more accessible to outside contributors.

Two other improvements have direct impact:

  • Error messages now have their stack traces prettified before throwing them. SnarkyJS has been notorious for its unwieldy stack traces, reflecting the deep multi-language stack it is built on. The O(1) Labs team is dedicated to improving the developer experience and continues this effort by cleaning up stack traces from noisy details that don’t contribute to finding the problem. Expect more error message improvements soon!
  • ZkPrograms have been enhanced with a new interface where you can now return a public output instead of accepting a public input as parameter of each method. The underlying effect is the same, but the new API is more natural in many cases and saves you from duplicating logic in- and outside provable code. Public outputs fit the mental model of proving a computation with some result exposed to the verifier.

A side note on language: The terminology of “circuits” is replaced with “provable code” for logic that eventually gets converted to a zero-knowledge proof. This month’s release reflects the language shift by deprecating the Circuit module, with methods like Circuit.if(), and replacing it with a new namespace called Provable. “Circuits” are an implementation detail for code that could equally well be run in other backend contexts like zkVMs or others that haven’t been invented yet. Moreover, the mapping that “circuit logic” means “provable logic” is unnecessary learning overhead for application developers.

Breaking changes

  • Rewrite of Provable.if() causes breaking changes to all deployed contracts (0.11.0, #889)
  • Remove all deprecated methods and properties on Field (0.11.0, #902)
    - The Field(x) constructor and other Field methods no longer accept a boolean as input. Instead, you can now pass in a bigint to all Field methods. (0.11.0, #902)

Added

  • Add field.assertNotEquals() to assert that a field element does not equal some value (0.11.0, #902)
    - More efficient than field.equals(x).assertFalse()

Changed

  • Make stack traces more readable (0.11.0, #890)
    - Stack traces thrown from SnarkyJS are cleaned up by filtering out unnecessary lines and other noisy details
  • Remove optional zkappKey argument in smartContract.init(), and instead assert that provedState is false when init() is called (0.11.0, #908)
  • Improve assertion error messages on Field methods (0.11.0, #743, #902)
  • Publicly expose the internal details of the Field type (0.11.0, #902)
  • Allow ZkPrograms to return their public output (0.10.1, #874, #876)
    - new option ZkProgram({ publicOutput?: Provable<any>, ... }); publicOutput has to match the return type of all ZkProgram methods.
    - the publicInput option becomes optional; if not provided, methods no longer expect the public input as the first argument
    - full usage example: https://github.com/o1-labs/snarkyjs/blob/f95cf2903e97292df9e703b74ee1fc3825df826d/src/examples/program.ts

Deprecated

  • Utility methods on Circuit are deprecated in favor of the same methods on Provable (0.11.0, #889)
    - Circuit.if(), Circuit.witness(), Circuit.log(), and others are replaced by Provable.if(), Provable.witness(), Provable.log()
    - Under the hood, some of these methods were rewritten in TypeScript
  • Deprecate field.isZero() (0.11.0, #902)

Fixed

  • Fix running SnarkyJS in Node.js on Windows (0.11.0, #19) @wizicer
  • Fix error reporting from GraphQL requests (0.11.0, #919)
  • Resolved an Out of Memory error experienced on iOS devices (iPhones and iPads) during the initialization of the WASM memory (0.11.0, #26)
  • Fix field.greaterThan() and other comparison methods outside provable code (0.11.0, #858, #902)
  • Fix field.assertBool() (0.11.0, #469, #902)
  • Fix Field(bigint) where bigint is larger than the field modulus (0.11.0, #432, #902)
    - The new behavior is to use the modular residual of the input
  • No longer fail on missing signature in tx.send(). This fixes the flow of deploying a zkApp from a UI via a wallet (0.11.0, #931) @marekyggdrasil

To watch

Subscribe to the official O(1) Labs YouTube channel youtube.com/@o1labsofficial.

To read

Guidance for branch compatibility for internal contributors in snarkyjs/README-dev.

To celebrate

We appreciate our community members @wizicer and @marekyggdrasil who contributed fixes.

A special shoutout goes to @yunus433 for working hard on improving doc comments on the Field class.

To contribute

--

--

Writer for

I'm a technical writer at O(1) Labs, a Write the Docs community member, and an advocate for building bridges to deliver technically accurate content.