Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 25 additions & 18 deletions soroban/contracts/carbon-credit-registry/src/credits.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use soroban_sdk::{Env, Address, BytesN, String, Map, Vec, Bytes};
use soroban_sdk::{Address, Bytes, BytesN, Env, Map, String, Vec};

use crate::{
CarbonCredit, CreditStatus, CreditEvent, EventType, DataKey,
};
use crate::{CarbonCredit, CreditEvent, CreditStatus, DataKey, EventType};

/// Record a credit event in the history
pub fn record_credit_event(
Expand All @@ -13,7 +11,10 @@ pub fn record_credit_event(
to: Option<Address>,
quantity: i128,
) {
let event_count: u32 = env.storage().instance().get(&DataKey::EventCount(credit_id.clone()))
let event_count: u32 = env
.storage()
.instance()
.get(&DataKey::EventCount(credit_id.clone()))
.unwrap_or(0);

let event = CreditEvent {
Expand All @@ -27,32 +28,38 @@ pub fn record_credit_event(
metadata: Map::new(env),
};

env.storage().instance().set(&DataKey::CreditEvent(credit_id.clone(), event_count), &event);
env.storage().instance().set(&DataKey::EventCount(credit_id.clone()), &(event_count + 1));
env.storage().instance().set(
&DataKey::CreditEvent(credit_id.clone(), event_count),
&event,
);
env.storage()
.instance()
.set(&DataKey::EventCount(credit_id.clone()), &(event_count + 1));
}

/// Get credit status and details
pub fn get_credit_status(
env: &Env,
credit_id: BytesN<32>,
) -> Option<CarbonCredit> {
pub fn get_credit_status(env: &Env, credit_id: BytesN<32>) -> Option<CarbonCredit> {
env.storage().instance().get(&DataKey::Credit(credit_id))
}

/// Get credit transaction history
pub fn get_credit_history(
env: &Env,
credit_id: BytesN<32>,
) -> Vec<CreditEvent> {
let event_count: u32 = env.storage().instance().get(&DataKey::EventCount(credit_id.clone()))
pub fn get_credit_history(env: &Env, credit_id: BytesN<32>) -> Vec<CreditEvent> {
let event_count: u32 = env
.storage()
.instance()
.get(&DataKey::EventCount(credit_id.clone()))
.unwrap_or(0);

let mut events = Vec::new(env);
for i in 0..event_count {
if let Some(event) = env.storage().instance().get::<DataKey, crate::CreditEvent>(&DataKey::CreditEvent(credit_id.clone(), i)) {
if let Some(event) = env
.storage()
.instance()
.get::<DataKey, crate::CreditEvent>(&DataKey::CreditEvent(credit_id.clone(), i))
{
events.push_back(event);
}
}

events
}
}
137 changes: 82 additions & 55 deletions soroban/contracts/carbon-credit-registry/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#![no_std]

use soroban_sdk::{contract, contractimpl, contracttype, Address, Env, Vec, BytesN, String, Map};
use soroban_sdk::{contract, contractimpl, contracttype, Address, BytesN, Env, Map, String, Vec};

pub mod credits;
pub mod trading;
pub mod utils;

#[cfg(test)]
mod test;
mod tests;

// Core data structures for carbon credits
#[contracttype]
Expand Down Expand Up @@ -77,7 +77,7 @@ pub struct TradingParams {
pub from: Address,
pub to: Address,
pub quantity: i128,
pub price: i128, // Price per ton of CO2
pub price: i128, // Price per ton of CO2
pub payment_token: Address, // Payment token address
}

Expand All @@ -101,7 +101,7 @@ pub enum DataKey {
CreditCount,
EventCount(BytesN<32>), // credit_id -> event_count
Admin,
TradingFeeRate, // Fee rate for trading (in basis points)
TradingFeeRate, // Fee rate for trading (in basis points)
RetirementFeeRate, // Fee rate for retirement (in basis points)
TotalCreditsIssued,
TotalCreditsRetired,
Expand All @@ -120,14 +120,22 @@ impl CarbonCreditRegistry {
retirement_fee_rate: u32,
) {
admin.require_auth();

env.storage().instance().set(&DataKey::Admin, &admin);
env.storage().instance().set(&DataKey::TradingFeeRate, &trading_fee_rate);
env.storage().instance().set(&DataKey::RetirementFeeRate, &retirement_fee_rate);
env.storage()
.instance()
.set(&DataKey::TradingFeeRate, &trading_fee_rate);
env.storage()
.instance()
.set(&DataKey::RetirementFeeRate, &retirement_fee_rate);
env.storage().instance().set(&DataKey::IssuerCount, &0u32);
env.storage().instance().set(&DataKey::CreditCount, &0u32);
env.storage().instance().set(&DataKey::TotalCreditsIssued, &0i128);
env.storage().instance().set(&DataKey::TotalCreditsRetired, &0i128);
env.storage()
.instance()
.set(&DataKey::TotalCreditsIssued, &0i128);
env.storage()
.instance()
.set(&DataKey::TotalCreditsRetired, &0i128);
}

/// Register a new issuer
Expand All @@ -137,8 +145,7 @@ impl CarbonCreditRegistry {
name: String,
verification_standards: Vec<String>,
) {
let admin: Address = env.storage().instance().get(&DataKey::Admin)
.unwrap();
let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap();
admin.require_auth();

let issuer_profile = IssuerProfile {
Expand All @@ -150,12 +157,19 @@ impl CarbonCreditRegistry {
total_retired: 0,
};

env.storage().instance().set(&DataKey::Issuer(issuer_address), &issuer_profile);

let mut issuer_count: u32 = env.storage().instance().get(&DataKey::IssuerCount)
env.storage()
.instance()
.set(&DataKey::Issuer(issuer_address), &issuer_profile);

let mut issuer_count: u32 = env
.storage()
.instance()
.get(&DataKey::IssuerCount)
.unwrap_or(0);
issuer_count += 1;
env.storage().instance().set(&DataKey::IssuerCount, &issuer_count);
env.storage()
.instance()
.set(&DataKey::IssuerCount, &issuer_count);
}

/// Issue a new carbon credit
Expand Down Expand Up @@ -192,7 +206,9 @@ impl CarbonCreditRegistry {
};

// Store the credit
env.storage().instance().set(&DataKey::Credit(credit_id.clone()), &credit);
env.storage()
.instance()
.set(&DataKey::Credit(credit_id.clone()), &credit);

// Record issuance event
credits::record_credit_event(
Expand All @@ -205,66 +221,66 @@ impl CarbonCreditRegistry {
);

// Increment credit count
let mut credit_count: u32 = env.storage().instance().get(&DataKey::CreditCount)
let mut credit_count: u32 = env
.storage()
.instance()
.get(&DataKey::CreditCount)
.unwrap_or(0);
credit_count += 1;
env.storage().instance().set(&DataKey::CreditCount, &credit_count);
env.storage()
.instance()
.set(&DataKey::CreditCount, &credit_count);

credit_id
}

/// Trade a carbon credit
pub fn trade_credit(
env: Env,
params: TradingParams,
) {
pub fn trade_credit(env: Env, params: TradingParams) {
trading::trade_credit(env, params)
}

/// Retire a carbon credit
pub fn retire_credit(
env: Env,
params: RetirementParams,
) {
pub fn retire_credit(env: Env, params: RetirementParams) {
trading::retire_credit(env, params)
}

/// Suspend a credit (admin only)
pub fn suspend_credit(
env: Env,
credit_id: BytesN<32>,
reason: String,
) {
let admin: Address = env.storage().instance().get(&DataKey::Admin)
.unwrap();
pub fn suspend_credit(env: Env, credit_id: BytesN<32>, reason: String) {
let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap();
admin.require_auth();

let mut credit: CarbonCredit = env.storage().instance().get(&DataKey::Credit(credit_id.clone()))
let mut credit: CarbonCredit = env
.storage()
.instance()
.get(&DataKey::Credit(credit_id.clone()))
.unwrap();

credit.status = CreditStatus::Suspended;
env.storage().instance().set(&DataKey::Credit(credit_id.clone()), &credit);
env.storage()
.instance()
.set(&DataKey::Credit(credit_id.clone()), &credit);
}

/// Get credit status and details
pub fn get_credit_status(
env: Env,
credit_id: BytesN<32>,
) -> Option<CarbonCredit> {
pub fn get_credit_status(env: Env, credit_id: BytesN<32>) -> Option<CarbonCredit> {
env.storage().instance().get(&DataKey::Credit(credit_id))
}

/// Get credit transaction history
pub fn get_credit_history(
env: Env,
credit_id: BytesN<32>,
) -> Vec<CreditEvent> {
let event_count: u32 = env.storage().instance().get(&DataKey::EventCount(credit_id.clone()))
pub fn get_credit_history(env: Env, credit_id: BytesN<32>) -> Vec<CreditEvent> {
let event_count: u32 = env
.storage()
.instance()
.get(&DataKey::EventCount(credit_id.clone()))
.unwrap_or(0);

let mut events = Vec::new(&env);
for i in 0..event_count {
if let Some(event) = env.storage().instance().get(&DataKey::CreditEvent(credit_id.clone(), i)) {
if let Some(event) = env
.storage()
.instance()
.get(&DataKey::CreditEvent(credit_id.clone(), i))
{
events.push_back(event);
}
}
Expand All @@ -273,24 +289,35 @@ impl CarbonCreditRegistry {
}

/// Get issuer profile
pub fn get_issuer_profile(
env: Env,
issuer_address: Address,
) -> Option<IssuerProfile> {
env.storage().instance().get(&DataKey::Issuer(issuer_address))
pub fn get_issuer_profile(env: Env, issuer_address: Address) -> Option<IssuerProfile> {
env.storage()
.instance()
.get(&DataKey::Issuer(issuer_address))
}

/// Get contract statistics
pub fn get_contract_stats(env: Env) -> (u32, u32, i128, i128) {
let issuer_count: u32 = env.storage().instance().get(&DataKey::IssuerCount)
let issuer_count: u32 = env
.storage()
.instance()
.get(&DataKey::IssuerCount)
.unwrap_or(0);
let credit_count: u32 = env.storage().instance().get(&DataKey::CreditCount)
let credit_count: u32 = env
.storage()
.instance()
.get(&DataKey::CreditCount)
.unwrap_or(0);
let total_issued: i128 = env.storage().instance().get(&DataKey::TotalCreditsIssued)
let total_issued: i128 = env
.storage()
.instance()
.get(&DataKey::TotalCreditsIssued)
.unwrap_or(0);
let total_retired: i128 = env.storage().instance().get(&DataKey::TotalCreditsRetired)
let total_retired: i128 = env
.storage()
.instance()
.get(&DataKey::TotalCreditsRetired)
.unwrap_or(0);

(issuer_count, credit_count, total_issued, total_retired)
}
}
}
1 change: 0 additions & 1 deletion soroban/contracts/carbon-credit-registry/src/test.rs

This file was deleted.

Loading