On-Chain Tally: DAO v1.1 Limits and a Deposit-Paired Voting Proposal

The quote describes DAO v1.1, not the full CKB story.

In DAO v1.1, the latest vote, the latest binding, and the DAO weight at the snapshot must be reconstructed from history rather than read from live cells, so the tally remains off-chain.

The proposed Deposit-Paired Voting design keeps decisive state in live cells and validates it during state transitions.

Summary

  • Off-chain tally: works when the operator role and recomputation path are explicit.
  • Recomputation: independent off-chain recomputation is not the same property as self-contained on-chain tally.
  • DAO v1.1: improves auditability over DAO v1.0, but does not support self-contained on-chain tally because decisive state is still reconstructed off-chain.
  • Missing proofs: latest-state completeness (proving no later vote or binding superseded the counted one) and snapshot-time DAO liveness, not arithmetic.
  • Requirement: self-contained on-chain tally needs proposal state, voter control state, and deposit binding to live in cells that protocol rules validate.
  • Proposal: Deposit-Paired Voting keeps proposal state, controller state, and deposit binding in VoteMeta, VotingRightOwner, and VotingRightOwned. It derives a time-independent, proposal-independent protocol weight from the backing deposit in cell_deps, the deposit’s creation header, and fixed genesis accumulated rate AR_0.
  • Costs: one proposal-wide serialized update lane, one per-voting-right serialized update lane, parked-deposit custody, and a one-pending-vote confirmation model.

What Self-Contained On-Chain Tally Requires

Self-contained on-chain tally on CKB requires a small set of properties:

  • authoritative proposal state in live cells validated by protocol rules
  • authoritative voter control state in live cells validated by protocol rules
  • an explicit, locally verifiable binding between voting power and the backing asset in the current transaction
  • voting weight derived from a script-verifiable deposit, its creation header, and fixed genesis AR_0, rather than reconstructed from raw DAO liveness at vote end
  • delegation, if retained, validated by current transitions rather than reconstructed later
  • finalization rules that use only inputs, deps, headers, and since relations that CKB can actually verify through header_deps, ckb_load_header, and the since verification rule

In every case, authoritative state must live where CKB validation can read it. CKB can read specific inputs, cell_deps, headers named in header_deps, and since locks. It cannot read the full live cell set from a block header alone.

How DAO v1.1 Produces a Result

DAO v1.1 reaches a result by rebuilding state off-chain and then summing it.

The result path in build_vote_results does five things:

  1. Loads latest vote rows from all_votes. Before that step, the vote indexer has already reduced history to one latest row per address through query_all_votes and query_vote_records_by_epoch_opt.
  2. Applies the duplicate-row guard, which invalidates any ckbAddress that appears more than once in the all_votes response.
  3. Expands bindings and stake through get_weight.
  4. Applies the bound-address override rule through the self_weight_addr_set filter.
  5. Sums the resulting weights into per-candidate totals.

That tally depends on five separate claims:

  1. The vote indexer supplied the correct latest vote rows.
  2. The binding indexer supplied the correct latest binding state before vote end.
  3. The DAO indexer supplied the correct live deposit weights at the snapshot height.
  4. The bound-address override rule was applied correctly.
  5. The arithmetic is correct.

Only claim 5 is a direct arithmetic check once the counted state is fixed. The other four are reconstructed-state claims about which state may be counted.

Why DAO v1.1 Still Depends on Off-Chain Reconstruction

DAO v1.1 cannot move tally on-chain because it cannot prove final vote state, current binding state, and snapshot-time DAO liveness.

1. Vote changing turns tally into a latest-state claim

Once votes and weights can change, tally requires proof that no later change superseded the counted state before vote end.

The DAO v1.1 vote-changing requirements explicitly allow vote changing, vote cancellation, and dynamic weights. The verified tally path uses query_vote_records_by_epoch_opt, get_weight, and query_dao_stake_until_height to reduce votes to latest indexed rows and apply weight snapshots at vote end.

The vote indexer makes that latest-state choice: it scans vote outputs in vote mode, vote_output_handle inserts them into vote_record, and query_vote_records_by_epoch_opt reduces them to one latest row per address. That remains an off-chain completeness decision.

2. Existing vote cells do not provide stable tally inputs

Current vote cells are not stable tally inputs. They are built for vote submission, not later self-contained aggregation.

Current vote-building clients create vote cells with lock: voteAddr.script in both the standalone user-vote transaction builder and the frontend voting transaction builder. The contract separately checks that VoteProof.lock_script_hash matches an input lock hash.

After the fact, an on-chain tally has only two options:

  • consume vote cells as inputs: every voter must sign the tally transaction
  • reference vote cells through cell_deps: the tally transaction needs no voter signatures, but every referenced dep must still be live at validation

The second option races with ordinary spending. If the tally builder selects vote cell V as a cell_dep and the voter spends V first, the tally transaction fails because resolve_transaction rejects dead outpoints while resolving deps.

Historical proof can show the vote transaction and its witnesses against a block header, but not the previous output lock scripts. Raw transaction inputs contain only previous_output and since, not those lock scripts. A TX-in-witness approach that keeps the current rule also needs proofs for the referenced input cells and their lock scripts.

3. Binding state is reconstructed off-chain

Binding state is also reconstructed from indexed history, not read from live protocol state. The address-bind indexer reads witness-carried bind data in verify_tx, stores it in bind_info while blocks are scanned, and answers queries through query_by_to_at_height.

An on-chain tally can derive “latest binding before vote end” only if binding becomes live state validated by protocol rules, or if the tally accepts an external completeness assumption.

4. DAO weight at vote end depends on snapshot-time liveness

Snapshot-time DAO liveness also remains off-chain, because CKB headers do not commit to the live cell set.

The CKB RawHeader schema includes transactions_root, proposals_hash, extra_hash, and dao, but no Ethereum-style state root. The transactions_root calculation commits to merkle_root([raw_transactions_root, witnesses_root]), not the live cell set.

A header alone cannot prove that a deposit cell was still live at snapshot block H. That is enough for audit-oriented recomputation, but not for a self-contained on-chain tally of raw DAO-backed weight.

What DAO v1.1 Publicly Claims

DAO v1.1 publicly claims independent off-chain recomputation, not self-contained on-chain tally.

Docs: DAO v1.1’s public docs frame the target as independently verifiable results. The same docs define address weight in terms of Nervos DAO stake, take the voter list source from DAO stakers, and later filter that list to DID users. That framing matches independently recomputable off-chain tally, not self-contained on-chain tally.

Forum claim: The public claim that anyone can recompute the tally without a centralized API still describes off-chain recomputation, not self-contained on-chain tally. Recomputing the result still requires rebuilding the same off-chain latest-state pipeline: latest vote rows from query_vote_records_by_epoch_opt, latest binding state from query_by_to_at_height, and DAO stake snapshots from query_dao_stake_until_height.

Implementation boundary: The implementation also requires proposal-time latest VoterList selection, VoteMeta SMT-root construction in build_vote_meta, and backend proof issuance through get_proof and prepare before a user can submit a vote. Those steps still shape who can vote and what proof the vote carries.

Deposit-Paired Voting Proposal

Deposit-Paired Voting is a proposed design that moves decisive state into live cells without minting a separate voting token.

State Model

The proposal keeps state in three live cell types:

  1. VoteMeta: a proposal cell
  2. VotingRightOwner: a user-owned controller cell
  3. VotingRightOwned: a protocol-locked backing DAO deposit cell

A VotingRightOwner and VotingRightOwned together form one voting-right pair.

  • VoteMeta stores the confirmed tally, one pending vote slot, the deadline, the open or final state, and proposal identity after the first vote or close
  • VotingRightOwner stores owner authority, optional delegate authority, the paired backing outpoint, and per-proposal entries
  • VotingRightOwned holds the parked DAO deposit and enforces custody only

Ordinary vote updates consume and recreate VoteMeta and VotingRightOwner. They do not move the backing deposit.

Proposal id: Each proposal needs a stable id that survives VoteMeta recreation. The initial VoteMeta stores no proposal id. The first vote or close transaction reads the consumed input’s previous_output, copies that creation OutPoint into the recreated VoteMeta, and later updates preserve it.

Custody: VotingRightOwned enforces only custody invariants: the backing deposit stays paired to one controller, cannot be redirected, and can be released only through the paired release path.

Initialization and Binding

Voting-right creation must establish the pair once and keep it stable afterward.

Voting-right creation uses one transaction:

  • create VotingRightOwned as a fresh DAO deposit under Deposit and lock it with the voting-right logic
  • create VotingRightOwner in the same transaction and pair it with that deposit

Existing deposits: If the user starts from an existing user-controlled DAO deposit, it must go through the normal Withdraw Phase 1 path and then be redeposited under the voting-right lock. Deposited input handling shows that a deposited DAO input cannot be re-locked directly into another deposited cell.

Pair binding: The creation transaction can link the pair by output position. Later vote and revote updates bind it by the committed OutPoint, so the backing deposit cannot be swapped behind the controller.

Proposal creation: A proposal starts as a fresh VoteMeta with no stored proposal id, a deadline, zero confirmed tally, an empty pending vote slot, and open state.

Authority and Release

Each cell validates the invariant it owns:

  • VoteMeta owns proposal identity, tally updates, pending-vote confirmation, and the open -> final transition
  • the voting-right logic owns correct pairing of VotingRightOwner and VotingRightOwned, weight derivation from the parked deposit and its creation header against AR_0, and custody of the parked deposit
  • the owner or delegate path owns vote and revote updates to per-proposal entries and delegated voting authority

Delegation: A delegate may cast and revote on behalf of the owner, but cannot redirect the backing deposit, release the voting right, or perform unrelated state changes.

Release: VotingRightOwner and VotingRightOwned are consumed together. Release succeeds only when every proposal entry recorded in VotingRightOwner is already past its deadline under the transaction’s encoded since threshold. CKB enforces that threshold under the since verification rule and verify_absolute_lock. Release does not depend on a third party closing every touched proposal. It depends only on whether all proposals previously touched by that voting right are past their deadlines.

Derived Weight and Verifiable Timing

The design derives weight and proves timing without snapshot-time DAO liveness.

Weight rule: Weight is neither the current withdrawable CKB amount at vote end nor a value stored in VotingRightOwner. Each calculation derives it from the backing deposit in cell_deps and its creation header. The DAO accumulated-rate formula defines AR_i and genesis AR_0 : 10 ^ 16, and CKB’s maximum withdraw formula uses the same ratio. With genesis normalization, the sketch is:

weight(counted_capacity, AR_m) {
    return counted_capacity * AR_0 / AR_m
}

Consequence: The protocol weight does not vary with later time or with the proposal being voted on. That said, User Interface can still show the deposit’s current withdrawable amount.

Runtime loading: The creation transaction can pair VotingRightOwner with VotingRightOwned, but it cannot compute voting weight because it cannot load its own inclusion header. CKB scripts read only explicit header_deps. They load creation headers through ckb_load_header from referenced inputs or cell_deps. A later vote, revote, or close transition must include the backing deposit in cell_deps, load its creation header, and derive weight there against fixed genesis AR_0.

Because a vote transaction cannot prove its own deadline position at submission time, VoteMeta carries the confirmed tally plus one pending vote slot. The pending slot stores the VotingRightOwner identity and the pending choice.

Vote and revote: vote and revote consume VoteMeta and VotingRightOwner. They keep VotingRightOwned parked, verify the pair through the backing deposit in cell_deps, and derive weight from the deposit’s creation header against AR_0. If the consumed VoteMeta was created before the deadline, the previous pending vote is confirmed into the tally. If it was created after the deadline, that pending vote is discarded.

Close: close consumes VoteMeta, proves finalization timing under the since verification rule and verify_absolute_lock, reloads the pending VotingRightOwner and backing deposit from cell_deps, derives the last pending vote’s weight against AR_0, and moves the proposal from open to final.

The one-pending-vote model follows directly from what a vote transaction can and cannot prove about its own inclusion time.

Why It Fits the On-Chain Tally Requirements

Against the requirements above, the proposal stores proposal state, controller state, and deposit binding in live cells, then validates timing and weight during each transition.

Compared with DAO v1.1:

Dimension DAO v1.1 Deposit-Paired Voting
Vote state Reconstructs latest vote state off-chain Stores current vote state in live cells
Binding state Reconstructs latest binding state off-chain Stores an explicit controller-to-deposit pair in live cells
Weight derivation Needs raw DAO snapshot liveness at vote end Derives the same protocol weight from the backing deposit and its creation header against AR_0 in each transition that needs it
Result assembly Relies on an off-chain tally job to assemble final state Updates tally state inline in VoteMeta
Delegation and binding Treats delegation and binding as off-chain interpretation Validates both during current transitions

The arithmetic rule stays the same. Deposit-Paired Voting moves authoritative state into live cells.

Tradeoffs and Limits

Deposit-Paired Voting still makes some Tradeoffs:

  • one proposal-wide serialized update lane through VoteMeta
  • one per-voting-right serialized update lane through each VotingRightOwner
  • the backing DAO deposit stays parked in VotingRightOwned while the voting right exists
  • a pending vote becomes confirmed only when a later vote or close resolves it

Conclusion

The limit is not CKB: tally follows the deciding state.

In DAO v1.1, that means off-chain tally, plus all the off-chain complexity that comes with it.

Deposit-Paired Voting is a proposed design that flips that setup. Put the deciding state in live cells. Then the tally can live there too: no separate voters whitelist, no off-chain reconstruction stack to run, no snapshot-time DAO liveness requirement.

Such is the difference between a system independently verifiable and one that lives on-chain.

6 Likes

非常简单直接的full onchain 投票方案。

这个方案理论上是可行的,但是落地到真实场景会有非常多的问题。

问题太多了,这个输入框根本放不下,所以我只会提最重要的3个问题:

  1. 投票状态放在vote meta cell里。这会有cell竞争的问题,两个人同时投票一定会有一个人失败。
  2. 投票交易的构造太复杂了,gas费会非常高。
  3. 现有的NervosDao质押cell必须进行一次转换。这意味着Neuron,JoyID,CKB Explorer等等NervosDao相关的生态工具都需要进行适配,这完全不现实。

也许在ckb底层还存在更多的限制导致该方案不可行,比如header deps的数量,cell的大小等。这个需要core team进行确认。 @quake @xjd

1 Like

Hey @david-fi5box, glad it picked your interest!

Yup, thank you for picking it up!! It was briefly mentioned in Tradeoff section, but merits a deeper analisys:

  1. State contention is not a road blocker for voting at the current levels of participation, worst case scenario a user just need to sign again a tx :white_check_mark:
  2. State contention tho is an issue for DoS potential: attacker can keep busy the VoteMeta cell, effectively denying participation of others to the vote :cross_mark:

As you are well aware this is a problem felt by deeply by the entire ecosystem, so much that we had over the years attempts over attempts to fix it, namely Intent Cells, Open Transactions and (weird but intriguing) PoW gated access to cells:

  • PoW gated access to cells is still in the ideation phase, needs research
  • Open Transactions would be the cleanest solution: we have working designs, but what’s currently lacking is EcoSystem agreement.
  • Intent Cells are the best candidate: user transforms VoteRightOwner into an intent cell by using a special lock on it (very similar to Delegation in this model) and an aggregator makes sure that his vote is included.

Side Note: user can choose which Lock he prefers, we don’t need to force everyone to use Intent Cells (nor Delegation OFC). Again, if he so prefers, a user can just keep signing again until his vote is included.

Not really a thing:

  • VoteMeta just store little constant information: not who voted, but what is the aggregated result and small Vote meta information
  • VotingRightOwner stores more information: there must be an entry for each vote participated to. That said, this entry can later on be garbage collected once the vote ends, so it doesn’t grow indefinitely and it’s proportional to the number of active votes at a certain moment.

We have the following trade-offs:

  1. Want to keep current deposits? → Fully off-chain system, doable, tricky part is to make sure it’s auditable, transparent and operator resistant.
  2. Want to have an elegant simple verified on-chain system? → You need to put a special lock on those deposits, hence withdraw and re-deposit.

Anything in the middle and you get way more complexity than you bargained for.

Yesterday I was explaining @chenyukang the reasoning underpinning the presented design:

Back to us

Thank you for the feedback @david-fi5box, keep it coming :hugs:

Phroi

PS: If you prefer, I can transform this design sketch into code and we can test it out together

2 Likes

From the perspective of researching technical solutions for a full on-chain voting system alone, I am quite willing to continue exploring this approach. In fact, I have discussed potential solutions to cell conflicts with many CKB developers, including the core team, developer relations, and developers from other ecosystem partners.

There are also many details within the specific solution that can be elaborated on. For example, DAO tokens staked by users may be distributed across multiple addresses, as well as across multiple cells under a single address—how can these cells be aggregated to avoid off-chain weight indexers; if multiple proposals are being voted on simultaneously, whether this solution allows users to cast votes on multiple proposals at the same time, and so on.

However, regarding the DAO 1.1 technical solution, I believe the three issues I mentioned earlier are already serious enough.

Of course, this is related to the project positioning of DAO 1.1.

I previously mentioned in another locked post that the foundation’s original plan was to go directly from DAO 1.0 to DAO 2.0. However, DAO 2.0 was delayed due to discussions triggered by the delegation system. Therefore, the initial goal of DAO 1.1 was to use relatively conservative and mature technology to complete a deployable system as soon as possible to replace Metaforo.

A specific example is our earlier discussion about the keystore. We initially designed a very streamlined private key custody solution, but it required wallet providers to make corresponding modifications. Because this would lead to unpredictable project delays, we had to adopt the solution that everyone sees now.

I’d also like to take this opportunity to briefly explain for NightLantern from another recently locked post.

The DAO 1.1 team members are indeed feeling quite frustrated right now. However, this is not because you or others pointed out problems with the DAO 1.1 project—a truly professional programmer feels pleased, not angry, when someone identifies bugs in their code.

Rather, it’s because I am certain that some people in the community are aware of the story behind the DAO 1.1 project and the various constraints we face. Yet during community discussions, they chose not to come forward and explain the situation.

To use a perhaps imperfect analogy: your neighbor suddenly falls ill in the middle of the night, and to get them to the hospital in time, you exceed the speed limit and run red lights. But when you want your neighbor to help explain the situation to the police to avoid your ticket, their response is: every citizen should obey traffic rules.

1 Like

I believe the version numbers 1.0, 1.1, and 2.0 already clearly indicate the project’s positioning. If we haven’t aligned on the project positioning, I find it meaningless to discuss the technical solution.

And discussions about project positioning have already gone beyond the scope of technology—I am currently waiting for updates. If the positioning of DAO 1.1 is not what I initially understood, I think starting a new project from scratch would be a better choice.

I suggest you open a separate thread to discuss the technical solution, without tying it to DAO 1.1.

By the way, I’ve noticed that discussion threads related to DAO 1.1 have a very high probability of being locked.

Rather than diving into technical specs, I want to talk about software engineering. I’ve spent 20+ years building software—both To B and To C. But the CKB community introduced me to something new, which I’ll call “To Community.”

In software engineering, locking down requirements is critical—it drives every downstream decision. In To B and To C, requirements are determinate. Even when end-user needs are fuzzy, someone owns the process of clarifying them, so at least for one sprint or cycle, the team knows what to build. To Community flips this. Requirements remain indeterminate. A proposal can pass, yet at delivery, voices pop up saying “this isn’t what we actually wanted.” In traditional settings, that’s a change request—you go back to the stakeholder, renegotiate, adjust. In CKB? There’s no single person accountable for requirements. So the project stalls. No one knows what “done” looks like.

What’s your take? If Rosen Bridge faced this, how would you handle it?

P.S. An AI told me: “You may need to redefine success. In To Community, ‘sustainable relationships’ might matter more than ‘shipping the right feature.’” :frowning:

2 Likes

@matt_ckb Hi Matt, Phroi and I have been discussing possible alternatives in this thread. If you have any suggestions, feel free to post them here as well.

However, so far, I don’t think the solution provided by Phroi can serve as an alternative to DAO 1.1.

First, there are the unresolved technical issues mentioned earlier.

More importantly, it’s about the goals and positioning of DAO 1.1. I believe the current technical solution of DAO 1.1 is optimal and is based on the content of the DAO 1.1 proposal that has already passed community voting.

But from last month until now, much of the discussion has actually gone beyond the content of the DAO 1.1 proposal, including this alternative solution.

From its version number alone, DAO 1.1 is clearly a minor improvement to DAO 1.0 (Metaforo). Therefore, it does not involve changes to meta-rules and must inherit many legacy rules and limitations from DAO 1.0 (Metaforo).

Take this alternative solution here, for example—it requires users to convert their existing NervosDao stake cells. Isn’t this a meta-rule modification? It requires wallet and browser adaptations. Can this be delivered within just a few months?

If the premise for discussing alternative solutions now is that these constraints no longer exist, then I don’t think this is the DAO 1.1 proposal anymore. Perhaps a new proposal should be initiated and voted on again.

@matt_ckb Yes, I also think the whitelist is a huge misunderstanding. But on the contrary, I don’t think we are the ones who misunderstood.
No matter what you call it—whitelist or any other term. DAO 1.1 does not change the boundaries of voting eligibility.
1.In DAO 1.0, only those who have staked in NervosDAO have voting weight. DAO 1.1 maintains consistency with this.
2. In DAO 1.0, address binding can be used to bind the stake from Neuron wallet to a voting address. DAO 1.1 maintains consistency with this and has implemented more detailed checks for duplicate weight calculations.
3. DAO 1.0 requires logging into Metaforo to vote. DAO 1.1 requires registering a DID to vote. I believe this is equivalent and does not change the boundaries of voting eligibility. Moreover, as I mentioned in my previous reply, Metaforo is a centralized system—if the server goes down, users cannot log in. However, DID is an on-chain identity system; as long as you have a wallet, you can register, and it has no relation to the DAO 1.1 system.

@matt_ckb There is another risk of making large-scale technical changes late in the project that I must remind everyone of.
Community members may suspect that the team is using technical changes as a pretext to slip unreviewed and unvoted proposals into an already approved proposal, thereby bypassing community voting.
I recommend starting over from project positioning, goals, and requirements, and then deriving the technical solution to be used. This is also standard software engineering practice when facing requirement changes.

@matt_ckb By the way, when I said earlier that I was disappointed with certain people, I wasn’t referring to any specific individual—not Jan, not Terry, certainly not Phroi, not anyone in particular. Rather, as I mentioned in my post about software engineering, if a proposal can pass a vote, it means the majority supported it. But in the subsequent discussions, I only saw voices of opposition, with no voices of support. It’s like I took on a project, but when it was almost ready for delivery, the person who placed the order disappeared.

Of course, there may be an issue of the “silent majority” here, but I haven’t seen any measures or rules from the community in this regard.

DAO 1.1 can fail—it was originally an attempt at community governance. However, I hope the community can pay attention to the issues exposed throughout this process.

1 Like

hi @david-fi5box Let me start by saying, that the reason that 1.1-related threads are getting locked is from them straying far from the topic they started with. That is the case here, but I will manage one thing at a time.

This is a topic for discussing alternatives, I do believe that our process would be served by discussing the challenges with implementing proposed ideas and how they might be improved in this respect.

White list comment


this refers to the conversation in January and everything that followed.

”I’m haoyang, one of the DAO steward team member, yeah the name does sound scary :sweat_smile:, but I can assure you that this is just a naming issue, it works like this:

the “whitelist” is to speed up this process so testers (like me) can start testing without waiting. We just finished a meeting and agreed that the name is quite misleading, maybe “voter snapshot” would be better.”

The response from the 1.1 team was not appropriate for the concern and the team bears responsibility for this. If this were handled differently, we would have been having this conversation 3 months ago, in a very different context.

While the 1.1 team is justified in feeling that their work is being unreasonably criticized, it is important to understand that there is a relationship between current and past events.

Centralized vs Decentralized

This comment is problematic. If the 1.1 server is down, users cannot register, nor can they get their SMT proofs to be able to vote. It is this contradiction between centralized and decentralized which is causing such an issue.

If the system were centralized, responsibility would be clear. With v1.1, it is not, after all things are “decentralized.”

While I greatly respect the effort and intention that has gone into v1.1, the “take it or leave it” kind of attitude I see is more indicative of producing a deliverable, rather than operating a product/platform.

We need to make sense of this centralized vs decentralized thing.

Looking forward

As Baiyu said in Telegram

“In fact, we also hope that the community can propose a more decentralized solution that does not require major changes to the current approach, and we would even be willing to extend the development period by one or two months for this purpose.”

This is the kind of attitude that is needed here, I understand your role as technical lead makes you protective of the implementation, and it may be the case that large scale changes would be needed to accomplish certain objectives.

However, we don’t know that without exploring the alternatives, and presuming changes would be extraordinary makes it more difficult to work through the process of assessing how issues raised might be addressed (whether today or in the future).

In a recent poll in Nervos Nation, 57% of responders supported the implementation as is. People want to see progress. I can understand that you probably feel the same way.

However we should consider that no voices in that silent majority are expressing that they disagree strongly with the issues being raised. The art is in balancing all of this.

Overall I believe “the community” will look at the entirety of this as yet another example of the challenges the project faces in executing. We can only make the best decisions we can today with what we know now.

Looking forward to working on fixing things.

Hey @david-fi5box, sorry for the delay :hugs:

Hopefully not our dev-to-dev exchange of views!!

Workable trade-offs? Maybe?

That voter whitelist tho: before I even mentioned it, every single kind of technical reviewer I talked with (human, Opus 4.6 max & GPT 5.4 xhigh), flagged it as serious concern.

TBH I’m surprised that it got past the design stage assessment, internal review (been there too with iCKB) and everybody else until I pick it up by chance, reading the docs.

You know, in the good old days, a couple times I (unwittingly) tried to sneak in a centralization point in iCKB design and my reviewer (politely but firmly) talked me out of it.

This is how I was developing iCKB in the open:

Wait wait, meta-rules part seems incorrect.

Voter whitelist (SMT-based, requiring Web5 DID registration + daily snapshot inclusion), it was not described in the governance rules voted on by the community. The proposal’s voting section states:

Voting power is based entirely on the user’s CKB deposits in the Nervos DAO, continuing the direct weighted voting model of v1.0.

The only mention of “whitelist” is a sub-item in the development cost table:

对提案投票 | 投票白名单收集、创建投票Cell、构造并发送投票交易、投票后的Cell处理、权重统计等 | 12000

(Voting on Proposals | Voting whitelist collection, create voting Cells, construct/send voting TXs, post-vote Cell processing, weight calculation, etc. | $12,000)

No description of what the whitelist is or how it restricts eligibility. This line was present unchanged since the original post on Sep 4, 2025 (verified across all 21 proposal revisions).

Under the DAO rules, changes to voting eligibility are meta-rule changes requiring 67% approval and 185M CKB quorum.

No such vote was held for this mechanism.

A new user cannot join an on-going vote, making them non eligible for that vote.

Incidentally, this is also one of the main drivers for participation and new user accounts creation.

May I ask you to quote which one?

Let me take Rosen Bridge as an example: we have a solid Technical Analysis, explaining all trade-offs and technical choiced made.

Not only that, as you may have noticed, I also briefly explained in the post all the technical choices, that other devs may consider trade-offs.

A similar analysis and brief explanation would have helped greatly communicating DAO v1.1 to the Community and asking for technical feedback before delivering the prototype.

DAO v1.1 Communication about technical choices would have been even more crucial:

  • Community Fund DAO v1.1 is at a way higher level of public interest
  • Rosen Bridge is important for DeFi EcoSystem development, but you don’t need to use it to get public funding

No worries, we will figure it out! Let’s stress test this thing called Community DAO :flexed_biceps:

Phroi

1 Like

@phroi @matt_ckb

Hi Phroi, I noticed your stance has changed—you previously kept asking us to remove the state root from the voting contract so that everyone could participate in voting. So I’ve been confused: doesn’t the meta-rule state that only those with stakes in NervosDAO have voting rights?

Glad to see our communication is finally making substantive progress.

So the current focal point is: does DID create a barrier for users who should have voting rights to participate in voting?

Clearly, our understanding of the meta-rules is inconsistent.

I don’t understand: why is requiring users to create a DID considered a barrier to their voting rights, while the alternative solution phroi proposed—requiring users to change the lock on their existing NervosDAO staked cells—is not considered a barrier?(phroi can comment if it’s not correct)

Of course, this issue has already gone beyond the technical scope. I’m not an expert on DAO rules; I’m just raising questions in my personal capacity.

But clearly, this is a very serious issue involving the fundamentals of DAO governance. I cannot make changes immediately upon hearing someone’s opinion, even if that person is Matt.

Please forgive my stubbornness, but on this issue, I must see a more formal conclusion.

Regarding DID, the DAO 1.1 project stated from the very beginning that it would use Web5 technology. Matt was present at the first AMA and even raised related questions, which the team answered. By the way, Phroi did not attend any of the AMAs.

Of course, some people may not have fully understood Web5 technology, but the slogan “Web5 = Web2 + Web3” should be widely known. Jan published three articles about Web5 six months before the DAO 1.1 project started (I’m not citing Jan as endorsement here, just stating objective facts).

So when Matt said at the M2 milestone of DAO 1.1 that those who voted in favor of DAO 1.1 actually wanted a fully on-chain voting system, I find it hard to agree that this represents community consensus rather than the personal views of certain individuals.

Finally, a word about my personal feelings.

I’m just the technical lead of the DAO 1.1 team. I report to and am accountable to the leader of the DAO 1.1 proposal team.

When discussing governance rules beyond the technical scope, I’m just an ordinary community member and do not represent the DAO 1.1 team.

Similarly, I believe Matt overstepped boundaries by bypassing the leader of the DAO 1.1 proposal team and directly pressuring me to accept the so-called alternative technical solution.

Of course, this is a community project, and I have an obligation to answer community members’ technical questions. But I must say, over the past month, I’ve spent a great deal of time replying on the forum, which has significantly impacted development tasks—including the occupation of my personal time and energy, as well as team members’ concerns about the project’s prospects. Meanwhile, during the DAO 1.1 project, we held 6 AMAs, four of which had no attendees at all.

To summarize:

  1. Regarding the issues with the DAO 1.1 proposal, I need a more formal conclusion.
  2. Regarding communication and discussion, I hope for a more focused and efficient approach.

我发现论坛的翻译插件有的时候会翻译错,所以我把中文版本也贴出来:

Hi phroi,我发现你的观点变了,你之前可是一直要求我们去除投票合约里的state root,以便让所有人都能参与投票。所以我一直很困惑,元规则里不是说了只有在nervos dao里有质押才有投票权吗?
很高兴看到我们的沟通终于有了实质性进展。

所以现在问题的焦点是: did 是否对本应有投票权的用户参与投票产生了阻碍?

显然我们对元规则的理解是不一致的。
我不明白:为什么需要用户创建一个did就是对用户的投票权设置了阻碍,而phroi提的替代方案里,需要用户把现有的nervos dao质押的cell换一个lock就不是设置阻碍了?

当然这个问题已经超出技术的范畴了,我不是dao规则方面的专家,只是以个人身份提出疑问。
但是显然这个问题非常严肃,涉及到dao治理的根本,我不可能随便听到一个人的意见就立即做出改变,即使提出意见的人是matt。
请原谅我的固执,关于这个问题我必须看到更加正式的结论。

另外关于 DID,dao1.1项目在一开始就声明了要使用web5技术。第一次AMA的时候matt也在场,还提出了相关的问题,团队也给出了解答。顺便一提,phroi没有参加任何一次AMA。
当然可能还有人没有详细了解web5技术,但是 web5 = web2 + web3 这个slogan应该是众所周知的。jan发布了3篇关于web5的文章可是在dao1.1项目开始半年以前的事情(此处没有拉jan背书的意思,只是陈述客观事实)。
所以matt在dao1.1已经到达M2的的时候,才说对dao1.1投赞成票的人其实是想要一个 full onchain的投票系统。我很难认同这是社区的共识,而不是某些人个人的想法。

最后说下我个人的感受。
我只是dao1.1团队的技术leader,我向dao1.1提案团队的负责人汇报并负责。
在讨论超过技术范畴的治理规则的时候我只是一个普通的社区成员,不代表dao1.1团队。
同样的,我认为matt越过dao1.1提案团队的负责人直接向我施压,要求我必须接收所谓的替代技术方案也是越界的。
当然这是一个社区项目,我有义务答复社区成员关于技术方面的疑问。但是我不得不说,最近一个月我把大量的时间花费在论坛的回复上,对开发任务产生了很大的影响,包括我个人时间和精力的占用,也包括团队成员对项目前景的担忧。但是于此同时,在dao1.1项目进行过程中,我们举办了6次AMA,其中四次一个人都没有。

最后总结一下:

  1. 关于dao1.1的方案存在的问题,我需要更加正式的结论
  2. 关于沟通和讨论,我希望能有更加集中的,更加高效的方式。
1 Like

I still insist that the discussion of the new technical solution be opened as a separate post.

  1. The DAO 1.1 discussion has been mixed with a large number of non-technical factors. So far, I still don’t see any connection between the new technical solution and DAO 1.1.

  2. This is a technical topic that many people are paying attention to. Therefore, it shouldn’t be just the two of us discussing it—more technical personnel should be invited to participate in the discussion. As far as I know, the core team has tried almost all technical solutions. And the technical solution currently adopted by DAO 1.1 also comes from one of the core team’s technical solutions. (Again, this is not citing the core team as endorsement, just stating objective facts.)

I am going to attribute things at this point to miscommunication, there doesn’t seem to be any connection between what each party is saying any more.

I have just about lost faith in this dialogue but I’ll continue to play since things are raised here that are quite concerning.

What does this refer to? I have never expressed anything to this effect. Did you see this message in the Telegram chat you referenced previously?

I did actually raise a question around the idea of does it make sense to publish votes to the chain in one of the Twitter AMA’s, This was new information that came out in the AMA, it was not published anywhere previously. I don’t remember being satisfied with the answer, those were long sessions where there was little actual productive discussion about points of disagreement.

However the bigger issue here is clearly that little was known about what you were actually going to implement (based on proposal docs) when these AMA’s were held.

No solution has been proposed yet that I could pressure you to accept. I have been trying to have a conversation about the issues that myself and others have raised over the last 3 months and what the options might be to improve things.

My conversations with Baiyu have been quite positive and productive, it is truly unfortunate that you are playing this role. While I appreciate the time you are taking to participate in this process, please understand that many of us have also given quite substantially of our time here.

Hey @david-fi5box, I feel like our words are getting past each other

DID clearly maps to creating an account on MetaForo, no trouble at all with that, issue is with the technical choice of using whitelist due to its centralization vector.

Forgetting for a second the centralization vector, the difference is still subtle but substantial:

  • In DAO v1.1 a user can be explicitly forbidden by design from participating in an existing vote. I can have a pre-existing deposit, but still being blocked from voting on a proposal: Didn’t create a DID in time? Excluded from whitelist, so not eligible to vote :cross_mark:
  • For example, in Deposit-Paired Voting a user can at any time withdraw its old deposit and participate in a Deposit-Paired Voting proposal. Let’s assume withdrawal day is too far: a user can still sell its DAO deposit to someone for CKB (withdraw deposit to buyer address) and then use use said CKB in Deposit-Paired Voting :white_check_mark:

Just a question: what’s the difference between those 6 official AMAs and these Nervos Talk public discussions?

Yesss!! Until threads get locked (which I’m actively trying to prevent), anyone can join at any time, that’s the beauty of Nervos Talk :star_struck:

Phroi

1 Like

Yes, these discussions are not pleasant for me either.

What I want now is just a formal verdict, not endless arguments. For technical solutions, I consider this to be a very straightforward matter.

As for the issues exposed in rules and procedures, I believe there will be professionals to handle them—this is not my area of expertise.