12345678910111213141516171819#![allow(dead_code)]2021mod traits;22pub use traits::*;23mod impls;2425#[cfg(test)]26mod test;2728#[cfg(not(feature = "std"))]29use alloc::vec::Vec;30use evm_core::ExitError;31use primitive_types::{H160, U256};3233use crate::{34 execution::{Result, Error},35 types::*,36};3738const ABI_ALIGNMENT: usize = 32;394041#[derive(Clone)]42pub struct AbiReader<'i> {43 buf: &'i [u8],44 subresult_offset: usize,45 offset: usize,46}47impl<'i> AbiReader<'i> {48 49 pub fn new(buf: &'i [u8]) -> Self {50 Self {51 buf,52 subresult_offset: 0,53 offset: 0,54 }55 }56 57 pub fn new_call(buf: &'i [u8]) -> Result<(bytes4, Self)> {58 if buf.len() < 4 {59 return Err(Error::Error(ExitError::OutOfOffset));60 }61 let mut method_id = [0; 4];62 method_id.copy_from_slice(&buf[0..4]);6364 Ok((65 method_id,66 Self {67 buf,68 subresult_offset: 4,69 offset: 4,70 },71 ))72 }7374 fn read_pad<const S: usize>(75 buf: &[u8],76 offset: usize,77 pad_start: usize,78 pad_size: usize,79 block_start: usize,80 block_size: usize,81 ) -> Result<[u8; S]> {82 if buf.len() - offset < ABI_ALIGNMENT {83 return Err(Error::Error(ExitError::OutOfOffset));84 }85 let mut block = [0; S];86 let is_pad_zeroed = buf[pad_start..pad_size].iter().all(|&v| v == 0);87 if !is_pad_zeroed {88 return Err(Error::Error(ExitError::InvalidRange));89 }90 block.copy_from_slice(&buf[block_start..block_size]);91 Ok(block)92 }9394 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {95 let offset = self.offset;96 self.offset += ABI_ALIGNMENT;97 Self::read_pad(98 self.buf,99 offset,100 offset,101 offset + ABI_ALIGNMENT - S,102 offset + ABI_ALIGNMENT - S,103 offset + ABI_ALIGNMENT,104 )105 }106107 fn read_padright<const S: usize>(&mut self) -> Result<[u8; S]> {108 let offset = self.offset;109 self.offset += ABI_ALIGNMENT;110 Self::read_pad(111 self.buf,112 offset,113 offset + S,114 offset + ABI_ALIGNMENT,115 offset,116 offset + S,117 )118 }119120 121 pub fn address(&mut self) -> Result<H160> {122 Ok(H160(self.read_padleft()?))123 }124125 126 pub fn bool(&mut self) -> Result<bool> {127 let data: [u8; 1] = self.read_padleft()?;128 match data[0] {129 0 => Ok(false),130 1 => Ok(true),131 _ => Err(Error::Error(ExitError::InvalidRange)),132 }133 }134135 136 pub fn bytes4(&mut self) -> Result<[u8; 4]> {137 self.read_padright()138 }139140 141 pub fn bytes(&mut self) -> Result<Vec<u8>> {142 let mut subresult = self.subresult(None)?;143 let length = subresult.uint32()? as usize;144 if subresult.buf.len() < subresult.offset + length {145 return Err(Error::Error(ExitError::OutOfOffset));146 }147 Ok(subresult.buf[subresult.offset..subresult.offset + length].into())148 }149150 151 pub fn string(&mut self) -> Result<string> {152 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))153 }154155 156 pub fn uint8(&mut self) -> Result<u8> {157 Ok(self.read_padleft::<1>()?[0])158 }159160 161 pub fn uint32(&mut self) -> Result<u32> {162 Ok(u32::from_be_bytes(self.read_padleft()?))163 }164165 166 pub fn uint128(&mut self) -> Result<u128> {167 Ok(u128::from_be_bytes(self.read_padleft()?))168 }169170 171 pub fn uint256(&mut self) -> Result<U256> {172 let buf: [u8; 32] = self.read_padleft()?;173 Ok(U256::from_big_endian(&buf))174 }175176 177 pub fn uint64(&mut self) -> Result<u64> {178 Ok(u64::from_be_bytes(self.read_padleft()?))179 }180181 182 #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]183 pub fn read_usize(&mut self) -> Result<usize> {184 Ok(usize::from_be_bytes(self.read_padleft()?))185 }186187 188 189 fn subresult(&mut self, size: Option<usize>) -> Result<AbiReader<'i>> {190 let subresult_offset = self.subresult_offset;191 let offset = if let Some(size) = size {192 self.offset += size;193 self.subresult_offset += size;194 0195 } else {196 self.uint32()? as usize197 };198199 if offset + self.subresult_offset > self.buf.len() {200 return Err(Error::Error(ExitError::InvalidRange));201 }202203 let new_offset = offset + subresult_offset;204 Ok(AbiReader {205 buf: self.buf,206 subresult_offset: new_offset,207 offset: new_offset,208 })209 }210211 212 pub fn is_finished(&self) -> bool {213 self.buf.len() == self.offset214 }215}216217218#[derive(Default)]219pub struct AbiWriter {220 static_part: Vec<u8>,221 dynamic_part: Vec<(usize, AbiWriter)>,222 had_call: bool,223 is_dynamic: bool,224}225impl AbiWriter {226 227 pub fn new() -> Self {228 Self::default()229 }230231 232 pub fn new_dynamic(is_dynamic: bool) -> Self {233 Self {234 is_dynamic,235 ..Default::default()236 }237 }238 239 pub fn new_call(method_id: u32) -> Self {240 let mut val = Self::new();241 val.static_part.extend(&method_id.to_be_bytes());242 val.had_call = true;243 val244 }245246 fn write_padleft(&mut self, block: &[u8]) {247 assert!(block.len() <= ABI_ALIGNMENT);248 self.static_part249 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);250 self.static_part.extend(block);251 }252253 fn write_padright(&mut self, block: &[u8]) {254 assert!(block.len() <= ABI_ALIGNMENT);255 self.static_part.extend(block);256 self.static_part257 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);258 }259260 261 pub fn address(&mut self, address: &H160) {262 self.write_padleft(&address.0)263 }264265 266 pub fn bool(&mut self, value: &bool) {267 self.write_padleft(&[if *value { 1 } else { 0 }])268 }269270 271 pub fn uint8(&mut self, value: &u8) {272 self.write_padleft(&[*value])273 }274275 276 pub fn uint32(&mut self, value: &u32) {277 self.write_padleft(&u32::to_be_bytes(*value))278 }279280 281 pub fn uint128(&mut self, value: &u128) {282 self.write_padleft(&u128::to_be_bytes(*value))283 }284285 286 pub fn uint256(&mut self, value: &U256) {287 let mut out = [0; 32];288 value.to_big_endian(&mut out);289 self.write_padleft(&out)290 }291292 293 #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]294 pub fn write_usize(&mut self, value: &usize) {295 self.write_padleft(&usize::to_be_bytes(*value))296 }297298 299 pub fn write_subresult(&mut self, result: Self) {300 self.dynamic_part.push((self.static_part.len(), result));301 302 self.write_padleft(&[]);303 }304305 fn memory(&mut self, value: &[u8]) {306 let mut sub = Self::new();307 sub.uint32(&(value.len() as u32));308 for chunk in value.chunks(ABI_ALIGNMENT) {309 sub.write_padright(chunk);310 }311 self.write_subresult(sub);312 }313314 315 pub fn string(&mut self, value: &str) {316 self.memory(value.as_bytes())317 }318319 320 pub fn bytes(&mut self, value: &[u8]) {321 self.memory(value)322 }323324 325 pub fn finish(mut self) -> Vec<u8> {326 for (static_offset, part) in self.dynamic_part {327 let part_offset = self.static_part.len()328 - if self.had_call { 4 } else { 0 }329 - if self.is_dynamic { ABI_ALIGNMENT } else { 0 };330331 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);332 let start = static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len();333 let stop = static_offset + ABI_ALIGNMENT;334 self.static_part[start..stop].copy_from_slice(&encoded_dynamic_offset);335 self.static_part.extend(part.finish())336 }337 self.static_part338 }339}