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.
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
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 (
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
OrgIdwhich is used in other modules to refer to the group and establish ownership over associated state
sunshine-vote- enables votes to be dispatched with
OrgIdmembers serving as the electorate; vote power may be configurably weighted by ownership or 1 account 1 vote
voteto 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
AccountIdto transfer funds to an
OrgIdsuch 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
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
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).
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.
flutterustis a generic template for using Rust libs from Flutter
dart-bindgenis a tool for generating Dart FFI bindings to C Header Files
allo-isolateruns multithreaded Rust along with Dart VM (in isolates)
frusty-loggeris 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!
netsim-embedis a rewrite of netsim that intends to be runtime agnostic and currently works with the
smolruntime; it will be useful for network simulation in general and nat traversal in particular
rust-ipldis a library for content addressable data storage formats
ipld-block-builderprovides an easy-to-use API for storing data in ipld blocks
tiny-multihashis a stack-based multihash implementation (so no allocations); it also supports no-std and provides a proc macro for custom codes
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).