neo3/neo_builder/transaction/signers/
contract_signer.rs1use crate::{
2 builder::{BuilderError, SignerTrait, SignerType, TransactionError, WitnessRule, WitnessScope},
3 codec::{Decoder, Encoder, NeoSerializable, VarSizeTrait},
4 config::NeoConstants,
5 crypto::Secp256r1PublicKey,
6 deserialize_script_hash, deserialize_vec_script_hash,
7 neo_types::{deserialize_vec_public_key, serialize_vec_public_key},
8 serialize_script_hash, serialize_vec_script_hash, ContractParameter,
9};
10use getset::{Getters, Setters};
11use primitive_types::H160;
12use serde::{Deserialize, Serialize};
13use std::hash::{Hash, Hasher};
14
15#[derive(Debug, Clone, Serialize, PartialEq, Deserialize, Getters, Setters)]
20pub struct ContractSigner {
21 #[serde(
22 serialize_with = "serialize_script_hash",
23 deserialize_with = "deserialize_script_hash"
24 )]
25 signer_hash: H160,
26 scopes: Vec<WitnessScope>,
27 #[serde(
28 serialize_with = "serialize_vec_script_hash",
29 deserialize_with = "deserialize_vec_script_hash"
30 )]
31 allowed_contracts: Vec<H160>,
32 #[serde(
33 serialize_with = "serialize_vec_public_key",
34 deserialize_with = "deserialize_vec_public_key"
35 )]
36 allowed_groups: Vec<Secp256r1PublicKey>,
37 rules: Vec<WitnessRule>,
38 #[getset(get = "pub")]
39 verify_params: Vec<ContractParameter>,
40 #[serde(
41 serialize_with = "serialize_script_hash",
42 deserialize_with = "deserialize_script_hash"
43 )]
44 #[serde(skip_deserializing)]
45 contract_hash: H160,
46 scope: WitnessScope,
47}
48
49impl Hash for ContractSigner {
50 fn hash<H: Hasher>(&self, state: &mut H) {
51 self.signer_hash.hash(state);
52 self.scopes.hash(state);
53 self.rules.hash(state);
56 self.verify_params.hash(state);
57 self.contract_hash.hash(state);
58 self.scope.hash(state);
59 }
60}
61
62impl SignerTrait for ContractSigner {
63 fn get_type(&self) -> SignerType {
64 SignerType::ContractSigner
65 }
66
67 fn get_signer_hash(&self) -> &H160 {
68 &self.signer_hash
69 }
70
71 fn set_signer_hash(&mut self, signer_hash: H160) {
72 self.signer_hash = signer_hash;
73 }
74
75 fn get_scopes(&self) -> &Vec<WitnessScope> {
76 &self.scopes
77 }
78
79 fn get_scopes_mut(&mut self) -> &mut Vec<WitnessScope> {
80 &mut self.scopes
81 }
82
83 fn set_scopes(&mut self, scopes: Vec<WitnessScope>) {
84 self.scopes = scopes;
85 }
86
87 fn get_allowed_contracts(&self) -> &Vec<H160> {
88 &self.allowed_contracts
89 }
90
91 fn get_allowed_contracts_mut(&mut self) -> &mut Vec<H160> {
92 &mut self.allowed_contracts
93 }
94
95 fn get_allowed_groups(&self) -> &Vec<Secp256r1PublicKey> {
96 &self.allowed_groups
97 }
98
99 fn get_allowed_groups_mut(&mut self) -> &mut Vec<Secp256r1PublicKey> {
100 &mut self.allowed_groups
101 }
102
103 fn get_rules(&self) -> &Vec<WitnessRule> {
104 &self.rules
105 }
106
107 fn get_rules_mut(&mut self) -> &mut Vec<WitnessRule> {
108 &mut self.rules
109 }
110}
111
112impl ContractSigner {
113 fn new(
114 contract_hash: H160,
115 scope: WitnessScope,
116 verify_params: Vec<ContractParameter>,
117 ) -> Self {
118 Self {
119 signer_hash: Default::default(),
120 scopes: vec![],
121 allowed_contracts: vec![],
122 allowed_groups: vec![],
123 rules: vec![],
124 verify_params,
125 contract_hash,
126 scope,
127 }
128 }
129
130 pub fn called_by_entry(contract_hash: H160, verify_params: &[ContractParameter]) -> Self {
137 Self::new(contract_hash, WitnessScope::CalledByEntry, verify_params.to_vec())
138 }
139
140 pub fn global(contract_hash: H160, verify_params: &[ContractParameter]) -> Self {
147 Self::new(contract_hash, WitnessScope::Global, verify_params.to_vec())
148 }
149}
150
151impl NeoSerializable for ContractSigner {
152 type Error = TransactionError;
153
154 fn size(&self) -> usize {
155 let mut size: usize = NeoConstants::HASH160_SIZE as usize;
156 if self.scopes.contains(&WitnessScope::CustomContracts) {
157 size += self.allowed_contracts.var_size();
158 }
159 if self.scopes.contains(&WitnessScope::CustomGroups) {
160 size += self.allowed_groups.var_size();
161 }
162 if self.scopes.contains(&WitnessScope::WitnessRules) {
163 size += self.rules.var_size();
164 }
165 size
166 }
167
168 fn encode(&self, writer: &mut Encoder) {
169 writer.write_serializable_fixed(&self.signer_hash);
170 writer.write_u8(WitnessScope::combine(&self.scopes));
171 if self.scopes.contains(&WitnessScope::CustomContracts) {
172 writer.write_serializable_variable_list(&self.allowed_contracts);
173 }
174 if self.scopes.contains(&WitnessScope::CustomGroups) {
175 writer.write_serializable_variable_list(&self.allowed_groups);
176 }
177 if self.scopes.contains(&WitnessScope::WitnessRules) {
178 writer.write_serializable_variable_list(&self.rules);
179 }
180 }
181
182 fn decode(reader: &mut Decoder) -> Result<Self, Self::Error>
183 where
184 Self: Sized,
185 {
186 let signer_hash = reader.read_serializable::<H160>().unwrap();
187 let scopes = WitnessScope::split(reader.read_u8());
188 let mut allowed_contracts = vec![];
189 let mut allowed_groups = vec![];
190 let mut rules = vec![];
191 if scopes.contains(&WitnessScope::CustomContracts) {
192 allowed_contracts = reader.read_serializable_list::<H160>().unwrap();
193 if allowed_contracts.len() > NeoConstants::MAX_SIGNER_SUBITEMS as usize {
194 return Err(BuilderError::SignerConfiguration(format!(
195 "A signer's scope can only contain {} allowed contracts. The input data contained {} contracts.",
196 NeoConstants::MAX_SIGNER_SUBITEMS,
197 allowed_contracts.len()
198 ))
199 .into());
200 }
201 }
202 if scopes.contains(&WitnessScope::CustomGroups) {
203 allowed_groups = reader.read_serializable_list::<Secp256r1PublicKey>().unwrap();
204 if allowed_groups.len() > NeoConstants::MAX_SIGNER_SUBITEMS as usize {
205 return Err(BuilderError::SignerConfiguration(format!(
206 "A signer's scope can only contain {} allowed contract groups. The input data contained {} groups.",
207 NeoConstants::MAX_SIGNER_SUBITEMS,
208 allowed_groups.len()
209 ))
210 .into());
211 }
212 }
213 if scopes.contains(&WitnessScope::WitnessRules) {
214 rules = reader.read_serializable_list::<WitnessRule>().unwrap();
215 if rules.len() > NeoConstants::MAX_SIGNER_SUBITEMS as usize {
216 return Err(BuilderError::SignerConfiguration(format!(
217 "A signer's scope can only contain {} rules. The input data contained {} rules.",
218 NeoConstants::MAX_SIGNER_SUBITEMS,
219 rules.len()
220 ))
221 .into());
222 }
223 }
224 Ok(Self {
225 signer_hash,
226 scopes,
227 allowed_contracts,
228 allowed_groups,
229 rules,
230 verify_params: vec![],
231 contract_hash: Default::default(),
232 scope: WitnessScope::None,
233 })
234 }
235
236 fn to_array(&self) -> Vec<u8> {
237 let mut writer = Encoder::new();
238 self.encode(&mut writer);
239 writer.to_bytes()
240 }
241}