You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Heute kennt zkCoins genau ein Asset (die faucet-geminte Einheit, fest verdrahtete MINTING_ADDRESS). Dieses Issue erweitert das System so, dass jeder Nutzer beliebig viele eigene Assets anlegen, minten, halten, senden und empfangen kann — permissionless, ohne Whitelist, ohne Namensregister.
Prinzip
Additive Erweiterung des bestehenden Mint/Send-Systems um ein Feld asset_id. Das Trust- und Proof-Modell bleibt unverändert: asset_id reitet als zusätzliches Feld auf Coins, Invoices und im Commitment-Preimage mit; Soundness kommt weiterhin aus dem rekursiven SNARK + der Bitcoin-verankerten Nullifier-Historie. Es wird nichts neu erfunden.
Identität: asset_id, nicht der Name
Der einzige Identifikator und die einzige Eindeutigkeit ist die asset_id:
Weil der creator_pubkey im Hash steckt, ist die asset_id global eindeutig ohne jede Koordination — zwei Ersteller, die denselben Namen wählen, erzeugen zwangsläufig verschiedene Assets.
Der Name ist ein freies Label (wie ein ERC-20-Ticker), nicht eindeutig. Mehrere Assets dürfen denselben Namen tragen — auch auf derselben Node. Kein name UNIQUE, kein First-come-first-served-Namespace, kein 409 Conflict.
Die asset_id ist deterministisch ableitbar; die assets-Tabelle ist nur ein Metadaten-Lookup (Name/Dezimalstellen zu einer asset_id), keine Autorität.
Das Wallet zeigt immer Name undasset_id; die asset_id ist der Trust-Anker, der Name ist reine Anzeige.
Funktionsablauf (Nutzersicht)
Anlegen — Name + Dezimalstellen angeben, mit dem Wallet-Key signieren → das Asset existiert (Menge 0). Kein Coin, kein Proof, kein Mint — nur ein Metadaten-Eintrag. Idempotent über die asset_id.
Minten — der Ersteller ruft den bestehenden Mint-Weg für sein Asset auf → erzeugt Einheiten an einen Empfänger. Beliebig oft, kein fixes Supply.
Senden / Empfangen — wie heute, der Nutzer wählt zusätzlich das Asset.
Anlegen und Minten sind getrennt, damit es nur einen Mint-Pfad gibt (der erste Mint ist kein Sonderfall).
Designentscheidungen
Anlegen ≠ Minten.asset/create erzeugt nur den Metadaten-Eintrag, keinen Proof. Supply startet bei 0.
asset_id = einzige Eindeutigkeit (kryptografisch via creator_pubkey). Name = freies, nicht-eindeutiges Label.
Kein fixes Supply — der Ersteller kann jederzeit nachminten. Keine protokollseitige Obergrenze. Vertrauen ins Asset = Vertrauen in den Ersteller.
Eine Transaktion bewegt genau ein Asset — kein Mischen, kein protokollinterner Swap.
Mint-Autorisierung — Off-circuit-Signaturprüfung gegen den beim Anlegen festgelegten mint_authority_pubkey, identisch zum bestehenden Send-Signatur-Check.
Technische Änderungen
Datenmodell
asset_id-Feld an Coin, CoinTemplate, Invoice.
Account: balance: u64 → balances: Map<AssetId, u64> (Persistenz als JSONB-Spalte). Ein Wallet hält beliebig viele Assets nebeneinander.
Neue Tabelle assets (PK asset_id, name als gewöhnliche Spalte ohne UNIQUE, decimals, mint_authority_pubkey, creator_address).
Circuit (rein additiv)
asset_id als ein neuer Public-Input (N_PROOF_DATA_PUBLIC_INPUTS 16 → 20).
Pro Slot ein Gleichheits-Gate: alle Ein-/Ausgangs-Coins einer Transaktion tragen dasselbe asset_id.
calculate_coin_identifier um asset_id erweitern.
Recursion-Padding (INNER_PAD_BITS…) bei 20 Public-Inputs neu verifizieren.
API
POST /api/asset/create(neu) — Name, Dezimalstellen, mint_authority_pubkey, Signatur → Metadaten-Eintrag. Idempotent über asset_id.
GET /api/asset/list, GET /api/asset/info/:id(neu).
POST /api/mint(erweitert) — asset_id + Creator-Signatur; bestehender Mint-Flow pro Asset statt single MINTING_ADDRESS.
POST /api/send(erweitert) — asset_id; Signatur deckt asset_id mit ab.
GET /api/balance(erweitert, breaking) — Map {asset_id: menge} statt Skalar.
GET /api/info — neues Capability-Flag multi_asset.
Nicht im Scope
Härtung der Ausgabe (D11): Off-circuit-Mint bleibt wie im heutigen System. In-Circuit-Mint-Verifikation und BTC-Bridge sind separate, spätere Themen.
Per-Asset-Privacy-Pools / Verstecken der asset_id on-chain.
Cross-Asset-Swap im Protokoll.
Schlüsselrotation der Mint-Authority, reiche Metadaten (Logo/URI), Burn.
Wallet-UI (zk-coins/app) — separater PR in jenem Repo.
Lieferung
Ein einziger PR in diesem Repo (kein Splitten). Feature-Branch → Draft-PR nach staging — dem Integrations-Buffer. develop (DEV-Deploy) und main (PRD) sind protected und werden ausschließlich per Auto-Promote-PR befüllt (staging → develop → main); siehe CONTRIBUTING.md „Branch model". Agents öffnen PRs als Draft; Maintainer mergen.
100 % Test-Coverage auf der neuen activated surface + grüne Heavy-Tests (M3-Ultra-Runner) — die CI-Gates des Repos gelten.
Pflicht-Negativtests
Zwei verschiedene Assets in einer Transaktion → abgelehnt.
Mint ohne gültige Authority-Signatur → abgelehnt.
Zwei gleichnamige Assets verschiedener Ersteller koexistieren (verschiedene asset_id).
Senden eines Assets ohne Guthaben → abgelehnt.
Referenzen
./MULTI_ASSET.md — Design-Vorlage. Dieses Issue weicht bewusst ab: (a) Anlegen und Minten getrennt, initial_supply entfällt; (b) kein First-come-first-served-Namespace / kein name UNIQUE (M3 verworfen) — asset_id ist die alleinige Eindeutigkeit.
Ziel
Heute kennt zkCoins genau ein Asset (die faucet-geminte Einheit, fest verdrahtete
MINTING_ADDRESS). Dieses Issue erweitert das System so, dass jeder Nutzer beliebig viele eigene Assets anlegen, minten, halten, senden und empfangen kann — permissionless, ohne Whitelist, ohne Namensregister.Prinzip
Additive Erweiterung des bestehenden Mint/Send-Systems um ein Feld
asset_id. Das Trust- und Proof-Modell bleibt unverändert:asset_idreitet als zusätzliches Feld auf Coins, Invoices und im Commitment-Preimage mit; Soundness kommt weiterhin aus dem rekursiven SNARK + der Bitcoin-verankerten Nullifier-Historie. Es wird nichts neu erfunden.Identität:
asset_id, nicht der NameDer einzige Identifikator und die einzige Eindeutigkeit ist die
asset_id:Weil der
creator_pubkeyim Hash steckt, ist dieasset_idglobal eindeutig ohne jede Koordination — zwei Ersteller, die denselben Namen wählen, erzeugen zwangsläufig verschiedene Assets.name UNIQUE, kein First-come-first-served-Namespace, kein409 Conflict.asset_idist deterministisch ableitbar; dieassets-Tabelle ist nur ein Metadaten-Lookup (Name/Dezimalstellen zu einerasset_id), keine Autorität.asset_id; dieasset_idist der Trust-Anker, der Name ist reine Anzeige.Funktionsablauf (Nutzersicht)
asset_id.Anlegen und Minten sind getrennt, damit es nur einen Mint-Pfad gibt (der erste Mint ist kein Sonderfall).
Designentscheidungen
asset/createerzeugt nur den Metadaten-Eintrag, keinen Proof. Supply startet bei 0.asset_id= einzige Eindeutigkeit (kryptografisch viacreator_pubkey). Name = freies, nicht-eindeutiges Label.mint_authority_pubkey, identisch zum bestehenden Send-Signatur-Check.Technische Änderungen
Datenmodell
asset_id-Feld anCoin,CoinTemplate,Invoice.Account:balance: u64→balances: Map<AssetId, u64>(Persistenz als JSONB-Spalte). Ein Wallet hält beliebig viele Assets nebeneinander.assets(PKasset_id,nameals gewöhnliche Spalte ohne UNIQUE,decimals,mint_authority_pubkey,creator_address).Circuit (rein additiv)
asset_idals ein neuer Public-Input (N_PROOF_DATA_PUBLIC_INPUTS16 → 20).asset_id.calculate_coin_identifierumasset_iderweitern.INNER_PAD_BITS…) bei 20 Public-Inputs neu verifizieren.API
POST /api/asset/create(neu) — Name, Dezimalstellen,mint_authority_pubkey, Signatur → Metadaten-Eintrag. Idempotent überasset_id.GET /api/asset/list,GET /api/asset/info/:id(neu).POST /api/mint(erweitert) —asset_id+ Creator-Signatur; bestehender Mint-Flow pro Asset statt singleMINTING_ADDRESS.POST /api/send(erweitert) —asset_id; Signatur decktasset_idmit ab.GET /api/balance(erweitert, breaking) — Map{asset_id: menge}statt Skalar.GET /api/info— neues Capability-Flagmulti_asset.Nicht im Scope
asset_id-als-Identität von Anfang an dezentral-kompatibel.asset_idon-chain.zk-coins/app) — separater PR in jenem Repo.Lieferung
staging— dem Integrations-Buffer.develop(DEV-Deploy) undmain(PRD) sind protected und werden ausschließlich per Auto-Promote-PR befüllt (staging→develop→main); siehe CONTRIBUTING.md „Branch model". Agents öffnen PRs als Draft; Maintainer mergen.asset_id→ Circuit → Registry+Endpoints → Mint → Send/Balance.Pflicht-Negativtests
asset_id).Referenzen
./MULTI_ASSET.md— Design-Vorlage. Dieses Issue weicht bewusst ab: (a) Anlegen und Minten getrennt,initial_supplyentfällt; (b) kein First-come-first-served-Namespace / keinname UNIQUE(M3 verworfen) —asset_idist die alleinige Eindeutigkeit../SPEC.md§8 (Mint-Branch), §15 D11.Session-ID:
99f19e87-cf2b-48f9-866b-99ebf93fd85e