neo3/neo_contract/
contract_management.rs

1use async_trait::async_trait;
2use futures::{FutureExt, TryFutureExt};
3use primitive_types::H160;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7	builder::TransactionBuilder,
8	neo_clients::{APITrait, JsonRpcProvider, RpcClient},
9	neo_contract::{ContractError, SmartContractTrait},
10	ContractIdentifiers,
11};
12use neo3::prelude::*;
13
14/// A struct representing contract management functionalities
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct ContractManagement<'a, P: JsonRpcProvider> {
17	#[serde(deserialize_with = "deserialize_script_hash")]
18	#[serde(serialize_with = "serialize_script_hash")]
19	script_hash: ScriptHash,
20	#[serde(skip)]
21	provider: Option<&'a RpcClient<P>>,
22}
23
24impl<'a, P: JsonRpcProvider + 'static> ContractManagement<'a, P> {
25	pub fn new(script_hash: H160, provider: Option<&'a RpcClient<P>>) -> Self {
26		Self { script_hash, provider }
27	}
28
29	pub async fn get_minimum_deployment_fee(&self) -> Result<u64, ContractError> {
30		Ok(self
31			.provider
32			.unwrap()
33			.invoke_function(&self.script_hash, "getMinimumDeploymentFee".to_string(), vec![], None)
34			.await?
35			.stack[0]
36			.as_int()
37			.unwrap() as u64)
38	}
39
40	pub async fn set_minimum_deployment_fee(&self, fee: u64) -> Result<u64, ContractError> {
41		Ok(self
42			.provider
43			.unwrap()
44			.invoke_function(
45				&self.script_hash,
46				"setMinimumDeploymentFee".to_string(),
47				vec![fee.into()],
48				None,
49			)
50			.await?
51			.stack[0]
52			.as_int()
53			.unwrap() as u64)
54	}
55
56	pub async fn get_contract(&self, hash: H160) -> Result<ContractState, ContractError> {
57		self.provider
58			.unwrap()
59			.get_contract_state(hash)
60			.await
61			.map_err(|e| ContractError::RuntimeError(e.to_string()))
62	}
63
64	pub async fn get_contract_by_id(&self, id: u32) -> Result<ContractState, ContractError> {
65		let hash = self.get_contract_hash_by_id(id).await.unwrap();
66		self.get_contract(hash).await
67	}
68
69	pub async fn get_contract_hash_by_id(&self, id: u32) -> Result<ScriptHash, ContractError> {
70		let result = self
71			.provider
72			.unwrap()
73			.invoke_function(
74				&self.script_hash,
75				"getContractById".to_string(),
76				vec![id.into()],
77				None,
78			)
79			.await
80			.unwrap()
81			.stack;
82
83		let item = &result[0];
84		Ok(ScriptHash::from_slice(&item.as_bytes().unwrap()))
85	}
86
87	pub async fn get_contract_hashes(&self) -> Result<ContractIdentifiers, ContractError> {
88		self.provider
89			.unwrap()
90			.invoke_function(&self.script_hash, "getContractHashes".to_string(), vec![], None)
91			.await
92			.map(|item| ContractIdentifiers::from_invocation_result(item).unwrap())
93			.map_err(|e| {
94				// Convert ProviderError to ContractError here
95				// This assumes you have a way to convert from ProviderError to ContractError
96				ContractError::from(e)
97			})
98	}
99
100	pub async fn has_method(
101		&self,
102		hash: H160,
103		method: &str,
104		params: usize,
105	) -> Result<bool, ContractError> {
106		self.provider
107			.unwrap()
108			.invoke_function(
109				&self.script_hash,
110				"hasMethod".to_string(),
111				vec![hash.into(), method.into(), params.into()],
112				None,
113			)
114			.await
115			.map(|item| item.stack[0].as_bool().unwrap())
116			.map_err(|e| ContractError::RuntimeError(e.to_string()))
117	}
118
119	pub async fn deploy(
120		&self,
121		nef: &NefFile,
122		manifest: &[u8],
123		data: Option<ContractParameter>,
124	) -> Result<TransactionBuilder<P>, ContractError> {
125		let params = vec![nef.into(), manifest.into(), data.unwrap()];
126		let tx = self.invoke_function("deploy", params).await;
127		tx
128	}
129}
130
131#[async_trait]
132impl<'a, P: JsonRpcProvider> SmartContractTrait<'a> for ContractManagement<'a, P> {
133	type P = P;
134
135	fn script_hash(&self) -> H160 {
136		self.script_hash.clone()
137	}
138
139	fn set_script_hash(&mut self, script_hash: H160) {
140		self.script_hash = script_hash;
141	}
142
143	fn provider(&self) -> Option<&RpcClient<P>> {
144		self.provider
145	}
146}