neo3/neo_builder/transaction/signers/
transaction_signer.rs1use std::hash::{Hash, Hasher};
2
3use crate::{
4 builder::{SignerTrait, SignerType, TransactionError, WitnessRule, WitnessScope},
5 codec::{Decoder, Encoder, NeoSerializable, VarSizeTrait},
6 config::NeoConstants,
7 crypto::Secp256r1PublicKey,
8 deserialize_scopes, deserialize_script_hash, deserialize_vec_script_hash_option,
9 neo_types::{deserialize_vec_public_key_option, serialize_vec_public_key_option},
10 serialize_scopes, serialize_script_hash, serialize_vec_script_hash_option,
11};
12use lazy_static::lazy_static;
13use primitive_types::H160;
14use serde::{Deserialize, Serialize};
15
16lazy_static! {
17 static ref EMPTY_CONTRACTS: Vec<H160> = Vec::new();
18 static ref EMPTY_GROUPS: Vec<Secp256r1PublicKey> = Vec::new();
19 static ref EMPTY_RULES: Vec<WitnessRule> = Vec::new();
20}
21
22#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
27pub struct TransactionSigner {
28 #[serde(rename = "account")]
29 #[serde(serialize_with = "serialize_script_hash")]
30 #[serde(deserialize_with = "deserialize_script_hash")]
31 pub account: H160,
32
33 #[serde(rename = "scopes")]
34 #[serde(serialize_with = "serialize_scopes")]
35 #[serde(deserialize_with = "deserialize_scopes")]
36 pub scopes: Vec<WitnessScope>,
37
38 #[serde(rename = "allowedcontracts")]
39 #[serde(serialize_with = "serialize_vec_script_hash_option")]
40 #[serde(deserialize_with = "deserialize_vec_script_hash_option")]
41 #[serde(skip_serializing_if = "Option::is_none")]
42 #[serde(default)]
43 pub allowed_contracts: Option<Vec<H160>>,
44
45 #[serde(rename = "allowedgroups")]
46 #[serde(serialize_with = "serialize_vec_public_key_option")]
47 #[serde(deserialize_with = "deserialize_vec_public_key_option")]
48 #[serde(skip_serializing_if = "Option::is_none")]
49 #[serde(default)]
50 pub allowed_groups: Option<Vec<Secp256r1PublicKey>>,
51
52 #[serde(rename = "rules")]
53 #[serde(default)]
54 pub rules: Option<Vec<WitnessRule>>,
55}
56
57impl Hash for TransactionSigner {
58 fn hash<H: Hasher>(&self, state: &mut H) {
59 self.account.hash(state);
60 self.scopes.hash(state);
61 self.allowed_contracts.hash(state);
62 self.allowed_groups.hash(state);
63 self.rules.hash(state);
64 }
65}
66
67impl TransactionSigner {
68 pub fn new(account: H160, scopes: Vec<WitnessScope>) -> Self {
75 Self { account, scopes, allowed_contracts: None, allowed_groups: None, rules: None }
76 }
77
78 pub fn new_full(
88 account: H160,
89 scopes: Vec<WitnessScope>,
90 allowed_contracts: Vec<H160>,
91 allowed_groups: Vec<Secp256r1PublicKey>,
92 rules: Vec<WitnessRule>,
93 ) -> Self {
94 Self {
95 account,
96 scopes,
97 allowed_contracts: Some(allowed_contracts),
98 allowed_groups: Some(allowed_groups),
99 rules: Some(rules),
100 }
101 }
102}
103
104impl SignerTrait for TransactionSigner {
105 fn get_type(&self) -> SignerType {
106 SignerType::TransactionSigner
107 }
108
109 fn get_signer_hash(&self) -> &H160 {
110 &self.account
111 }
112
113 fn set_signer_hash(&mut self, signer_hash: H160) {
114 self.account = signer_hash;
115 }
116
117 fn get_scopes(&self) -> &Vec<WitnessScope> {
118 &self.scopes
119 }
120
121 fn get_scopes_mut(&mut self) -> &mut Vec<WitnessScope> {
122 &mut self.scopes
123 }
124
125 fn set_scopes(&mut self, scopes: Vec<WitnessScope>) {
126 self.scopes = scopes;
127 }
128
129 fn get_allowed_contracts(&self) -> &Vec<H160> {
130 self.allowed_contracts.as_ref().unwrap_or(&EMPTY_CONTRACTS)
131 }
132
133 fn get_allowed_contracts_mut(&mut self) -> &mut Vec<H160> {
134 self.allowed_contracts.get_or_insert_with(Vec::new)
135 }
136
137 fn get_allowed_groups(&self) -> &Vec<Secp256r1PublicKey> {
138 self.allowed_groups.as_ref().unwrap_or(&EMPTY_GROUPS)
139 }
140
141 fn get_allowed_groups_mut(&mut self) -> &mut Vec<Secp256r1PublicKey> {
142 self.allowed_groups.get_or_insert_with(Vec::new)
143 }
144
145 fn get_rules(&self) -> &Vec<WitnessRule> {
146 self.rules.as_ref().unwrap_or(&EMPTY_RULES)
147 }
148
149 fn get_rules_mut(&mut self) -> &mut Vec<WitnessRule> {
150 self.rules.get_or_insert_with(Vec::new)
151 }
152}
153
154impl NeoSerializable for TransactionSigner {
155 type Error = TransactionError;
156
157 fn size(&self) -> usize {
159 let mut size = (NeoConstants::HASH160_SIZE + 1) as usize;
160 if self.scopes.contains(&WitnessScope::CustomContracts) {
161 size += &self.allowed_contracts.clone().unwrap().var_size();
162 }
163 if self.scopes.contains(&WitnessScope::CustomGroups) {
164 size += &self.allowed_groups.clone().unwrap().var_size();
165 }
166
167 if self.scopes.contains(&WitnessScope::WitnessRules) {
168 size += &self.rules.clone().unwrap().var_size();
169 }
170
171 size
172 }
173
174 fn encode(&self, writer: &mut Encoder) {
176 writer.write_serializable_fixed(self.get_signer_hash());
177 writer.write_u8(WitnessScope::combine(self.scopes.as_slice()));
178 if self.scopes.contains(&WitnessScope::CustomContracts) {
179 writer.write_serializable_variable_list(self.allowed_contracts.as_ref().unwrap());
180 }
181 if self.scopes.contains(&WitnessScope::CustomGroups) {
182 writer.write_serializable_variable_list(self.allowed_groups.as_ref().unwrap());
183 }
184 if self.scopes.contains(&WitnessScope::WitnessRules) {
185 writer.write_serializable_variable_list(self.rules.as_ref().unwrap());
186 }
187 }
188
189 fn decode(reader: &mut Decoder) -> Result<Self, Self::Error>
191 where
192 Self: Sized,
193 {
194 let mut signer = TransactionSigner::default();
195 signer.set_signer_hash(reader.read_serializable().unwrap());
196 let scopes = WitnessScope::split(reader.read_u8());
197 signer.set_scopes(scopes);
198 if signer.get_scopes().contains(&WitnessScope::CustomContracts) {
199 signer.allowed_contracts = Some(reader.read_serializable_list().unwrap());
200 }
201 if signer.get_scopes().contains(&WitnessScope::CustomGroups) {
202 signer.allowed_groups = Some(reader.read_serializable_list().unwrap());
203 }
204 if signer.get_scopes().contains(&WitnessScope::WitnessRules) {
205 signer.rules = Some(reader.read_serializable_list().unwrap());
206 }
207 Ok(signer)
208 }
209
210 fn to_array(&self) -> Vec<u8> {
212 let writer = &mut Encoder::new();
213 self.encode(writer);
214 writer.to_bytes()
215 }
216}