1234567891011121314151617181920#![allow(dead_code)]2122#[cfg(not(feature = "std"))]23use alloc::vec::Vec;24use evm_core::ExitError;25use primitive_types::{H160, U256};2627use crate::{28 execution::{Error, ResultWithPostInfo, WithPostDispatchInfo},29 types::{string, self},30};31use crate::execution::Result;3233const ABI_ALIGNMENT: usize = 32;3435#[derive(Clone)]36pub struct AbiReader<'i> {37 buf: &'i [u8],38 subresult_offset: usize,39 offset: usize,40}41impl<'i> AbiReader<'i> {42 pub fn new(buf: &'i [u8]) -> Self {43 Self {44 buf,45 subresult_offset: 0,46 offset: 0,47 }48 }49 pub fn new_call(buf: &'i [u8]) -> Result<(types::bytes4, Self)> {50 if buf.len() < 4 {51 return Err(Error::Error(ExitError::OutOfOffset));52 }53 let mut method_id = [0; 4];54 method_id.copy_from_slice(&buf[0..4]);5556 Ok((57 method_id,58 Self {59 buf,60 subresult_offset: 4,61 offset: 4,62 },63 ))64 }6566 fn read_pad<const S: usize>(67 buf: &[u8],68 offset: usize,69 pad_start: usize,70 pad_size: usize,71 block_start: usize,72 block_size: usize,73 ) -> Result<[u8; S]> {74 if buf.len() - offset < ABI_ALIGNMENT {75 return Err(Error::Error(ExitError::OutOfOffset));76 }77 let mut block = [0; S];78 79 if !buf[pad_start..pad_size].iter().all(|&v| v == 0) {80 return Err(Error::Error(ExitError::InvalidRange));81 }82 block.copy_from_slice(&buf[block_start..block_size]);83 Ok(block)84 }8586 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {87 let offset = self.offset;88 self.offset += ABI_ALIGNMENT;89 Self::read_pad(90 self.buf,91 offset,92 offset,93 offset + ABI_ALIGNMENT - S,94 offset + ABI_ALIGNMENT - S,95 offset + ABI_ALIGNMENT,96 )97 }9899 fn read_padright<const S: usize>(&mut self) -> Result<[u8; S]> {100 let offset = self.offset;101 self.offset += ABI_ALIGNMENT;102 Self::read_pad(103 self.buf,104 offset,105 offset + S,106 offset + ABI_ALIGNMENT,107 offset,108 offset + S,109 )110 }111112 pub fn address(&mut self) -> Result<H160> {113 Ok(H160(self.read_padleft()?))114 }115116 pub fn bool(&mut self) -> Result<bool> {117 let data: [u8; 1] = self.read_padleft()?;118 match data[0] {119 0 => Ok(false),120 1 => Ok(true),121 _ => Err(Error::Error(ExitError::InvalidRange)),122 }123 }124125 pub fn bytes4(&mut self) -> Result<[u8; 4]> {126 self.read_padright()127 }128129 pub fn bytes(&mut self) -> Result<Vec<u8>> {130 let mut subresult = self.subresult()?;131 let length = subresult.read_usize()?;132 if subresult.buf.len() < subresult.offset + length {133 return Err(Error::Error(ExitError::OutOfOffset));134 }135 Ok(subresult.buf[subresult.offset..subresult.offset + length].into())136 }137 pub fn string(&mut self) -> Result<string> {138 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))139 }140141 pub fn uint8(&mut self) -> Result<u8> {142 Ok(self.read_padleft::<1>()?[0])143 }144145 pub fn uint32(&mut self) -> Result<u32> {146 Ok(u32::from_be_bytes(self.read_padleft()?))147 }148149 pub fn uint128(&mut self) -> Result<u128> {150 Ok(u128::from_be_bytes(self.read_padleft()?))151 }152153 pub fn uint256(&mut self) -> Result<U256> {154 let buf: [u8; 32] = self.read_padleft()?;155 Ok(U256::from_big_endian(&buf))156 }157158 pub fn uint64(&mut self) -> Result<u64> {159 Ok(u64::from_be_bytes(self.read_padleft()?))160 }161162 pub fn read_usize(&mut self) -> Result<usize> {163 Ok(usize::from_be_bytes(self.read_padleft()?))164 }165166 fn subresult(&mut self) -> Result<AbiReader<'i>> {167 let offset = self.read_usize()?;168 if offset + self.subresult_offset > self.buf.len() {169 return Err(Error::Error(ExitError::InvalidRange));170 }171 Ok(AbiReader {172 buf: self.buf,173 subresult_offset: offset + self.subresult_offset,174 offset: offset + self.subresult_offset,175 })176 }177178 pub fn is_finished(&self) -> bool {179 self.buf.len() == self.offset180 }181}182183#[derive(Default)]184pub struct AbiWriter {185 static_part: Vec<u8>,186 dynamic_part: Vec<(usize, AbiWriter)>,187 had_call: bool,188}189impl AbiWriter {190 pub fn new() -> Self {191 Self::default()192 }193 pub fn new_call(method_id: u32) -> Self {194 let mut val = Self::new();195 val.static_part.extend(&method_id.to_be_bytes());196 val.had_call = true;197 val198 }199200 fn write_padleft(&mut self, block: &[u8]) {201 assert!(block.len() <= ABI_ALIGNMENT);202 self.static_part203 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);204 self.static_part.extend(block);205 }206207 fn write_padright(&mut self, bytes: &[u8]) {208 assert!(bytes.len() <= ABI_ALIGNMENT);209 self.static_part.extend(bytes);210 self.static_part211 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - bytes.len()]);212 }213214 pub fn address(&mut self, address: &H160) {215 self.write_padleft(&address.0)216 }217218 pub fn bool(&mut self, value: &bool) {219 self.write_padleft(&[if *value { 1 } else { 0 }])220 }221222 pub fn uint8(&mut self, value: &u8) {223 self.write_padleft(&[*value])224 }225226 pub fn uint32(&mut self, value: &u32) {227 self.write_padleft(&u32::to_be_bytes(*value))228 }229230 pub fn uint128(&mut self, value: &u128) {231 self.write_padleft(&u128::to_be_bytes(*value))232 }233234 pub fn uint256(&mut self, value: &U256) {235 let mut out = [0; 32];236 value.to_big_endian(&mut out);237 self.write_padleft(&out)238 }239240 pub fn write_usize(&mut self, value: &usize) {241 self.write_padleft(&usize::to_be_bytes(*value))242 }243244 pub fn write_subresult(&mut self, result: Self) {245 self.dynamic_part.push((self.static_part.len(), result));246 247 self.write_padleft(&[]);248 }249250 pub fn memory(&mut self, value: &[u8]) {251 let mut sub = Self::new();252 sub.write_usize(&value.len());253 for chunk in value.chunks(ABI_ALIGNMENT) {254 sub.write_padright(chunk);255 }256 self.write_subresult(sub);257 }258259 pub fn string(&mut self, value: &str) {260 self.memory(value.as_bytes())261 }262263 pub fn bytes(&mut self, value: &[u8]) {264 self.memory(value)265 }266267 pub fn finish(mut self) -> Vec<u8> {268 for (static_offset, part) in self.dynamic_part {269 let part_offset = self.static_part.len() - self.had_call.then(|| 4).unwrap_or(0);270271 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);272 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()273 ..static_offset + ABI_ALIGNMENT]274 .copy_from_slice(&encoded_dynamic_offset);275 self.static_part.extend(part.finish())276 }277 self.static_part278 }279}280281pub trait AbiRead<T> {282 fn abi_read(&mut self) -> Result<T>;283}284285macro_rules! impl_abi_readable {286 ($ty:ty, $method:ident) => {287 impl AbiRead<$ty> for AbiReader<'_> {288 fn abi_read(&mut self) -> Result<$ty> {289 self.$method()290 }291 }292 };293}294295impl_abi_readable!(u8, uint8);296impl_abi_readable!(u32, uint32);297impl_abi_readable!(u64, uint64);298impl_abi_readable!(u128, uint128);299impl_abi_readable!(U256, uint256);300impl_abi_readable!([u8; 4], bytes4);301impl_abi_readable!(H160, address);302impl_abi_readable!(Vec<u8>, bytes);303impl_abi_readable!(bool, bool);304impl_abi_readable!(string, string);305306mod sealed {307 308 pub trait CanBePlacedInVec {}309}310311impl sealed::CanBePlacedInVec for U256 {}312impl sealed::CanBePlacedInVec for string {}313impl sealed::CanBePlacedInVec for H160 {}314315impl<R: sealed::CanBePlacedInVec> AbiRead<Vec<R>> for AbiReader<'_>316where317 Self: AbiRead<R>,318{319 fn abi_read(&mut self) -> Result<Vec<R>> {320 let mut sub = self.subresult()?;321 let size = sub.read_usize()?;322 sub.subresult_offset = sub.offset;323 let mut out = Vec::with_capacity(size);324 for _ in 0..size {325 out.push(<Self as AbiRead<R>>::abi_read(&mut sub)?);326 }327 Ok(out)328 }329}330331macro_rules! impl_tuples_abi_reader {332 ($($ident:ident)+) => {333 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}334 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>335 where336 $(Self: AbiRead<$ident>),+337 {338 fn abi_read(&mut self) -> Result<($($ident,)+)> {339 let mut subresult = self.subresult()?;340 Ok((341 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+342 ))343 }344 }345 };346}347348impl_tuples_abi_reader! {A}349impl_tuples_abi_reader! {A B}350impl_tuples_abi_reader! {A B C}351impl_tuples_abi_reader! {A B C D}352impl_tuples_abi_reader! {A B C D E}353impl_tuples_abi_reader! {A B C D E F}354impl_tuples_abi_reader! {A B C D E F G}355impl_tuples_abi_reader! {A B C D E F G H}356impl_tuples_abi_reader! {A B C D E F G H I}357impl_tuples_abi_reader! {A B C D E F G H I J}358359pub trait AbiWrite {360 fn abi_write(&self, writer: &mut AbiWriter);361 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {362 let mut writer = AbiWriter::new();363 self.abi_write(&mut writer);364 Ok(writer.into())365 }366}367368impl<T: AbiWrite> AbiWrite for ResultWithPostInfo<T> {369 370 371 372 373 374 375 fn abi_write(&self, _writer: &mut AbiWriter) {376 debug_assert!(false, "shouldn't be called, see comment")377 }378 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {379 match self {380 Ok(v) => Ok(WithPostDispatchInfo {381 post_info: v.post_info.clone(),382 data: {383 let mut out = AbiWriter::new();384 v.data.abi_write(&mut out);385 out386 },387 }),388 Err(e) => Err(e.clone()),389 }390 }391}392393macro_rules! impl_abi_writeable {394 ($ty:ty, $method:ident) => {395 impl AbiWrite for $ty {396 fn abi_write(&self, writer: &mut AbiWriter) {397 writer.$method(&self)398 }399 }400 };401}402403impl_abi_writeable!(u8, uint8);404impl_abi_writeable!(u32, uint32);405impl_abi_writeable!(u128, uint128);406impl_abi_writeable!(U256, uint256);407impl_abi_writeable!(H160, address);408impl_abi_writeable!(bool, bool);409impl_abi_writeable!(&str, string);410impl AbiWrite for &string {411 fn abi_write(&self, writer: &mut AbiWriter) {412 writer.string(self)413 }414}415impl AbiWrite for &Vec<u8> {416 fn abi_write(&self, writer: &mut AbiWriter) {417 writer.bytes(self)418 }419}420421impl AbiWrite for () {422 fn abi_write(&self, _writer: &mut AbiWriter) {}423}424425macro_rules! impl_tuples_abi_writer {426 ($($ident:ident)+) => {427 #[allow(non_snake_case)]428 impl<$($ident),+> AbiWrite for &($($ident,)+)429 where430 $($ident: AbiWrite,)+431 {432 fn abi_write(&self, writer: &mut AbiWriter) {433 let ($($ident,)+) = self;434 $($ident.abi_write(writer);)+435 }436 }437 };438}439440impl_tuples_abi_writer! {A}441impl_tuples_abi_writer! {A B}442impl_tuples_abi_writer! {A B C}443impl_tuples_abi_writer! {A B C D}444impl_tuples_abi_writer! {A B C D E}445impl_tuples_abi_writer! {A B C D E F}446impl_tuples_abi_writer! {A B C D E F G}447impl_tuples_abi_writer! {A B C D E F G H}448impl_tuples_abi_writer! {A B C D E F G H I}449impl_tuples_abi_writer! {A B C D E F G H I J}450451#[macro_export]452macro_rules! abi_decode {453 ($reader:expr, $($name:ident: $typ:ident),+ $(,)?) => {454 $(455 let $name = $reader.$typ()?;456 )+457 }458}459#[macro_export]460macro_rules! abi_encode {461 ($($typ:ident($value:expr)),* $(,)?) => {{462 #[allow(unused_mut)]463 let mut writer = ::evm_coder::abi::AbiWriter::new();464 $(465 writer.$typ($value);466 )*467 writer468 }};469 (call $val:expr; $($typ:ident($value:expr)),* $(,)?) => {{470 #[allow(unused_mut)]471 let mut writer = ::evm_coder::abi::AbiWriter::new_call($val);472 $(473 writer.$typ($value);474 )*475 writer476 }}477}478479#[cfg(test)]480pub mod test {481 use crate::{482 abi::AbiRead,483 types::{string, uint256},484 };485486 use super::{AbiReader, AbiWriter};487 use hex_literal::hex;488489 #[test]490 fn dynamic_after_static() {491 let mut encoder = AbiWriter::new();492 encoder.bool(&true);493 encoder.string("test");494 let encoded = encoder.finish();495496 let mut encoder = AbiWriter::new();497 encoder.bool(&true);498 499 encoder.uint32(&(32 * 2));500 501 encoder.uint32(&4);502 encoder.write_padright(&[b't', b'e', b's', b't']);503 let alternative_encoded = encoder.finish();504505 assert_eq!(encoded, alternative_encoded);506507 let mut decoder = AbiReader::new(&encoded);508 assert_eq!(decoder.bool().unwrap(), true);509 assert_eq!(decoder.string().unwrap(), "test");510 }511512 #[test]513 fn mint_sample() {514 let (call, mut decoder) = AbiReader::new_call(&hex!(515 "516 50bb4e7f517 000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374518 0000000000000000000000000000000000000000000000000000000000000001519 0000000000000000000000000000000000000000000000000000000000000060520 0000000000000000000000000000000000000000000000000000000000000008521 5465737420555249000000000000000000000000000000000000000000000000522 "523 ))524 .unwrap();525 assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));526 assert_eq!(527 format!("{:?}", decoder.address().unwrap()),528 "0xad2c0954693c2b5404b7e50967d3481bea432374"529 );530 assert_eq!(decoder.uint32().unwrap(), 1);531 assert_eq!(decoder.string().unwrap(), "Test URI");532 }533534 #[test]535 fn mint_bulk() {536 let (call, mut decoder) = AbiReader::new_call(&hex!(537 "538 36543006539 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address540 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]541 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]542543 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem544 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem545 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem546547 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60548 0000000000000000000000000000000000000000000000000000000000000040 // offset of string549 000000000000000000000000000000000000000000000000000000000000000a // size of string550 5465737420555249203000000000000000000000000000000000000000000000 // string551552 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0553 0000000000000000000000000000000000000000000000000000000000000040 // offset of string554 000000000000000000000000000000000000000000000000000000000000000a // size of string555 5465737420555249203100000000000000000000000000000000000000000000 // string556557 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160558 0000000000000000000000000000000000000000000000000000000000000040 // offset of string559 000000000000000000000000000000000000000000000000000000000000000a // size of string560 5465737420555249203200000000000000000000000000000000000000000000 // string561 "562 ))563 .unwrap();564 assert_eq!(call, u32::to_be_bytes(0x36543006));565 let _ = decoder.address().unwrap();566 let data =567 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();568 assert_eq!(569 data,570 vec![571 (1.into(), "Test URI 0".to_string()),572 (11.into(), "Test URI 1".to_string()),573 (12.into(), "Test URI 2".to_string())574 ]575 );576 }577}