go-blockchain/docs/superpowers/specs/2026-03-16-hf5-confidential-assets-design.md
Snider 34128d8e98
Some checks failed
Security Scan / security (pull_request) Successful in 11s
Test / Test (pull_request) Failing after 19s
refactor: migrate module path to dappco.re/go/core/blockchain
Update go.mod module line, all require/replace directives, and every
.go import path from forge.lthn.ai/core/go-blockchain to
dappco.re/go/core/blockchain. Add replace directives to bridge
dappco.re paths to existing forge.lthn.ai registry during migration.
Update CLAUDE.md, README, and docs to reflect the new module path.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 01:49:26 +00:00

155 lines
6.2 KiB
Markdown

# HF5 Confidential Assets Support
**Date:** 2026-03-16
**Author:** Charon
**Package:** `dappco.re/go/core/blockchain`
**Status:** Draft
**Depends on:** HF1 (types refactor), HF3 (block version), HF4 (Zarcanum — already implemented)
## Context
HF5 introduces confidential assets — the ability to deploy, emit, update, and burn custom asset types on the Lethean chain. This is the Zano asset system: every output has a `blinded_asset_id` that proves (via BGE surjection proofs) it corresponds to a legitimate input asset without revealing which one.
On mainnet, HF5 is at height 999,999,999 (future). On testnet, HF5 activates at height 200.
**What's already implemented:**
- BGE surjection proof verification (`crypto.VerifyBGE`) — crypto bridge done
- BGE proof parsing (`readBGEProof`, `readZCAssetSurjectionProof`) — wire done
- `verifyBGEProofs` in consensus/verify.go — verification logic done
- Transaction version 3 wire format with `hardfork_id` field — wire done
- `VersionPostHF5` constant and `decodePrefixV2` hardfork_id handling — done
**What's NOT implemented:**
- Asset operation types in extra/attachment fields
- Asset descriptor structures
- Consensus validation for asset operations
- Pre-hardfork transaction freeze (60 blocks before HF5 activation)
- Minimum build version enforcement
## Scope
### Phase A: Asset descriptor types (types/)
New types for the `asset_descriptor_operation` extra variant:
```go
// AssetDescriptorBase holds the core asset metadata.
type AssetDescriptorBase struct {
Ticker string // max 6 chars
FullName string // max 64 chars
TotalMaxSupply uint64 // maximum supply cap
CurrentSupply uint64 // current circulating supply
DecimalPoint uint8 // display precision
MetaInfo string // arbitrary metadata (JSON)
OwnerKey PublicKey // asset owner's public key
// etc: reserved variant vector for future fields
Etc []byte // opaque
}
// AssetDescriptorOperation represents a deploy/emit/update/burn operation.
type AssetDescriptorOperation struct {
Version uint8 // currently 0 or 1
OperationType uint8 // ASSET_DESCRIPTOR_OPERATION_REGISTER, _EMIT, _UPDATE, _BURN, _PUBLIC_BURN
Descriptor *AssetDescriptorBase // present for register and update
AssetID Hash // target asset ID (absent for register)
AmountToEmit uint64 // for emit operations
AmountToBurn uint64 // for burn operations
Etc []byte // opaque
}
```
Operation type constants:
```go
const (
AssetOpRegister uint8 = 0 // deploy new asset
AssetOpEmit uint8 = 1 // emit additional supply
AssetOpUpdate uint8 = 2 // update metadata
AssetOpBurn uint8 = 3 // burn supply (with proof)
AssetOpPublicBurn uint8 = 4 // burn supply (public amount)
)
```
### Phase B: Wire encoding for asset operations (wire/)
The `asset_descriptor_operation` appears as a variant element in the tx extra field (tag 40 in the C++ SET_VARIANT_TAGS).
Add to `readVariantElementData`:
```
case tagAssetDescriptorOperation (40):
read version transition header
read operation_type (uint8)
read opt_asset_id (optional hash)
read opt_descriptor (optional AssetDescriptorBase)
read amount_to_emit/burn (varint)
read etc (opaque vector)
```
This is stored as raw bytes in the extra field (same opaque pattern as everything else), but we need the wire reader to not choke on tag 40 during deserialization.
### Phase C: Asset operation proof types (wire/)
New proof variant tags for HF5:
```
tagAssetOperationProof = 49 // asset_operation_proof
tagAssetOperationOwnershipProof = 50 // asset_operation_ownership_proof
tagAssetOperationOwnershipETH = 51 // asset_operation_ownership_proof_eth
```
Each needs a reader in `readVariantElementData`. The proof structures contain crypto elements (Schnorr signatures, public keys) that are fixed-size.
### Phase D: Consensus validation (consensus/)
**Transaction version enforcement:**
- After HF5: transaction version must be 3 (not 2)
- `hardfork_id` field must be present and match current hardfork
**Pre-hardfork freeze:**
- 60 blocks before HF5 activation, reject non-coinbase transactions
- `config.PreHardforkTxFreezePeriod = 60` already defined
**Asset operation validation:**
- Register: descriptor must be valid (ticker length, supply caps, owner key non-zero)
- Emit: asset_id must exist, caller must prove ownership
- Update: asset_id must exist, caller must prove ownership
- Burn: amount must not exceed current supply
**Minimum build version:**
- C++ enforces `MINIMUM_REQUIRED_BUILD_VERSION = 601` for mainnet, 2 for testnet
- Go equivalent: reject connections from peers with build version below threshold
### Phase E: Asset state tracking (chain/)
Need to track:
- Asset registry: asset_id → AssetDescriptorBase
- Current supply per asset
- Asset ownership proofs
This requires new storage groups in `chain/store.go`.
## What can be deferred
- **Full asset operation validation** — complex, needs ownership proof verification. Can accept blocks containing asset operations structurally (wire parsing) without deep validation initially, then add validation incrementally.
- **Asset state tracking** — needed for wallet/explorer, not strictly for block sync if we trust the C++ daemon's validation.
- **Wallet asset support** — separate design.
## Recommended approach
**Minimum viable HF5:** Wire parsing only. Add tag 40 and the asset proof tags to `readVariantElementData` so the Go node can deserialise HF5 blocks without crashing. Store asset operations as opaque bytes in the extra field (existing pattern). Gate transaction version 3 on HF5.
This follows the same pattern used for extra, attachment, etc_details — opaque bytes for bit-identical round-tripping. Deep validation can layer on top.
## Testing
- Wire round-trip tests with constructed v3 transactions containing asset operations
- Testnet block parsing past height 200 (HF5 activation)
- Version enforcement tests (reject v2 after HF5, accept v3)
- Pre-hardfork freeze tests (reject non-coinbase 60 blocks before activation)
## Out of scope
- Wallet asset management (deploy/emit/burn CLI)
- Asset explorer UI
- Asset whitelist management
- Cross-asset atomic swaps
- HF6 block time halving (separate spec)