bucky_objects/objects/
contract.rs

1use crate::*;
2
3use generic_array::typenum::U32;
4use generic_array::GenericArray;
5use std::convert::TryFrom;
6use std::ops::{Deref, DerefMut};
7use bucky_error::{BuckyError, BuckyResult};
8
9#[derive(Clone, Debug, RawEncode, RawDecode)]
10pub struct ERC20 {
11    pub name: String,
12    pub symbol: String,
13    pub decimals: u8,
14    pub total_supply: u64,
15}
16
17#[derive(Clone, Debug, RawEncode, RawDecode)]
18pub struct SNContract {
19    pub service_id: ObjectId,
20    pub account: UnionAccount,
21    pub start_time: u64,
22    pub stop_time: u64,
23}
24
25#[derive(Clone, Debug, RawEncode, RawDecode)]
26pub enum ServiceAuthType {
27    Any,
28    WhiteList,
29    BlackList,
30}
31
32#[derive(Clone, Debug, RawEncode, RawDecode)]
33pub struct SNContractBody {
34    auth_type: ServiceAuthType,
35    list: Vec<ObjectId>,
36}
37
38#[derive(Clone, Debug, RawEncode, RawDecode)]
39pub enum ContractTypeCode {
40    DSG,
41    Solidity,
42}
43
44#[derive(Clone, Debug, RawEncode, RawDecode)]
45pub struct ContractDescContent<T> {
46    pub contract_type: ContractTypeCode,
47    pub data: T,
48}
49
50impl<T> Deref for ContractDescContent<T> {
51    type Target = T;
52
53    fn deref(&self) -> &Self::Target {
54        &self.data
55    }
56}
57
58impl<T> DerefMut for ContractDescContent<T> {
59    fn deref_mut(&mut self) -> &mut Self::Target {
60        &mut self.data
61    }
62}
63
64#[derive(Clone, Debug, RawEncode, RawDecode)]
65pub struct ContractData {
66    pub data: Vec<u8>,
67}
68
69impl Deref for ContractData {
70    type Target = Vec<u8>;
71
72    fn deref(&self) -> &Self::Target {
73        &self.data
74    }
75}
76
77impl<T> DescContent for ContractDescContent<T> {
78    fn obj_type() -> u16 {
79        ObjectTypeCode::Contract.into()
80    }
81
82    type OwnerType = Option<ObjectId>;
83    type AreaType = SubDescNone;
84    type AuthorType = Option<ObjectId>;
85    type PublicKeyType = SubDescNone;
86}
87
88#[derive(Clone, Debug)]
89pub struct ContractBodyContent<T> {
90    pub data: T,
91}
92
93impl TryFrom<protos::ContractBodyContent> for ContractBodyContent<ContractData> {
94    type Error = BuckyError;
95
96    fn try_from(mut value: protos::ContractBodyContent) -> BuckyResult<Self> {
97        Ok(Self {
98            data: ContractData {
99                data: value.take_data(),
100            },
101        })
102    }
103}
104
105impl TryFrom<&ContractBodyContent<ContractData>> for protos::ContractBodyContent {
106    type Error = BuckyError;
107
108    fn try_from(value: &ContractBodyContent<ContractData>) -> BuckyResult<Self> {
109        let mut ret = protos::ContractBodyContent::new();
110        ret.set_data(value.data.data.clone());
111
112        Ok(ret)
113    }
114}
115
116impl<T> BodyContent for ContractBodyContent<T> {
117    fn format(&self) -> u8 {
118        OBJECT_CONTENT_CODEC_FORMAT_PROTOBUF
119    }
120}
121
122type ContractBodyContentContractData = ContractBodyContent<ContractData>;
123inner_impl_default_protobuf_raw_codec!(
124    ContractBodyContentContractData,
125    protos::ContractBodyContent
126);
127
128type ContractType =
129    NamedObjType<ContractDescContent<ContractData>, ContractBodyContent<ContractData>>;
130pub type ContractBuilder =
131    NamedObjectBuilder<ContractDescContent<ContractData>, ContractBodyContent<ContractData>>;
132
133pub type ContractDesc = NamedObjectDesc<ContractDescContent<ContractData>>;
134pub type ContractId = NamedObjectId<ContractType>;
135pub type Contract = NamedObjectBase<ContractType>;
136
137impl ContractDesc {
138    pub fn contract_id(&self) -> ContractId {
139        ContractId::try_from(self.calculate_id()).unwrap()
140    }
141}
142
143impl ContractId {
144    pub fn from_hash_256(hash: GenericArray<u8, U32>) -> Self {
145        let mut id = Self::default();
146        id.object_id_mut().as_mut_slice()[1..].copy_from_slice(&hash[1..]);
147        id
148    }
149}
150
151impl NamedObjectBase<ContractType> {
152    pub fn new(
153        owner: ObjectId,
154        author: ObjectId,
155        desc: ContractDescContent<ContractData>,
156        body: ContractBodyContent<ContractData>,
157    ) -> ContractBuilder {
158        ContractBuilder::new(desc, body).owner(owner).author(author)
159    }
160}
161
162#[cfg(test)]
163mod test {
164    use crate::{Contract, RawConvertTo, RawFrom};
165    use crate::{
166        ContractBodyContent, ContractData, ContractDescContent, ContractTypeCode, ObjectId,
167    };
168
169    #[test]
170    fn contract() {
171        let desc = ContractDescContent {
172            contract_type: ContractTypeCode::DSG,
173            data: ContractData { data: Vec::new() },
174        };
175
176        let body = ContractBodyContent {
177            data: ContractData { data: Vec::new() },
178        };
179
180        let object = Contract::new(ObjectId::default(), ObjectId::default(), desc, body).build();
181
182        // let p = Path::new("f:\\temp\\contract.obj");
183        // if p.parent().unwrap().exists() {
184        //     object.clone().encode_to_file(p, false);
185        // }
186
187        let buf = object.to_vec().unwrap();
188        let _obj = Contract::clone_from_slice(&buf).unwrap();
189    }
190}