diff --git a/README.md b/README.md
index a3c538c..cf55bbc 100644
--- a/README.md
+++ b/README.md
@@ -29,49 +29,20 @@
## 📝 About
+
Exploring the development of a crowdfunding smart contract on the Solana blockchain, leveraging the Rust programming language and the Anchor framework. Crowdfunding has emerged as a popular method for raising funds for various projects, initiatives, and charitable causes, and blockchain technology introduces new possibilities for enhancing transparency, security, and efficiency in this process.
## 🏛️ Architecture
+
-```sh
-- User Interface
- ┌───────────────┐ ┌───────────────┐ ┌───────────────┐
- │ Frontend │ │ Frontend │ │ Frontend │
- └───────┬───────┘ └───────┬───────┘ └───────┬───────┘
- │ │ │
- ▼ ▼ ▼
- ┌───────────────┐ ┌───────────────┐ ┌───────────────┐
- │ User Wallet │ │ User Wallet │ │ User Wallet │
- └───────────────┘ └───────────────┘ └───────────────┘
- │ │ │
- └───────────────┬──────────┼───────────────┬──────────┼───────────────┐
- ▼ │ ▼ │ │
- ┌───────────────┐ │ ┌───────────────┐ │ Smart │
- │ Solana RPC │ │ │ Solana RPC │ │ Contracts │
- └───────────────┘ │ └───────────────┘ │ │
- │ │ │ │ │
- └──────────┼──────────────┼──────────┼───────────────┘
- ▼ ▼ │
- ┌─────────────────────────┐ │
- │ Anchor Lang Program │◀──────┘
- └─────────────────────────┘
- │ │ │
- │ │ │
- ┌────────────┘ │ └────────────┐
- │ │ │
- ┌────────────────┐┌────────────────┐┌────────────────┐
- │ Create ││ Withdraw ││ Donate │
- │ Function ││ Function ││ Function │
- └────────────────┘└────────────────┘└────────────────┘
-```
-
## 🎯 Features
-The crowdfunding smart contract implemented using the Anchor framework on the Solana blockchain offers a range of features designed to enhance the fundraising experience while ensuring transparency, security, and efficiency.
+
+The crowdfunding smart contract implemented using the Anchor framework on the Solana blockchain offers a range of features designed to enhance the fundraising experience while ensuring transparency, security, and efficiency.
1. Campaign Creation:
@@ -122,6 +93,17 @@ category : "which type of campaign"
8. Immutable Record Keeping:
- Transactional data and campaign details recorded on the Solana blockchain are immutable and tamper-proof, providing a permanent and verifiable record of fundraising activities.
-Immutable records enhance auditability, mitigating the risk of fraud or data manipulation and fostering trust among stakeholders.
+ Immutable records enhance auditability, mitigating the risk of fraud or data manipulation and fostering trust among stakeholders.
-##
\ No newline at end of file
+## 🗂️ Folder Structure.
+
+```sh
+CrowdFund/
+├── programs/smart-contracts/
+├ ├── src/
+├ ├── lib.rs (contains smart contracts code)
+├── tests/
+ ├── smart-contracts.ts (contains test cases for smart contracts)
+
+
+```
diff --git a/programs/smart-contracts/src/lib.rs b/programs/smart-contracts/src/lib.rs
index 3174354..6bc6eb2 100644
--- a/programs/smart-contracts/src/lib.rs
+++ b/programs/smart-contracts/src/lib.rs
@@ -1,111 +1,147 @@
use anchor_lang::prelude::*;
use anchor_lang::solana_program::entrypoint::ProgramResult;
-declare_id!("HYCWfDk8ZU8SF5oF9CE2CyChgBU6yndn82Umo4iE1Q9T");
+declare_id!("E4fXqx7ybioeqZsHWNndNnqnpQ93DnV99gKnnxWXjvdu");
#[program]
pub mod smart_contracts {
- use super::*;
-
- //creates a campaign
- pub fn create(
- ctx: Context,
- name: String,
- description: String,
- target_amount: u64,
- project_url: String,
- progress_update_url: String,
- project_image_url: String,
- category: String
- ) -> ProgramResult {
- let campaign = &mut ctx.accounts.campaign;
- campaign.name = name;
- campaign.description = description;
- campaign.target_amount = target_amount;
- campaign.project_url = project_url;
- campaign.progress_update_url = progress_update_url;
- campaign.project_image_url = project_image_url;
- campaign.category = category;
- campaign.amount_donated = 0;
- campaign.amount_withdrawn = 0;
- campaign.admin = *ctx.accounts.user.key;
- Ok(())
+ use super::*;
+
+ //creates a campaign
+ pub fn create(
+ ctx: Context,
+ name: String,
+ description: String,
+ target_amount: u64,
+ project_url: String,
+ progress_update_url: String,
+ project_image_url: String,
+ category: String
+ ) -> ProgramResult {
+ let campaign = &mut ctx.accounts.campaign;
+ campaign.name = name;
+ campaign.description = description;
+ campaign.target_amount = target_amount;
+ campaign.project_url = project_url;
+ campaign.progress_update_url = progress_update_url;
+ campaign.project_image_url = project_image_url;
+ campaign.category = category;
+ campaign.amount_donated = 0;
+ campaign.amount_withdrawn = 0;
+ campaign.admin = *ctx.accounts.user.key;
+ Ok(())
+ }
+
+
+
+ //Withdraw from a campaign
+ pub fn withdraw(ctx: Context, amount: u64) -> ProgramResult {
+ let campaign = &mut ctx.accounts.campaign;
+ let user = &mut ctx.accounts.user;
+ //restricts Withdrawal to campaign admin
+ if campaign.admin != *user.key {
+ return Err(ProgramError::IncorrectProgramId);
}
- //Withdraw from a campaign
- pub fn withdraw(ctx: Context, amount: u64) -> ProgramResult {
- let campaign = &mut ctx.accounts.campaign;
- let user = &mut ctx.accounts.user;
- //restricts Withdrawal to campaign admin
- if campaign.admin != *user.key {
- return Err(ProgramError::IncorrectProgramId);
- }
- let rent_balance = Rent::get()?.minimum_balance(campaign.to_account_info().data_len());
- if **campaign.to_account_info().lamports.borrow() - rent_balance < amount {
- return Err(ProgramError::InsufficientFunds);
- }
- **campaign.to_account_info().try_borrow_mut_lamports()? -= amount;
- **user.to_account_info().try_borrow_mut_lamports()? += amount;
- (&mut ctx.accounts.campaign).amount_withdrawn += amount;
- Ok(())
+ let rent_balance = Rent::get()?.minimum_balance(campaign.to_account_info().data_len());
+ if **campaign.to_account_info().lamports.borrow() - rent_balance < amount {
+ return Err(ProgramError::InsufficientFunds);
}
- //Donate to a campaign
- pub fn donate(ctx: Context, amount: u64) -> ProgramResult {
- let ix = anchor_lang::solana_program::system_instruction::transfer(
- &ctx.accounts.user.key(),
- &ctx.accounts.campaign.key(),
- amount
- );
- anchor_lang::solana_program::program::invoke(
- &ix,
- &[ctx.accounts.user.to_account_info(), ctx.accounts.campaign.to_account_info()]
- );
- (&mut ctx.accounts.campaign).amount_donated += amount;
- Ok(())
+ **campaign.to_account_info().try_borrow_mut_lamports()? -= amount;
+ **user.to_account_info().try_borrow_mut_lamports()? += amount;
+ (&mut ctx.accounts.campaign).amount_withdrawn += amount;
+ Ok(())
+ }
+
+
+
+ //Donate to a campaign
+ pub fn donate(ctx: Context, amount: u64) -> ProgramResult {
+ let ix = anchor_lang::solana_program::system_instruction::transfer(
+ &ctx.accounts.user.key(),
+ &ctx.accounts.campaign.key(),
+ amount
+ );
+ // Store the result of the invoke function call
+ let result = anchor_lang::solana_program::program::invoke(
+ &ix,
+ &[ctx.accounts.user.to_account_info(), ctx.accounts.campaign.to_account_info()]
+ );
+ // Check if the invoke operation was successful
+ if let Err(e) = result {
+ return Err(e.into()); // Convert the error to a ProgramResult
+ }
+ // Proceed with the rest of the function
+ (&mut ctx.accounts.campaign).amount_donated += amount;
+ Ok(())
+ }
+
+ //Get the campaign
+ pub fn get_campaign(ctx: Context) -> ProgramResult {
+ let campaign = &ctx.accounts.campaign;
+ let user = &ctx.accounts.user;
+ if campaign.admin != *user.key {
+ return Err(ProgramError::IncorrectProgramId);
+ }
+ Ok(())
}
+
+
}
#[derive(Accounts)]
pub struct Create<'info> {
- #[account(
- init,
- payer = user,
- space = 9000,
- seeds = [b"CROWDFUND".as_ref(), user.key().as_ref()],
- bump
- )]
- pub campaign: Account<'info, Campaign>,
- #[account(mut)]
- pub user: Signer<'info>,
- pub system_program: Program<'info, System>,
+ #[account(
+ init,
+ payer = user,
+ space = 9000,
+ seeds = [b"CROWDFUND".as_ref(), user.key().as_ref()],
+ bump
+ )]
+ pub campaign: Account<'info, Campaign>,
+ #[account(mut)]
+ pub user: Signer<'info>,
+ pub system_program: Program<'info, System>,
}
+
#[derive(Accounts)]
pub struct Withdraw<'info> {
- #[account(mut)]
- pub campaign: Account<'info, Campaign>,
- #[account(mut)]
- pub user: Signer<'info>,
+ #[account(mut)]
+ pub campaign: Account<'info, Campaign>,
+ #[account(mut)]
+ pub user: Signer<'info>,
}
+
+
#[derive(Accounts)]
pub struct Donate<'info> {
- #[account(mut)]
- pub campaign: Account<'info, Campaign>,
- #[account(mut)]
- pub user: Signer<'info>,
- pub system_program: Program<'info, System>,
+ #[account(mut)]
+ pub campaign: Account<'info, Campaign>,
+ #[account(mut)]
+ pub user: Signer<'info>,
+ pub system_program: Program<'info, System>,
}
+#[derive(Accounts)]
+pub struct GetCampaign<'info> {
+ #[account(mut)]
+ pub campaign: Account<'info, Campaign>,
+ #[account(mut)]
+ pub user: Signer<'info>,
+}
+
+
#[account]
pub struct Campaign {
- pub admin: Pubkey,
- pub name: String,
- pub description: String,
- pub target_amount: u64,
- pub project_url: String,
- pub progress_update_url: String,
- pub project_image_url: String,
- pub category: String,
- pub amount_donated: u64,
- pub amount_withdrawn: u64,
+ pub admin: Pubkey,
+ pub name: String,
+ pub description: String,
+ pub target_amount: u64,
+ pub project_url: String,
+ pub progress_update_url: String,
+ pub project_image_url: String,
+ pub category: String,
+ pub amount_donated: u64,
+ pub amount_withdrawn: u64,
}
diff --git a/public/system-design.png b/public/system-design.png
index daaca26..c292bd3 100644
Binary files a/public/system-design.png and b/public/system-design.png differ