|
|
|
|
| use sha2::{Sha256, Digest};
|
| use serde::{Deserialize, Serialize};
|
|
|
|
|
| #[derive(Debug, Clone, Serialize, Deserialize)]
|
| pub struct ContractivityReceipt {
|
| pub prime_index: u64,
|
| pub hash: String,
|
| pub timestamp: String,
|
| pub operator: String,
|
| }
|
|
|
|
|
| pub struct ContractivityEngine {
|
| counter: u64,
|
| }
|
|
|
| impl ContractivityEngine {
|
| pub fn new() -> Self {
|
| Self { counter: 0 }
|
| }
|
|
|
|
|
| pub fn generate_receipt(&mut self, prime_index: u64, operator: &str) -> ContractivityReceipt {
|
| self.counter += 1;
|
|
|
| let content = format!(
|
| "{}:{}:{}:{}",
|
| operator, prime_index, self.counter,
|
| chrono::Utc::now().to_rfc3339()
|
| );
|
|
|
| let hash = {
|
| let mut hasher = Sha256::new();
|
| hasher.update(content.as_bytes());
|
| hex::encode(hasher.finalize())
|
| };
|
|
|
| ContractivityReceipt {
|
| prime_index,
|
| hash,
|
| timestamp: chrono::Utc::now().to_rfc3339(),
|
| operator: operator.to_string(),
|
| }
|
| }
|
|
|
|
|
| pub fn verify(&self, receipt: &ContractivityReceipt) -> bool {
|
| let content = format!(
|
| "{}:{}:{}:{}",
|
| receipt.operator,
|
| receipt.prime_index,
|
| 1,
|
| receipt.timestamp
|
| );
|
|
|
| let mut hasher = Sha256::new();
|
| hasher.update(content.as_bytes());
|
| let expected = hex::encode(hasher.finalize());
|
|
|
| receipt.hash == expected
|
| }
|
| }
|
|
|