At the end of December 2019, I left Parity to write a voting library with substrate called Sunshine. The project is supported by a grant from the Web3 Foundation. I’m grateful for this opportunity and am proud of the work funded by this grant.

More recently, the project has taken on a new shape based on the emergent needs of the Polkadot/Web3 ecosystem. We’re building a Substrate Bounty Chain! Conceptually, it’s like if Gitcoin and Aragon had a baby and it was a substrate chain.

During the last few months of development, our team has contributed open source infrastructure to the Substrate, Rust, and Flutter ecosystems. This post lists those contributions. We intend to go into more detail on each project on dev.to.

Sunshine Runtime Pallets

Polkadot’s governance is more advanced than any other on-chain governance. For example, the use of Phragmén’s Method to spread the allocation of validator nominations is particularly interesting (see frame/elections-phragmen).

Sunshine aspires to realize a vision for a generic DAO chain. Instead of modules oriented around a single council or treasury, Sunshine’s runtime allows people to register groups, each of which could have its own council, treasury, and, ultimately, direct democracy. Here’s a list of the modules with descriptions of their functionality as of the latest release (0.0.6)

  • sunshine-org - allows groups (Vec<AccountId>) to register such that each member (AccountId) has ownership in the group represented by Shares; each group has an OrgId which is used in other modules to refer to the group and establish ownership over associated state
  • sunshine-vote - enables votes to be dispatched with OrgId members serving as the electorate; vote power may be configurably weighted by ownership or 1 account 1 vote
  • sunshine-court - uses vote to dispatch votes to resolve disputes between two parties; like insurance, one party might only agree to enter into an external contract with the other party if they agree to stake collateral and forfeit that collateral in the event that the dispatched vote resolves against them
  • sunshine-donate - allows any AccountId to transfer funds to an OrgId such that the funds are distributed to the members of the group in proportion to their ownership in the group
  • sunshine-bank - enables orgs to create joint bank accounts with spends governed by group votes
  • sunshine-bounty - allows orgs or individuals to post bounties and govern/supervise execution; also allows orgs or individuals to apply for bounties and submit milestones for payment upon approval

The code can be found in sunshine-bounty/pallets. There’s still lots of room for improvement and I appreciate feedback (via issues/PRs, twitter DMs, email, or smoke signal).

David recently won the surprise category of the Polkadot Launch hackathon with his implementation of Keybase Local Key Security in sunshine-identity.

Substrate-Subxt

Most substrate projects rely on polkadot-js for all encoding/decoding and communication with the substrate node. This is convenient for web apps because it is written in typescript.

Our project knew from the beginning that the browser’s memory and computation limits would not be enough for our ideal, local-first architecture. Likewise, our client is written in Rust and uses substrate-subxt to communicate with the substrate node.

David has made significant contributions upstream to this project, motivated by our application’s requirements. To list a few of his more notable PRs,

  • proc macros to derive subxt clients
  • support for light clients and unit testing
  • fixed bugs related to zero sized types and optional store items
  • support for plain/double-map items

We’re excited to see at least two other Parity projects using substrate-subxt, taking advantage of the features listed above:

Our motivation for using substrate-subxt is a native Rust client. Writing our client in Rust fosters greater flexibility in terms of the application’s

  1. storage
  2. computation

For (1), we refuse to store user private keys in the application state or on Amazon AWS servers. Instead, our keystore stores the user’s keys in the device’s local storage. This allows us to easily rotate keys and support device-based revocability.

(2) is more long-term thinking. The constraints of privacy-oriented cryptography encourage client-side computation because outsourcing computation to servers is often insecure and, at the very least, introduces an access bottleneck. Modern solutions like Private Information Retrieval are computationally expensive (see SealPIR).

Rust-Dart FFI Tools

Instead of calling polkadot-js from a flutter application like Polkawallet, our Flutter interface communicates directly between Rust and Dart. Although this decision required significant upfront investment, it was worth it. The payoff is efficient native applications.

While building our Rust-Dart FFI infrastructure, Shady has done an excellent job separating out components and open sourcing them so that they are useful to the broader Rust and Flutter ecosystems.

  • flutterust is a generic template for using Rust libs from Flutter
  • dart-bindgen is a tool for generating Dart FFI bindings to C Header Files
  • allo-isolate runs multithreaded Rust along with Dart VM (in isolates)
  • frusty-logger is a bridge between the Rust log crate and Flutter debugPrint function

Shady also wrote two blog posts on his work, the first of which went viral!

  1. Dart Meets Rust: a match made in heaven
  2. Dart and Rust: the async story

Ipfs-Embed

Mobile application constraints motivate a single backing database instead of two databases. Likewise, our application shares its backing sled db between the light client and an embedded ipfs node.

Ipfs-Embed was written by David. To supplement this project, he’s written lots of generally useful code under the IPFS-Rust organization. To list a few repos,

  • netsim-embed is a rewrite of netsim that intends to be runtime agnostic and currently works with the smol runtime; it will be useful for network simulation in general and nat traversal in particular
  • rust-ipld is a library for content addressable data storage formats
  • ipld-block-builder provides an easy-to-use API for storing data in ipld blocks
  • tiny-multihash is a stack-based multihash implementation (so no allocations); it also supports no-std and provides a proc macro for custom codes

Looking Ahead

Open source funding is still a very hard problem. Our team will be forever grateful to the Web3 foundation for giving these projects life by affording us the opportunity to build them. I look forward to continue giving back to the Web3/Polkadot ecosystems through open source contributions as well as our commercial product (substrate bounty platform).