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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
///! A set of useful methods and abstractions.

use crate::ERC20Error;
use web3::types::{
	Bytes,
	H160,
	H256,
	U256,
};

/// Converts `Bytes` and `Vec<u8>` to H160, H256, and U256.
pub struct BytesToFixedNumber {
	data: Vec<u8>,
	index: usize,
}

impl From<Vec<u8>> for BytesToFixedNumber {
	#[inline]
	fn from(data: Vec<u8>) -> Self {
		Self {
			data,
			index: 0,
		}
	}
}

impl From<Bytes> for BytesToFixedNumber {
	#[inline]
	fn from(data: Bytes) -> Self {
		data.0.into()
	}
}

impl BytesToFixedNumber {
	/// Returns the next vector for the specified size.
	///
	/// # Arguments
	///
	/// * `size` - The size requested for the next vector.
	///
	pub fn next_vec(&mut self, size: usize) -> Result<Vec<u8>, ERC20Error> {
		if self.index + size > self.data.len() {
			return Err(ERC20Error::UnexpectedEndOfData);
		}
		let mut resp = Vec::new();
		for i in 0..size {
			resp.push(self.data[self.index + i]);
		}
		self.index += size;
		Ok(resp)
	}

	/// Skips a specified number of bytes.
	///
	/// # Arguments
	///
	/// * `size` - The number of bytes to skip.
	///
	pub fn skip(&mut self, size: usize) -> Result<(), ERC20Error> {
		if self.index + size > self.data.len() {
			return Err(ERC20Error::UnexpectedEndOfData);
		}
		self.index += size;
		Ok(())
	}

	/// Returns the next H160.
	pub fn next_h160(&mut self) -> Result<H160, ERC20Error> {
		self.skip((256 - 160) / 8)?;
		self.next_h160_not_padded()
	}

	/// Returns the next H160 with no padding to 32 bytes.
	pub fn next_h160_not_padded(&mut self) -> Result<H160, ERC20Error> {
		let vec_resp = self.next_vec(20)?;
		let mut the_vec: [u8; 20] = [0; 20];
		for i in 0..20 {
			the_vec[i] = vec_resp[i];
		}
		Ok(the_vec.into())
	}

	/// Returns the next H256.
	pub fn next_h256(&mut self) -> Result<H256, ERC20Error> {
		let vec_resp = self.next_vec(32)?;
		let mut the_vec: [u8; 32] = [0; 32];
		for i in 0..32 {
			the_vec[i] = vec_resp[i];
		}
		Ok(the_vec.into())
	}

	/// Returns the next U256.
	pub fn next_u256(&mut self) -> Result<U256, ERC20Error> {
		let vec_resp = self.next_vec(32)?;
		let mut the_vec: [u8; 32] = [0; 32];
		for i in 0..32 {
			the_vec[i] = vec_resp[i];
		}
		Ok(the_vec.into())
	}
}

/// Converts H160, H256, and U256 into `Vec<u8>` which can be used to create a `Bytes`.
pub struct FixedNumberToBytes {
	data: Vec<u8>,
}

impl FixedNumberToBytes {
	/// Pushes a vector of bytes to the tail of the current byte array.
	///
	/// # Arguments
	///
	/// * `vec` - Vector with the bytes to be added.
	///
	pub fn push_vec(&mut self, vec: &Vec<u8>) {
		for it in vec {
			self.data.push(*it);
		}
	}

	/// Pushes a H160 to the tail of the current byte array.
	///
	/// # Arguments
	///
	/// * `value` - H160 to be pushed.
	///
	pub fn push_h160(&mut self, value: &H160) {
		for _ in 0..((256 - 160) / 8) {
			self.data.push(0);
		}
		self.push_h160_not_padded(value);
	}

	/// Pushes a H160 to the tail of the current byte array, with no padding to 32 bytes.
	///
	/// # Arguments
	///
	/// * `value` - H160 to be pushed.
	///
	pub fn push_h160_not_padded(&mut self, value: &H160) {
		for it in value.0.iter() {
			self.data.push(*it);
		}
	}

	/// Pushes a H256 to the tail of the current byte array.
	///
	/// # Arguments
	///
	/// * `value` - H256 to be pushed.
	///
	pub fn push_h256(&mut self, value: &H256) {
		for it in value.0.iter() {
			self.data.push(*it);
		}
	}

	/// Pushes an U256 to the tail of the current byte array.
	///
	/// # Arguments
	///
	/// * `value` - U256 to be pushed.
	///
	pub fn push_u256(&mut self, value: &U256) {
		for i in (0..(256 / 8)).rev() {
			self.data.push(value.byte(i));
		}
	}
}

impl Default for FixedNumberToBytes {
	fn default() -> Self {
		Self {
			data: Vec::new(),
		}
	}
}

impl From<FixedNumberToBytes> for Vec<u8> {
	fn from(data: FixedNumberToBytes) -> Self {
		data.data
	}
}