Addresses, keys & wallets
Every Dogecoin app eventually comes down to keys: who holds them, where addresses come from, and what you must never do with them. This lesson builds the vocabulary you'll use in every later lesson – and in every code review of a wallet-touching pull request.
From private key to D-address
The chain of custody works exactly like Bitcoin's, with Dogecoin's own cosmetic prefixes:
- A private key is 32 random bytes. Whoever knows it can spend the funds. Full stop.
- The matching public key is derived from it with elliptic-curve math (secp256k1, same curve as Bitcoin).
- The public key is hashed (SHA-256, then RIPEMD-160), a version byte is prepended, a checksum is appended, and the result is Base58-encoded into an address.
That version byte is why address types are visually recognizable:
| Type | Version byte | Looks like |
|---|---|---|
| Mainnet pay-to-pubkey-hash (P2PKH) | 0x1E | D... (the classic Dogecoin address) |
| Mainnet pay-to-script-hash (P2SH, e.g. multisig) | 0x16 | 9... or A... |
| Testnet P2PKH | 0x71 | n... (or similar) |
Private keys travel in WIF (Wallet Import Format) – the same Base58Check idea applied to the key itself. Treat any string like that as radioactive: never log it, never commit it, never paste it into a chat.
The only rule that has no exceptions: never write your own key or address code from scratch. Use Libdogecoin, your node's RPC (getnewaddress), or a heavily-used library. Hand-rolled Base58 is how funds get burned to unspendable addresses.
HD wallets: one seed, endless addresses
Modern wallets are hierarchical deterministic (HD): a single seed (those 12 or 24 words, BIP-39) deterministically generates a tree of key pairs (BIP-32). A standard derivation path (BIP-44) tells wallets where to look. Dogecoin's registered coin type is 3, so the first receiving address of the first account lives at:
m / 44' / 3' / 0' / 0 / 0
Why you care as a developer: back up the seed once and every future address is recoverable; and any wallet that follows the standard can restore any other wallet's funds. If you build wallet-adjacent software, follow the standard – users' recovery expectations depend on it.
Address hygiene for apps
- Generate a fresh address per purpose. Address reuse is bad for privacy and makes payment detection ambiguous (which payment was for which invoice?). Fresh-address-per-invoice is the backbone of the payment-detection lesson.
- Validate before you send. Dogecoin Core's
validateaddressRPC tells you whether a string is a well-formed address for the network you're on – call it before every user-supplied withdrawal. - Testnet and mainnet addresses are incompatible on purpose, so a testing mistake can't spend real funds. Develop on testnet; the prefixes will keep you honest.
The custody decision
Before writing a line of code, decide which side of this line your app lives on:
- Self-custodial: users hold their own keys (MyDoge-style). Your app never touches funds – simplest legally and safest technically, but you can't move money on users' behalf.
- Custodial: your service holds keys and owes users balances (exchange-style, and most tip bots). You gain UX power and take on real responsibility: security, accounting, and possibly regulation depending on jurisdiction and scale.
This curriculum teaches both patterns and is blunt about the responsibilities of the second. The tip-bot lesson is a guided tour of exactly this trade-off.
Key takeaways
- Address = hashed public key + version byte, Base58Check-encoded; mainnet Dogecoin addresses start with
D. - HD wallets derive everything from one seed; Dogecoin's BIP-44 coin type is 3.
- Never hand-roll crypto; use Libdogecoin, node RPC, or proven libraries.
- Fresh address per invoice; validate every user-supplied address; testnet first.
- Custodial vs self-custodial is a product and legal decision – make it consciously.