Browse Source

doc: dao notes

zero 2 years ago
parent
commit
70cce66740
2 changed files with 114 additions and 14 deletions
  1. 109 14
      doc/src/arch/dao.md
  2. 5 0
      doc/src/arch/wallet.md

+ 109 - 14
doc/src/arch/dao.md

@@ -107,18 +107,113 @@ proposal where voting passed the threshold and so on.
 Assuming both contracts validate successfully, the funds are transferred out
 Assuming both contracts validate successfully, the funds are transferred out
 of the DAO treasury.
 of the DAO treasury.
 
 
-## Generalizing DAO Calling Mechanism
-
-Currently the calling params for a contract is just a big binary blob.
-The idea is we introduce some kind of ABI.
-
-Then the DAO proposal would commit to some part of those params that
-we are interested in.
-
-In the final step of `DAO::exec()`, only these params would be checked.
-For more info see
-[DEP 0002](https://darkrenaissance.github.io/darkfi/dep/0002.html).
-
-This would be one way to enable composability, but by no means is it the
-only way.
+# Formalism
+
+Let the $ℂ$ be the category for all sets of coins $C$ with one-way arrows
+$C → C'$ such that $C ⊆ C'$ and an initial object $C₀ = ∅ $.
+We require that arrows with the same source and target commute.
+$$ \begin{CD}
+   C @>c_b>> C_b \\
+@VcₐVV @Vc_a'VV \\
+   Cₐ @>c_b'>> C_{ab}
+\end{CD} $$
+
+We define the nullifier functor $N : ℂ^{\t{op}} → ℕ$ which is an isomorphism
+of $ℂ$ that reverses arrows.
+
+$$ \begin{CD}
+   C @>>> NC \\
+@VcVV @AANcA \\
+   C' @>>> NC'
+\end{CD} $$
+We can see the action of adding $c$ to $C$ (expressed as the left downwards
+arrow) gets lifted to the arrow going backwards in the nullifier category.
+The collection of arrows in $ℂ$ and $ℕ$ then describes the coins and nullifier
+sets which are represented in merkle trees.
+
+From the diagram we see that $C → C' → NC' → NC → C$ so that $Nc$ cancels $c$.
+Pasting diagrams together, we get
+
+$$ \begin{CD}
+   C₀ @>>> NC₀ \\
+@Vc₁VV @AANc₁A \\
+   C₁ @>>> NC₁ \\
+@Vc₂VV @AANc₂A \\
+   C₂ @>>> NC₂ \\
+\end{CD} $$
+where all squares commute. Since all paths in $ℂ$ are one way, proving a
+coin $cₖ : Cₖ₋₁ → Cₖ$ exists is equivalent to being at any state $Cₖ, Cₖ₊₁, Cₖ₊₂, …$.
+
+**Lemma:** If our state is $Cₖ$ then our set must contain the coins
+represented as arrows $c₁, …, cₖ$.
+
+# Anon Voting Mechanics
+
+When making a proposal, we need to prove ownership of a threshold of coins.
+Likewise for voting. Essentially they are similar problems of proving ownership
+of a coin $c$ that is still valid. As showed above this reduces to the following
+statements:
+
+* Is $c$ in the set of all coins $C$?
+* If yes, then is $n(c)$ *not* in the set of nullifiers $N$?
+
+Normally this logic is handled by transfers, but we need to additionally
+check it without leaking info about $c$. Since $n(c)$ is derived
+deterministically, leaking $n(c)$ also leaks info on $c$.
+
+Nullifiers must be checked otherwise expired coins can be used.
+
+## Forking the Global State
+
+The first method involves copying the coins state $C$. Every proof makes use
+of $C$ while revealing $n(c)$ which is checked against the current nullifier
+state. To avoid anonymity leaks from revealing $n(c)$, we additionally move the coin
+using a `Money::transfer()` call.
+
+The downside is that wallets need to:
+
+* Keep track of the coins tree $C$. This will involve logic to periodically
+  checkpoint the incremental tree in a deterministic way.
+* When doing any action, the wallet must move coins simultaneously.
+  Wallets must also keep track of the unspent coin since for example it might
+  be used in another vote (or the wallet makes a proposal and wants to vote
+  with the same coin).
+
+Additionally you cannot obtain a coin then vote. You must own the coin before
+the vote is proposed.
+
+## Forking the Global State (with SMT)
+
+Instead of revealing the nullifier, we instead snapshot the the nullifier
+tree alongside $C$.
+
+The downsides are:
+
+* More expensive for voters since SMT is expensive in ZK.
+* We're taking an older snapshot of the coins state. Spent coins spent after
+  the vote are proposed will still be able to vote.
+
+## Tracking Coins with Local State
+
+Each coin's `user_data` contains an SMT of all proposals they voted in.
+When transferring a coin, you must preserve this `user_data`.
+The `spend_hook` only allows modifying it with a parent call that adds
+proposals when voting to the SMT field in the coin.
+
+The downside for wallets is that:
+
+* The SMT committed to is large and needs to be transferred to receivers
+  when sending the coin.
+    * Alternatively coins could contain a special key (also in the `user_data`
+      field), which when voting you must make a verifiable encryption.
+      That way wallets can later scan all proposals for a DAO to find where
+      their particular governance token voted.
+* It's very complex. For example, can DAOs own governance tokens? So far DAO
+  tokens must have the `spend_hook` set, but with this, we now require another
+  `spend_hook` which preserves the SMT when transferring coins. The mechanics
+  for two parents of a call aren't specified, so we'd maybe have to add some
+  concept of symlinks.
+
+However while complex, it is the most accurate of all 3 methods reflecting
+the current state.
 
 

+ 5 - 0
doc/src/arch/wallet.md

@@ -224,3 +224,8 @@ See also the [Blender Human Interface Guidelines: Paradigms](https://developer.b
 
 
 Steps 3 and 4 can be done in parallel.
 Steps 3 and 4 can be done in parallel.
 
 
+## References
+
+* [Veil: Private Browsing Semantics Without Browser-side Assistance](https://mickens.seas.harvard.edu/files/mickens/files/veil.pdf)
+* [Atlantis: Robust, Extensible Execution Environments for Web Applications](https://scholar.harvard.edu/files/mickens/files/atlantis.pdf)
+