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>
6.2 KiB
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 verifyBGEProofsin consensus/verify.go — verification logic done- Transaction version 3 wire format with
hardfork_idfield — wire done VersionPostHF5constant anddecodePrefixV2hardfork_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:
// 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:
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_idfield must be present and match current hardfork
Pre-hardfork freeze:
- 60 blocks before HF5 activation, reject non-coinbase transactions
config.PreHardforkTxFreezePeriod = 60already 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 = 601for 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)