Bitcoin Cash (BCH) API implementation rules. Critical pattern for embedding Bitcoin struct and overriding BCH-specific methods...
This is a non-negotiable architectural rule. BCH implementation uses struct embedding with method override pattern.
// internal/infrastructure/api/btc/bch/bitcoin_cash.go
type BitcoinCash struct {
apibtcimpl.Bitcoin // Embeds BTC implementation
}
Key Principle: BitcoinCash embeds Bitcoin, inheriting all BTC methods by default.
When BCH requires different logic from BTC:
internal/infrastructure/api/btc/bch/BitcoinCashBitcoin methodinternal/infrastructure/api/btc/btc/ for BCH-specific requirements| Reason | Explanation |
|---|---|
| Separation of Concerns | BTC code remains pure and focused |
| Maintainability | BCH changes don't affect BTC |
| Clarity | BCH differences are explicit in BCH directory |
| Safety | BTC modifications can't accidentally break BCH |
BCH has a different response structure for getaddressinfo RPC:
// internal/infrastructure/api/btc/bch/address.go
// BCH-specific response type
type GetAddressInfoResult struct {
Address string `json:"address"`
ScriptPubKey string `json:"scriptPubKey"`
Label string `json:"label,omitempty"` // BCH uses Label (singular)
Labels []struct { // BCH has different Labels structure
Name string `json:"name"`
Purpose string `json:"purpose"`
} `json:"labels"`
// ... other BCH-specific fields
}
// Override GetAddressInfo for BCH
func (b *BitcoinCash) GetAddressInfo(addr string) (*dtobtc.AddressInfo, error) {
// BCH-specific implementation
// ...
}
BCH requires different logic for getting account info:
// internal/infrastructure/api/btc/bch/account.go
func (b *BitcoinCash) GetAccount(addr string) (string, error) {
// BCH calls GetAddressInfo (which is also overridden)
res, err := b.GetAddressInfo(addr)
if err != nil {
return "", fmt.Errorf("fail to call btc.GetAddressInfo() in bch: %w", err)
}
// BCH-specific label extraction
if len(res.Labels) == 0 {
return "", nil
}
return res.Labels[0], nil
}
BCH has different network magic numbers:
// internal/infrastructure/api/btc/bch/bitcoin_cash.go
const (
MainnetMagic wire.BitcoinNet = 0xe8f3e1e3 // BCH-specific
TestnetMagic wire.BitcoinNet = 0xf4f3e5f4 // BCH-specific
Regtestmagic wire.BitcoinNet = 0xfabfb5da // BCH-specific
)
func (b *BitcoinCash) initChainParams() {
// Override chain parameters for BCH
}
| Feature | BTC | BCH |
|---|---|---|
| SegWit | ā Supported | ā Not supported |
| Taproot | ā Supported | ā Not supported |
| Address Format | Legacy, SegWit, Taproot | Legacy, CashAddr |
| Network Magic | BTC values | BCH-specific values |
internal/infrastructure/api/btc/
āāā btc/ # BTC implementation (DO NOT modify for BCH)
ā āāā bitcoin.go # Bitcoin struct and methods
ā āāā account.go
ā āāā address.go
ā āāā ...
āāā bch/ # BCH overrides (ADD new files here)
ā āāā bitcoin_cash.go # BitcoinCash struct (embeds Bitcoin)
ā āāā account.go # Override: GetAccount
ā āāā address.go # Override: GetAddressInfo
ā āāā ...
āāā connection.go # Shared connection logic
When implementing BCH-specific logic:
internal/infrastructure/api/btc/bch/ (NOT in btc/)internal/infrastructure/api/btc/btc/// internal/infrastructure/api/btc/btc/account.go
func (b *Bitcoin) GetAccount(addr string) (string, error) {
if b.coinTypeCode == domainCoin.BCH { // DON'T DO THIS!
// BCH-specific logic
}
// BTC logic
}
// internal/infrastructure/api/btc/bch/account.go
func (b *BitcoinCash) GetAccount(addr string) (string, error) {
// BCH-specific logic here
}
When BitcoinCash embeds Bitcoin:
Bitcoin methods are "promoted" to BitcoinCashBitcoinCash defines a method with the same name, it takes precedenceBitcoin methods can still be called via b.Bitcoin.MethodName()// Call overridden method (uses BitcoinCash.GetAddressInfo)
info, _ := bch.GetAddressInfo(addr)
// Call embedded method directly (uses Bitcoin.GetAddressInfo)
info, _ := bch.Bitcoin.GetAddressInfo(addr)
| File | Purpose |
|---|---|
internal/infrastructure/api/btc/bch/bitcoin_cash.go |
BitcoinCash struct definition |
internal/infrastructure/api/btc/btc/bitcoin.go |
Bitcoin struct (embedded by BCH) |
internal/application/ports/btc/interface.go |
Bitcoiner interface |