V4.0 Split Contract Architecture — 5 Production Contracts

Documentation

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

MCTToken V8 Registry V7 RelayManager V13 ProofVerifier V2

📜 Smart Contracts

4 production contracts on Ramestta Mainnet (Chain ID: 1370)

🪙

MCTToken V8

ERC-20 utility token with halving, fee pool, and verified minting.

Address: 0xEfD7B65676FCD4b6d242CbC067C2470df19df1dE
View on RamaScan

Key Functions

// ERC-20
function balanceOf(address) view returns (uint256)
function transfer(address to, 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 V7

On-chain identity, user blocking, and public key storage.

Address: 0x4f8D4955F370881B05b68D2344345E749d8632e3
View on RamaScan

Key Functions

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

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

RelayManager V13

Node identity, tier-based staking, daily pool rewards, and violation handling.

Address: 0xF78F840eF0e321512b09e98C76eA0229Affc4b73
View on RamaScan

Key Functions

// Node Registration (V7 Node Identity)
function registerNodeWithId(
    bytes32 nodeId,
    bytes32 machineIdHash,
    bytes32 serialHash,
    string endpoint,
    uint256 storageMB,
    NodeTier tier  // Bronze=0 to Platinum=3
)
function heartbeatByNodeId(bytes32 nodeId)
function deactivateNodeById(bytes32 nodeId)

// Daily Pool Rewards
function claimDailyPoolReward(uint256 dayId)

// Protection
function reportViolation(bytes32 nodeId, string reason)
function slashNode(bytes32 nodeId, string reason)

ProofVerifier V2

On-chain relay proof verification with commit-verify pattern. Anti-gaming protection.

Address: 0x9Ac287F9067F9DecaDa3ab20dda0d8E0f965006f
View on RamaScan

Key Functions

// Commit-Verify Pattern
function commitRelayBatch(
    bytes32 nodeId,
    bytes32[] calldata messageHashes
)
function verifyAndReward(
    bytes32 nodeId,
    uint256 claimedCount
)

// Anti-Gaming
// 35s commit cooldown
// 10K max hashes per batch
// Global hash uniqueness check
// Authorized consumer pattern
Encryption

Encryption Specification

MumbleChat uses real X25519 Diffie-Hellman key exchange (BouncyCastle on Android, Web Crypto P-256 on browser) with AES-256-GCM symmetric encryption. Messages are authenticated with Ed25519 digital signatures.

🔑 X25519 ECDH 🔒 AES-256-GCM ✍️ Ed25519 🗄️ SQLCipher

┌───────────────────────────────────────────────────────────────────────┐
│                   MUMBLECHAT ENCRYPTION FLOW                          │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  1. KEY GENERATION (per user)                                        │
│     ├── Algorithm: X25519 (Curve25519 ECDH via BouncyCastle)         │
│     ├── Private Key: 32 bytes random                                 │
│     └── Public Key: 32 bytes (stored on-chain in Registry)           │
│                                                                       │
│  2. KEY EXCHANGE (per conversation)                                  │
│     ├── Alice gets Bob's public key from Registry contract           │
│     ├── Perform X25519 ECDH: shared = X25519(alice_priv, bob_pub)   │
│     ├── Derive key: HKDF-SHA256(shared, salt, 256 bits)             │
│     └── 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)                  │
│     └── Output: nonce ‖ ciphertext ‖ authTag (16 bytes)             │
│                                                                       │
│  4. MESSAGE AUTHENTICATION                                           │
│     ├── Algorithm: Ed25519 (BouncyCastle)                            │
│     ├── Sign: Ed25519(privateKey, messageHash)                       │
│     └── Verify: Ed25519.verify(publicKey, signature, hash)           │
│                                                                       │
│  5. LOCAL STORAGE                                                    │
│     ├── Database: SQLCipher (AES-256 encrypted SQLite)               │
│     ├── Key: Derived from wallet private key                         │
│     └── All messages, contacts, keys encrypted at rest               │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘
                

🔌 API Reference

👤 Identity Functions (Registry V7)

register(string username, bytes32 publicKey)

Register on-chain identity with X25519 public key. Wallet-signed authentication.

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 X25519 public key for ECDH key exchange.

updatePublicKey(bytes32 newPublicKey)

Rotate your public key. Old conversations will need re-keying.

📡 RelayManager V13 Functions

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

Register as relay node with V7 Node Identity. Requires MCT stake.

Parameters:
  • nodeId - SHA256 hash of node identity
  • machineIdHash - Hash of machine MAC address
  • serialHash - Hash of hardware serial
  • endpoint - P2P endpoint (multiaddr)
  • tier - Bronze=0, Silver=1, Gold=2, Platinum=3
Stake Required:
Bronze: 100 MCT
Silver: 200 MCT
Gold: 300 MCT
Platinum: 400 MCT

heartbeatByNodeId(bytes32 nodeId)

Record uptime. Call every 5 minutes.

claimDailyPoolReward(uint256 dayId)

Claim your share of the daily 100 MCT pool.

reportViolation(bytes32 nodeId, string reason)

Report a node for protocol violation. Triggers review.

✅ ProofVerifier V2 Functions

commitRelayBatch(bytes32 nodeId, bytes32[] messageHashes)

Commit message hashes to blockchain before claiming rewards. 35s cooldown between commits.

verifyAndReward(bytes32 nodeId, uint256 claimedCount)

Verify committed hashes ≥ claimed count, then mint reward via MCTToken.

🔧 Integration Guide

JavaScript / Web3 Example

import { ethers } from 'ethers';

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

// Contract addresses (production)
const REGISTRY = '0x4f8D4955F370881B05b68D2344345E749d8632e3';
const MCT = '0xEfD7B65676FCD4b6d242CbC067C2470df19df1dE';
const RELAY_MGR = '0xF78F840eF0e321512b09e98C76eA0229Affc4b73';
const VERIFIER = '0x9Ac287F9067F9DecaDa3ab20dda0d8E0f965006f';

// Register identity with X25519 public key
const { publicKey, privateKey } = generateX25519KeyPair();
await registry.register('MyUsername', publicKey);

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

// X25519 ECDH → shared secret → AES-256-GCM encrypt
const sharedSecret = x25519.scalarMult(myPrivateKey, recipientPubKey);
const ciphertext = encryptAES256GCM(message, sharedSecret);

// Send via relay node (encrypted, zero-knowledge)
relay.send({ to: recipientAddress, data: ciphertext });

Network Configuration

Network NameRamestta Mainnet
Chain ID1370
RPC URLhttps://blockchain.ramestta.com
Block Explorerhttps://ramascan.com
Currency SymbolRAMA
Currency Decimals18
P2P Network

P2P Architecture

Kademlia DHT for peer discovery, UDP hole punching for NAT traversal, wallet-signed Sybil resistance, and battery-aware notification strategies. Rate limiting prevents DoS attacks at every layer.

🔗 Kademlia DHT 🛡️ Sybil Resistance ⚡ Rate Limited 🔋 Battery-Aware
🔗

Kademlia DHT

  • K-Bucket: 20 nodes
  • Concurrency: α = 3
  • XOR distance metric
🛡️

NAT Traversal

  • UDP hole punching
  • Relay node fallback
  • Full/Restricted/Symmetric
🔒

Sybil Resistance

  • ECDSA wallet signatures
  • 5-minute expiry
  • Peer verification

Rate Limiting

  • 10 peers/min
  • 100 msgs/peer/min
  • 50 DHT ops/min

Battery-Aware Notification Strategy

StrategyConditionBehavior
PERSISTENTCharging + WiFiAlways-on WebSocket, act as relay
ACTIVEApp in foregroundFull P2P, 1-minute keepalive
LAZYBattery saver / low15-minute polling, no relay
STORE_FORWARDBackground / dozeRely on relay nodes, sync on wake

🔗 Resources

📄 Contract ABIs

Full ABI JSON for contract integration.

MCTToken V8 ABI

[
  "function name() view returns (string)",
  "function symbol() view returns (string)",
  "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 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)",
  "event Transfer(address indexed from, address indexed to, uint256 value)",
  "event RewardClaimed(address indexed user, uint256 amount)"
]

MumbleChatRegistry V7 ABI

[
  "function register(string username, bytes32 publicKey)",
  "function updatePublicKey(bytes32 newPublicKey)",
  "function isRegistered(address user) view returns (bool)",
  "function getPublicKey(address user) view returns (bytes32)",
  "function blockUser(address userToBlock)",
  "function unblockUser(address userToUnblock)",
  "function isBlocked(address,address) view returns (bool)",
  "function registerAsRelay(uint256 storageGB)",
  "function getActiveRelays() view returns (address[])",
  "event UserRegistered(address indexed user, string username)",
  "event RelayRegistered(address indexed relay, uint256 storageGB)"
]