Project Registry
Grantpicks Project Registry contract - Stellar
The Stellar Contract for Project Registry serves as a foundational component of the GrantPicks platform, enabling the management and organization of project submissions. This contract facilitates project creation, updates, and retrieval while ensuring that relevant information is securely stored and accessible.
Storage Structure
The contract utilizes a structured storage approach with defined keys to manage various aspects of project data:
ContractKey Enum: This enum defines the keys used in the contract's storage:
NumOfProjects: Keeps track of the total number of projects submitted.
Projects: Stores detailed data about each project.
RegistryAdmin: Identifies the administrators responsible for managing the registry.
ApplicantToProjectID: Maps applicants to their respective project IDs, establishing a one-to-one relationship.
#[contracttype]
#[derive(Clone)]
pub enum ContractKey {
NumOfProjects, // Project ID & Counter
Projects, // Project Data
RegistryAdmin, // Admin For Registry
ApplicantToProjectID, // Applicant Owned Project ID (1 to 1 relation)
}
Contract Error Code
The contract includes predefined error codes to handle common issues during project submissions:
EmptyName: Triggered if the project name is not provided.
EmptyOverview: Raised when the project overview is missing.
EmptyContacts: Indicates that contact information is not supplied.
EmptyAdmins: Occurs if no administrators are assigned to a project.
EmptyImageUrl: Raised when the image URL is not provided.
AdminOrOwnerOnly: Restricts certain actions to admins or project owners only.
OwnerOnly: Limits specific operations to the project owner.
ContractOwnerOnly: Restricts actions to the contract owner.
AlreadyApplied: Indicates that an applicant has already submitted a project.
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Error {
EmptyName = 1,
EmptyOverview = 2,
EmptyContacts = 3,
EmptyAdmins = 4,
EmptyImageUrl = 5,
AdminOrOwnerOnly = 6,
OwnerOnly = 7,
ContractOwnerOnly = 8,
AlreadyApplied = 9,
}
Data Type
The contract defines several data structures to represent project-related information:
Project: Contains comprehensive details about a project, including:
id
: Unique identifier for the project.image_url
: URL of the project's image.video_url
: URL for a promotional video.name
: Title of the project.overview
: Brief description of what the project entails.owner
: Address of the project owner.payout_address
: Address where funds will be sent upon approval.contacts
: List of contact information for team members.contracts
: List of associated contracts relevant to the project.team_members
: Information about team members involved in the project.repositories
: Links to relevant code repositories (e.g., GitHub).submitted_ms
: Timestamp of when the project was submitted.updated_ms
: Optional timestamp for when the project was last updated.admins
: List of administrators managing the project.
// project information
#[contracttype]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Project {
pub id: u128,
pub image_url: String,
pub video_url: String,
pub name: String,
pub overview: String,
pub owner: Address,
pub payout_address: Address,
pub contacts: Vec<ProjectContact>,
pub contracts: Vec<ProjectContract>,
pub team_members: Vec<ProjectTeamMember>,
pub repositories: Vec<ProjectRepository>,
pub submited_ms: u64,
pub updated_ms: Option<u64>,
pub admins: Vec<Address>,
}
#[contracttype]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProjectContact {
pub name: String,
pub value: String,
}
#[contracttype]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProjectContract {
pub name: String,
pub contract_address: String,
}
#[contracttype]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProjectTeamMember {
pub name: String,
pub value: String,
}
#[contracttype]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProjectRepository {
pub label: String,
pub url: String,
}
#[contracttype]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProjectFundingHistory {
pub source: String,
pub amount: u128,
pub denomination: String,
pub description: String,
pub funded_ms: u64,
}
// Project Create Params
#[contracttype]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CreateProjectParams {
pub image_url: String,
pub video_url: String,
pub name: String,
pub overview: String,
pub payout_address: Address,
pub contacts: Vec<ProjectContact>,
pub contracts: Vec<ProjectContract>,
pub team_members: Vec<ProjectTeamMember>,
pub repositories: Vec<ProjectRepository>,
pub fundings: Vec<ProjectFundingHistory>,
pub admins: Vec<Address>,
}
// update project params
#[contracttype]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UpdateProjectParams {
pub image_url: String,
pub video_url: String,
pub name: String,
pub overview: String,
pub payout_address: Address,
pub contacts: Vec<ProjectContact>,
pub contracts: Vec<ProjectContract>,
pub team_members: Vec<ProjectTeamMember>,
pub repositories: Vec<ProjectRepository>,
pub fundings: Vec<ProjectFundingHistory>,
}
Supporting Structures:
ProjectContact, ProjectContract, ProjectTeamMember, and ProjectRepository define additional details associated with each project.
Methods
The contract provides various methods for interacting with projects:
Initialization
initialize(env: &Env, contract_owner: Address)
: Initializes the contract with a specified owner.
Project Manipulation
apply(env: &Env, applicant: Address, params: CreateProjectParams) -> Project
: Allows an applicant to submit a new project based on provided parameters.update_project(env: &Env, admin: Address, project_id: u128, new_project_params: UpdateProjectParams)
: Enables an admin to update an existing project's details.add_admin(env: &Env, admin: Address, project_id: u128, new_admin: Address)
: Adds a new administrator to a specific project.remove_admin(env: &Env, admin: Address, project_id: u128, admin_to_remove: Address)
: Removes an administrator from a specific project.
Viewing Projects
get_project_by_id(env: &Env, project_id: u128) -> Option<Project>
: Retrieves a project's details using its ID.get_projects(env: &Env, skip: Option<u64>, limit: Option<u64>) -> Vec<Project>
: Fetches a list of projects with optional pagination parameters.get_project_admins(env: &Env, project_id: u128) -> Vec<Address>
: Returns a list of administrators for a specific project.get_total_projects(env: &Env) -> u32
: Provides the total number of projects submitted in the registry.get_project_from_applicant(env: &Env, applicant: Address) -> Option<Project>
: Retrieves projects associated with a specific applicant.
//WRITE
// init contract
fn initialize(env: &Env, contract_owner: Address);
// Project Manipulation
fn apply(env: &Env, applicant: Address, params: CreateProjectParams) -> Project;
fn update_project(
env: &Env,
admin: Address,
project_id: u128,
new_project_params: UpdateProjectParams,
);
fn add_admin(env: &Env, admin: Address, project_id: u128, new_admin: Address);
fn remove_admin(env: &Env, admin: Address, project_id: u128, admin_to_remove: Address);
fn upgrade(env: &Env, owner: Address, new_wasm_hash: BytesN<32>);
// VIEW
fn get_project_by_id(env: &Env, project_id: u128) -> Option<Project>;
fn get_projects(env: &Env, skip: Option<u64>, limit: Option<u64>) -> Vec<Project>;
fn get_project_admins(env: &Env, project_id: u128) -> Vec<Address>;
fn get_total_projects(env: &Env) -> u32;
fn get_project_from_applicant(env: &Env, applicant: Address) -> Option<Project>;
Events
The contract emits events to notify external systems about significant actions:
log_create_project_event(env: &Env, project: Project)
: Publishes an event when a new project is created.log_update_project_event(env: &Env, project: Project)
: Publishes an event when an existing project's details are updated.
pub fn log_create_project_event(env: &Env, project: Project) {
env.events().publish(
(symbol_short!("c_project"), env.current_contract_address()),
project,
);
}
pub fn log_update_project_event(env: &Env, project: Project) {
env.events().publish(
(symbol_short!("u_project"), env.current_contract_address()),
project,
);
}
Last updated
Was this helpful?