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: 0xb8A3CcD263248Cad0de86dA271D46fc963c60C68
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: 0xabd36A48abbEb5EF692A4841FF2896cf6eC9420F
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: 0xd3FCf60D852EA14979E28B01c5Cfe47882ddc2F4
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: 0xD375c65c1CA41A116750b87bD53b14f2a29d06c0
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 = '0xabd36A48abbEb5EF692A4841FF2896cf6eC9420F';
const MCT = '0xb8A3CcD263248Cad0de86dA271D46fc963c60C68';
const RELAY_MGR = '0xd3FCf60D852EA14979E28B01c5Cfe47882ddc2F4';
const VERIFIER = '0xD375c65c1CA41A116750b87bD53b14f2a29d06c0';

// 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)"
]