neo3/neo_contract/famous/
grandshare.rs

1use async_trait::async_trait;
2use primitive_types::H160;
3use serde::{Deserialize, Serialize};
4use std::str::FromStr;
5
6use crate::{
7	builder::{AccountSigner, TransactionBuilder},
8	neo_clients::{APITrait, JsonRpcProvider, RpcClient},
9	neo_contract::{ContractError, SmartContractTrait},
10	neo_protocol::Account,
11};
12use neo3::prelude::*;
13
14/// GrandShare contract interface for Neo N3
15///
16/// GrandShare is a governance and funding platform for Neo ecosystem projects.
17/// This contract interface provides methods to interact with the GrandShare smart contract.
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct GrandShareContract<'a, P: JsonRpcProvider> {
20	#[serde(deserialize_with = "deserialize_script_hash")]
21	#[serde(serialize_with = "serialize_script_hash")]
22	script_hash: ScriptHash,
23	#[serde(skip)]
24	provider: Option<&'a RpcClient<P>>,
25}
26
27impl<'a, P: JsonRpcProvider + 'static> GrandShareContract<'a, P> {
28	/// The script hash of the GrandShare contract on Neo N3 MainNet
29	pub const CONTRACT_HASH: &'static str = "74f2dc36a68fdc4682034178eb2220729231db76";
30
31	// Method constants
32	/// Method name for submitting a proposal
33	pub const SUBMIT_PROPOSAL: &'static str = "submitProposal";
34	/// Method name for voting on a proposal
35	pub const VOTE: &'static str = "vote";
36	/// Method name for funding a project
37	pub const FUND_PROJECT: &'static str = "fundProject";
38	/// Method name for claiming funds
39	pub const CLAIM_FUNDS: &'static str = "claimFunds";
40
41	/// Creates a new GrandShareContract instance with the default contract hash
42	///
43	/// # Arguments
44	///
45	/// * `provider` - An optional reference to an RPC client
46	///
47	/// # Returns
48	///
49	/// A new GrandShareContract instance
50	pub fn new(provider: Option<&'a RpcClient<P>>) -> Self {
51		Self { script_hash: ScriptHash::from_str(Self::CONTRACT_HASH).unwrap(), provider }
52	}
53
54	/// Creates a new GrandShareContract instance with a custom script hash
55	///
56	/// # Arguments
57	///
58	/// * `script_hash` - The script hash of the GrandShare contract
59	/// * `provider` - An optional reference to an RPC client
60	///
61	/// # Returns
62	///
63	/// A new GrandShareContract instance
64	pub fn with_script_hash(script_hash: ScriptHash, provider: Option<&'a RpcClient<P>>) -> Self {
65		Self { script_hash, provider }
66	}
67
68	/// Submits a proposal to GrandShare
69	///
70	/// # Arguments
71	///
72	/// * `title` - The title of the proposal
73	/// * `description` - The description of the proposal
74	/// * `requested_amount` - The amount of funds requested
75	/// * `account` - The account that will sign the transaction
76	///
77	/// # Returns
78	///
79	/// A transaction builder that can be used to build and sign the transaction
80	pub async fn submit_proposal(
81		&self,
82		title: &str,
83		description: &str,
84		requested_amount: i64,
85		account: &Account,
86	) -> Result<TransactionBuilder<P>, ContractError> {
87		let params =
88			vec![title.into(), description.into(), ContractParameter::integer(requested_amount)];
89
90		let mut builder = self.invoke_function(Self::SUBMIT_PROPOSAL, params).await?;
91		builder.set_signers(vec![AccountSigner::called_by_entry(account).unwrap().into()]);
92
93		Ok(builder)
94	}
95
96	/// Votes on a proposal in GrandShare
97	///
98	/// # Arguments
99	///
100	/// * `proposal_id` - The ID of the proposal to vote on
101	/// * `vote_type` - The type of vote (true for yes, false for no)
102	/// * `account` - The account that will sign the transaction
103	///
104	/// # Returns
105	///
106	/// A transaction builder that can be used to build and sign the transaction
107	pub async fn vote(
108		&self,
109		proposal_id: i32,
110		vote_type: bool,
111		account: &Account,
112	) -> Result<TransactionBuilder<P>, ContractError> {
113		let params = vec![
114			ContractParameter::integer(proposal_id.into()),
115			ContractParameter::bool(vote_type),
116		];
117
118		let mut builder = self.invoke_function(Self::VOTE, params).await?;
119		builder.set_signers(vec![AccountSigner::called_by_entry(account).unwrap().into()]);
120
121		Ok(builder)
122	}
123
124	/// Funds a project in GrandShare
125	///
126	/// # Arguments
127	///
128	/// * `project_id` - The ID of the project to fund
129	/// * `amount` - The amount of funds to provide
130	/// * `account` - The account that will sign the transaction
131	///
132	/// # Returns
133	///
134	/// A transaction builder that can be used to build and sign the transaction
135	pub async fn fund_project(
136		&self,
137		project_id: i32,
138		amount: i64,
139		account: &Account,
140	) -> Result<TransactionBuilder<P>, ContractError> {
141		let params =
142			vec![ContractParameter::integer(project_id.into()), ContractParameter::integer(amount)];
143
144		let mut builder = self.invoke_function(Self::FUND_PROJECT, params).await?;
145		builder.set_signers(vec![AccountSigner::called_by_entry(account).unwrap().into()]);
146
147		Ok(builder)
148	}
149
150	/// Claims funds from a funded project in GrandShare
151	///
152	/// # Arguments
153	///
154	/// * `project_id` - The ID of the project to claim funds from
155	/// * `account` - The account that will sign the transaction
156	///
157	/// # Returns
158	///
159	/// A transaction builder that can be used to build and sign the transaction
160	pub async fn claim_funds(
161		&self,
162		project_id: i32,
163		account: &Account,
164	) -> Result<TransactionBuilder<P>, ContractError> {
165		let params = vec![ContractParameter::integer(project_id.into())];
166
167		let mut builder = self.invoke_function(Self::CLAIM_FUNDS, params).await?;
168		builder.set_signers(vec![AccountSigner::called_by_entry(account).unwrap().into()]);
169
170		Ok(builder)
171	}
172}
173
174#[async_trait]
175impl<'a, P: JsonRpcProvider> SmartContractTrait<'a> for GrandShareContract<'a, P> {
176	type P = P;
177
178	fn script_hash(&self) -> H160 {
179		self.script_hash
180	}
181
182	fn set_script_hash(&mut self, script_hash: H160) {
183		self.script_hash = script_hash;
184	}
185
186	fn provider(&self) -> Option<&RpcClient<P>> {
187		self.provider
188	}
189}