12345678910111213141516171819#![allow(dead_code)]2021#[cfg(not(feature = "std"))]22use alloc::vec::Vec;23use evm_core::ExitError;24use primitive_types::{H160, U256};2526use crate::{27 execution::{Error, ResultWithPostInfo, WithPostDispatchInfo},28 types::{string, self},29};30use crate::execution::Result;3132const ABI_ALIGNMENT: usize = 32;333435#[derive(Clone)]36pub struct AbiReader<'i> {37 buf: &'i [u8],38 subresult_offset: usize,39 offset: usize,40}41impl<'i> AbiReader<'i> {42 43 pub fn new(buf: &'i [u8]) -> Self {44 Self {45 buf,46 subresult_offset: 0,47 offset: 0,48 }49 }50 51 pub fn new_call(buf: &'i [u8]) -> Result<(types::bytes4, Self)> {52 if buf.len() < 4 {53 return Err(Error::Error(ExitError::OutOfOffset));54 }55 let mut method_id = [0; 4];56 method_id.copy_from_slice(&buf[0..4]);5758 Ok((59 method_id,60 Self {61 buf,62 subresult_offset: 4,63 offset: 4,64 },65 ))66 }6768 fn read_pad<const S: usize>(69 buf: &[u8],70 offset: usize,71 pad_start: usize,72 pad_size: usize,73 block_start: usize,74 block_size: usize,75 ) -> Result<[u8; S]> {76 if buf.len() - offset < ABI_ALIGNMENT {77 return Err(Error::Error(ExitError::OutOfOffset));78 }79 let mut block = [0; S];80 81 if !buf[pad_start..pad_size].iter().all(|&v| v == 0) {82 return Err(Error::Error(ExitError::InvalidRange));83 }84 block.copy_from_slice(&buf[block_start..block_size]);85 Ok(block)86 }8788 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {89 let offset = self.offset;90 self.offset += ABI_ALIGNMENT;91 Self::read_pad(92 self.buf,93 offset,94 offset,95 offset + ABI_ALIGNMENT - S,96 offset + ABI_ALIGNMENT - S,97 offset + ABI_ALIGNMENT,98 )99 }100101 fn read_padright<const S: usize>(&mut self) -> Result<[u8; S]> {102 let offset = self.offset;103 self.offset += ABI_ALIGNMENT;104 Self::read_pad(105 self.buf,106 offset,107 offset + S,108 offset + ABI_ALIGNMENT,109 offset,110 offset + S,111 )112 }113114 115 pub fn address(&mut self) -> Result<H160> {116 Ok(H160(self.read_padleft()?))117 }118119 120 pub fn bool(&mut self) -> Result<bool> {121 let data: [u8; 1] = self.read_padleft()?;122 match data[0] {123 0 => Ok(false),124 1 => Ok(true),125 _ => Err(Error::Error(ExitError::InvalidRange)),126 }127 }128129 130 pub fn bytes4(&mut self) -> Result<[u8; 4]> {131 self.read_padright()132 }133134 135 pub fn bytes(&mut self) -> Result<Vec<u8>> {136 let mut subresult = self.subresult()?;137 let length = subresult.uint32()? as usize;138 if subresult.buf.len() < subresult.offset + length {139 return Err(Error::Error(ExitError::OutOfOffset));140 }141 Ok(subresult.buf[subresult.offset..subresult.offset + length].into())142 }143144 145 pub fn string(&mut self) -> Result<string> {146 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))147 }148149 150 pub fn uint8(&mut self) -> Result<u8> {151 Ok(self.read_padleft::<1>()?[0])152 }153154 155 pub fn uint32(&mut self) -> Result<u32> {156 Ok(u32::from_be_bytes(self.read_padleft()?))157 }158159 160 pub fn uint128(&mut self) -> Result<u128> {161 Ok(u128::from_be_bytes(self.read_padleft()?))162 }163164 165 pub fn uint256(&mut self) -> Result<U256> {166 let buf: [u8; 32] = self.read_padleft()?;167 Ok(U256::from_big_endian(&buf))168 }169170 171 pub fn uint64(&mut self) -> Result<u64> {172 Ok(u64::from_be_bytes(self.read_padleft()?))173 }174175 176 #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]177 pub fn read_usize(&mut self) -> Result<usize> {178 Ok(usize::from_be_bytes(self.read_padleft()?))179 }180181 182 fn subresult(&mut self) -> Result<AbiReader<'i>> {183 let offset = self.uint32()? as usize;184 if offset + self.subresult_offset > self.buf.len() {185 return Err(Error::Error(ExitError::InvalidRange));186 }187 Ok(AbiReader {188 buf: self.buf,189 subresult_offset: offset + self.subresult_offset,190 offset: offset + self.subresult_offset,191 })192 }193194 195 pub fn is_finished(&self) -> bool {196 self.buf.len() == self.offset197 }198}199200201#[derive(Default)]202pub struct AbiWriter {203 static_part: Vec<u8>,204 dynamic_part: Vec<(usize, AbiWriter)>,205 had_call: bool,206}207impl AbiWriter {208 209 pub fn new() -> Self {210 Self::default()211 }212 213 pub fn new_call(method_id: u32) -> Self {214 let mut val = Self::new();215 val.static_part.extend(&method_id.to_be_bytes());216 val.had_call = true;217 val218 }219220 fn write_padleft(&mut self, block: &[u8]) {221 assert!(block.len() <= ABI_ALIGNMENT);222 self.static_part223 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);224 self.static_part.extend(block);225 }226227 fn write_padright(&mut self, bytes: &[u8]) {228 assert!(bytes.len() <= ABI_ALIGNMENT);229 self.static_part.extend(bytes);230 self.static_part231 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - bytes.len()]);232 }233234 235 pub fn address(&mut self, address: &H160) {236 self.write_padleft(&address.0)237 }238239 240 pub fn bool(&mut self, value: &bool) {241 self.write_padleft(&[if *value { 1 } else { 0 }])242 }243244 245 pub fn uint8(&mut self, value: &u8) {246 self.write_padleft(&[*value])247 }248249 250 pub fn uint32(&mut self, value: &u32) {251 self.write_padleft(&u32::to_be_bytes(*value))252 }253254 255 pub fn uint128(&mut self, value: &u128) {256 self.write_padleft(&u128::to_be_bytes(*value))257 }258259 260 pub fn uint256(&mut self, value: &U256) {261 let mut out = [0; 32];262 value.to_big_endian(&mut out);263 self.write_padleft(&out)264 }265266 267 #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]268 pub fn write_usize(&mut self, value: &usize) {269 self.write_padleft(&usize::to_be_bytes(*value))270 }271272 273 pub fn write_subresult(&mut self, result: Self) {274 self.dynamic_part.push((self.static_part.len(), result));275 276 self.write_padleft(&[]);277 }278279 fn memory(&mut self, value: &[u8]) {280 let mut sub = Self::new();281 sub.uint32(&(value.len() as u32));282 for chunk in value.chunks(ABI_ALIGNMENT) {283 sub.write_padright(chunk);284 }285 self.write_subresult(sub);286 }287288 289 pub fn string(&mut self, value: &str) {290 self.memory(value.as_bytes())291 }292293 294 pub fn bytes(&mut self, value: &[u8]) {295 self.memory(value)296 }297298 299 pub fn finish(mut self) -> Vec<u8> {300 for (static_offset, part) in self.dynamic_part {301 let part_offset = self.static_part.len() - self.had_call.then(|| 4).unwrap_or(0);302303 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);304 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()305 ..static_offset + ABI_ALIGNMENT]306 .copy_from_slice(&encoded_dynamic_offset);307 self.static_part.extend(part.finish())308 }309 self.static_part310 }311}312313314315316317318pub trait AbiRead<T> {319 320 fn abi_read(&mut self) -> Result<T>;321}322323macro_rules! impl_abi_readable {324 ($ty:ty, $method:ident) => {325 impl AbiRead<$ty> for AbiReader<'_> {326 fn abi_read(&mut self) -> Result<$ty> {327 self.$method()328 }329 }330 };331}332333impl_abi_readable!(u8, uint8);334impl_abi_readable!(u32, uint32);335impl_abi_readable!(u64, uint64);336impl_abi_readable!(u128, uint128);337impl_abi_readable!(U256, uint256);338impl_abi_readable!([u8; 4], bytes4);339impl_abi_readable!(H160, address);340impl_abi_readable!(Vec<u8>, bytes);341impl_abi_readable!(bool, bool);342impl_abi_readable!(string, string);343344mod sealed {345 346 pub trait CanBePlacedInVec {}347}348349impl sealed::CanBePlacedInVec for U256 {}350impl sealed::CanBePlacedInVec for string {}351impl sealed::CanBePlacedInVec for H160 {}352353impl<R: sealed::CanBePlacedInVec> AbiRead<Vec<R>> for AbiReader<'_>354where355 Self: AbiRead<R>,356{357 fn abi_read(&mut self) -> Result<Vec<R>> {358 let mut sub = self.subresult()?;359 let size = sub.uint32()? as usize;360 sub.subresult_offset = sub.offset;361 let mut out = Vec::with_capacity(size);362 for _ in 0..size {363 out.push(<Self as AbiRead<R>>::abi_read(&mut sub)?);364 }365 Ok(out)366 }367}368369macro_rules! impl_tuples {370 ($($ident:ident)+) => {371 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}372 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>373 where374 $(Self: AbiRead<$ident>),+375 {376 fn abi_read(&mut self) -> Result<($($ident,)+)> {377 let mut subresult = self.subresult()?;378 Ok((379 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+380 ))381 }382 }383 #[allow(non_snake_case)]384 impl<$($ident),+> AbiWrite for &($($ident,)+)385 where386 $($ident: AbiWrite,)+387 {388 fn abi_write(&self, writer: &mut AbiWriter) {389 let ($($ident,)+) = self;390 $($ident.abi_write(writer);)+391 }392 }393 };394}395396impl_tuples! {A}397impl_tuples! {A B}398impl_tuples! {A B C}399impl_tuples! {A B C D}400impl_tuples! {A B C D E}401impl_tuples! {A B C D E F}402impl_tuples! {A B C D E F G}403impl_tuples! {A B C D E F G H}404impl_tuples! {A B C D E F G H I}405impl_tuples! {A B C D E F G H I J}406407408409pub trait AbiWrite {410 411 fn abi_write(&self, writer: &mut AbiWriter);412 413 414 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {415 let mut writer = AbiWriter::new();416 self.abi_write(&mut writer);417 Ok(writer.into())418 }419}420421422423424425impl<T: AbiWrite> AbiWrite for ResultWithPostInfo<T> {426 fn abi_write(&self, _writer: &mut AbiWriter) {427 debug_assert!(false, "shouldn't be called, see comment")428 }429 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {430 match self {431 Ok(v) => Ok(WithPostDispatchInfo {432 post_info: v.post_info.clone(),433 data: {434 let mut out = AbiWriter::new();435 v.data.abi_write(&mut out);436 out437 },438 }),439 Err(e) => Err(e.clone()),440 }441 }442}443444macro_rules! impl_abi_writeable {445 ($ty:ty, $method:ident) => {446 impl AbiWrite for $ty {447 fn abi_write(&self, writer: &mut AbiWriter) {448 writer.$method(&self)449 }450 }451 };452}453454impl_abi_writeable!(u8, uint8);455impl_abi_writeable!(u32, uint32);456impl_abi_writeable!(u128, uint128);457impl_abi_writeable!(U256, uint256);458impl_abi_writeable!(H160, address);459impl_abi_writeable!(bool, bool);460impl_abi_writeable!(&str, string);461impl AbiWrite for &string {462 fn abi_write(&self, writer: &mut AbiWriter) {463 writer.string(self)464 }465}466impl AbiWrite for &Vec<u8> {467 fn abi_write(&self, writer: &mut AbiWriter) {468 writer.bytes(self)469 }470}471472impl AbiWrite for () {473 fn abi_write(&self, _writer: &mut AbiWriter) {}474}475476477#[deprecated]478#[macro_export]479macro_rules! abi_decode {480 ($reader:expr, $($name:ident: $typ:ident),+ $(,)?) => {481 $(482 let $name = $reader.$typ()?;483 )+484 }485}486487488#[deprecated]489#[macro_export]490macro_rules! abi_encode {491 ($($typ:ident($value:expr)),* $(,)?) => {{492 #[allow(unused_mut)]493 let mut writer = ::evm_coder::abi::AbiWriter::new();494 $(495 writer.$typ($value);496 )*497 writer498 }};499 (call $val:expr; $($typ:ident($value:expr)),* $(,)?) => {{500 #[allow(unused_mut)]501 let mut writer = ::evm_coder::abi::AbiWriter::new_call($val);502 $(503 writer.$typ($value);504 )*505 writer506 }}507}508509#[cfg(test)]510pub mod test {511 use crate::{512 abi::AbiRead,513 types::{string, uint256},514 };515516 use super::{AbiReader, AbiWriter};517 use hex_literal::hex;518519 #[test]520 fn dynamic_after_static() {521 let mut encoder = AbiWriter::new();522 encoder.bool(&true);523 encoder.string("test");524 let encoded = encoder.finish();525526 let mut encoder = AbiWriter::new();527 encoder.bool(&true);528 529 encoder.uint32(&(32 * 2));530 531 encoder.uint32(&4);532 encoder.write_padright(&[b't', b'e', b's', b't']);533 let alternative_encoded = encoder.finish();534535 assert_eq!(encoded, alternative_encoded);536537 let mut decoder = AbiReader::new(&encoded);538 assert_eq!(decoder.bool().unwrap(), true);539 assert_eq!(decoder.string().unwrap(), "test");540 }541542 #[test]543 fn mint_sample() {544 let (call, mut decoder) = AbiReader::new_call(&hex!(545 "546 50bb4e7f547 000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374548 0000000000000000000000000000000000000000000000000000000000000001549 0000000000000000000000000000000000000000000000000000000000000060550 0000000000000000000000000000000000000000000000000000000000000008551 5465737420555249000000000000000000000000000000000000000000000000552 "553 ))554 .unwrap();555 assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));556 assert_eq!(557 format!("{:?}", decoder.address().unwrap()),558 "0xad2c0954693c2b5404b7e50967d3481bea432374"559 );560 assert_eq!(decoder.uint32().unwrap(), 1);561 assert_eq!(decoder.string().unwrap(), "Test URI");562 }563564 #[test]565 fn mint_bulk() {566 let (call, mut decoder) = AbiReader::new_call(&hex!(567 "568 36543006569 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address570 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]571 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]572573 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem574 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem575 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem576577 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60578 0000000000000000000000000000000000000000000000000000000000000040 // offset of string579 000000000000000000000000000000000000000000000000000000000000000a // size of string580 5465737420555249203000000000000000000000000000000000000000000000 // string581582 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0583 0000000000000000000000000000000000000000000000000000000000000040 // offset of string584 000000000000000000000000000000000000000000000000000000000000000a // size of string585 5465737420555249203100000000000000000000000000000000000000000000 // string586587 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160588 0000000000000000000000000000000000000000000000000000000000000040 // offset of string589 000000000000000000000000000000000000000000000000000000000000000a // size of string590 5465737420555249203200000000000000000000000000000000000000000000 // string591 "592 ))593 .unwrap();594 assert_eq!(call, u32::to_be_bytes(0x36543006));595 let _ = decoder.address().unwrap();596 let data =597 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();598 assert_eq!(599 data,600 vec![601 (1.into(), "Test URI 0".to_string()),602 (11.into(), "Test URI 1".to_string()),603 (12.into(), "Test URI 2".to_string())604 ]605 );606 }607}