📚 MumbleChat V4.0 - Split Contract Architecture

Documentation

Smart contract APIs, P2P networking, Kademlia DHT, and everything you need to build on MumbleChat Protocol.

📜 Smart Contracts

Deployed on Ramestta Mainnet (Chain ID: 1370)

🪙

MCT Token (MCTToken V3)

ERC-20 utility token with halving and fee pool.

Address: 0xEfD7B65676FCD4b6d242CbC067C2470df19df1dE

Key Functions

// Standard ERC-20
function balanceOf(address) view returns (uint256)
function transfer(address to, uint256 amount) returns (bool)
function approve(address spender, uint256 amount) returns (bool)

// MCT-specific
function mintForRelay(address relay, uint256 messages)
function claimFeePoolReward()
function currentRate() view returns (uint256)
function halvingLevel() view returns (uint256)
function feePool() view returns (uint256)
📋

MumbleChatRegistry V4

Core identity and user blocking registry.

Address: 0x4f8D4955F370881B05b68D2344345E749d8632e3

Key Functions

// Identity
function register(bytes32 publicKeyX, string displayName)
function isRegistered(address) view returns (bool)
function updatePublicKey(bytes32 newPublicKeyX)
function updateDisplayName(string newDisplayName)
function deactivate()

// User Blocking
function blockUser(address userToBlock)
function unblockUser(address userToUnblock)
function isBlocked(address blocker, address blocked) view

// Legacy Relay (use RelayManager for V4)
function registerAsRelay(string endpoint, uint256 storageMB)
function heartbeat()
📡

MumbleChatRelayManager V1 (NEW)

V4 Node Identity System with tier-based staking and rewards.

Address: 0xF78F840eF0e321512b09e98C76eA0229Affc4b73

Key Functions

// Node Registration (V4 Node Identity)
function registerNodeWithId(
    bytes32 nodeId,
    bytes32 machineIdHash,
    bytes32 serialHash,
    string endpoint,
    uint256 storageMB,
    NodeTier tier  // Bronze=0, Silver=1, Gold=2, Platinum=3
)
function deactivateNodeById(bytes32 nodeId)
function heartbeatByNodeId(bytes32 nodeId)

// Tier Staking (100/200/300/400 MCT)
function getStakeForTier(NodeTier tier) view returns (uint256)
function getUptimeForTier(NodeTier tier) view returns (uint256)
function getFeePercentForTier(NodeTier tier) view returns (uint256)

// Daily Pool Rewards
function claimDailyPoolReward(uint256 dayId)
function submitRelayProof(bytes32 nodeId, bytes32 messageHash, ...)

// Protection Protocol
function reportViolation(bytes32 nodeId, string reason)
function slashNode(bytes32 nodeId, string reason)  // owner only
function blacklistNode(address wallet, string reason)  // owner only

// View Functions
function getNodeByNodeId(bytes32 nodeId) view
function getWalletNodeIds(address wallet) view returns (bytes32[])
function getActiveNodeIds() view returns (bytes32[], address[])

🔌 API Reference

👤 Identity Functions

register(string username, bytes32 publicKey)

Register a new identity on-chain with your X25519 public key.

Parameters:
  • username - Display name (3-32 chars)
  • publicKey - 32-byte X25519 public key
Returns: void
Gas: ~80,000

getPublicKey(address user) view returns (bytes32)

Get the public key for a registered user. Used for key exchange.

Parameters:
  • user - User's wallet address
Returns: bytes32 - Public key
Gas: Free (view)

updatePublicKey(bytes32 newPublicKey)

Update your public key (key rotation).

🌐 RelayManager Node Functions (V4)

registerNodeWithId(bytes32 nodeId, bytes32 machineIdHash, bytes32 serialHash, string endpoint, uint256 storageMB, NodeTier tier)

Register as a relay node with V4 Node Identity. Requires MCT stake based on tier.

Parameters:
  • nodeId - Unique node identifier (SHA256 hash)
  • machineIdHash - Hash of machine MAC address
  • serialHash - Hash of hardware serial
  • endpoint - P2P endpoint (multiaddr format)
  • storageMB - Storage capacity in MB
  • tier - Bronze=0, Silver=1, Gold=2, Platinum=3
Stake Required:
• Bronze: 100 MCT
• Silver: 200 MCT
• Gold: 300 MCT
• Platinum: 400 MCT
Gas: ~150,000

heartbeatByNodeId(bytes32 nodeId)

Heartbeat function. Call every 5 minutes to record uptime.

deactivateNodeById(bytes32 nodeId)

Stop being a relay node. Returns staked MCT.

claimDailyPoolReward(uint256 dayId)

Claim your share of the daily 100 MCT pool for a specific day.

submitRelayProof(bytes32 nodeId, bytes32 messageHash, address sender, address recipient, uint256 timestamp, bytes senderSignature)

Submit cryptographic proof of message relay for rewards.

💬 Messaging Functions

sendMessage(address to, bytes ciphertext)

Send an encrypted message to a recipient.

Parameters:
  • to - Recipient wallet address
  • ciphertext - AES-256-GCM encrypted message
Returns: uint256 - Message ID
Gas: ~50,000 + calldata

getMessages(address user) view returns (Message[])

Get all messages for a user (encrypted).

🔧 Integration Guide

JavaScript/Web3 Example

import { ethers } from 'ethers';

// Connect to Ramestta
const provider = new ethers.JsonRpcProvider('https://blockchain.ramestta.com');
const signer = new ethers.Wallet(PRIVATE_KEY, provider);

// Contract addresses
const REGISTRY = '0x4f8D4955F370881B05b68D2344345E749d8632e3';
const MCT = '0xEfD7B65676FCD4b6d242CbC067C2470df19df1dE';

// Load contract (simplified ABI)
const registryABI = [
  'function register(string username, bytes32 publicKey)',
  'function getPublicKey(address user) view returns (bytes32)',
  'function isRegistered(address user) view returns (bool)'
];
const registry = new ethers.Contract(REGISTRY, registryABI, signer);

// Check if registered
const isReg = await registry.isRegistered(myAddress);
console.log('Registered:', isReg);

// Register identity
if (!isReg) {
  const { publicKey, privateKey } = generateX25519KeyPair();
  await registry.register('MyUsername', publicKey);
}

// Get recipient's public key for encryption
const recipientPubKey = await registry.getPublicKey(recipientAddress);

// Derive shared secret using X25519 ECDH
const sharedSecret = x25519.scalarMult(myPrivateKey, recipientPubKey);

// Encrypt message with AES-256-GCM
const ciphertext = encryptAES256GCM(message, sharedSecret);

// Send encrypted message on-chain
await registry.sendMessage(recipientAddress, ciphertext);

Network Configuration

Network Name Ramestta Mainnet
Chain ID 1370
RPC URL https://blockchain.ramestta.com
Block Explorer https://ramascan.com
Currency Symbol RAMA
Currency Decimals 18

🔐 Encryption Specification


┌─────────────────────────────────────────────────────────────────────────┐
│                    MUMBLECHAT ENCRYPTION FLOW                            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│   1. KEY GENERATION (per user)                                          │
│      ├── Algorithm: X25519 (Curve25519 ECDH)                            │
│      ├── Private Key: 32 bytes random                                   │
│      └── Public Key: 32 bytes (stored on-chain)                         │
│                                                                          │
│   2. KEY EXCHANGE (per conversation)                                    │
│      ├── Alice gets Bob's public key from contract                      │
│      ├── Perform X25519 ECDH: shared = X25519(alice_priv, bob_pub)     │
│      ├── Derive encryption key: key = HKDF-SHA256(shared, salt)        │
│      └── Same shared secret on both sides (symmetric)                   │
│                                                                          │
│   3. MESSAGE ENCRYPTION                                                 │
│      ├── Algorithm: AES-256-GCM                                         │
│      ├── Key: derived shared secret (256 bits)                          │
│      ├── Nonce: 12 bytes random (unique per message)                    │
│      ├── Plaintext: UTF-8 message                                       │
│      └── Output: nonce || ciphertext || authTag                         │
│                                                                          │
│   4. MESSAGE FORMAT (on-chain)                                          │
│      ├── Bytes 0-11: Nonce (12 bytes)                                   │
│      ├── Bytes 12-N: Ciphertext (variable)                              │
│      └── Bytes N-N+16: Authentication Tag (16 bytes)                    │
│                                                                          │
│   5. DECRYPTION (recipient)                                             │
│      ├── Extract nonce, ciphertext, authTag                             │
│      ├── Derive same shared secret via ECDH                             │
│      ├── AES-256-GCM decrypt with authTag verification                  │
│      └── Return plaintext or throw if tampered                          │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘
                

🌐 P2P Architecture

Kademlia DHT, NAT traversal, and security features in V3

🔗

Kademlia DHT

Distributed hash table for peer discovery without central servers.

  • K-Bucket Size: 20 nodes per bucket
  • Lookup Concurrency: α = 3 parallel requests
  • Node ID: keccak256(walletAddress)[:20]
  • XOR Distance Metric: Standard Kademlia
🛡️

NAT Traversal

STUN servers and UDP hole punching for direct P2P connections.

  • STUN Servers: Google (19302), Cloudflare
  • Protocol: UDP hole punching
  • Fallback: Relay nodes for symmetric NAT
  • Detection: Full Cone, Restricted, Symmetric
🔒

Sybil Resistance

Wallet signature verification prevents fake node attacks.

  • Peer Verification: ECDSA wallet signature
  • Signature Expiry: 5 minutes max age
  • Message Format: "mumblechat:peer:{nodeId}:{timestamp}"
  • Trusted Sources: Blockchain peer resolver bypasses check

Rate Limiting

Per-category rate limits prevent DoS and spam attacks.

  • Peer Addition: 10 new peers/minute
  • Message Send: 100 messages/peer/minute
  • DHT Operations: 50 ops/minute
  • Relay Requests: 20 requests/minute

Battery-Aware Notification Strategy

Strategy Condition Behavior
PERSISTENT Charging + WiFi Always-on WebSocket, act as relay
ACTIVE App in foreground Full P2P, 1-minute keepalive
LAZY Battery saver / low battery 15-minute polling, no relay
STORE_FORWARD Background / doze mode Rely on relay nodes, sync on wake

🔗 Resources

📄 Contract ABIs

Full ABI JSON files for contract integration.

MCTToken ABI (Simplified)

[
  "function name() view returns (string)",
  "function symbol() view returns (string)",
  "function decimals() view returns (uint8)",
  "function totalSupply() view returns (uint256)",
  "function balanceOf(address) view returns (uint256)",
  "function transfer(address to, uint256 amount) returns (bool)",
  "function approve(address spender, uint256 amount) returns (bool)",
  "function allowance(address owner, address spender) view returns (uint256)",
  "function transferFrom(address from, address to, uint256 amount) returns (bool)",
  "function mintForRelay(address relay, uint256 messageCount)",
  "function claimFeePoolReward()",
  "function currentRate() view returns (uint256)",
  "function halvingLevel() view returns (uint256)",
  "function totalMinted() view returns (uint256)",
  "function feePool() view returns (uint256)",
  "function lastClaimBlock(address) view returns (uint256)",
  "event Transfer(address indexed from, address indexed to, uint256 value)",
  "event Approval(address indexed owner, address indexed spender, uint256 value)",
  "event FeeCollected(uint256 amount)",
  "event RewardClaimed(address indexed user, uint256 amount)"
]

MumbleChatRegistry ABI (Simplified)

[
  "function register(string username, bytes32 publicKey)",
  "function updatePublicKey(bytes32 newPublicKey)",
  "function updateUsername(string newUsername)",
  "function isRegistered(address user) view returns (bool)",
  "function getPublicKey(address user) view returns (bytes32)",
  "function getUsername(address user) view returns (string)",
  "function registerAsRelay(uint256 storageGB)",
  "function deactivateRelay()",
  "function recordUptime()",
  "function getTier(address relay) view returns (uint8)",
  "function isActiveRelay(address relay) view returns (bool)",
  "function getRelayInfo(address relay) view returns (tuple)",
  "function getActiveRelays() view returns (address[])",
  "function sendMessage(address to, bytes ciphertext) returns (uint256)",
  "function getMessages(address user) view returns (tuple[])",
  "function markMessageRead(uint256 messageId)",
  "event UserRegistered(address indexed user, string username)",
  "event RelayRegistered(address indexed relay, uint256 storageGB)",
  "event RelayDeactivated(address indexed relay)",
  "event MessageSent(address indexed from, address indexed to, uint256 id)",
  "event TierUpdated(address indexed relay, uint8 newTier)"
]