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>(buf: &[u8], offset: usize, pad_start: usize, pad_size: usize, block_start: usize, block_size: usize) -> Result<[u8; S]> {67 if buf.len() - offset < ABI_ALIGNMENT {68 return Err(Error::Error(ExitError::OutOfOffset));69 }70 let mut block = [0; S];71 72 if !buf[pad_start..pad_size]73 .iter()74 .all(|&v| v == 0)75 {76 return Err(Error::Error(ExitError::InvalidRange));77 }78 block.copy_from_slice(79 &buf[block_start..block_size],80 );81 Ok(block)82 }8384 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {85 let offset = self.offset;86 self.offset += ABI_ALIGNMENT;87 Self::read_pad(88 self.buf,89 offset,90 offset, 91 offset + ABI_ALIGNMENT - S,92 offset + ABI_ALIGNMENT - S,93 offset + ABI_ALIGNMENT94 )95 }9697 fn read_padright<const S: usize>(&mut self) -> Result<[u8; S]> {98 let offset = self.offset;99 self.offset += ABI_ALIGNMENT;100 Self::read_pad(101 self.buf,102 offset,103 offset + S, 104 offset + ABI_ALIGNMENT,105 offset,106 offset + S107 )108 }109 110 pub fn address(&mut self) -> Result<H160> {111 Ok(H160(self.read_padleft()?))112 }113114 pub fn bool(&mut self) -> Result<bool> {115 let data: [u8; 1] = self.read_padleft()?;116 match data[0] {117 0 => Ok(false),118 1 => Ok(true),119 _ => Err(Error::Error(ExitError::InvalidRange)),120 }121 }122123 pub fn bytes4(&mut self) -> Result<[u8; 4]> {124 self.read_padright()125 }126127 pub fn bytes(&mut self) -> Result<Vec<u8>> {128 let mut subresult = self.subresult()?;129 let length = subresult.read_usize()?;130 if subresult.buf.len() <= subresult.offset + length {131 return Err(Error::Error(ExitError::OutOfOffset));132 }133 Ok(subresult.buf[subresult.offset..subresult.offset + length].into())134 }135 pub fn string(&mut self) -> Result<string> {136 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))137 }138139 pub fn uint8(&mut self) -> Result<u8> {140 Ok(self.read_padleft::<1>()?[0])141 }142143 pub fn uint32(&mut self) -> Result<u32> {144 Ok(u32::from_be_bytes(self.read_padleft()?))145 }146147 pub fn uint128(&mut self) -> Result<u128> {148 Ok(u128::from_be_bytes(self.read_padleft()?))149 }150151 pub fn uint256(&mut self) -> Result<U256> {152 let buf: [u8; 32] = self.read_padleft()?;153 Ok(U256::from_big_endian(&buf))154 }155156 pub fn uint64(&mut self) -> Result<u64> {157 Ok(u64::from_be_bytes(self.read_padleft()?))158 }159160 pub fn read_usize(&mut self) -> Result<usize> {161 Ok(usize::from_be_bytes(self.read_padleft()?))162 }163164 fn subresult(&mut self) -> Result<AbiReader<'i>> {165 let offset = self.read_usize()?;166 if offset + self.subresult_offset > self.buf.len() {167 return Err(Error::Error(ExitError::InvalidRange));168 }169 Ok(AbiReader {170 buf: self.buf,171 subresult_offset: offset + self.subresult_offset,172 offset: offset + self.subresult_offset,173 })174 }175176 pub fn is_finished(&self) -> bool {177 self.buf.len() == self.offset178 }179}180181#[derive(Default)]182pub struct AbiWriter {183 static_part: Vec<u8>,184 dynamic_part: Vec<(usize, AbiWriter)>,185}186impl AbiWriter {187 pub fn new() -> Self {188 Self::default()189 }190 pub fn new_call(method_id: u32) -> Self {191 let mut val = Self::new();192 val.static_part.extend(&method_id.to_be_bytes());193 val194 }195196 fn write_padleft(&mut self, block: &[u8]) {197 assert!(block.len() <= ABI_ALIGNMENT);198 self.static_part199 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);200 self.static_part.extend(block);201 }202203 fn write_padright(&mut self, bytes: &[u8]) {204 assert!(bytes.len() <= ABI_ALIGNMENT);205 self.static_part.extend(bytes);206 self.static_part207 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - bytes.len()]);208 }209210 pub fn address(&mut self, address: &H160) {211 self.write_padleft(&address.0)212 }213214 pub fn bool(&mut self, value: &bool) {215 self.write_padleft(&[if *value { 1 } else { 0 }])216 }217218 pub fn uint8(&mut self, value: &u8) {219 self.write_padleft(&[*value])220 }221222 pub fn uint32(&mut self, value: &u32) {223 self.write_padleft(&u32::to_be_bytes(*value))224 }225226 pub fn uint128(&mut self, value: &u128) {227 self.write_padleft(&u128::to_be_bytes(*value))228 }229230 pub fn uint256(&mut self, value: &U256) {231 let mut out = [0; 32];232 value.to_big_endian(&mut out);233 self.write_padleft(&out)234 }235236 pub fn write_usize(&mut self, value: &usize) {237 self.write_padleft(&usize::to_be_bytes(*value))238 }239240 pub fn write_subresult(&mut self, result: Self) {241 self.dynamic_part.push((self.static_part.len(), result));242 243 self.write_padleft(&[]);244 }245246 pub fn memory(&mut self, value: &[u8]) {247 let mut sub = Self::new();248 sub.write_usize(&value.len());249 for chunk in value.chunks(ABI_ALIGNMENT) {250 sub.write_padright(chunk);251 }252 self.write_subresult(sub);253 }254255 pub fn string(&mut self, value: &str) {256 self.memory(value.as_bytes())257 }258259 pub fn bytes(&mut self, value: &[u8]) {260 self.memory(value)261 }262263 pub fn finish(mut self) -> Vec<u8> {264 for (static_offset, part) in self.dynamic_part {265 let part_offset = self.static_part.len();266267 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);268 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()269 ..static_offset + ABI_ALIGNMENT]270 .copy_from_slice(&encoded_dynamic_offset);271 self.static_part.extend(part.finish())272 }273 self.static_part274 }275}276277pub trait AbiRead<T> {278 fn abi_read(&mut self) -> Result<T>;279}280281macro_rules! impl_abi_readable {282 ($ty:ty, $method:ident) => {283 impl AbiRead<$ty> for AbiReader<'_> {284 fn abi_read(&mut self) -> Result<$ty> {285 self.$method()286 }287 }288 };289}290291impl_abi_readable!(u8, uint8);292impl_abi_readable!(u32, uint32);293impl_abi_readable!(u64, uint64);294impl_abi_readable!(u128, uint128);295impl_abi_readable!(U256, uint256);296impl_abi_readable!([u8; 4], bytes4);297impl_abi_readable!(H160, address);298impl_abi_readable!(Vec<u8>, bytes);299impl_abi_readable!(bool, bool);300impl_abi_readable!(string, string);301302mod sealed {303 304 pub trait CanBePlacedInVec {}305}306307impl sealed::CanBePlacedInVec for U256 {}308impl sealed::CanBePlacedInVec for string {}309impl sealed::CanBePlacedInVec for H160 {}310311impl<R: sealed::CanBePlacedInVec> AbiRead<Vec<R>> for AbiReader<'_>312where313 Self: AbiRead<R>,314{315 fn abi_read(&mut self) -> Result<Vec<R>> {316 let mut sub = self.subresult()?;317 let size = sub.read_usize()?;318 sub.subresult_offset = sub.offset;319 let mut out = Vec::with_capacity(size);320 for _ in 0..size {321 out.push(<Self as AbiRead<R>>::abi_read(&mut sub)?);322 }323 Ok(out)324 }325}326327macro_rules! impl_tuples {328 ($($ident:ident)+) => {329 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}330 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>331 where332 $(Self: AbiRead<$ident>),+333 {334 fn abi_read(&mut self) -> Result<($($ident,)+)> {335 let mut subresult = self.subresult()?;336 Ok((337 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+338 ))339 }340 }341 };342}343344impl_tuples! {A}345impl_tuples! {A B}346impl_tuples! {A B C}347impl_tuples! {A B C D}348impl_tuples! {A B C D E}349impl_tuples! {A B C D E F}350impl_tuples! {A B C D E F G}351impl_tuples! {A B C D E F G H}352impl_tuples! {A B C D E F G H I}353impl_tuples! {A B C D E F G H I J}354355pub trait AbiWrite {356 fn abi_write(&self, writer: &mut AbiWriter);357 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {358 let mut writer = AbiWriter::new();359 self.abi_write(&mut writer);360 Ok(writer.into())361 }362}363364impl<T: AbiWrite> AbiWrite for ResultWithPostInfo<T> {365 366 367 368 369 370 371 fn abi_write(&self, _writer: &mut AbiWriter) {372 debug_assert!(false, "shouldn't be called, see comment")373 }374 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {375 match self {376 Ok(v) => Ok(WithPostDispatchInfo {377 post_info: v.post_info.clone(),378 data: {379 let mut out = AbiWriter::new();380 v.data.abi_write(&mut out);381 out382 },383 }),384 Err(e) => Err(e.clone()),385 }386 }387}388389macro_rules! impl_abi_writeable {390 ($ty:ty, $method:ident) => {391 impl AbiWrite for $ty {392 fn abi_write(&self, writer: &mut AbiWriter) {393 writer.$method(&self)394 }395 }396 };397}398399impl_abi_writeable!(u8, uint8);400impl_abi_writeable!(u32, uint32);401impl_abi_writeable!(u128, uint128);402impl_abi_writeable!(U256, uint256);403impl_abi_writeable!(H160, address);404impl_abi_writeable!(bool, bool);405impl_abi_writeable!(&str, string);406impl AbiWrite for &string {407 fn abi_write(&self, writer: &mut AbiWriter) {408 writer.string(self)409 }410}411impl AbiWrite for &Vec<u8> {412 fn abi_write(&self, writer: &mut AbiWriter) {413 writer.bytes(self)414 }415}416417impl AbiWrite for () {418 fn abi_write(&self, _writer: &mut AbiWriter) {}419}420421#[macro_export]422macro_rules! abi_decode {423 ($reader:expr, $($name:ident: $typ:ident),+ $(,)?) => {424 $(425 let $name = $reader.$typ()?;426 )+427 }428}429#[macro_export]430macro_rules! abi_encode {431 ($($typ:ident($value:expr)),* $(,)?) => {{432 #[allow(unused_mut)]433 let mut writer = ::evm_coder::abi::AbiWriter::new();434 $(435 writer.$typ($value);436 )*437 writer438 }};439 (call $val:expr; $($typ:ident($value:expr)),* $(,)?) => {{440 #[allow(unused_mut)]441 let mut writer = ::evm_coder::abi::AbiWriter::new_call($val);442 $(443 writer.$typ($value);444 )*445 writer446 }}447}448449#[cfg(test)]450pub mod test {451 use crate::{452 abi::AbiRead,453 types::{string, uint256},454 };455456 use super::{AbiReader, AbiWriter};457 use hex_literal::hex;458459 #[test]460 fn dynamic_after_static() {461 let mut encoder = AbiWriter::new();462 encoder.bool(&true);463 encoder.string("test");464 let encoded = encoder.finish();465466 let mut encoder = AbiWriter::new();467 encoder.bool(&true);468 469 encoder.uint32(&(32 * 2));470 471 encoder.uint32(&4);472 encoder.write_padright(&[b't', b'e', b's', b't']);473 let alternative_encoded = encoder.finish();474475 assert_eq!(encoded, alternative_encoded);476477 let mut decoder = AbiReader::new(&encoded);478 assert_eq!(decoder.bool().unwrap(), true);479 assert_eq!(decoder.string().unwrap(), "test");480 }481482 #[test]483 fn mint_sample() {484 let (call, mut decoder) = AbiReader::new_call(&hex!(485 "486 50bb4e7f487 000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374488 0000000000000000000000000000000000000000000000000000000000000001489 0000000000000000000000000000000000000000000000000000000000000060490 0000000000000000000000000000000000000000000000000000000000000008491 5465737420555249000000000000000000000000000000000000000000000000492 "493 ))494 .unwrap();495 assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));496 assert_eq!(497 format!("{:?}", decoder.address().unwrap()),498 "0xad2c0954693c2b5404b7e50967d3481bea432374"499 );500 assert_eq!(decoder.uint32().unwrap(), 1);501 assert_eq!(decoder.string().unwrap(), "Test URI");502 }503504 #[test]505 fn mint_bulk() {506 let (call, mut decoder) = AbiReader::new_call(&hex!(507 "508 36543006509 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address510 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]511 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]512513 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem514 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem515 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem516517 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60518 0000000000000000000000000000000000000000000000000000000000000040 // offset of string519 000000000000000000000000000000000000000000000000000000000000000a // size of string520 5465737420555249203000000000000000000000000000000000000000000000 // string521522 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0523 0000000000000000000000000000000000000000000000000000000000000040 // offset of string524 000000000000000000000000000000000000000000000000000000000000000a // size of string525 5465737420555249203100000000000000000000000000000000000000000000 // string526527 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160528 0000000000000000000000000000000000000000000000000000000000000040 // offset of string529 000000000000000000000000000000000000000000000000000000000000000a // size of string530 5465737420555249203200000000000000000000000000000000000000000000 // string531 "532 ))533 .unwrap();534 assert_eq!(call, u32::to_be_bytes(0x36543006));535 let _ = decoder.address().unwrap();536 let data =537 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();538 assert_eq!(539 data,540 vec![541 (1.into(), "Test URI 0".to_string()),542 (11.into(), "Test URI 1".to_string()),543 (12.into(), "Test URI 2".to_string())544 ]545 );546 }547}