36 KiB
Spécification du Service 4NK Certificator
Version: 1.0 Date: 1 octobre 2025 Auteur: Système 4NK
Table des matières
- Vue d'ensemble
- Objectifs et cas d'usage
- Architecture technique
- Protocole d'ancrage
- Modèle de données
- API et interfaces
- Sécurité et validation
- Déploiement et configuration
- Roadmap et évolutions
1. Vue d'ensemble
1.1 Définition
Le Certificator est un service d'ancrage cryptographique qui enregistre périodiquement sur le mainnet Bitcoin l'état des échanges de données transitant par les relais 4NK. Il fournit une preuve vérifiable et immuable du volume de données échangées, avec un système de paiement conditionnel pour activer l'ancrage.
1.2 Principes fondamentaux
- Ancrage périodique : Enregistrement mensuel (en nombre de blocs Bitcoin) de l'empreinte des données
- Paiement conditionnel : Ancrage activé uniquement si paiement détecté
- Immutabilité : Utilisation du mainnet Bitcoin comme registre de vérité
- Transparence : Vérification publique des ancrages via la blockchain
- Intégrité : Hash cryptographique de l'état du processus
1.3 Composants principaux
┌────────────────────────────────────────────────────────────┐
│ Écosystème 4NK │
│ ┌──────────────┐ ┌──────────────────┐ ┌──────────────┐ │
│ │ sdk_relay │───►│ 4NK Certificator │───►│Bitcoin Mainnet│
│ │ (messages) │ │ (ancrage) │ │ (OP_RETURN) │
│ └──────────────┘ └──────┬───────┘ └──────────────┘ │
│ │ │
│ ┌──────▼───────┐ │
│ │ Process DB │ │
│ │ (metrics + │ │
│ │ anchors) │ │
│ └──────────────┘ │
└────────────────────────────────────────────────────────────┘
2. Objectifs et cas d'usage
2.1 Objectifs principaux
- Traçabilité : Enregistrer l'historique des volumes échangés
- Auditabilité : Permettre la vérification indépendante des métriques
- Monétisation : Système de paiement pour services premium (ancrage garanti)
- Non-répudiation : Preuve cryptographique de l'activité réseau
- Conformité : Support pour audits réglementaires
2.2 Cas d'usage
Cas 1 : Facturation basée sur l'usage
Scénario:
- Un processus collaboratif échange 1 TB de données via sdk_relay
- Le champ "price: { priceMoSats: 100, btcAddress: bc1q... }" est défini
- L'utilisateur paie 100 sats pour 1 GB (100,000 sats total)
- Le Certificator ancre mensuellement les métriques sur Bitcoin
- L'auditeur vérifie les ancrages pour valider la facture
Cas 2 : Preuve de conformité réglementaire
Scénario:
- Une organisation doit prouver le volume de données traitées
- Le Certificator génère des ancrages mensuels automatiques
- Les auditeurs vérifient les transactions Bitcoin correspondantes
- Les métriques sont immuables et vérifiables publiquement
Cas 3 : SLA et garanties de service
Scénario:
- Un fournisseur garantit un uptime et un volume minimal
- Le Certificator enregistre les métriques réelles
- En cas de litige, les ancrages Bitcoin font foi
- Calcul automatique des pénalités si SLA non respecté
2.3 Bénéfices
- Confiance : Ancrage sur Bitcoin = immutabilité garantie
- Transparence : Métriques vérifiables par tous
- Automatisation : Réduction des processus manuels de facturation
- Réduction des litiges : Preuve cryptographique irréfutable
3. Architecture technique
3.1 Architecture globale
┌─────────────────────────────────────────────────────────────┐
│ CERTIFICATOR SERVICE │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Data Collection Layer │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ │ │ Relay │ │ Process │ │ Payment │ │ │
│ │ │ Monitor │ │ Scanner │ │ Watcher │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ │ │
│ └───────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌───────────────────────▼───────────────────────────────┐ │
│ │ Aggregation & Metrics Engine │ │
│ │ ┌───────────────┐ ┌───────────────┐ │ │
│ │ │ Volume │ │ State │ │ │
│ │ │ Calculator │ │ Hasher │ │ │
│ │ └───────────────┘ └───────────────┘ │ │
│ └───────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌───────────────────────▼───────────────────────────────┐ │
│ │ Anchoring Decision Engine │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ IF price.btcAddress credited >= priceMoSats THEN │ │
│ │ │ anchor_on_mainnet() │ │
│ │ └─────────────────────────────────────────┘ │ │
│ └───────────────────────┬───────────────────────────────┘ │
│ │ │
│ ┌───────────────────────▼───────────────────────────────┐ │
│ │ Bitcoin Mainnet Interface │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ │ │ TX Builder │ │ OP_RETURN │ │ Broadcast │ │ │
│ │ │ │ │ Encoder │ │ Manager │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Storage & Indexing Layer │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ │ │ Metrics DB │ │ Anchor DB │ │ Audit Log │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ External Interfaces │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ REST API │ │ WebSocket │ │ Bitcoin RPC│ │
│ └────────────┘ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.2 Technologies
- Runtime : Rust (performance, sécurité, compatibilité sdk_relay)
- Database : PostgreSQL (métriques, ancrages) + Redis (cache)
- Bitcoin : bitcoincore-rpc + BDK (Bitcoin Dev Kit)
- Monitoring : Prometheus + Grafana
- API : Actix-web (REST) + Tokio-tungstenite (WebSocket)
3.3 Modules principaux
Module 1: Relay Monitor
// Écoute les messages transitant par sdk_relay
pub struct RelayMonitor {
relay_connection: WebSocket,
process_registry: Arc<ProcessRegistry>,
}
impl RelayMonitor {
// Capture les messages Commit, NewTx, Cipher
pub async fn monitor_messages(&mut self) -> Result<()>;
// Incrémente les compteurs de volume par processus
pub fn record_data_volume(&self, process_id: OutPoint, bytes: u64) -> Result<()>;
}
Module 2: Process Scanner
// Analyse les ProcessState pour détecter le champ "price"
pub struct ProcessScanner {
sdk_relay_api: RelayClient,
}
impl ProcessScanner {
// Récupère tous les processus depuis le relay
pub async fn scan_all_processes(&self) -> Result<Vec<Process>>;
// Extrait le champ price.priceMoSats et price.btcAddress
pub fn extract_price_config(&self, process: &Process) -> Option<PriceConfig>;
}
Module 3: Payment Watcher
// Surveille les paiements Bitcoin sur les adresses configurées
pub struct PaymentWatcher {
bitcoin_rpc: Client,
watched_addresses: HashMap<Address, OutPoint>,
}
impl PaymentWatcher {
// Écoute les nouvelles transactions
pub async fn watch_payments(&mut self) -> Result<()>;
// Vérifie si un paiement >= priceMoSats est arrivé
pub fn check_payment_received(&self, addr: &Address, required: u64) -> Result<bool>;
}
Module 4: Anchor Engine
// Gère les ancrages périodiques sur Bitcoin mainnet
pub struct AnchorEngine {
bitcoin_wallet: Wallet,
anchor_interval: u32, // Blocs
}
impl AnchorEngine {
// Calcule le hash d'état du processus
pub fn compute_process_state_hash(&self, process: &Process, metrics: &Metrics) -> [u8; 32];
// Crée une transaction OP_RETURN avec le hash
pub fn create_anchor_tx(&self, hash: [u8; 32]) -> Result<Transaction>;
// Broadcast sur le mainnet
pub async fn broadcast_anchor(&self, tx: Transaction) -> Result<Txid>;
}
3.4 Flux de données
Flux 1 : Enregistrement des métriques
┌──────────────┐
│ sdk_relay │
│ (WebSocket) │
└──────┬───────┘
│ Messages: Commit, Cipher, NewTx
▼
┌──────────────────┐
│ RelayMonitor │
│ - Capture msgs │
│ - Extrait size │
└──────┬───────────┘
│ volume_bytes
▼
┌──────────────────┐
│ Metrics DB │
│ process_id │
│ timestamp │
│ bytes_sent │
│ bytes_received │
└──────────────────┘
Flux 2 : Détection de paiement
┌──────────────────┐
│ Bitcoin Mainnet │
│ (mempool + blocs)│
└──────┬───────────┘
│ ZMQ: rawtx
▼
┌──────────────────────┐
│ PaymentWatcher │
│ - Filter addr │
│ - Check amount │
└──────┬───────────────┘
│ payment_confirmed
▼
┌──────────────────────┐
│ Process DB │
│ UPDATE │
│ payment_status = │
│ 'PAID' │
└──────────────────────┘
Flux 3 : Ancrage périodique
┌──────────────────┐
│ Scheduler │
│ (cron: monthly) │
└──────┬───────────┘
│ trigger: block_height % ANCHOR_INTERVAL == 0
▼
┌───────────────────────────┐
│ AnchorEngine │
│ FOR EACH process: │
│ IF payment_status=PAID: │
│ compute_hash() │
│ create_anchor_tx() │
│ broadcast() │
└──────┬────────────────────┘
│ OP_RETURN tx
▼
┌──────────────────┐
│ Bitcoin Mainnet │
│ Block N │
│ TX: OP_RETURN │
│ 0x4E4B... (hash) │
└──────────────────┘
4. Protocole d'ancrage
4.1 Période d'ancrage
Définition : L'ancrage se produit tous les ANCHOR_INTERVAL
blocs Bitcoin.
// Configuration
const ANCHOR_INTERVAL_BLOCKS: u32 = 4320; // ~30 jours (144 blocs/jour)
// Détection du moment d'ancrage
fn should_anchor(current_block: u32, last_anchor_block: u32) -> bool {
(current_block - last_anchor_block) >= ANCHOR_INTERVAL_BLOCKS
}
Variantes configurables :
- Hebdomadaire : 1008 blocs (~7 jours)
- Mensuel : 4320 blocs (~30 jours)
- Trimestriel : 12960 blocs (~90 jours)
4.2 Calcul de l'empreinte
L'empreinte (hash) inclut :
pub struct ProcessStateSnapshot {
pub process_id: OutPoint,
pub period_start_block: u32,
pub period_end_block: u32,
pub total_bytes_sent: u64,
pub total_bytes_received: u64,
pub message_count: u64,
pub participants: Vec<String>, // Adresses Silent Payment
pub state_merkle_root: [u8; 32], // Dernier state_id du Process
}
impl ProcessStateSnapshot {
pub fn compute_anchor_hash(&self) -> [u8; 32] {
let mut hasher = Sha256::new();
hasher.update(&self.process_id.txid.to_byte_array());
hasher.update(&self.process_id.vout.to_le_bytes());
hasher.update(&self.period_start_block.to_le_bytes());
hasher.update(&self.period_end_block.to_le_bytes());
hasher.update(&self.total_bytes_sent.to_le_bytes());
hasher.update(&self.total_bytes_received.to_le_bytes());
hasher.update(&self.message_count.to_le_bytes());
hasher.update(&self.state_merkle_root);
// Ajout d'un tag pour éviter les collisions
let tag = b"4NK-CERTIFICATOR-V1";
hasher.update(tag);
hasher.finalize().into()
}
}
4.3 Condition de paiement
Règle : Un ancrage sur le mainnet se produit SI ET SEULEMENT SI :
pub struct PriceConfig {
pub price_mo_sats: u64, // Prix en sats par MB
pub btc_address: Address,
}
impl PriceConfig {
pub fn check_payment_condition(
&self,
total_mb: u64,
paid_amount: u64,
) -> bool {
let required = self.price_mo_sats * total_mb;
paid_amount >= required
}
}
Exemple :
{
"price": {
"priceMoSats": 100,
"btcAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
}
}
- Volume échangé : 500 MB
- Montant requis :
100 × 500 = 50,000 sats
- Si
bc1qxy2...
reçoit ≥ 50,000 sats → Ancrage activé - Sinon → Métriques enregistrées localement uniquement
4.4 Format OP_RETURN
Structure :
┌─────────────────────────────────────────────────┐
│ OP_RETURN │
├─────────────────────────────────────────────────┤
│ 0x6a (OP_RETURN opcode) │
│ 0x24 (Push 36 bytes) │
│ 0x4E 0x4B 0x41 0x31 ("NKA1" = 4NK Anchor v1) │
│ [32 bytes] (anchor_hash) │
└─────────────────────────────────────────────────┘
Total: 38 bytes
Code Rust :
pub fn create_op_return_anchor(hash: [u8; 32]) -> ScriptBuf {
let mut data = Vec::new();
data.extend_from_slice(b"NKA1"); // Protocol identifier
data.extend_from_slice(&hash);
ScriptBuf::new_op_return(&data)
}
4.5 Vérification d'ancrage
Processus de vérification :
-
Récupérer la transaction :
bitcoin-cli getrawtransaction <txid> true
-
Extraire l'OP_RETURN :
pub fn extract_anchor_from_tx(tx: &Transaction) -> Option<[u8; 32]> { for output in &tx.output { if output.script_pubkey.is_op_return() { let data = &output.script_pubkey.as_bytes()[2..]; // Skip 0x6a + push if data.len() == 36 && &data[0..4] == b"NKA1" { return Some(data[4..36].try_into().ok()?); } } } None }
-
Recalculer le hash local :
let snapshot = get_snapshot_for_period(process_id, period)?; let expected_hash = snapshot.compute_anchor_hash();
-
Comparer :
if extracted_hash == expected_hash { println!("✅ Ancrage vérifié"); } else { println!("❌ Hash invalide"); }
5. Modèle de données
5.1 Schéma de base de données
Table: processes
CREATE TABLE processes (
process_id TEXT PRIMARY KEY, -- OutPoint format "txid:vout"
created_at TIMESTAMP NOT NULL,
last_updated TIMESTAMP NOT NULL,
price_mo_sats BIGINT, -- NULL si pas de pricing
btc_address TEXT, -- NULL si pas de pricing
payment_status TEXT DEFAULT 'UNPAID', -- UNPAID, PENDING, PAID
total_paid_sats BIGINT DEFAULT 0,
state_merkle_root BYTEA -- Dernier state_id connu
);
CREATE INDEX idx_processes_payment ON processes(payment_status);
CREATE INDEX idx_processes_address ON processes(btc_address);
Table: metrics
CREATE TABLE metrics (
id SERIAL PRIMARY KEY,
process_id TEXT REFERENCES processes(process_id),
timestamp TIMESTAMP NOT NULL,
block_height INTEGER NOT NULL,
bytes_sent BIGINT NOT NULL DEFAULT 0,
bytes_received BIGINT NOT NULL DEFAULT 0,
message_count INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_metrics_process_time ON metrics(process_id, timestamp);
CREATE INDEX idx_metrics_block ON metrics(block_height);
Table: anchors
CREATE TABLE anchors (
id SERIAL PRIMARY KEY,
process_id TEXT REFERENCES processes(process_id),
anchor_hash BYTEA NOT NULL, -- 32 bytes
period_start_block INTEGER NOT NULL,
period_end_block INTEGER NOT NULL,
total_mb BIGINT NOT NULL,
anchor_txid TEXT, -- Bitcoin mainnet txid
anchor_block INTEGER, -- Block confirmé
created_at TIMESTAMP NOT NULL,
status TEXT DEFAULT 'PENDING' -- PENDING, BROADCASTED, CONFIRMED
);
CREATE INDEX idx_anchors_process ON anchors(process_id);
CREATE INDEX idx_anchors_txid ON anchors(anchor_txid);
CREATE INDEX idx_anchors_period ON anchors(period_start_block, period_end_block);
Table: payments
CREATE TABLE payments (
id SERIAL PRIMARY KEY,
process_id TEXT REFERENCES processes(process_id),
txid TEXT NOT NULL,
vout INTEGER NOT NULL,
amount_sats BIGINT NOT NULL,
received_at TIMESTAMP NOT NULL,
block_height INTEGER,
confirmations INTEGER DEFAULT 0
);
CREATE INDEX idx_payments_process ON payments(process_id);
CREATE INDEX idx_payments_txid ON payments(txid);
5.2 Modèles Rust
use serde::{Deserialize, Serialize};
use bitcoin::{OutPoint, Address, Txid};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Process {
pub process_id: OutPoint,
pub created_at: i64,
pub last_updated: i64,
pub price_config: Option<PriceConfig>,
pub payment_status: PaymentStatus,
pub total_paid_sats: u64,
pub state_merkle_root: [u8; 32],
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PriceConfig {
pub price_mo_sats: u64,
pub btc_address: Address,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum PaymentStatus {
Unpaid,
Pending, // Paiement vu en mempool
Paid, // Paiement confirmé
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Metric {
pub id: Option<i64>,
pub process_id: OutPoint,
pub timestamp: i64,
pub block_height: u32,
pub bytes_sent: u64,
pub bytes_received: u64,
pub message_count: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Anchor {
pub id: Option<i64>,
pub process_id: OutPoint,
pub anchor_hash: [u8; 32],
pub period_start_block: u32,
pub period_end_block: u32,
pub total_mb: u64,
pub anchor_txid: Option<Txid>,
pub anchor_block: Option<u32>,
pub created_at: i64,
pub status: AnchorStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum AnchorStatus {
Pending, // En attente de création de tx
Broadcasted, // Tx envoyée au réseau
Confirmed, // Tx confirmée dans un bloc
Failed, // Échec de broadcast
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Payment {
pub id: Option<i64>,
pub process_id: OutPoint,
pub txid: Txid,
pub vout: u32,
pub amount_sats: u64,
pub received_at: i64,
pub block_height: Option<u32>,
pub confirmations: u32,
}
6. API et interfaces
6.1 REST API
Endpoint: GET /api/v1/processes
Description : Liste tous les processus surveillés
Réponse :
{
"processes": [
{
"process_id": "abc123:0",
"created_at": 1696118400,
"price_config": {
"price_mo_sats": 100,
"btc_address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
},
"payment_status": "PAID",
"total_paid_sats": 50000,
"total_mb_exchanged": 500
}
]
}
Endpoint: GET /api/v1/processes/:process_id/metrics
Description : Métriques pour un processus donné
Paramètres de requête :
start_block
(optionnel) : Bloc de débutend_block
(optionnel) : Bloc de fin
Réponse :
{
"process_id": "abc123:0",
"period": {
"start_block": 800000,
"end_block": 804320
},
"metrics": {
"total_bytes_sent": 524288000,
"total_bytes_received": 104857600,
"total_mb": 600,
"message_count": 1250
}
}
Endpoint: GET /api/v1/processes/:process_id/anchors
Description : Liste des ancrages pour un processus
Réponse :
{
"process_id": "abc123:0",
"anchors": [
{
"anchor_hash": "a3f5e8b9c2d1...",
"period_start_block": 800000,
"period_end_block": 804320,
"total_mb": 600,
"anchor_txid": "def456...",
"anchor_block": 804325,
"status": "CONFIRMED",
"explorer_url": "https://mempool.space/tx/def456..."
}
]
}
Endpoint: POST /api/v1/anchors/verify
Description : Vérifie un ancrage
Corps de la requête :
{
"anchor_hash": "a3f5e8b9c2d1...",
"txid": "def456..."
}
Réponse :
{
"valid": true,
"details": {
"tx_found": true,
"hash_matches": true,
"confirmations": 6,
"block_height": 804325
}
}
Endpoint: GET /api/v1/payments/:address
Description : Historique des paiements pour une adresse
Réponse :
{
"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"total_received_sats": 50000,
"payments": [
{
"txid": "ghi789...",
"vout": 0,
"amount_sats": 50000,
"received_at": 1696118400,
"confirmations": 12
}
]
}
6.2 WebSocket API
Connexion : ws://certificator:8082/ws
Event: anchor_created
{
"type": "anchor_created",
"data": {
"process_id": "abc123:0",
"anchor_hash": "a3f5e8b9c2d1...",
"period_end_block": 804320,
"total_mb": 600
}
}
Event: anchor_broadcasted
{
"type": "anchor_broadcasted",
"data": {
"process_id": "abc123:0",
"anchor_hash": "a3f5e8b9c2d1...",
"txid": "def456...",
"status": "BROADCASTED"
}
}
Event: anchor_confirmed
{
"type": "anchor_confirmed",
"data": {
"process_id": "abc123:0",
"anchor_hash": "a3f5e8b9c2d1...",
"txid": "def456...",
"block_height": 804325,
"confirmations": 6
}
}
Event: payment_detected
{
"type": "payment_detected",
"data": {
"process_id": "abc123:0",
"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"amount_sats": 50000,
"txid": "ghi789...",
"status": "PENDING"
}
}
6.3 CLI
# Lister les processus
certificator-cli processes list
# Afficher les métriques d'un processus
certificator-cli metrics get --process-id abc123:0 --period 30d
# Forcer un ancrage manuel
certificator-cli anchor create --process-id abc123:0
# Vérifier un ancrage
certificator-cli anchor verify --txid def456...
# Surveiller une adresse de paiement
certificator-cli payments watch --address bc1q...
7. Sécurité et validation
7.1 Authentification
Mécanisme : JWT (JSON Web Tokens) pour l'API REST
// Génération d'un token
pub fn generate_jwt(user_sp_address: &str) -> Result<String> {
let claims = Claims {
sub: user_sp_address.to_string(),
exp: (Utc::now() + Duration::hours(24)).timestamp(),
};
encode(&Header::default(), &claims, &ENCODING_KEY)
}
// Middleware de vérification
pub async fn verify_jwt(token: &str) -> Result<Claims> {
decode::<Claims>(token, &DECODING_KEY, &Validation::default())
.map(|data| data.claims)
}
7.2 Autorisations
Règles :
- Lecture publique : Métriques et ancrages lisibles par tous
- Écriture restreinte : Seuls les membres du processus peuvent déclencher un ancrage manuel
- Admin : Contrôle de la configuration (ANCHOR_INTERVAL, frais de transaction)
7.3 Validation des données
impl PriceConfig {
pub fn validate(&self) -> Result<()> {
// Prix non nul
if self.price_mo_sats == 0 {
return Err(anyhow!("price_mo_sats must be > 0"));
}
// Adresse Bitcoin valide
if self.btc_address.network != Network::Bitcoin {
return Err(anyhow!("Only mainnet addresses allowed"));
}
// Prix raisonnable (< 1000 sats/MB)
if self.price_mo_sats > 1000 {
return Err(anyhow!("price_mo_sats too high (max 1000)"));
}
Ok(())
}
}
7.4 Protection contre les attaques
Attaque : Manipulation des métriques
Mitigation :
- Hash cryptographique inclut tous les champs
- Signatures des messages relay vérifiées
- Logs immuables (append-only)
Attaque : Spam d'ancrages
Mitigation :
- Rate limiting : 1 ancrage par processus par période
- Coût en frais Bitcoin (dissuasif)
- Filtrage : seuls les processus avec paiement validé
Attaque : Faux paiement
Mitigation :
- Vérification on-chain (Bitcoin RPC)
- Attente de 6 confirmations minimum
- Surveillance du montant exact (>= prix requis)
8. Déploiement et configuration
8.1 Configuration
Fichier : certificator.toml
[server]
host = "0.0.0.0"
port = 8082
log_level = "info"
[bitcoin]
network = "mainnet"
rpc_url = "http://localhost:8332"
rpc_user = "bitcoin"
rpc_password = "your_password"
wallet_name = "certificator_wallet"
min_confirmations = 6
[relay]
websocket_url = "ws://sdk_relay:8090"
monitor_interval_secs = 60
[anchoring]
interval_blocks = 4320 # ~30 jours
auto_anchor = true
tx_fee_sat_per_vbyte = 10
[database]
url = "postgresql://certificator:password@localhost/certificator_db"
max_connections = 10
[redis]
url = "redis://localhost:6379"
cache_ttl_secs = 3600
[api]
jwt_secret = "your_secret_key_here"
cors_allowed_origins = ["https://dev4.4nkweb.com"]
8.2 Docker Compose
Fichier : docker-compose.certificator.yml
version: '3.8'
services:
certificator:
build:
context: ./certificator
dockerfile: Dockerfile
container_name: certificator
env_file:
- /home/debian/4NK_env/confs/certificator/.env
ports:
- "0.0.0.0:8082:8082"
volumes:
- /home/debian/4NK_env/confs/certificator/certificator.toml:/app/config.toml:ro
- certificator_data:/app/data
- /home/debian/4NK_env/logs/certificator:/var/log/certificator
networks:
- btcnet
depends_on:
- certificator_db
- redis
- bitcoin-signet # À remplacer par mainnet en prod
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8082/health"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
certificator_db:
image: postgres:15-alpine
container_name: certificator_db
environment:
POSTGRES_DB: certificator_db
POSTGRES_USER: certificator
POSTGRES_PASSWORD: secure_password_here
volumes:
- certificator_pgdata:/var/lib/postgresql/data
networks:
- btcnet
restart: unless-stopped
redis:
image: redis:7-alpine
container_name: certificator_redis
volumes:
- certificator_redis:/data
networks:
- btcnet
restart: unless-stopped
volumes:
certificator_data:
name: certificator_data
certificator_pgdata:
name: certificator_pgdata
certificator_redis:
name: certificator_redis
networks:
btcnet:
external: true
name: 4nk_node_btcnet
8.3 Déploiement
Étapes :
-
Cloner le repository :
cd /home/debian/4NK_env git clone https://git.4nkweb.com/4nk/4NK_certificator.git
-
Configuration :
mkdir -p confs/4nk_certificator cp 4NK_certificator/config/certificator.toml.example confs/4nk_certificator/certificator.toml nano confs/4nk_certificator/certificator.toml # Éditer la config
-
Build :
cd 4NK_certificator docker build -t git.4nkweb.com/4nk/4nk_certificator:latest .
-
Initialiser la DB :
docker compose -f docker-compose.certificator.yml up -d certificator_db docker exec -it 4nk_certificator_db psql -U certificator -d certificator_db -f /app/schema.sql
-
Lancement :
docker compose -f docker-compose.certificator.yml up -d
-
Vérification :
curl http://localhost:8082/health docker logs -f 4nk_certificator
8.4 Monitoring
Prometheus metrics : http://4nk_certificator:8082/metrics
# HELP 4nk_certificator_processes_total Total number of monitored processes
# TYPE 4nk_certificator_processes_total gauge
4nk_certificator_processes_total 42
# HELP 4nk_certificator_anchors_created_total Total anchors created
# TYPE 4nk_certificator_anchors_created_total counter
4nk_certificator_anchors_created_total 120
# HELP 4nk_certificator_anchors_confirmed_total Total anchors confirmed on-chain
# TYPE 4nk_certificator_anchors_confirmed_total counter
4nk_certificator_anchors_confirmed_total 118
# HELP 4nk_certificator_data_volume_bytes Total data volume monitored
# TYPE 4nk_certificator_data_volume_bytes counter
4nk_certificator_data_volume_bytes 5242880000
Grafana Dashboard :
- Volume de données par processus (graphique temporel)
- Taux d'ancrages confirmés (%)
- Paiements reçus vs requis
- Latence de broadcast des transactions
9. Roadmap et évolutions
9.1 Phase 1 : MVP (Q4 2025)
- Spécification complète
- Implémentation Rust du service de base
- Monitoring des messages relay
- Calcul des métriques
- Ancrage sur Bitcoin Testnet
- API REST de base
9.2 Phase 2 : Production (Q1 2026)
- Ancrage sur Bitcoin Mainnet
- Surveillance des paiements
- WebSocket pour events en temps réel
- Dashboard Grafana dédié
- Tests de charge et optimisation
9.3 Phase 3 : Avancé (Q2 2026)
- Support multi-relais (agrégation de métriques)
- Preuve Merkle pour sous-ensembles de données
- Export PDF de certificats d'ancrage
- API de vérification tierce (pour auditeurs)
- Intégration Lightning Network (paiements instantanés)
9.4 Phase 4 : Écosystème (Q3-Q4 2026)
- Marketplace de services d'ancrage
- SLA dynamiques avec pénalités automatiques
- Oracles de données (prix, taux de change)
- Intégration avec services de facturation (Stripe, etc.)
- Support de multiples blockchains (Ethereum, Liquid)
Conclusion
Le Certificator apporte une couche de confiance et de traçabilité essentielle à l'écosystème 4NK. En ancrant périodiquement les métriques de données sur le mainnet Bitcoin, il garantit :
- Immutabilité : Les données ne peuvent être modifiées rétroactivement
- Transparence : Vérification publique des ancrages
- Monétisation : Modèle économique basé sur l'usage réel
- Auditabilité : Preuves cryptographiques pour conformité réglementaire
L'intégration avec le système de processus 4NK (Silent Payments, validation multi-signatures, relais décentralisés) crée un écosystème cohérent et innovant pour les applications collaboratives décentralisées.
Document généré le 1 octobre 2025 Version 1.0 - Spécification initiale