Blockchain System Exploration: Implementing Wallet Addresses

·

The Critical Role of Wallets in Blockchain

In blockchain technology, particularly the Bitcoin network, wallets serve as a vital component for facilitating "value transfer." This process requires:

Key Cryptographic Foundations

  1. Private Keys: Random numbers that authenticate transaction ownership
  2. Public Keys: Derived from elliptic curve multiplication between the generator point (G) and the private key

These keys enable transaction verification:

Wallet Address Generation: Step-by-Step Process

Phase 1: Key Derivation

Given private key N:

  1. Multiply N with elliptic curve point G to obtain public key P (a point with x,y coordinates)
  2. Preprocess the 32-byte coordinate values

Preprocessing Methods

Method A: Uncompressed Format

def sec(self):
    return b'\x04' + self.x.num.to_bytes(32, 'big') + self.y.num.to_bytes(32, 'big')

Output Example:
0x04,[x_coordinates],[y_coordinates]

Method B: Compressed Format (33 bytes)

def sec(self, compressed=True):
    if compressed:
        prefix = b'\x02' if self.y.num % 2 == 0 else b'\x03'
        return prefix + self.x.num.to_bytes(32, 'big')

Output Example:
0x02,[x_coordinates] (for even y-values)

Phase 2: Key Recovery Mathematics

For curve y² = x³ + 7:

def sqrt(self):
    return self ** ((P+1) // 4)

def parse(sec_array):
    x = int.from_bytes(sec_array[1:33], 'big')
    y_squared = x**3 + 7
    y = y_squared.sqrt()
    # Adjust y based on prefix byte (0x02 or 0x03)
    return S256Point(x, adjusted_y)

Phase 3: Address Construction Pipeline

  1. Perform Hash160 (SHA256 followed by RIPEMD160) on the processed public key
  2. Add network prefix:

    • 0x00 for mainnet
    • 0x6f for testnet
  3. Compute checksum via Hash256 (double SHA256)
  4. Base58 encode the final result
def address(self, compressed=True, testnet=False):
    h160 = hash160(self.sec(compressed))
    prefix = b'\x6f' if testnet else b'\x00'
    return encode_base58_checksum(prefix + h160)

Example Output:
1PRTTaJesdNovgne6EHCdu1fpEdX7913CK

Key Technical Components

Base58 Encoding Implementation

BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'

def encode_base58(s):
    num = int.from_bytes(s, 'big')
    result = ''
    while num > 0:
        num, mod = divmod(num, 58)
        result = BASE58_ALPHABET[mod] + result
    return result

Security Considerations

  1. Private Key Protection: Never expose private keys
  2. Checksum Validation: Always verify address checksums
  3. Network Specification: Use correct prefixes for mainnet/testnet

👉 Explore advanced wallet implementations

Frequently Asked Questions

Q: Why use compressed public keys?

A: Compressed keys (33 bytes) provide significant bandwidth savings compared to uncompressed versions (65 bytes) without compromising security.

Q: How secure is the Base58 encoding?

A: Base58 eliminates ambiguous characters (0/O, 1/I) to prevent human reading errors, while maintaining cryptographic security of the underlying data.

Q: Can I recover private keys from wallet addresses?

A: No. Wallet addresses are hashed versions of public keys. The private-to-public key relationship remains secure through elliptic curve cryptography.

Q: What's the difference between mainnet and testnet addresses?

A: Besides different prefix bytes, testnet addresses are used for development testing and don't represent real value.

Q: Why does Bitcoin use RIPEMD160 after SHA256?

A: This combination provides security through diverse cryptographic algorithms while keeping hash lengths manageable (20 bytes).

Conclusion

Implementing wallet addresses requires careful attention to:

👉 Learn more about blockchain security practices