1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use super::alloc::vec::Vec;
use super::bytesrepr::{Error, FromBytes, ToBytes};
use crate::contract_api::pointers::*;
#[repr(C)]
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash, PartialOrd, Ord)]
pub enum Key {
Account([u8; 20]),
Hash([u8; 32]),
URef([u8; 32]),
}
use self::Key::*;
impl Key {
pub fn to_u_ptr<T>(self) -> Option<UPointer<T>> {
if let URef(id) = self {
Some(UPointer::new(id))
} else {
None
}
}
pub fn to_c_ptr(self) -> Option<ContractPointer> {
match self {
URef(id) => Some(ContractPointer::URef(UPointer::new(id))),
Hash(id) => Some(ContractPointer::Hash(id)),
_ => None,
}
}
}
const ACCOUNT_ID: u8 = 0;
const HASH_ID: u8 = 1;
const UREF_ID: u8 = 2;
pub const UREF_SIZE: usize = 37;
impl ToBytes for Key {
fn to_bytes(&self) -> Vec<u8> {
match self {
Account(addr) => {
let mut result = Vec::with_capacity(25);
result.push(ACCOUNT_ID);
result.append(&mut (20u32).to_bytes());
result.extend(addr);
result
}
Hash(hash) => {
let mut result = Vec::with_capacity(37);
result.push(HASH_ID);
result.append(&mut hash.to_bytes());
result
}
URef(rf) => {
let mut result = Vec::with_capacity(37);
result.push(UREF_ID);
result.append(&mut rf.to_bytes());
result
}
}
}
}
impl FromBytes for Key {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
let (id, rest): (u8, &[u8]) = FromBytes::from_bytes(bytes)?;
match id {
ACCOUNT_ID => {
let (addr, rem): (Vec<u8>, &[u8]) = FromBytes::from_bytes(rest)?;
if addr.len() != 20 {
Err(Error::FormattingError)
} else {
let mut addr_array = [0u8; 20];
addr_array.copy_from_slice(&addr);
Ok((Account(addr_array), rem))
}
}
HASH_ID => {
let (hash, rem): ([u8; 32], &[u8]) = FromBytes::from_bytes(rest)?;
Ok((Hash(hash), rem))
}
UREF_ID => {
let (rf, rem): ([u8; 32], &[u8]) = FromBytes::from_bytes(rest)?;
Ok((URef(rf), rem))
}
_ => Err(Error::FormattingError),
}
}
}
impl FromBytes for Vec<Key> {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
let (size, rest): (u32, &[u8]) = FromBytes::from_bytes(bytes)?;
let mut result: Vec<Key> = Vec::with_capacity((size as usize) * UREF_SIZE);
let mut stream = rest;
for _ in 0..size {
let (t, rem): (Key, &[u8]) = FromBytes::from_bytes(stream)?;
result.push(t);
stream = rem;
}
Ok((result, stream))
}
}
impl ToBytes for Vec<Key> {
fn to_bytes(&self) -> Vec<u8> {
let size = self.len() as u32;
let mut result: Vec<u8> = Vec::with_capacity(4 + (size as usize) * UREF_SIZE);
result.extend(size.to_bytes());
result.extend(self.iter().flat_map(ToBytes::to_bytes));
result
}
}
impl AsRef<[u8]> for Key {
fn as_ref(&self) -> &[u8] {
match self {
Account(a) => a,
Hash(h) => h,
URef(u) => u,
}
}
}