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;31use crate::solidity::SolidityTypeName;3233const ABI_ALIGNMENT: usize = 32;343536#[derive(Clone)]37pub struct AbiReader<'i> {38 buf: &'i [u8],39 subresult_offset: usize,40 offset: usize,41}42impl<'i> AbiReader<'i> {43 44 pub fn new(buf: &'i [u8]) -> Self {45 Self {46 buf,47 subresult_offset: 0,48 offset: 0,49 }50 }51 52 pub fn new_call(buf: &'i [u8]) -> Result<(types::bytes4, Self)> {53 if buf.len() < 4 {54 return Err(Error::Error(ExitError::OutOfOffset));55 }56 let mut method_id = [0; 4];57 method_id.copy_from_slice(&buf[0..4]);5859 Ok((60 method_id,61 Self {62 buf,63 subresult_offset: 4,64 offset: 4,65 },66 ))67 }6869 fn read_pad<const S: usize>(70 buf: &[u8],71 offset: usize,72 pad_start: usize,73 pad_size: usize,74 block_start: usize,75 block_size: usize,76 ) -> Result<[u8; S]> {77 if buf.len() - offset < ABI_ALIGNMENT {78 return Err(Error::Error(ExitError::OutOfOffset));79 }80 let mut block = [0; S];81 let is_pad_zeroed = buf[pad_start..pad_size].iter().all(|&v| v == 0);82 if !is_pad_zeroed {83 return Err(Error::Error(ExitError::InvalidRange));84 }85 block.copy_from_slice(&buf[block_start..block_size]);86 Ok(block)87 }8889 fn read_padleft<const S: usize>(&mut self) -> Result<[u8; S]> {90 let offset = self.offset;91 self.offset += ABI_ALIGNMENT;92 Self::read_pad(93 self.buf,94 offset,95 offset,96 offset + ABI_ALIGNMENT - S,97 offset + ABI_ALIGNMENT - S,98 offset + ABI_ALIGNMENT,99 )100 }101102 fn read_padright<const S: usize>(&mut self) -> Result<[u8; S]> {103 let offset = self.offset;104 self.offset += ABI_ALIGNMENT;105 Self::read_pad(106 self.buf,107 offset,108 offset + S,109 offset + ABI_ALIGNMENT,110 offset,111 offset + S,112 )113 }114115 116 pub fn address(&mut self) -> Result<H160> {117 Ok(H160(self.read_padleft()?))118 }119120 121 pub fn bool(&mut self) -> Result<bool> {122 let data: [u8; 1] = self.read_padleft()?;123 match data[0] {124 0 => Ok(false),125 1 => Ok(true),126 _ => Err(Error::Error(ExitError::InvalidRange)),127 }128 }129130 131 pub fn bytes4(&mut self) -> Result<[u8; 4]> {132 self.read_padright()133 }134135 136 pub fn bytes(&mut self) -> Result<Vec<u8>> {137 let mut subresult = self.subresult(None)?;138 let length = subresult.uint32()? as usize;139 if subresult.buf.len() < subresult.offset + length {140 return Err(Error::Error(ExitError::OutOfOffset));141 }142 Ok(subresult.buf[subresult.offset..subresult.offset + length].into())143 }144145 146 pub fn string(&mut self) -> Result<string> {147 string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))148 }149150 151 pub fn uint8(&mut self) -> Result<u8> {152 Ok(self.read_padleft::<1>()?[0])153 }154155 156 pub fn uint32(&mut self) -> Result<u32> {157 Ok(u32::from_be_bytes(self.read_padleft()?))158 }159160 161 pub fn uint128(&mut self) -> Result<u128> {162 Ok(u128::from_be_bytes(self.read_padleft()?))163 }164165 166 pub fn uint256(&mut self) -> Result<U256> {167 let buf: [u8; 32] = self.read_padleft()?;168 Ok(U256::from_big_endian(&buf))169 }170171 172 pub fn uint64(&mut self) -> Result<u64> {173 Ok(u64::from_be_bytes(self.read_padleft()?))174 }175176 177 #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]178 pub fn read_usize(&mut self) -> Result<usize> {179 Ok(usize::from_be_bytes(self.read_padleft()?))180 }181182 183 184 fn subresult(&mut self, size: Option<usize>) -> Result<AbiReader<'i>> {185 let subresult_offset = self.subresult_offset;186 let offset = if let Some(size) = size {187 self.offset += size;188 self.subresult_offset += size;189 0190 } else {191 self.uint32()? as usize192 };193194 if offset + self.subresult_offset > self.buf.len() {195 return Err(Error::Error(ExitError::InvalidRange));196 }197198 let new_offset = offset + subresult_offset;199 Ok(AbiReader {200 buf: self.buf,201 subresult_offset: new_offset,202 offset: new_offset,203 })204 }205206 207 pub fn is_finished(&self) -> bool {208 self.buf.len() == self.offset209 }210}211212213#[derive(Default)]214pub struct AbiWriter {215 static_part: Vec<u8>,216 dynamic_part: Vec<(usize, AbiWriter)>,217 had_call: bool,218}219impl AbiWriter {220 221 pub fn new() -> Self {222 Self::default()223 }224 225 pub fn new_call(method_id: u32) -> Self {226 let mut val = Self::new();227 val.static_part.extend(&method_id.to_be_bytes());228 val.had_call = true;229 val230 }231232 fn write_padleft(&mut self, block: &[u8]) {233 assert!(block.len() <= ABI_ALIGNMENT);234 self.static_part235 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);236 self.static_part.extend(block);237 }238239 fn write_padright(&mut self, bytes: &[u8]) {240 assert!(bytes.len() <= ABI_ALIGNMENT);241 self.static_part.extend(bytes);242 self.static_part243 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - bytes.len()]);244 }245246 247 pub fn address(&mut self, address: &H160) {248 self.write_padleft(&address.0)249 }250251 252 pub fn bool(&mut self, value: &bool) {253 self.write_padleft(&[if *value { 1 } else { 0 }])254 }255256 257 pub fn uint8(&mut self, value: &u8) {258 self.write_padleft(&[*value])259 }260261 262 pub fn uint32(&mut self, value: &u32) {263 self.write_padleft(&u32::to_be_bytes(*value))264 }265266 267 pub fn uint128(&mut self, value: &u128) {268 self.write_padleft(&u128::to_be_bytes(*value))269 }270271 272 pub fn uint256(&mut self, value: &U256) {273 let mut out = [0; 32];274 value.to_big_endian(&mut out);275 self.write_padleft(&out)276 }277278 279 #[deprecated = "dangerous, as usize may have different width in wasm and native execution"]280 pub fn write_usize(&mut self, value: &usize) {281 self.write_padleft(&usize::to_be_bytes(*value))282 }283284 285 pub fn write_subresult(&mut self, result: Self) {286 self.dynamic_part.push((self.static_part.len(), result));287 288 self.write_padleft(&[]);289 }290291 fn memory(&mut self, value: &[u8]) {292 let mut sub = Self::new();293 sub.uint32(&(value.len() as u32));294 for chunk in value.chunks(ABI_ALIGNMENT) {295 sub.write_padright(chunk);296 }297 self.write_subresult(sub);298 }299300 301 pub fn string(&mut self, value: &str) {302 self.memory(value.as_bytes())303 }304305 306 pub fn bytes(&mut self, value: &[u8]) {307 self.memory(value)308 }309310 311 pub fn finish(mut self) -> Vec<u8> {312 for (static_offset, part) in self.dynamic_part {313 let part_offset = self.static_part.len() - self.had_call.then(|| 4).unwrap_or(0);314315 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);316 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()317 ..static_offset + ABI_ALIGNMENT]318 .copy_from_slice(&encoded_dynamic_offset);319 self.static_part.extend(part.finish())320 }321 self.static_part322 }323}324325326327328329330pub trait AbiRead<T> {331 332 fn abi_read(&mut self) -> Result<T>;333 fn size() -> usize;334}335336macro_rules! impl_abi_readable {337 ($ty:ty, $method:ident) => {338 impl AbiRead<$ty> for AbiReader<'_> {339 fn abi_read(&mut self) -> Result<$ty> {340 self.$method()341 }342343 fn size() -> usize {344 ABI_ALIGNMENT345 }346 }347 };348}349350impl_abi_readable!(u8, uint8);351impl_abi_readable!(u32, uint32);352impl_abi_readable!(u64, uint64);353impl_abi_readable!(u128, uint128);354impl_abi_readable!(U256, uint256);355impl_abi_readable!([u8; 4], bytes4);356impl_abi_readable!(H160, address);357impl_abi_readable!(Vec<u8>, bytes);358impl_abi_readable!(bool, bool);359impl_abi_readable!(string, string);360361mod sealed {362 363 pub trait CanBePlacedInVec {}364}365366impl sealed::CanBePlacedInVec for U256 {}367impl sealed::CanBePlacedInVec for string {}368impl sealed::CanBePlacedInVec for H160 {}369370impl<R: sealed::CanBePlacedInVec> AbiRead<Vec<R>> for AbiReader<'_>371where372 Self: AbiRead<R>,373{374 fn abi_read(&mut self) -> Result<Vec<R>> {375 let mut sub = self.subresult(None)?;376 let size = sub.uint32()? as usize;377 sub.subresult_offset = sub.offset;378 let mut out = Vec::with_capacity(size);379 for _ in 0..size {380 out.push(<Self as AbiRead<R>>::abi_read(&mut sub)?);381 }382 Ok(out)383 }384385 fn size() -> usize {386 ABI_ALIGNMENT387 }388}389390macro_rules! impl_tuples {391 ($($ident:ident)+) => {392 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}393 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>394 where395 $(396 Self: AbiRead<$ident>,397 )+398 ($($ident,)+): SolidityTypeName,399 {400 fn abi_read(&mut self) -> Result<($($ident,)+)> {401 let size = if <($($ident,)+)>::is_simple() { Some(<Self as AbiRead<($($ident,)+)>>::size()) } else { None };402 let mut subresult = self.subresult(size)?;403 Ok((404 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+405 ))406 }407408 fn size() -> usize {409 0 $(+ {let _ : $ident; ABI_ALIGNMENT})+410 }411 }412 #[allow(non_snake_case)]413 impl<$($ident),+> AbiWrite for &($($ident,)+)414 where415 $($ident: AbiWrite,)+416 {417 fn abi_write(&self, writer: &mut AbiWriter) {418 let ($($ident,)+) = self;419 $($ident.abi_write(writer);)+420 }421 }422 };423}424425impl_tuples! {A}426impl_tuples! {A B}427impl_tuples! {A B C}428impl_tuples! {A B C D}429impl_tuples! {A B C D E}430impl_tuples! {A B C D E F}431impl_tuples! {A B C D E F G}432impl_tuples! {A B C D E F G H}433impl_tuples! {A B C D E F G H I}434impl_tuples! {A B C D E F G H I J}435436437438pub trait AbiWrite {439 440 fn abi_write(&self, writer: &mut AbiWriter);441 442 443 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {444 let mut writer = AbiWriter::new();445 self.abi_write(&mut writer);446 Ok(writer.into())447 }448}449450451452453454impl<T: AbiWrite> AbiWrite for ResultWithPostInfo<T> {455 fn abi_write(&self, _writer: &mut AbiWriter) {456 debug_assert!(false, "shouldn't be called, see comment")457 }458 fn to_result(&self) -> ResultWithPostInfo<AbiWriter> {459 match self {460 Ok(v) => Ok(WithPostDispatchInfo {461 post_info: v.post_info.clone(),462 data: {463 let mut out = AbiWriter::new();464 v.data.abi_write(&mut out);465 out466 },467 }),468 Err(e) => Err(e.clone()),469 }470 }471}472473macro_rules! impl_abi_writeable {474 ($ty:ty, $method:ident) => {475 impl AbiWrite for $ty {476 fn abi_write(&self, writer: &mut AbiWriter) {477 writer.$method(&self)478 }479 }480 };481}482483impl_abi_writeable!(u8, uint8);484impl_abi_writeable!(u32, uint32);485impl_abi_writeable!(u128, uint128);486impl_abi_writeable!(U256, uint256);487impl_abi_writeable!(H160, address);488impl_abi_writeable!(bool, bool);489impl_abi_writeable!(&str, string);490impl AbiWrite for &string {491 fn abi_write(&self, writer: &mut AbiWriter) {492 writer.string(self)493 }494}495impl AbiWrite for &Vec<u8> {496 fn abi_write(&self, writer: &mut AbiWriter) {497 writer.bytes(self)498 }499}500501impl AbiWrite for () {502 fn abi_write(&self, _writer: &mut AbiWriter) {}503}504505506#[deprecated]507#[macro_export]508macro_rules! abi_decode {509 ($reader:expr, $($name:ident: $typ:ident),+ $(,)?) => {510 $(511 let $name = $reader.$typ()?;512 )+513 }514}515516517#[deprecated]518#[macro_export]519macro_rules! abi_encode {520 ($($typ:ident($value:expr)),* $(,)?) => {{521 #[allow(unused_mut)]522 let mut writer = ::evm_coder::abi::AbiWriter::new();523 $(524 writer.$typ($value);525 )*526 writer527 }};528 (call $val:expr; $($typ:ident($value:expr)),* $(,)?) => {{529 #[allow(unused_mut)]530 let mut writer = ::evm_coder::abi::AbiWriter::new_call($val);531 $(532 writer.$typ($value);533 )*534 writer535 }}536}537538#[cfg(test)]539pub mod test {540 use crate::{541 abi::AbiRead,542 types::{string, uint256},543 };544545 use super::{AbiReader, AbiWriter};546 use hex_literal::hex;547548 #[test]549 fn dynamic_after_static() {550 let mut encoder = AbiWriter::new();551 encoder.bool(&true);552 encoder.string("test");553 let encoded = encoder.finish();554555 let mut encoder = AbiWriter::new();556 encoder.bool(&true);557 558 encoder.uint32(&(32 * 2));559 560 encoder.uint32(&4);561 encoder.write_padright(&[b't', b'e', b's', b't']);562 let alternative_encoded = encoder.finish();563564 assert_eq!(encoded, alternative_encoded);565566 let mut decoder = AbiReader::new(&encoded);567 assert!(decoder.bool().unwrap());568 assert_eq!(decoder.string().unwrap(), "test");569 }570571 #[test]572 fn mint_sample() {573 let (call, mut decoder) = AbiReader::new_call(&hex!(574 "575 50bb4e7f576 000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374577 0000000000000000000000000000000000000000000000000000000000000001578 0000000000000000000000000000000000000000000000000000000000000060579 0000000000000000000000000000000000000000000000000000000000000008580 5465737420555249000000000000000000000000000000000000000000000000581 "582 ))583 .unwrap();584 assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));585 assert_eq!(586 format!("{:?}", decoder.address().unwrap()),587 "0xad2c0954693c2b5404b7e50967d3481bea432374"588 );589 assert_eq!(decoder.uint32().unwrap(), 1);590 assert_eq!(decoder.string().unwrap(), "Test URI");591 }592593 #[test]594 fn mint_bulk() {595 let (call, mut decoder) = AbiReader::new_call(&hex!(596 "597 36543006598 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address599 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]600 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]601602 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem603 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem604 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem605606 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60607 0000000000000000000000000000000000000000000000000000000000000040 // offset of string608 000000000000000000000000000000000000000000000000000000000000000a // size of string609 5465737420555249203000000000000000000000000000000000000000000000 // string610611 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0612 0000000000000000000000000000000000000000000000000000000000000040 // offset of string613 000000000000000000000000000000000000000000000000000000000000000a // size of string614 5465737420555249203100000000000000000000000000000000000000000000 // string615616 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160617 0000000000000000000000000000000000000000000000000000000000000040 // offset of string618 000000000000000000000000000000000000000000000000000000000000000a // size of string619 5465737420555249203200000000000000000000000000000000000000000000 // string620 "621 ))622 .unwrap();623 assert_eq!(call, u32::to_be_bytes(0x36543006));624 let _ = decoder.address().unwrap();625 let data =626 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();627 assert_eq!(628 data,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 );635 }636637 #[test]638 fn parse_vec_with_simple_type() {639 use crate::types::address;640 use primitive_types::{H160, U256};641642 let (call, mut decoder) = AbiReader::new_call(&hex!(643 "644 1ACF2D55645 0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]646 0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]647648 0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address649 000000000000000000000000000000000000000000000000000000000000000A // uint256650651 000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address652 0000000000000000000000000000000000000000000000000000000000000014 // uint256653654 0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address655 000000000000000000000000000000000000000000000000000000000000001E // uint256656 "657 ))658 .unwrap();659 assert_eq!(call, u32::to_be_bytes(0x1ACF2D55));660 let data =661 <AbiReader<'_> as AbiRead<Vec<(address, uint256)>>>::abi_read(&mut decoder).unwrap();662 assert_eq!(data.len(), 3);663 assert_eq!(664 data,665 vec![666 (667 H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),668 U256([10, 0, 0, 0])669 ),670 (671 H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),672 U256([20, 0, 0, 0])673 ),674 (675 H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),676 U256([30, 0, 0, 0])677 ),678 ]679 );680 }681}