1234#![allow(dead_code)]56#[cfg(not(feature = "std"))]7use alloc::vec::Vec;8use evm_core::ExitError;9use primitive_types::{H160, U256};1011use crate::{12 execution::{Error, ResultWithPostInfo, WithPostDispatchInfo},13 types::string,14};15use crate::execution::Result;1617const ABI_ALIGNMENT: usize = 32;1819#[derive(Clone)]20pub struct AbiReader<'i> {21 buf: &'i [u8],22 subresult_offset: usize,23 offset: usize,24}25impl<'i> AbiReader<'i> {26 pub fn new(buf: &'i [u8]) -> Self {27 Self {28 buf,29 subresult_offset: 0,30 offset: 0,31 }32 }33 pub fn new_call(buf: &'i [u8]) -> Result<(u32, Self)> {34 if buf.len() < 4 {35 return Err(Error::Error(ExitError::OutOfOffset));36 }37 let mut method_id = [0; 4];38 method_id.copy_from_slice(&buf[0..4]);3940 Ok((41 u32::from_be_bytes(method_id),42 Self {43 buf,44 subresult_offset: 4,45 offset: 4,46 },47 ))48 }4950 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {51 if self.buf.len() - self.offset < ABI_ALIGNMENT {52 return Err(Error::Error(ExitError::OutOfOffset));53 }54 let mut block = [0; S];55 56 if !self.buf[self.offset..self.offset + ABI_ALIGNMENT - S]57 .iter()58 .all(|&v| v == 0)59 {60 return Err(Error::Error(ExitError::InvalidRange));61 }62 block.copy_from_slice(63 &self.buf[self.offset + ABI_ALIGNMENT - S..self.offset + ABI_ALIGNMENT],64 );65 self.offset += ABI_ALIGNMENT;66 Ok(block)67 }6869 pub fn address(&mut self) -> Result<H160> {70 Ok(H160(self.read_padleft()?))71 }7273 pub fn bool(&mut self) -> Result<bool> {74 let data: [u8; 1] = self.read_padleft()?;75 match data[0] {76 0 => Ok(false),77 1 => Ok(true),78 _ => Err(Error::Error(ExitError::InvalidRange)),79 }80 }8182 pub fn bytes4(&mut self) -> Result<[u8; 4]> {83 self.read_padleft()84 }8586 pub fn bytes(&mut self) -> Result<Vec<u8>> {87 let mut subresult = self.subresult()?;88 let length = subresult.read_usize()?;89 if subresult.buf.len() <= subresult.offset + length {90 return Err(Error::Error(ExitError::OutOfOffset));91 }92 Ok(subresult.buf[subresult.offset..subresult.offset + length].into())93 }94 pub fn string(&mut self) -> Result<string> {95 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))96 }9798 pub fn uint8(&mut self) -> Result<u8> {99 Ok(self.read_padleft::<1>()?[0])100 }101102 pub fn uint32(&mut self) -> Result<u32> {103 Ok(u32::from_be_bytes(self.read_padleft()?))104 }105106 pub fn uint128(&mut self) -> Result<u128> {107 Ok(u128::from_be_bytes(self.read_padleft()?))108 }109110 pub fn uint256(&mut self) -> Result<U256> {111 let buf: [u8; 32] = self.read_padleft()?;112 Ok(U256::from_big_endian(&buf))113 }114115 pub fn uint64(&mut self) -> Result<u64> {116 Ok(u64::from_be_bytes(self.read_padleft()?))117 }118119 pub fn read_usize(&mut self) -> Result<usize> {120 Ok(usize::from_be_bytes(self.read_padleft()?))121 }122123 fn subresult(&mut self) -> Result<AbiReader<'i>> {124 let offset = self.read_usize()?;125 if offset + self.subresult_offset > self.buf.len() {126 return Err(Error::Error(ExitError::InvalidRange));127 }128 Ok(AbiReader {129 buf: self.buf,130 subresult_offset: offset + self.subresult_offset,131 offset: offset + self.subresult_offset,132 })133 }134135 pub fn is_finished(&self) -> bool {136 self.buf.len() == self.offset137 }138}139140#[derive(Default)]141pub struct AbiWriter {142 static_part: Vec<u8>,143 dynamic_part: Vec<(usize, AbiWriter)>,144}145impl AbiWriter {146 pub fn new() -> Self {147 Self::default()148 }149 pub fn new_call(method_id: u32) -> Self {150 let mut val = Self::new();151 val.static_part.extend(&method_id.to_be_bytes());152 val153 }154155 fn write_padleft(&mut self, block: &[u8]) {156 assert!(block.len() <= ABI_ALIGNMENT);157 self.static_part158 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);159 self.static_part.extend(block);160 }161162 fn write_padright(&mut self, bytes: &[u8]) {163 assert!(bytes.len() <= ABI_ALIGNMENT);164 self.static_part.extend(bytes);165 self.static_part166 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - bytes.len()]);167 }168169 pub fn address(&mut self, address: &H160) {170 self.write_padleft(&address.0)171 }172173 pub fn bool(&mut self, value: &bool) {174 self.write_padleft(&[if *value { 1 } else { 0 }])175 }176177 pub fn uint8(&mut self, value: &u8) {178 self.write_padleft(&[*value])179 }180181 pub fn uint32(&mut self, value: &u32) {182 self.write_padleft(&u32::to_be_bytes(*value))183 }184185 pub fn uint128(&mut self, value: &u128) {186 self.write_padleft(&u128::to_be_bytes(*value))187 }188189 pub fn uint256(&mut self, value: &U256) {190 let mut out = [0; 32];191 value.to_big_endian(&mut out);192 self.write_padleft(&out)193 }194195 pub fn write_usize(&mut self, value: &usize) {196 self.write_padleft(&usize::to_be_bytes(*value))197 }198199 pub fn write_subresult(&mut self, result: Self) {200 self.dynamic_part.push((self.static_part.len(), result));201 202 self.write_padleft(&[]);203 }204205 pub fn memory(&mut self, value: &[u8]) {206 let mut sub = Self::new();207 sub.write_usize(&value.len());208 for chunk in value.chunks(ABI_ALIGNMENT) {209 sub.write_padright(chunk);210 }211 self.write_subresult(sub);212 }213214 pub fn string(&mut self, value: &str) {215 self.memory(value.as_bytes())216 }217218 pub fn bytes(&mut self, value: &[u8]) {219 self.memory(value)220 }221222 pub fn finish(mut self) -> Vec<u8> {223 for (static_offset, part) in self.dynamic_part {224 let part_offset = self.static_part.len();225226 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);227 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()228 ..static_offset + ABI_ALIGNMENT]229 .copy_from_slice(&encoded_dynamic_offset);230 self.static_part.extend(part.finish())231 }232 self.static_part233 }234}235236pub trait AbiRead<T> {237 fn abi_read(&mut self) -> Result<T>;238}239240macro_rules! impl_abi_readable {241 ($ty:ty, $method:ident) => {242 impl AbiRead<$ty> for AbiReader<'_> {243 fn abi_read(&mut self) -> Result<$ty> {244 self.$method()245 }246 }247 };248}249250impl_abi_readable!(u8, uint8);251impl_abi_readable!(u32, uint32);252impl_abi_readable!(u64, uint64);253impl_abi_readable!(u128, uint128);254impl_abi_readable!(U256, uint256);255impl_abi_readable!(H160, address);256impl_abi_readable!(Vec<u8>, bytes);257impl_abi_readable!(bool, bool);258impl_abi_readable!(string, string);259260mod sealed {261 262 pub trait CanBePlacedInVec {}263}264265impl sealed::CanBePlacedInVec for U256 {}266impl sealed::CanBePlacedInVec for string {}267impl sealed::CanBePlacedInVec for H160 {}268269impl<R: sealed::CanBePlacedInVec> AbiRead<Vec<R>> for AbiReader<'_>270where271 Self: AbiRead<R>,272{273 fn abi_read(&mut self) -> Result<Vec<R>> {274 let mut sub = self.subresult()?;275 let size = sub.read_usize()?;276 sub.subresult_offset = sub.offset;277 let mut out = Vec::with_capacity(size);278 for _ in 0..size {279 out.push(<Self as AbiRead<R>>::abi_read(&mut sub)?);280 }281 Ok(out)282 }283}284285macro_rules! impl_tuples {286 ($($ident:ident)+) => {287 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}288 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>289 where290 $(Self: AbiRead<$ident>),+291 {292 fn abi_read(&mut self) -> Result<($($ident,)+)> {293 let mut subresult = self.subresult()?;294 Ok((295 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+296 ))297 }298 }299 };300}301302impl_tuples! {A}303impl_tuples! {A B}304impl_tuples! {A B C}305impl_tuples! {A B C D}306impl_tuples! {A B C D E}307impl_tuples! {A B C D E F}308impl_tuples! {A B C D E F G}309impl_tuples! {A B C D E F G H}310impl_tuples! {A B C D E F G H I}311impl_tuples! {A B C D E F G H I J}312313pub trait AbiWrite {314 fn abi_write(&self, writer: &mut AbiWriter);315 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {316 let mut writer = AbiWriter::new();317 self.abi_write(&mut writer);318 Ok(writer.into())319 }320}321322impl<T: AbiWrite> AbiWrite for ResultWithPostInfo<T> {323 324 325 326 327 328 329 fn abi_write(&self, _writer: &mut AbiWriter) {330 debug_assert!(false, "shouldn't be called, see comment")331 }332 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {333 match self {334 Ok(v) => Ok(WithPostDispatchInfo {335 post_info: v.post_info.clone(),336 data: {337 let mut out = AbiWriter::new();338 v.data.abi_write(&mut out);339 out340 },341 }),342 Err(e) => Err(e.clone()),343 }344 }345}346347macro_rules! impl_abi_writeable {348 ($ty:ty, $method:ident) => {349 impl AbiWrite for $ty {350 fn abi_write(&self, writer: &mut AbiWriter) {351 writer.$method(&self)352 }353 }354 };355}356357impl_abi_writeable!(u8, uint8);358impl_abi_writeable!(u32, uint32);359impl_abi_writeable!(u128, uint128);360impl_abi_writeable!(U256, uint256);361impl_abi_writeable!(H160, address);362impl_abi_writeable!(bool, bool);363impl_abi_writeable!(&str, string);364impl AbiWrite for &string {365 fn abi_write(&self, writer: &mut AbiWriter) {366 writer.string(self)367 }368}369impl AbiWrite for &Vec<u8> {370 fn abi_write(&self, writer: &mut AbiWriter) {371 writer.bytes(self)372 }373}374375impl AbiWrite for () {376 fn abi_write(&self, _writer: &mut AbiWriter) {}377}378379#[macro_export]380macro_rules! abi_decode {381 ($reader:expr, $($name:ident: $typ:ident),+ $(,)?) => {382 $(383 let $name = $reader.$typ()?;384 )+385 }386}387#[macro_export]388macro_rules! abi_encode {389 ($($typ:ident($value:expr)),* $(,)?) => {{390 #[allow(unused_mut)]391 let mut writer = ::evm_coder::abi::AbiWriter::new();392 $(393 writer.$typ($value);394 )*395 writer396 }};397 (call $val:expr; $($typ:ident($value:expr)),* $(,)?) => {{398 #[allow(unused_mut)]399 let mut writer = ::evm_coder::abi::AbiWriter::new_call($val);400 $(401 writer.$typ($value);402 )*403 writer404 }}405}406407#[cfg(test)]408pub mod test {409 use crate::{410 abi::AbiRead,411 types::{string, uint256},412 };413414 use super::{AbiReader, AbiWriter};415 use hex_literal::hex;416417 #[test]418 fn dynamic_after_static() {419 let mut encoder = AbiWriter::new();420 encoder.bool(&true);421 encoder.string("test");422 let encoded = encoder.finish();423424 let mut encoder = AbiWriter::new();425 encoder.bool(&true);426 427 encoder.uint32(&(32 * 2));428 429 encoder.uint32(&4);430 encoder.write_padright(&[b't', b'e', b's', b't']);431 let alternative_encoded = encoder.finish();432433 assert_eq!(encoded, alternative_encoded);434435 let mut decoder = AbiReader::new(&encoded);436 assert_eq!(decoder.bool().unwrap(), true);437 assert_eq!(decoder.string().unwrap(), "test");438 }439440 #[test]441 fn mint_sample() {442 let (call, mut decoder) = AbiReader::new_call(&hex!(443 "444 50bb4e7f445 000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374446 0000000000000000000000000000000000000000000000000000000000000001447 0000000000000000000000000000000000000000000000000000000000000060448 0000000000000000000000000000000000000000000000000000000000000008449 5465737420555249000000000000000000000000000000000000000000000000450 "451 ))452 .unwrap();453 assert_eq!(call, 0x50bb4e7f);454 assert_eq!(455 format!("{:?}", decoder.address().unwrap()),456 "0xad2c0954693c2b5404b7e50967d3481bea432374"457 );458 assert_eq!(decoder.uint32().unwrap(), 1);459 assert_eq!(decoder.string().unwrap(), "Test URI");460 }461462 #[test]463 fn mint_bulk() {464 let (call, mut decoder) = AbiReader::new_call(&hex!(465 "466 36543006467 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address468 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]469 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]470471 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem472 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem473 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem474475 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60476 0000000000000000000000000000000000000000000000000000000000000040 // offset of string477 000000000000000000000000000000000000000000000000000000000000000a // size of string478 5465737420555249203000000000000000000000000000000000000000000000 // string479480 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0481 0000000000000000000000000000000000000000000000000000000000000040 // offset of string482 000000000000000000000000000000000000000000000000000000000000000a // size of string483 5465737420555249203100000000000000000000000000000000000000000000 // string484485 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160486 0000000000000000000000000000000000000000000000000000000000000040 // offset of string487 000000000000000000000000000000000000000000000000000000000000000a // size of string488 5465737420555249203200000000000000000000000000000000000000000000 // string489 "490 ))491 .unwrap();492 assert_eq!(call, 0x36543006);493 let _ = decoder.address().unwrap();494 let data =495 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();496 assert_eq!(497 data,498 vec![499 (1.into(), "Test URI 0".to_string()),500 (11.into(), "Test URI 1".to_string()),501 (12.into(), "Test URI 2".to_string())502 ]503 );504 }505}