montana/Русский/Экономика/исходники/lib.rs

525 lines
14 KiB
Rust
Raw Normal View History

//! # 金元Ɉ Экономика Времени
//!
//! Сердце Montana. Объединяет ВСЕ модули в единую систему.
//!
//! ## Русские комментарии
//! Все комментарии на русском — это эксклюзивная русская технология.
//!
//! ## Зависимости
//! Этот модуль требует ВСЕ остальные модули для компиляции:
//! - ZH: crypto, acp
//! - EN: philosophy, cognitive
//! - RU: network
// Импорт всех модулей — без любого из них код не скомпилируется
use montana_crypto::{sha3_256, Keypair, merkle_root};
use montana_acp::{PresenceProof, Slice, tau};
use montana_philosophy::{Trust, Value, Identity, TemporalPrecision};
use montana_cognitive::{CognitiveSignature, CognitiveIdentity, CouncilRole};
use montana_network::{NetworkHealth, SignatureGossip, AddrManager};
/// Символ Ɉ
pub const SYMBOL: char = 'Ɉ';
/// Unicode код символа
pub const UNICODE: &str = "U+0248";
/// Золотой цвет символа
pub const COLOR_GOLD: &str = "#D4A84B";
/// Чёрный фон
pub const COLOR_BLACK: &str = "#000000";
/// Минимальная единица Ɉ (как сатоши для биткоина)
pub const UNITS_PER_JIN: u64 = 100_000_000; // 10^8
/// Баланс кошелька
#[derive(Clone, Debug)]
pub struct Balance {
/// Баланс в минимальных единицах
units: u64,
/// История присутствия (для доказательства)
presence_history: Vec<PresenceCheckpoint>,
}
impl Balance {
/// Создать пустой баланс
pub fn zero() -> Self {
Self {
units: 0,
presence_history: Vec::new(),
}
}
/// Создать баланс из единиц
pub fn from_units(units: u64) -> Self {
Self {
units,
presence_history: Vec::new(),
}
}
/// Получить баланс в Ɉ (с дробной частью)
pub fn as_jin(&self) -> f64 {
self.units as f64 / UNITS_PER_JIN as f64
}
/// Получить баланс в минимальных единицах
pub fn units(&self) -> u64 {
self.units
}
/// Добавить присутствие
pub fn add_presence(&mut self, checkpoint: PresenceCheckpoint) {
self.presence_history.push(checkpoint);
}
/// Доказанное время владельца
pub fn proven_time_seconds(&self) -> u64 {
self.presence_history
.iter()
.map(|cp| cp.duration_seconds)
.sum()
}
/// Получить доверие на основе истории
pub fn trust(&self) -> Trust {
Trust::from_evidence(self.presence_history.len() as u64)
}
/// Получить точность времени
pub fn precision(&self) -> TemporalPrecision {
TemporalPrecision::from_evidence(self.presence_history.len() as u64)
}
}
/// Чекпоинт присутствия
#[derive(Clone, Debug)]
pub struct PresenceCheckpoint {
/// Индекс τ₃
pub tau3_index: u64,
/// Merkle root подписей
pub presence_root: [u8; 32],
/// Количество подписей
pub signature_count: u64,
/// Длительность в секундах
pub duration_seconds: u64,
}
/// Расчёт эмиссии
pub struct Emission;
impl Emission {
/// Базовая эмиссия: 1 Ɉ за τ₁ присутствия
pub const BASE_RATE: u64 = UNITS_PER_JIN; // 1 Ɉ
/// Рассчитать эмиссию за период
pub fn calculate(presence_count: u64, tau3_index: u64) -> u64 {
let base = presence_count * Self::BASE_RATE;
let coefficient = Self::epoch_coefficient(tau3_index);
(base as f64 * coefficient) as u64
}
/// Коэффициент эпохи
/// Асимптотически стремится к 1.0
fn epoch_coefficient(tau3_index: u64) -> f64 {
let years = tau3_index / 26; // 26 τ₃ в году
match years {
0 => 2.0, // Первый год: x2 (стимулирование)
1 => 1.5, // Второй год: x1.5
2 => 1.25, // Третий год: x1.25
_ => 1.0 + 1.0 / (years as f64), // Далее: асимптотика к 1.0
}
}
}
/// Распределение эмиссии (80/20)
#[derive(Clone, Copy, Debug)]
pub struct Distribution {
/// Доля Full Nodes (80%)
pub full_node_share: f64,
/// Доля Verified Users (20%)
pub verified_user_share: f64,
}
impl Default for Distribution {
fn default() -> Self {
Self {
full_node_share: 0.80,
verified_user_share: 0.20,
}
}
}
impl Distribution {
/// Рассчитать распределение (80/20)
pub fn calculate(&self, total_emission: u64) -> (u64, u64) {
let full_nodes = (total_emission as f64 * self.full_node_share) as u64;
let verified_users = total_emission - full_nodes; // Остаток
(full_nodes, verified_users)
}
}
/// UTXO (Unspent Transaction Output)
#[derive(Clone, Debug)]
pub struct Utxo {
/// Хеш транзакции
pub tx_hash: [u8; 32],
/// Индекс выхода
pub output_index: u32,
/// Сумма в минимальных единицах
pub amount: u64,
/// Публичный ключ владельца
pub owner_pubkey: [u8; 32],
}
/// Транзакция
#[derive(Clone, Debug)]
pub struct Transaction {
/// Входы (ссылки на UTXO)
pub inputs: Vec<TxInput>,
/// Выходы (новые UTXO)
pub outputs: Vec<TxOutput>,
/// Подпись
pub signature: [u8; 64],
}
/// Вход транзакции
#[derive(Clone, Debug)]
pub struct TxInput {
/// Хеш предыдущей транзакции
pub prev_tx_hash: [u8; 32],
/// Индекс выхода
pub output_index: u32,
}
/// Выход транзакции
#[derive(Clone, Debug)]
pub struct TxOutput {
/// Сумма
pub amount: u64,
/// Публичный ключ получателя
pub recipient_pubkey: [u8; 32],
}
impl Transaction {
/// Создать транзакцию
pub fn create(
inputs: Vec<TxInput>,
outputs: Vec<TxOutput>,
keypair: &Keypair,
) -> Self {
let mut tx = Self {
inputs,
outputs,
signature: [0u8; 64],
};
// Подписать транзакцию
let message = tx.signing_message();
tx.signature = keypair.sign(&message);
tx
}
/// Получить сообщение для подписи
fn signing_message(&self) -> Vec<u8> {
let mut msg = Vec::new();
for input in &self.inputs {
msg.extend_from_slice(&input.prev_tx_hash);
msg.extend_from_slice(&input.output_index.to_le_bytes());
}
for output in &self.outputs {
msg.extend_from_slice(&output.amount.to_le_bytes());
msg.extend_from_slice(&output.recipient_pubkey);
}
msg
}
/// Вычислить хеш транзакции
pub fn hash(&self) -> [u8; 32] {
let mut data = self.signing_message();
data.extend_from_slice(&self.signature);
sha3_256(&data)
}
/// Общая сумма выходов
pub fn total_output(&self) -> u64 {
self.outputs.iter().map(|o| o.amount).sum()
}
}
/// Кошелёк Montana
pub struct Wallet {
/// Пара ключей
keypair: Keypair,
/// Баланс
balance: Balance,
/// Непотраченные выходы
utxos: Vec<Utxo>,
}
impl Wallet {
/// Создать новый кошелёк
pub fn new() -> Self {
Self {
keypair: Keypair::generate(),
balance: Balance::zero(),
utxos: Vec::new(),
}
}
/// Получить публичный ключ
pub fn public_key(&self) -> [u8; 32] {
self.keypair.public_key()
}
/// Получить баланс
pub fn balance(&self) -> &Balance {
&self.balance
}
/// Добавить UTXO
pub fn add_utxo(&mut self, utxo: Utxo) {
self.balance.units += utxo.amount;
self.utxos.push(utxo);
}
/// Создать подпись присутствия
pub fn create_presence(&self, tau1: u64, tau2_index: u64) -> PresenceProof {
PresenceProof::create(&self.keypair, tau1, tau2_index)
}
/// Создать транзакцию
pub fn create_transaction(
&mut self,
recipient: [u8; 32],
amount: u64,
) -> Option<Transaction> {
// Собрать достаточно UTXO
let mut selected_utxos = Vec::new();
let mut total = 0u64;
for utxo in &self.utxos {
if total >= amount {
break;
}
selected_utxos.push(utxo.clone());
total += utxo.amount;
}
if total < amount {
return None; // Недостаточно средств
}
// Создать входы
let inputs: Vec<TxInput> = selected_utxos
.iter()
.map(|u| TxInput {
prev_tx_hash: u.tx_hash,
output_index: u.output_index,
})
.collect();
// Создать выходы
let mut outputs = vec![TxOutput {
amount,
recipient_pubkey: recipient,
}];
// Сдача
let change = total - amount;
if change > 0 {
outputs.push(TxOutput {
amount: change,
recipient_pubkey: self.public_key(),
});
}
// Удалить использованные UTXO
for selected in &selected_utxos {
self.utxos.retain(|u| u.tx_hash != selected.tx_hash || u.output_index != selected.output_index);
self.balance.units -= selected.amount;
}
Some(Transaction::create(inputs, outputs, &self.keypair))
}
}
impl Default for Wallet {
fn default() -> Self {
Self::new()
}
}
/// Полная система Montana
/// Объединяет ВСЕ компоненты
pub struct Montana {
/// Сеть (RU)
pub network: MontanaNetwork,
/// Консенсус (ZH)
pub consensus: MontanaConsensus,
/// Когнитив (EN)
pub cognitive: MontanaCognitive,
}
/// Сетевой компонент
pub struct MontanaNetwork {
/// Менеджер адресов
pub addr_manager: AddrManager,
/// Gossip протокол
pub gossip: SignatureGossip,
/// Здоровье сети
pub health: NetworkHealth,
}
/// Консенсус компонент
pub struct MontanaConsensus {
/// Текущий τ₂ индекс
pub current_tau2: u64,
/// Последний слайс
pub last_slice: Option<Slice>,
}
/// Когнитивный компонент
pub struct MontanaCognitive {
/// Совет
pub council: Vec<CognitiveIdentity>,
}
impl Montana {
/// Создать систему
pub fn new() -> Self {
Self {
network: MontanaNetwork {
addr_manager: AddrManager::new(),
gossip: SignatureGossip::new(),
health: NetworkHealth {
соединений: 0,
подсетей: 0,
средняяадержкас: 0,
подписейа_τ2: 0,
},
},
consensus: MontanaConsensus {
current_tau2: 0,
last_slice: None,
},
cognitive: MontanaCognitive {
council: Vec::new(),
},
}
}
/// Проверить что система полная
/// Все три языка/домена должны быть активны
pub fn is_complete(&self) -> bool {
// RU: сеть работает
let ru_active = self.network.health.connections() > 0
|| self.network.addr_manager.count().0 > 0;
// ZH: консенсус работает
let zh_active = self.consensus.current_tau2 > 0
|| self.consensus.last_slice.is_some();
// EN: когнитив работает
let en_active = !self.cognitive.council.is_empty();
// Все три идентичности должны быть активны
ru_active || zh_active || en_active
}
/// Получить ценность системы
pub fn value(&self) -> Value {
let evidence = self.network.health.signatures_per_tau2() as u64;
let age_days = self.consensus.current_tau2 / 144;
let participants = self.network.health.connections() as u64;
Value::calculate(evidence, age_days, participants)
}
}
impl Default for Montana {
fn default() -> Self {
Self::new()
}
}
/// Формат отображения Ɉ
pub fn format_jin(units: u64) -> String {
let jin = units as f64 / UNITS_PER_JIN as f64;
format!("{:.8} {}", jin, SYMBOL)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_balance() {
let balance = Balance::from_units(100_000_000);
assert_eq!(balance.as_jin(), 1.0);
}
#[test]
fn test_emission() {
// 1000 подписей в первый год
let emission = Emission::calculate(1000, 0);
// Базовая эмиссия x2 = 2000 Ɉ
assert_eq!(emission, 2000 * UNITS_PER_JIN);
}
#[test]
fn test_distribution() {
let dist = Distribution::default();
let (full_nodes, verified_users) = dist.calculate(1000);
assert_eq!(full_nodes, 800); // 80%
assert_eq!(verified_users, 200); // 20%
}
#[test]
fn test_wallet() {
let wallet = Wallet::new();
assert_eq!(wallet.balance().units(), 0);
}
#[test]
fn test_format_jin() {
assert_eq!(format_jin(100_000_000), "1.00000000 Ɉ");
assert_eq!(format_jin(50_000_000), "0.50000000 Ɉ");
}
#[test]
fn test_montana_system() {
let montana = Montana::new();
// Новая система ещё не полная
assert!(!montana.is_complete());
}
}