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;3334trait TypeHelper {35 36 fn is_dynamic() -> bool;3738 39 fn size() -> usize;40}414243#[derive(Clone)]44pub struct AbiReader<'i> {45 buf: &'i [u8],46 subresult_offset: usize,47 offset: usize,48}49impl<'i> AbiReader<'i> {50 51 pub fn new(buf: &'i [u8]) -> Self {52 Self {53 buf,54 subresult_offset: 0,55 offset: 0,56 }57 }58 59 pub fn new_call(buf: &'i [u8]) -> Result<(types::bytes4, Self)> {60 if buf.len() < 4 {61 return Err(Error::Error(ExitError::OutOfOffset));62 }63 let mut method_id = [0; 4];64 method_id.copy_from_slice(&buf[0..4]);6566 Ok((67 method_id,68 Self {69 buf,70 subresult_offset: 4,71 offset: 4,72 },73 ))74 }7576 fn read_pad<const S: usize>(77 buf: &[u8],78 offset: usize,79 pad_start: usize,80 pad_size: usize,81 block_start: usize,82 block_size: usize,83 ) -> Result<[u8; S]> {84 if buf.len() - offset < ABI_ALIGNMENT {85 return Err(Error::Error(ExitError::OutOfOffset));86 }87 let mut block = [0; S];88 let is_pad_zeroed = buf[pad_start..pad_size].iter().all(|&v| v == 0);89 if !is_pad_zeroed {90 return Err(Error::Error(ExitError::InvalidRange));91 }92 block.copy_from_slice(&buf[block_start..block_size]);93 Ok(block)94 }9596 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {97 let offset = self.offset;98 self.offset += ABI_ALIGNMENT;99 Self::read_pad(100 self.buf,101 offset,102 offset,103 offset + ABI_ALIGNMENT - S,104 offset + ABI_ALIGNMENT - S,105 offset + ABI_ALIGNMENT,106 )107 }108109 fn read_padright<const S: usize>(&mut self) -> Result<[u8; S]> {110 let offset = self.offset;111 self.offset += ABI_ALIGNMENT;112 Self::read_pad(113 self.buf,114 offset,115 offset + S,116 offset + ABI_ALIGNMENT,117 offset,118 offset + S,119 )120 }121122 123 pub fn address(&mut self) -> Result<H160> {124 Ok(H160(self.read_padleft()?))125 }126127 128 pub fn bool(&mut self) -> Result<bool> {129 let data: [u8; 1] = self.read_padleft()?;130 match data[0] {131 0 => Ok(false),132 1 => Ok(true),133 _ => Err(Error::Error(ExitError::InvalidRange)),134 }135 }136137 138 pub fn bytes4(&mut self) -> Result<[u8; 4]> {139 self.read_padright()140 }141142 143 pub fn bytes(&mut self) -> Result<Vec<u8>> {144 let mut subresult = self.subresult(None)?;145 let length = subresult.uint32()? as usize;146 if subresult.buf.len() < subresult.offset + length {147 return Err(Error::Error(ExitError::OutOfOffset));148 }149 Ok(subresult.buf[subresult.offset..subresult.offset + length].into())150 }151152 153 pub fn string(&mut self) -> Result<string> {154 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))155 }156157 158 pub fn uint8(&mut self) -> Result<u8> {159 Ok(self.read_padleft::<1>()?[0])160 }161162 163 pub fn uint32(&mut self) -> Result<u32> {164 Ok(u32::from_be_bytes(self.read_padleft()?))165 }166167 168 pub fn uint128(&mut self) -> Result<u128> {169 Ok(u128::from_be_bytes(self.read_padleft()?))170 }171172 173 pub fn uint256(&mut self) -> Result<U256> {174 let buf: [u8; 32] = self.read_padleft()?;175 Ok(U256::from_big_endian(&buf))176 }177178 179 pub fn uint64(&mut self) -> Result<u64> {180 Ok(u64::from_be_bytes(self.read_padleft()?))181 }182183 184 #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]185 pub fn read_usize(&mut self) -> Result<usize> {186 Ok(usize::from_be_bytes(self.read_padleft()?))187 }188189 190 191 fn subresult(&mut self, size: Option<usize>) -> Result<AbiReader<'i>> {192 let subresult_offset = self.subresult_offset;193 let offset = if let Some(size) = size {194 self.offset += size;195 self.subresult_offset += size;196 0197 } else {198 self.uint32()? as usize199 };200201 if offset + self.subresult_offset > self.buf.len() {202 return Err(Error::Error(ExitError::InvalidRange));203 }204205 let new_offset = offset + subresult_offset;206 Ok(AbiReader {207 buf: self.buf,208 subresult_offset: new_offset,209 offset: new_offset,210 })211 }212213 214 pub fn is_finished(&self) -> bool {215 self.buf.len() == self.offset216 }217}218219220#[derive(Default)]221pub struct AbiWriter {222 static_part: Vec<u8>,223 dynamic_part: Vec<(usize, AbiWriter)>,224 had_call: bool,225}226impl AbiWriter {227 228 pub fn new() -> Self {229 Self::default()230 }231 232 pub fn new_call(method_id: u32) -> Self {233 let mut val = Self::new();234 val.static_part.extend(&method_id.to_be_bytes());235 val.had_call = true;236 val237 }238239 fn write_padleft(&mut self, block: &[u8]) {240 assert!(block.len() <= ABI_ALIGNMENT);241 self.static_part242 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);243 self.static_part.extend(block);244 }245246 fn write_padright(&mut self, bytes: &[u8]) {247 assert!(bytes.len() <= ABI_ALIGNMENT);248 self.static_part.extend(bytes);249 self.static_part250 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - bytes.len()]);251 }252253 254 pub fn address(&mut self, address: &H160) {255 self.write_padleft(&address.0)256 }257258 259 pub fn bool(&mut self, value: &bool) {260 self.write_padleft(&[if *value { 1 } else { 0 }])261 }262263 264 pub fn uint8(&mut self, value: &u8) {265 self.write_padleft(&[*value])266 }267268 269 pub fn uint32(&mut self, value: &u32) {270 self.write_padleft(&u32::to_be_bytes(*value))271 }272273 274 pub fn uint128(&mut self, value: &u128) {275 self.write_padleft(&u128::to_be_bytes(*value))276 }277278 279 pub fn uint256(&mut self, value: &U256) {280 let mut out = [0; 32];281 value.to_big_endian(&mut out);282 self.write_padleft(&out)283 }284285 286 #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]287 pub fn write_usize(&mut self, value: &usize) {288 self.write_padleft(&usize::to_be_bytes(*value))289 }290291 292 pub fn write_subresult(&mut self, result: Self) {293 self.dynamic_part.push((self.static_part.len(), result));294 295 self.write_padleft(&[]);296 }297298 fn memory(&mut self, value: &[u8]) {299 let mut sub = Self::new();300 sub.uint32(&(value.len() as u32));301 for chunk in value.chunks(ABI_ALIGNMENT) {302 sub.write_padright(chunk);303 }304 self.write_subresult(sub);305 }306307 308 pub fn string(&mut self, value: &str) {309 self.memory(value.as_bytes())310 }311312 313 pub fn bytes(&mut self, value: &[u8]) {314 self.memory(value)315 }316317 318 pub fn finish(mut self) -> Vec<u8> {319 for (static_offset, part) in self.dynamic_part {320 let part_offset = self.static_part.len() - if self.had_call { 4 } else { 0 };321322 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);323 let start = static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len();324 let stop = static_offset + ABI_ALIGNMENT;325 self.static_part[start..stop].copy_from_slice(&encoded_dynamic_offset);326 self.static_part.extend(part.finish())327 }328 self.static_part329 }330}331332333334335336337pub trait AbiRead<T> {338 339 fn abi_read(&mut self) -> Result<T>;340}341342macro_rules! impl_abi_readable {343 ($ty:ty, $method:ident, $dynamic:literal) => {344 impl TypeHelper for $ty {345 fn is_dynamic() -> bool {346 $dynamic347 }348349 fn size() -> usize {350 ABI_ALIGNMENT351 }352 }353 impl AbiRead<$ty> for AbiReader<'_> {354 fn abi_read(&mut self) -> Result<$ty> {355 self.$method()356 }357 }358 };359}360361impl_abi_readable!(u8, uint8, false);362impl_abi_readable!(u32, uint32, false);363impl_abi_readable!(u64, uint64, false);364impl_abi_readable!(u128, uint128, false);365impl_abi_readable!(U256, uint256, false);366impl_abi_readable!([u8; 4], bytes4, false);367impl_abi_readable!(H160, address, false);368impl_abi_readable!(Vec<u8>, bytes, true);369impl_abi_readable!(bool, bool, true);370impl_abi_readable!(string, string, true);371372mod sealed {373 374 pub trait CanBePlacedInVec {}375}376377impl sealed::CanBePlacedInVec for U256 {}378impl sealed::CanBePlacedInVec for string {}379impl sealed::CanBePlacedInVec for H160 {}380381impl<R: sealed::CanBePlacedInVec> AbiRead<Vec<R>> for AbiReader<'_>382where383 Self: AbiRead<R>,384{385 fn abi_read(&mut self) -> Result<Vec<R>> {386 let mut sub = self.subresult(None)?;387 let size = sub.uint32()? as usize;388 sub.subresult_offset = sub.offset;389 let mut out = Vec::with_capacity(size);390 for _ in 0..size {391 out.push(<Self as AbiRead<R>>::abi_read(&mut sub)?);392 }393 Ok(out)394 }395}396397macro_rules! impl_tuples {398 ($($ident:ident)+) => {399 impl<$($ident: TypeHelper,)+> TypeHelper for ($($ident,)+)400 where401 $(402 $ident: TypeHelper,403 )+404 {405 fn is_dynamic() -> bool {406 false407 $(408 || <$ident>::is_dynamic()409 )*410 }411412 fn size() -> usize {413 0 $(+ <$ident>::size())+414 }415 }416 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}417 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>418 where419 $(420 Self: AbiRead<$ident>,421 )+422 ($($ident,)+): TypeHelper,423 {424 fn abi_read(&mut self) -> Result<($($ident,)+)> {425 let size = if !<($($ident,)+)>::is_dynamic() { Some(<($($ident,)+)>::size()) } else { None };426 let mut subresult = self.subresult(size)?;427 Ok((428 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+429 ))430 }431 }432 #[allow(non_snake_case)]433 impl<$($ident),+> AbiWrite for ($($ident,)+)434 where435 $($ident: AbiWrite,)+436 {437 fn abi_write(&self, writer: &mut AbiWriter) {438 let ($($ident,)+) = self;439 $($ident.abi_write(writer);)+440 }441 }442 };443}444445impl_tuples! {A}446impl_tuples! {A B}447impl_tuples! {A B C}448impl_tuples! {A B C D}449impl_tuples! {A B C D E}450impl_tuples! {A B C D E F}451impl_tuples! {A B C D E F G}452impl_tuples! {A B C D E F G H}453impl_tuples! {A B C D E F G H I}454impl_tuples! {A B C D E F G H I J}455456457458pub trait AbiWrite {459 460 fn abi_write(&self, writer: &mut AbiWriter);461 462 463 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {464 let mut writer = AbiWriter::new();465 self.abi_write(&mut writer);466 Ok(writer.into())467 }468}469470471472473474impl<T: AbiWrite> AbiWrite for ResultWithPostInfo<T> {475 fn abi_write(&self, _writer: &mut AbiWriter) {476 debug_assert!(false, "shouldn't be called, see comment")477 }478 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {479 match self {480 Ok(v) => Ok(WithPostDispatchInfo {481 post_info: v.post_info.clone(),482 data: {483 let mut out = AbiWriter::new();484 v.data.abi_write(&mut out);485 out486 },487 }),488 Err(e) => Err(e.clone()),489 }490 }491}492493macro_rules! impl_abi_writeable {494 ($ty:ty, $method:ident) => {495 impl AbiWrite for $ty {496 fn abi_write(&self, writer: &mut AbiWriter) {497 writer.$method(&self)498 }499 }500 };501}502503impl_abi_writeable!(u8, uint8);504impl_abi_writeable!(u32, uint32);505impl_abi_writeable!(u128, uint128);506impl_abi_writeable!(U256, uint256);507impl_abi_writeable!(H160, address);508impl_abi_writeable!(bool, bool);509impl_abi_writeable!(&str, string);510impl AbiWrite for string {511 fn abi_write(&self, writer: &mut AbiWriter) {512 writer.string(self)513 }514}515516517518519520521impl<T: AbiWrite> AbiWrite for Vec<T> {522 fn abi_write(&self, writer: &mut AbiWriter) {523 let mut sub = AbiWriter::new();524 (self.len() as u32).abi_write(&mut sub);525 for item in self {526 item.abi_write(&mut sub);527 }528 writer.write_subresult(sub);529 }530}531532impl AbiWrite for () {533 fn abi_write(&self, _writer: &mut AbiWriter) {}534}535536537#[deprecated]538#[macro_export]539macro_rules! abi_decode {540 ($reader:expr, $($name:ident: $typ:ident),+ $(,)?) => {541 $(542 let $name = $reader.$typ()?;543 )+544 }545}546547548#[deprecated]549#[macro_export]550macro_rules! abi_encode {551 ($($typ:ident($value:expr)),* $(,)?) => {{552 #[allow(unused_mut)]553 let mut writer = ::evm_coder::abi::AbiWriter::new();554 $(555 writer.$typ($value);556 )*557 writer558 }};559 (call $val:expr; $($typ:ident($value:expr)),* $(,)?) => {{560 #[allow(unused_mut)]561 let mut writer = ::evm_coder::abi::AbiWriter::new_call($val);562 $(563 writer.$typ($value);564 )*565 writer566 }}567}568569#[cfg(test)]570pub mod test {571 use crate::{572 abi::{AbiRead, AbiWrite},573 types::{string, uint256, address},574 };575576 use super::{AbiReader, AbiWriter};577 use hex_literal::hex;578 use primitive_types::{H160, U256};579580 #[test]581 fn dynamic_after_static() {582 let mut encoder = AbiWriter::new();583 encoder.bool(&true);584 encoder.string("test");585 let encoded = encoder.finish();586587 let mut encoder = AbiWriter::new();588 encoder.bool(&true);589 590 encoder.uint32(&(32 * 2));591 592 encoder.uint32(&4);593 encoder.write_padright(&[b't', b'e', b's', b't']);594 let alternative_encoded = encoder.finish();595596 assert_eq!(encoded, alternative_encoded);597598 let mut decoder = AbiReader::new(&encoded);599 assert!(decoder.bool().unwrap());600 assert_eq!(decoder.string().unwrap(), "test");601 }602603 #[test]604 fn mint_sample() {605 let (call, mut decoder) = AbiReader::new_call(&hex!(606 "607 50bb4e7f608 000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374609 0000000000000000000000000000000000000000000000000000000000000001610 0000000000000000000000000000000000000000000000000000000000000060611 0000000000000000000000000000000000000000000000000000000000000008612 5465737420555249000000000000000000000000000000000000000000000000613 "614 ))615 .unwrap();616 assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));617 assert_eq!(618 format!("{:?}", decoder.address().unwrap()),619 "0xad2c0954693c2b5404b7e50967d3481bea432374"620 );621 assert_eq!(decoder.uint32().unwrap(), 1);622 assert_eq!(decoder.string().unwrap(), "Test URI");623 }624625 #[test]626 fn parse_vec_with_dynamic_type() {627 let decoded_data = (628 0x36543006,629 vec![630 (1.into(), "Test URI 0".to_string()),631 (11.into(), "Test URI 1".to_string()),632 (12.into(), "Test URI 2".to_string()),633 ],634 );635636 let encoded_data = &hex!(637 "638 36543006639 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address640 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]641 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]642643 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem644 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem645 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem646647 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60648 0000000000000000000000000000000000000000000000000000000000000040 // offset of string649 000000000000000000000000000000000000000000000000000000000000000a // size of string650 5465737420555249203000000000000000000000000000000000000000000000 // string651652 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0653 0000000000000000000000000000000000000000000000000000000000000040 // offset of string654 000000000000000000000000000000000000000000000000000000000000000a // size of string655 5465737420555249203100000000000000000000000000000000000000000000 // string656657 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160658 0000000000000000000000000000000000000000000000000000000000000040 // offset of string659 000000000000000000000000000000000000000000000000000000000000000a // size of string660 5465737420555249203200000000000000000000000000000000000000000000 // string661 "662 );663664 let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();665 assert_eq!(call, u32::to_be_bytes(decoded_data.0));666 let _ = decoder.address().unwrap();667 let data =668 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();669 assert_eq!(data, decoded_data.1);670671 let mut writer = AbiWriter::new_call(decoded_data.0);672 decoded_data.1.abi_write(&mut writer);673 let ed = writer.finish();674 assert_eq!(encoded_data, ed.as_slice());675 }676677 #[test]678 fn parse_vec_with_simple_type() {679 let decoded_data = (680 0x1ACF2D55,681 vec![682 (683 H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),684 U256([10, 0, 0, 0]),685 ),686 (687 H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),688 U256([20, 0, 0, 0]),689 ),690 (691 H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),692 U256([30, 0, 0, 0]),693 ),694 ],695 );696697 let encoded_data = &hex!(698 "699 1ACF2D55700 0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]701 0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]702703 0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address704 000000000000000000000000000000000000000000000000000000000000000A // uint256705706 000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address707 0000000000000000000000000000000000000000000000000000000000000014 // uint256708709 0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address710 000000000000000000000000000000000000000000000000000000000000001E // uint256711 "712 );713714 let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();715 assert_eq!(call, u32::to_be_bytes(decoded_data.0));716 let data =717 <AbiReader<'_> as AbiRead<Vec<(address, uint256)>>>::abi_read(&mut decoder).unwrap();718 assert_eq!(data.len(), 3);719 assert_eq!(data, decoded_data.1);720721 let mut writer = AbiWriter::new_call(decoded_data.0);722 decoded_data.1.abi_write(&mut writer);723 let ed = writer.finish();724 assert_eq!(encoded_data, ed.as_slice());725 }726}