ewasm.rs 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391
  1. use ethabi::{decode, ethereum_types, RawLog, Token};
  2. use num_derive::FromPrimitive;
  3. use num_traits::FromPrimitive;
  4. use rand::Rng;
  5. use ripemd::Ripemd160;
  6. use sha2::{Digest, Sha256};
  7. use std::collections::HashMap;
  8. use std::ffi::OsStr;
  9. use std::fmt;
  10. use tiny_keccak::{Hasher, Keccak};
  11. use wasmi::memory_units::Pages;
  12. use wasmi::*;
  13. use solang::{compile, file_resolver::FileResolver, Target};
  14. mod ewasm_tests;
  15. type Address = [u8; 20];
  16. pub fn address_new() -> Address {
  17. let mut rng = rand::thread_rng();
  18. let mut a = [0u8; 20];
  19. rng.fill(&mut a[..]);
  20. a
  21. }
  22. struct VirtualMachine {
  23. memory: MemoryRef,
  24. cur: Address,
  25. code: Vec<u8>,
  26. input: Vec<u8>,
  27. output: Vec<u8>,
  28. returndata: Vec<u8>,
  29. }
  30. impl VirtualMachine {
  31. fn new(code: Vec<u8>, address: Address) -> Self {
  32. VirtualMachine {
  33. memory: MemoryInstance::alloc(Pages(2), Some(Pages(2))).unwrap(),
  34. input: Vec::new(),
  35. output: Vec::new(),
  36. returndata: Vec::new(),
  37. code,
  38. cur: address,
  39. }
  40. }
  41. }
  42. struct TestRuntime {
  43. abi: ethabi::Contract,
  44. contracts: Vec<Vec<u8>>,
  45. value: u128,
  46. caller: Address,
  47. accounts: HashMap<Address, (Vec<u8>, u128)>,
  48. store: HashMap<(Address, [u8; 32]), [u8; 32]>,
  49. vm: VirtualMachine,
  50. events: Vec<Event>,
  51. }
  52. struct Event {
  53. topics: Vec<[u8; 32]>,
  54. data: Vec<u8>,
  55. }
  56. #[derive(FromPrimitive)]
  57. #[allow(non_camel_case_types)]
  58. pub enum Extern {
  59. getCallDataSize = 1,
  60. callDataCopy,
  61. storageLoad,
  62. storageStore,
  63. finish,
  64. revert,
  65. printMem,
  66. getCodeSize,
  67. codeCopy,
  68. create,
  69. call,
  70. returnDataCopy,
  71. getReturnDataSize,
  72. getCallValue,
  73. getCaller,
  74. getAddress,
  75. getExternalBalance,
  76. selfDestruct,
  77. log,
  78. }
  79. #[derive(Debug, Clone, PartialEq)]
  80. struct HostCodeFinish {}
  81. impl HostError for HostCodeFinish {}
  82. impl fmt::Display for HostCodeFinish {
  83. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  84. write!(f, "finish")
  85. }
  86. }
  87. #[derive(Debug, Clone, PartialEq)]
  88. struct HostCodeRevert {}
  89. impl fmt::Display for HostCodeRevert {
  90. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  91. write!(f, "revert")
  92. }
  93. }
  94. impl HostError for HostCodeRevert {}
  95. impl Externals for TestRuntime {
  96. fn invoke_index(
  97. &mut self,
  98. index: usize,
  99. args: RuntimeArgs,
  100. ) -> Result<Option<RuntimeValue>, Trap> {
  101. match FromPrimitive::from_usize(index) {
  102. Some(Extern::getCallDataSize) => {
  103. Ok(Some(RuntimeValue::I32(self.vm.input.len() as i32)))
  104. }
  105. Some(Extern::getCodeSize) => Ok(Some(RuntimeValue::I32(self.vm.code.len() as i32))),
  106. Some(Extern::getReturnDataSize) => {
  107. Ok(Some(RuntimeValue::I32(self.vm.returndata.len() as i32)))
  108. }
  109. Some(Extern::callDataCopy) => {
  110. let dest = args.nth_checked::<u32>(0)?;
  111. let input_offset = args.nth_checked::<u32>(1)? as usize;
  112. let input_len = args.nth_checked::<u32>(2)? as usize;
  113. self.vm
  114. .memory
  115. .set(
  116. dest,
  117. &self.vm.input[input_offset as usize..input_offset + input_len],
  118. )
  119. .expect("calldatacopy should work");
  120. Ok(None)
  121. }
  122. Some(Extern::codeCopy) => {
  123. let dest = args.nth_checked::<u32>(0)?;
  124. let code_offset = args.nth_checked::<u32>(1)? as usize;
  125. let code_len = args.nth_checked::<u32>(2)? as usize;
  126. let data = &self.vm.code[code_offset as usize..code_offset + code_len];
  127. println!("codeCopy {} {}", code_len, hex::encode(data));
  128. self.vm
  129. .memory
  130. .set(dest, data)
  131. .expect("codeCopy should work");
  132. Ok(None)
  133. }
  134. Some(Extern::returnDataCopy) => {
  135. let dest = args.nth_checked::<u32>(0)?;
  136. let data_offset = args.nth_checked::<u32>(1)? as usize;
  137. let data_len = args.nth_checked::<u32>(2)? as usize;
  138. let data = &self.vm.returndata[data_offset as usize..data_offset + data_len];
  139. println!("returnDataCopy {} {}", data_len, hex::encode(data));
  140. self.vm
  141. .memory
  142. .set(dest, data)
  143. .expect("returnDataCopy should work");
  144. Ok(None)
  145. }
  146. Some(Extern::finish) => {
  147. let src: u32 = args.nth_checked(0)?;
  148. let len: u32 = args.nth_checked(1)?;
  149. let mut output = Vec::new();
  150. output.resize(len as usize, 0);
  151. self.vm.memory.get_into(src, &mut output).unwrap();
  152. println!("finish: {} {}", len, hex::encode(&output));
  153. self.vm.output = output;
  154. Err(Trap::new(TrapKind::Host(Box::new(HostCodeFinish {}))))
  155. }
  156. Some(Extern::revert) => {
  157. let src: u32 = args.nth_checked(0)?;
  158. let len: u32 = args.nth_checked(1)?;
  159. let mut output = Vec::new();
  160. output.resize(len as usize, 0);
  161. self.vm.memory.get_into(src, &mut output).unwrap();
  162. self.vm.output = output;
  163. println!(
  164. "revert {} {}",
  165. self.vm.output.len(),
  166. hex::encode(&self.vm.output)
  167. );
  168. Err(Trap::new(TrapKind::Host(Box::new(HostCodeRevert {}))))
  169. }
  170. Some(Extern::storageLoad) => {
  171. let key_ptr: u32 = args.nth_checked(0)?;
  172. let data_ptr: u32 = args.nth_checked(1)?;
  173. let mut key = [0u8; 32];
  174. self.vm
  175. .memory
  176. .get_into(key_ptr, &mut key)
  177. .expect("copy key from wasm memory");
  178. let res = if let Some(v) = self.store.get(&(self.vm.cur, key)) {
  179. v
  180. } else {
  181. &[0u8; 32]
  182. };
  183. println!("storageLoad {} -> {}", hex::encode(&key), hex::encode(&res));
  184. self.vm
  185. .memory
  186. .set(data_ptr, res)
  187. .expect("copy key from wasm memory");
  188. Ok(None)
  189. }
  190. Some(Extern::storageStore) => {
  191. let key_ptr: u32 = args.nth_checked(0)?;
  192. let data_ptr: u32 = args.nth_checked(1)?;
  193. let mut key = [0u8; 32];
  194. let mut data = [0u8; 32];
  195. self.vm
  196. .memory
  197. .get_into(key_ptr, &mut key)
  198. .expect("copy key from wasm memory");
  199. self.vm
  200. .memory
  201. .get_into(data_ptr, &mut data)
  202. .expect("copy key from wasm memory");
  203. println!(
  204. "storageStore {} <- {}",
  205. hex::encode(&key),
  206. hex::encode(&data)
  207. );
  208. if data.iter().any(|n| *n != 0) {
  209. self.store.insert((self.vm.cur, key), data);
  210. } else {
  211. self.store.remove(&(self.vm.cur, key));
  212. }
  213. Ok(None)
  214. }
  215. Some(Extern::printMem) => {
  216. let data_ptr: u32 = args.nth_checked(0)?;
  217. let len: u32 = args.nth_checked(1)?;
  218. let mut buf = Vec::new();
  219. buf.resize(len as usize, 0u8);
  220. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut buf) {
  221. panic!("printMem: {}", e);
  222. }
  223. println!("{}", String::from_utf8_lossy(&buf));
  224. Ok(None)
  225. }
  226. Some(Extern::create) => {
  227. //let balance_ptr: u32 = args.nth_checked(0)?;
  228. let input_ptr: u32 = args.nth_checked(1)?;
  229. let input_len: u32 = args.nth_checked(2)?;
  230. let address_ptr: u32 = args.nth_checked(3)?;
  231. let mut buf = Vec::new();
  232. buf.resize(input_len as usize, 0u8);
  233. if let Err(e) = self.vm.memory.get_into(input_ptr, &mut buf) {
  234. panic!("create: {}", e);
  235. }
  236. println!("create code: {}", hex::encode(&buf));
  237. let addr = address_new();
  238. println!("create address: {}", hex::encode(&addr));
  239. // when ewasm creates a contract, the abi encoded args are concatenated to the
  240. // code. So, find which code is was and use that instead. Otherwise, the
  241. // wasm validator will trip
  242. let code = self
  243. .contracts
  244. .iter()
  245. .find(|c| buf.starts_with(c))
  246. .unwrap()
  247. .clone();
  248. let mut vm = VirtualMachine::new(buf, addr);
  249. std::mem::swap(&mut self.vm, &mut vm);
  250. let module = self.create_module(&code);
  251. if let Some(ExternVal::Memory(memory_ref)) = module.export_by_name("memory") {
  252. self.vm.memory = memory_ref;
  253. }
  254. match module.invoke_export("main", &[], self) {
  255. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  256. TrapKind::Host(host_error) => {
  257. assert!(
  258. host_error.downcast_ref::<HostCodeRevert>().is_none(),
  259. "revert executed"
  260. );
  261. }
  262. _ => panic!("fail to invoke main via create: {}", trap),
  263. },
  264. Ok(_) => {}
  265. Err(e) => panic!("fail to invoke main via create: {}", e),
  266. }
  267. let res = self.vm.output.clone();
  268. println!("create returns: {}", hex::encode(&res));
  269. std::mem::swap(&mut self.vm, &mut vm);
  270. self.accounts.insert(addr, (res, 0));
  271. self.vm
  272. .memory
  273. .set(address_ptr, &addr[..])
  274. .expect("copy key from wasm memory");
  275. Ok(Some(RuntimeValue::I32(0)))
  276. }
  277. Some(Extern::call) => {
  278. //let gas: u64 = args.nth_checked(0)?;
  279. let address_ptr: u32 = args.nth_checked(1)?;
  280. //let value_ptr: u32 = args.nth_checked(2)?;
  281. let input_ptr: u32 = args.nth_checked(3)?;
  282. let input_len: u32 = args.nth_checked(4)?;
  283. let mut buf = Vec::new();
  284. buf.resize(input_len as usize, 0u8);
  285. if let Err(e) = self.vm.memory.get_into(input_ptr, &mut buf) {
  286. panic!("call: {}", e);
  287. }
  288. let mut addr = [0u8; 20];
  289. if let Err(e) = self.vm.memory.get_into(address_ptr, &mut addr) {
  290. panic!("address: {}", e);
  291. }
  292. println!(
  293. "extern call address: {} data: {}",
  294. hex::encode(&addr),
  295. hex::encode(&buf)
  296. );
  297. // if the first 19 bytes are 0, it's a precompile
  298. if addr[0..19].iter().all(|v| *v == 0) {
  299. match addr[19] {
  300. 20 => {
  301. let mut hasher = Keccak::v256();
  302. let mut hash = [0u8; 32];
  303. hasher.update(&buf);
  304. hasher.finalize(&mut hash);
  305. self.vm.returndata = hash.to_vec();
  306. return Ok(Some(RuntimeValue::I32(0)));
  307. }
  308. 2 => {
  309. let mut hasher = Sha256::new();
  310. hasher.update(&buf);
  311. self.vm.returndata = hasher.finalize().to_vec();
  312. return Ok(Some(RuntimeValue::I32(0)));
  313. }
  314. 3 => {
  315. let mut hasher = Ripemd160::new();
  316. hasher.update(&buf);
  317. self.vm.returndata = hasher.finalize().to_vec();
  318. return Ok(Some(RuntimeValue::I32(0)));
  319. }
  320. n => {
  321. panic!("unknown precompile {}", n);
  322. }
  323. }
  324. }
  325. // when ewasm creates a contract, the abi encoded args are concatenated to the
  326. // code. So, find which code is was and use that instead. Otherwise, the
  327. // wasm validator will trip
  328. let (code, _) = self.accounts.get(&addr).unwrap().clone();
  329. let mut vm = VirtualMachine::new(code.to_vec(), addr);
  330. std::mem::swap(&mut self.vm, &mut vm);
  331. self.vm.input = buf;
  332. let module = self.create_module(&code);
  333. if let Some(ExternVal::Memory(memory_ref)) = module.export_by_name("memory") {
  334. self.vm.memory = memory_ref;
  335. }
  336. let ret = match module.invoke_export("main", &[], self) {
  337. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  338. TrapKind::Host(kind) => {
  339. if format!("{}", kind) == "revert" {
  340. 1
  341. } else {
  342. 0
  343. }
  344. }
  345. _ => panic!("fail to invoke main via create: {}", trap),
  346. },
  347. Ok(_) => 0,
  348. Err(e) => panic!("fail to invoke main via create: {}", e),
  349. };
  350. let res = self.vm.output.clone();
  351. std::mem::swap(&mut self.vm, &mut vm);
  352. self.vm.returndata = res;
  353. self.vm
  354. .memory
  355. .set(address_ptr, &addr[..])
  356. .expect("copy key from wasm memory");
  357. Ok(Some(RuntimeValue::I32(ret)))
  358. }
  359. Some(Extern::getCallValue) => {
  360. let value_ptr: u32 = args.nth_checked(0)?;
  361. let value = self.value.to_le_bytes();
  362. println!("getCallValue: {}", hex::encode(&value));
  363. self.vm.memory.set(value_ptr, &value).expect("set value");
  364. Ok(None)
  365. }
  366. Some(Extern::getAddress) => {
  367. let address_ptr: u32 = args.nth_checked(0)?;
  368. println!("getAddress: {}", hex::encode(&self.vm.cur));
  369. self.vm
  370. .memory
  371. .set(address_ptr, &self.vm.cur[..])
  372. .expect("set address");
  373. Ok(None)
  374. }
  375. Some(Extern::getCaller) => {
  376. let address_ptr: u32 = args.nth_checked(0)?;
  377. println!("getCaller: {}", hex::encode(&self.caller));
  378. self.vm
  379. .memory
  380. .set(address_ptr, &self.caller[..])
  381. .expect("set address");
  382. Ok(None)
  383. }
  384. Some(Extern::getExternalBalance) => {
  385. let address_ptr: u32 = args.nth_checked(0)?;
  386. let balance_ptr: u32 = args.nth_checked(1)?;
  387. let mut addr = [0u8; 20];
  388. if let Err(e) = self.vm.memory.get_into(address_ptr, &mut addr) {
  389. panic!("call: {}", e);
  390. }
  391. let value = self.accounts.get(&addr).map(|a| a.1).unwrap_or(0);
  392. println!("getExternalBalance: {} {}", hex::encode(&addr), value);
  393. self.vm
  394. .memory
  395. .set(balance_ptr, &value.to_le_bytes()[..])
  396. .expect("set balance");
  397. Ok(None)
  398. }
  399. Some(Extern::selfDestruct) => {
  400. let address_ptr: u32 = args.nth_checked(0)?;
  401. let mut addr = [0u8; 20];
  402. if let Err(e) = self.vm.memory.get_into(address_ptr, &mut addr) {
  403. panic!("selfDestruct: {}", e);
  404. }
  405. let remaining = self.accounts[&self.vm.cur].1;
  406. self.accounts.get_mut(&addr).unwrap().1 += remaining;
  407. println!("selfDestruct: {} {}", hex::encode(&addr), remaining);
  408. self.accounts.remove(&self.vm.cur);
  409. Err(Trap::new(TrapKind::Host(Box::new(HostCodeFinish {}))))
  410. }
  411. Some(Extern::log) => {
  412. let data_ptr: u32 = args.nth_checked(0)?;
  413. let data_len: u32 = args.nth_checked(1)?;
  414. let mut data = Vec::new();
  415. data.resize(data_len as usize, 0u8);
  416. if let Err(e) = self.vm.memory.get_into(data_ptr, &mut data) {
  417. panic!("log: {}", e);
  418. }
  419. let topic_count: u32 = args.nth_checked(2)?;
  420. let mut event = Event {
  421. data,
  422. topics: Vec::new(),
  423. };
  424. assert!(topic_count <= 4, "log: wrong topic count {}", topic_count);
  425. for topic in 0..topic_count {
  426. let topic_ptr: u32 = args.nth_checked(3 + topic as usize)?;
  427. let mut topic_data = [0u8; 32];
  428. if let Err(e) = self.vm.memory.get_into(topic_ptr, &mut topic_data) {
  429. panic!("log: topic {} {}", topic, e);
  430. }
  431. event.topics.push(topic_data);
  432. }
  433. println!(
  434. "log: data: {} topics: {}",
  435. hex::encode(&event.data),
  436. event
  437. .topics
  438. .iter()
  439. .map(hex::encode)
  440. .collect::<Vec<String>>()
  441. .join(" ")
  442. );
  443. self.events.push(event);
  444. Ok(None)
  445. }
  446. _ => panic!("external {} unknown", index),
  447. }
  448. }
  449. }
  450. impl ModuleImportResolver for TestRuntime {
  451. fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
  452. let index = match field_name {
  453. "getCallDataSize" => Extern::getCallDataSize,
  454. "callDataCopy" => Extern::callDataCopy,
  455. "finish" => Extern::finish,
  456. "revert" => Extern::revert,
  457. "storageStore" => Extern::storageStore,
  458. "storageLoad" => Extern::storageLoad,
  459. "printMem" => Extern::printMem,
  460. "getCodeSize" => Extern::getCodeSize,
  461. "codeCopy" => Extern::codeCopy,
  462. "create" => Extern::create,
  463. "call" => Extern::call,
  464. "returnDataCopy" => Extern::returnDataCopy,
  465. "getReturnDataSize" => Extern::getReturnDataSize,
  466. "getCallValue" => Extern::getCallValue,
  467. "getCaller" => Extern::getCaller,
  468. "getAddress" => Extern::getAddress,
  469. "getExternalBalance" => Extern::getExternalBalance,
  470. "selfDestruct" => Extern::selfDestruct,
  471. "log" => Extern::log,
  472. _ => {
  473. panic!("{} not implemented", field_name);
  474. }
  475. };
  476. Ok(FuncInstance::alloc_host(signature.clone(), index as usize))
  477. }
  478. fn resolve_memory(
  479. &self,
  480. _field_name: &str,
  481. _memory_type: &MemoryDescriptor,
  482. ) -> Result<MemoryRef, Error> {
  483. Ok(self.vm.memory.clone())
  484. }
  485. }
  486. impl TestRuntime {
  487. fn create_module(&self, code: &[u8]) -> ModuleRef {
  488. let module = Module::from_buffer(&code).expect("parse wasm should work");
  489. ModuleInstance::new(
  490. &module,
  491. &ImportsBuilder::new().with_resolver("ethereum", self),
  492. )
  493. .expect("Failed to instantiate module")
  494. .run_start(&mut NopExternals)
  495. .expect("Failed to run start function in module")
  496. }
  497. fn function(&mut self, name: &str, args: &[Token]) -> Vec<Token> {
  498. let calldata = match self.abi.functions[name][0].encode_input(args) {
  499. Ok(n) => n,
  500. Err(x) => panic!("{}", x),
  501. };
  502. let module = self.create_module(&self.accounts[&self.vm.cur].0);
  503. println!("FUNCTION CALLDATA: {}", hex::encode(&calldata));
  504. self.vm.input = calldata;
  505. if let Some(ExternVal::Memory(memory_ref)) = module.export_by_name("memory") {
  506. self.vm.memory = memory_ref;
  507. }
  508. match module.invoke_export("main", &[], self) {
  509. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  510. TrapKind::Host(host_error) => {
  511. assert!(
  512. host_error.downcast_ref::<HostCodeFinish>().is_some(),
  513. "fail to invoke main: {}",
  514. host_error
  515. );
  516. }
  517. _ => panic!("fail to invoke main: {}", trap),
  518. },
  519. Ok(Some(RuntimeValue::I32(0))) => {}
  520. Ok(Some(RuntimeValue::I32(ret))) => panic!("main returns: {}", ret),
  521. Err(e) => panic!("fail to invoke main: {}", e),
  522. Ok(None) => panic!("fail to invoke main"),
  523. _ => panic!("fail to invoke main, unknown"),
  524. }
  525. println!("RETURNDATA: {}", hex::encode(&self.vm.output));
  526. self.abi.functions[name][0]
  527. .decode_output(&self.vm.output)
  528. .unwrap()
  529. }
  530. fn function_abi_fail(&mut self, name: &str, args: &[Token], patch: fn(&mut Vec<u8>)) {
  531. let mut calldata = match self.abi.functions[name][0].encode_input(args) {
  532. Ok(n) => n,
  533. Err(x) => panic!("{}", x),
  534. };
  535. patch(&mut calldata);
  536. let module = self.create_module(&self.accounts[&self.vm.cur].0);
  537. println!("FUNCTION CALLDATA: {}", hex::encode(&calldata));
  538. if let Some(ExternVal::Memory(memory_ref)) = module.export_by_name("memory") {
  539. self.vm.memory = memory_ref;
  540. }
  541. self.vm.input = calldata;
  542. match module.invoke_export("main", &[], self) {
  543. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  544. TrapKind::Host(host_error) => {
  545. assert!(
  546. host_error.downcast_ref::<HostCodeFinish>().is_some(),
  547. "fail to invoke main: {}",
  548. host_error
  549. );
  550. }
  551. _ => panic!("fail to invoke main: {}", trap),
  552. },
  553. Ok(Some(RuntimeValue::I32(3))) => {}
  554. Ok(Some(RuntimeValue::I32(ret))) => panic!("main returns: {}", ret),
  555. Err(e) => panic!("fail to invoke main: {}", e),
  556. Ok(None) => panic!("fail to invoke main"),
  557. _ => panic!("fail to invoke main, unknown"),
  558. }
  559. }
  560. fn function_revert(&mut self, name: &str, args: &[Token]) -> Option<String> {
  561. let calldata = match self.abi.functions[name][0].encode_input(args) {
  562. Ok(n) => n,
  563. Err(x) => panic!("{}", x),
  564. };
  565. let module = self.create_module(&self.accounts[&self.vm.cur].0);
  566. println!("FUNCTION CALLDATA: {}", hex::encode(&calldata));
  567. self.vm.input = calldata;
  568. if let Some(ExternVal::Memory(memory_ref)) = module.export_by_name("memory") {
  569. self.vm.memory = memory_ref;
  570. }
  571. match module.invoke_export("main", &[], self) {
  572. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  573. TrapKind::Host(host_error) => {
  574. if host_error.downcast_ref::<HostCodeRevert>().is_none() {
  575. panic!("function was suppose to revert, not finish")
  576. }
  577. }
  578. _ => panic!("fail to invoke main: {}", trap),
  579. },
  580. Ok(Some(RuntimeValue::I32(1))) => {}
  581. Err(e) => panic!("fail to invoke main: {}", e),
  582. _ => panic!("fail to invoke main"),
  583. }
  584. println!("RETURNDATA: {}", hex::encode(&self.vm.output));
  585. if self.vm.output.is_empty() {
  586. return None;
  587. }
  588. assert_eq!(self.vm.output[..4], 0x08c3_79a0u32.to_be_bytes());
  589. if let Ok(v) = decode(&[ethabi::ParamType::String], &self.vm.output[4..]) {
  590. assert_eq!(v.len(), 1);
  591. if let ethabi::Token::String(r) = &v[0] {
  592. return Some(r.to_owned());
  593. }
  594. }
  595. panic!("failed to decode");
  596. }
  597. fn constructor_expect_revert(&mut self, args: &[Token]) {
  598. assert!(!self.do_constructor(args));
  599. }
  600. fn constructor(&mut self, args: &[Token]) {
  601. assert!(self.do_constructor(args));
  602. }
  603. fn do_constructor(&mut self, args: &[Token]) -> bool {
  604. let calldata = if let Some(constructor) = &self.abi.constructor {
  605. constructor.encode_input(Vec::new(), args).unwrap()
  606. } else {
  607. Vec::new()
  608. };
  609. let module = self.create_module(self.contracts.last().unwrap());
  610. println!("CONSTRUCTOR CALLDATA: {}", hex::encode(&calldata));
  611. if let Some(ExternVal::Memory(memory_ref)) = module.export_by_name("memory") {
  612. self.vm.memory = memory_ref;
  613. }
  614. self.vm.code.extend(calldata);
  615. self.vm.cur = address_new();
  616. match module.invoke_export("main", &[], self) {
  617. Err(wasmi::Error::Trap(trap)) => match trap.kind() {
  618. TrapKind::Host(host_error) => {
  619. if host_error.downcast_ref::<HostCodeRevert>().is_some() {
  620. return false;
  621. }
  622. }
  623. _ => panic!("fail to invoke main: {}", trap),
  624. },
  625. Ok(_) => {}
  626. Err(e) => panic!("fail to invoke main: {}", e),
  627. }
  628. println!(
  629. "DEPLOYER RETURNS: {} {}",
  630. self.vm.output.len(),
  631. hex::encode(&self.vm.output)
  632. );
  633. self.accounts
  634. .insert(self.vm.cur, (self.vm.output.clone(), 0));
  635. true
  636. }
  637. fn events(&self) -> Vec<RawLog> {
  638. self.events
  639. .iter()
  640. .map(|e| RawLog {
  641. data: e.data.clone(),
  642. topics: e.topics.iter().map(ethereum_types::H256::from).collect(),
  643. })
  644. .collect()
  645. }
  646. }
  647. fn build_solidity(src: &str) -> TestRuntime {
  648. let mut cache = FileResolver::new();
  649. cache.set_file_contents("test.sol", src.to_string());
  650. let (res, ns) = compile(
  651. OsStr::new("test.sol"),
  652. &mut cache,
  653. inkwell::OptimizationLevel::Default,
  654. Target::Ewasm,
  655. false,
  656. );
  657. ns.print_diagnostics_in_plain(&cache, false);
  658. for v in &res {
  659. println!("contract size:{}", v.0.len());
  660. }
  661. assert!(!res.is_empty());
  662. // resolve
  663. let (bc, abi) = res.last().unwrap().clone();
  664. TestRuntime {
  665. accounts: HashMap::new(),
  666. vm: VirtualMachine::new(bc, [0u8; 20]),
  667. value: 0,
  668. store: HashMap::new(),
  669. abi: ethabi::Contract::load(abi.as_bytes()).unwrap(),
  670. contracts: res.into_iter().map(|v| v.0).collect(),
  671. events: Vec::new(),
  672. caller: address_new(),
  673. }
  674. }
  675. #[test]
  676. fn simple_solidiy_compile_and_run() {
  677. // parse
  678. let mut runtime = build_solidity(
  679. "
  680. contract test {
  681. function foo() public returns (uint32) {
  682. return 2;
  683. }
  684. }",
  685. );
  686. // call constructor
  687. runtime.constructor(&[]);
  688. let returns = runtime.function("foo", &[]);
  689. assert_eq!(
  690. returns,
  691. vec![ethabi::Token::Uint(ethereum_types::U256::from(2))]
  692. );
  693. }
  694. #[test]
  695. fn simple_loops() {
  696. let mut runtime = build_solidity(
  697. r##"
  698. contract test3 {
  699. function foo(uint32 a) public returns (uint32) {
  700. uint32 b = 50 - a;
  701. uint32 c;
  702. c = 100 * b;
  703. c += 5;
  704. return a * 1000 + c;
  705. }
  706. function bar(uint32 b, bool x) public returns (uint32) {
  707. uint32 i = 1;
  708. if (x) {
  709. do {
  710. i += 10;
  711. }
  712. while (b-- > 0);
  713. } else {
  714. uint32 j;
  715. for (j=2; j<10; j++) {
  716. i *= 3;
  717. }
  718. }
  719. return i;
  720. }
  721. function baz(uint32 x) public returns (uint32) {
  722. for (uint32 i = 0; i<100; i++) {
  723. x *= 7;
  724. if (x > 200) {
  725. break;
  726. }
  727. x++;
  728. }
  729. return x;
  730. }
  731. }"##,
  732. );
  733. // call constructor
  734. runtime.constructor(&[]);
  735. for i in 0..=50 {
  736. let res = ((50 - i) * 100 + 5) + i * 1000;
  737. let returns =
  738. runtime.function("foo", &[ethabi::Token::Uint(ethereum_types::U256::from(i))]);
  739. assert_eq!(
  740. returns,
  741. vec![ethabi::Token::Uint(ethereum_types::U256::from(res))]
  742. );
  743. }
  744. for i in 0..=50 {
  745. let res = (i + 1) * 10 + 1;
  746. let returns = runtime.function(
  747. "bar",
  748. &[
  749. ethabi::Token::Uint(ethereum_types::U256::from(i)),
  750. ethabi::Token::Bool(true),
  751. ],
  752. );
  753. assert_eq!(
  754. returns,
  755. vec![ethabi::Token::Uint(ethereum_types::U256::from(res))]
  756. );
  757. }
  758. for i in 0..=50 {
  759. let mut res = 1;
  760. for _ in 2..10 {
  761. res *= 3;
  762. }
  763. let returns = runtime.function(
  764. "bar",
  765. &[
  766. ethabi::Token::Uint(ethereum_types::U256::from(i)),
  767. ethabi::Token::Bool(false),
  768. ],
  769. );
  770. assert_eq!(
  771. returns,
  772. vec![ethabi::Token::Uint(ethereum_types::U256::from(res))]
  773. );
  774. }
  775. for i in 1..=50 {
  776. let mut res = i;
  777. for _ in 0..100 {
  778. res *= 7;
  779. if res > 200 {
  780. break;
  781. }
  782. res += 1;
  783. }
  784. let returns =
  785. runtime.function("baz", &[ethabi::Token::Uint(ethereum_types::U256::from(i))]);
  786. assert_eq!(
  787. returns,
  788. vec![ethabi::Token::Uint(ethereum_types::U256::from(res))]
  789. );
  790. }
  791. }
  792. #[test]
  793. fn stack_test() {
  794. let mut runtime = build_solidity(
  795. r##"
  796. contract test3 {
  797. function foo() public returns (bool) {
  798. uint b = 18446744073709551616;
  799. uint c = 36893488147419103232;
  800. return b * 2 == c;
  801. }
  802. }"##,
  803. );
  804. // call constructor
  805. runtime.constructor(&[]);
  806. let returns = runtime.function("foo", &[]);
  807. assert_eq!(returns, vec![ethabi::Token::Bool(true)]);
  808. }
  809. #[test]
  810. fn abi_call_return_test() {
  811. let mut runtime = build_solidity(
  812. r##"
  813. contract test {
  814. function foo() public returns (uint32) {
  815. return 102;
  816. }
  817. }"##,
  818. );
  819. // call constructor
  820. runtime.constructor(&[]);
  821. let returns = runtime.function("foo", &[]);
  822. assert_eq!(
  823. returns,
  824. vec![ethabi::Token::Uint(ethereum_types::U256::from(102))]
  825. );
  826. }
  827. #[test]
  828. fn abi_call_pass_return_test() {
  829. let mut runtime = build_solidity(
  830. r##"
  831. contract x {
  832. function test() public {
  833. }
  834. }
  835. contract bar {
  836. function foo(uint32 a) public returns (uint32) {
  837. return a;
  838. }
  839. }"##,
  840. );
  841. // call constructor
  842. runtime.constructor(&[]);
  843. for val in [102i32, 255, 256, 0x7fff_ffff].iter() {
  844. let returns = runtime.function(
  845. "foo",
  846. &[ethabi::Token::Uint(ethereum_types::U256::from(*val))],
  847. );
  848. assert_eq!(
  849. returns,
  850. vec![ethabi::Token::Uint(ethereum_types::U256::from(*val))]
  851. );
  852. }
  853. }
  854. #[test]
  855. fn contract_storage_test() {
  856. let mut runtime = build_solidity(
  857. r##"
  858. contract test {
  859. uint32 foo;
  860. constructor() public {
  861. foo = 102;
  862. }
  863. function getFoo() public returns (uint32) {
  864. return foo + 256;
  865. }
  866. function setFoo(uint32 a) public {
  867. foo = a - 256;
  868. }
  869. }"##,
  870. );
  871. // call constructor
  872. runtime.constructor(&[]);
  873. for val in [4096u32, 1000u32].iter() {
  874. let eval = ethabi::Token::Uint(ethereum_types::U256::from(*val));
  875. // create call for foo
  876. let returns = runtime.function("setFoo", &[eval]);
  877. assert_eq!(returns, vec![]);
  878. // create call for foo
  879. let returns = runtime.function("getFoo", &[]);
  880. let eval = ethabi::Token::Uint(ethereum_types::U256::from(*val));
  881. assert_eq!(returns, vec![eval]);
  882. }
  883. }
  884. #[test]
  885. fn large_ints_encoded() {
  886. let mut runtime = build_solidity(
  887. r##"
  888. contract test {
  889. uint foo;
  890. constructor() public {
  891. foo = 102;
  892. }
  893. function getFoo() public returns (uint) {
  894. return foo + 256;
  895. }
  896. function setFoo(uint a) public {
  897. foo = a - 256;
  898. }
  899. }"##,
  900. );
  901. // call constructor
  902. runtime.constructor(&[]);
  903. for val in [4096u32, 1000u32].iter() {
  904. let eval = ethabi::Token::Uint(ethereum_types::U256::from(*val));
  905. // create call for foo
  906. let returns = runtime.function("setFoo", &[eval]);
  907. assert_eq!(returns, vec![]);
  908. // create call for foo
  909. let returns = runtime.function("getFoo", &[]);
  910. let eval = ethabi::Token::Uint(ethereum_types::U256::from(*val));
  911. assert_eq!(returns, vec![eval]);
  912. }
  913. }
  914. #[test]
  915. fn address() {
  916. let mut runtime = build_solidity(
  917. "
  918. contract address_tester {
  919. function encode_const() public returns (address) {
  920. return 0x52908400098527886E0F7030069857D2E4169EE7;
  921. }
  922. function test_arg(address foo) public {
  923. assert(foo == 0x27b1fdb04752bbc536007a920d24acb045561c26);
  924. // this literal is a number
  925. int x = 0x27b1fdb047_52bbc536007a920d24acb045561C26;
  926. assert(int(foo) == x);
  927. }
  928. function allones() public returns (address) {
  929. return address(1);
  930. }
  931. }",
  932. );
  933. // call constructor
  934. runtime.constructor(&[]);
  935. let ret = runtime.function("encode_const", &[]);
  936. assert_eq!(
  937. ret,
  938. [ethabi::Token::Address(ethereum_types::Address::from_slice(
  939. &hex::decode("52908400098527886E0F7030069857D2E4169EE7").unwrap()
  940. ))]
  941. );
  942. runtime.function(
  943. "test_arg",
  944. &[ethabi::Token::Address(ethereum_types::Address::from_slice(
  945. &hex::decode("27b1fdb04752bbc536007a920d24acb045561c26").unwrap(),
  946. ))],
  947. );
  948. let ret = runtime.function("allones", &[]);
  949. assert_eq!(
  950. ret,
  951. [ethabi::Token::Address(ethereum_types::Address::from_slice(
  952. &hex::decode("0000000000000000000000000000000000000001").unwrap()
  953. ))]
  954. );
  955. // no arithmetic/bitwise allowed on address
  956. // no ordered comparison allowed
  957. // address 0x27b1fdb04752bbc536007a920d24acb045561C26 should be a warning
  958. }
  959. #[test]
  960. fn bytes() {
  961. let mut runtime = build_solidity(
  962. r##"
  963. contract bar {
  964. bytes4 constant foo = hex"11223344";
  965. function get_foo() public returns (bytes4) {
  966. return foo;
  967. }
  968. function bytes4asuint32() public view returns (uint32) {
  969. return uint32(foo);
  970. }
  971. function bytes4asuint64() public view returns (uint64) {
  972. return uint64(bytes8(foo));
  973. }
  974. function bytes4asbytes2() public view returns (bytes2) {
  975. return bytes2(foo);
  976. }
  977. function passthrough(bytes4 bar) public view returns (bytes4) {
  978. return bar;
  979. }
  980. function entry(uint index) public view returns (bytes1) {
  981. return foo[index];
  982. }
  983. function entry2(uint index) public pure returns (bytes1) {
  984. return hex"AABBCCDD"[index];
  985. }
  986. function shiftedleft() public view returns (bytes4) {
  987. return foo << 8;
  988. }
  989. function shiftedright() public view returns (bytes4) {
  990. return foo >> 8;
  991. }
  992. }"##,
  993. );
  994. runtime.constructor(&[]);
  995. let ret = runtime.function("get_foo", &[]);
  996. assert_eq!(
  997. ret,
  998. [ethabi::Token::FixedBytes(vec!(0x11, 0x22, 0x33, 0x44))]
  999. );
  1000. let ret = runtime.function("bytes4asuint32", &[]);
  1001. assert_eq!(
  1002. ret,
  1003. [ethabi::Token::Uint(ethereum_types::U256::from(
  1004. 0x11_22_33_44
  1005. ))]
  1006. );
  1007. let ret = runtime.function("bytes4asuint64", &[]);
  1008. assert_eq!(
  1009. ret,
  1010. [ethabi::Token::Uint(ethereum_types::U256::from(
  1011. 0x1122_3344_0000_0000u64
  1012. ))]
  1013. );
  1014. let ret = runtime.function("bytes4asbytes2", &[]);
  1015. assert_eq!(ret, [ethabi::Token::FixedBytes(vec!(0x11, 0x22))]);
  1016. let val = vec![ethabi::Token::FixedBytes(vec![0x41, 0x42, 0x43, 0x44])];
  1017. assert_eq!(runtime.function("passthrough", &val), val);
  1018. let val = vec![ethabi::Token::Uint(ethereum_types::U256::from(1))];
  1019. let ret = runtime.function("entry", &val);
  1020. assert_eq!(ret, [ethabi::Token::FixedBytes(vec!(0x22))]);
  1021. let ret = runtime.function("entry2", &val);
  1022. assert_eq!(ret, [ethabi::Token::FixedBytes(vec!(0xBB))]);
  1023. }
  1024. #[test]
  1025. fn array() {
  1026. let mut runtime = build_solidity(
  1027. r##"
  1028. contract foo {
  1029. function f(uint i1) public returns (int) {
  1030. int[8] bar = [ int(10), 20, 30, 4, 5, 6, 7, 8 ];
  1031. bar[2] = 0x7_f;
  1032. return bar[i1];
  1033. }
  1034. function bar() public returns (uint) {
  1035. uint[2][3][4] array;
  1036. return array.length;
  1037. }
  1038. }"##,
  1039. );
  1040. runtime.constructor(&[]);
  1041. let val = vec![ethabi::Token::Uint(ethereum_types::U256::from(1))];
  1042. let ret = runtime.function("f", &val);
  1043. assert_eq!(ret, [ethabi::Token::Int(ethereum_types::U256::from(20))]);
  1044. let val = vec![ethabi::Token::Uint(ethereum_types::U256::from(2))];
  1045. let ret = runtime.function("f", &val);
  1046. assert_eq!(ret, [ethabi::Token::Int(ethereum_types::U256::from(127))]);
  1047. let ret = runtime.function("bar", &[]);
  1048. assert_eq!(ret, [ethabi::Token::Uint(ethereum_types::U256::from(4))]);
  1049. }
  1050. #[test]
  1051. fn encode_array() {
  1052. let mut runtime = build_solidity(
  1053. r##"
  1054. contract foo {
  1055. function f(int32[4] a, uint i) public returns (int32) {
  1056. return a[i];
  1057. }
  1058. }"##,
  1059. );
  1060. runtime.constructor(&[]);
  1061. let array = vec![
  1062. ethabi::Token::Int(ethereum_types::U256::from(0x20)),
  1063. ethabi::Token::Int(ethereum_types::U256::from(0x40)),
  1064. ethabi::Token::Int(ethereum_types::U256::from(0x80)),
  1065. ethabi::Token::Int(ethereum_types::U256::from(0x100)),
  1066. ];
  1067. for i in 0..4 {
  1068. let ret = runtime.function(
  1069. "f",
  1070. &[
  1071. ethabi::Token::FixedArray(array.clone()),
  1072. ethabi::Token::Uint(ethereum_types::U256::from(i)),
  1073. ],
  1074. );
  1075. assert_eq!(ret, [array[i].clone()]);
  1076. }
  1077. }
  1078. #[test]
  1079. #[should_panic]
  1080. fn array_bounds_uint() {
  1081. let mut runtime = build_solidity(
  1082. r##"
  1083. contract foo {
  1084. function f(int32[4] a, uint i) public returns (int32) {
  1085. return a[i];
  1086. }
  1087. }"##,
  1088. );
  1089. runtime.constructor(&[]);
  1090. let array = vec![
  1091. ethabi::Token::Int(ethereum_types::U256::from(0x20)),
  1092. ethabi::Token::Int(ethereum_types::U256::from(0x40)),
  1093. ethabi::Token::Int(ethereum_types::U256::from(0x80)),
  1094. ethabi::Token::Int(ethereum_types::U256::from(0x100)),
  1095. ];
  1096. runtime.function(
  1097. "f",
  1098. &[
  1099. ethabi::Token::FixedArray(array),
  1100. ethabi::Token::Uint(ethereum_types::U256::from(4)),
  1101. ],
  1102. );
  1103. }
  1104. fn array_bounds_int(index: ethabi::Token) {
  1105. let mut runtime = build_solidity(
  1106. r##"
  1107. contract foo {
  1108. function f(int32[4] a, int i) public returns (int32) {
  1109. return a[i];
  1110. }
  1111. }"##,
  1112. );
  1113. runtime.constructor(&[]);
  1114. let array = vec![
  1115. ethabi::Token::Int(ethereum_types::U256::from(0x20)),
  1116. ethabi::Token::Int(ethereum_types::U256::from(0x40)),
  1117. ethabi::Token::Int(ethereum_types::U256::from(0x80)),
  1118. ethabi::Token::Int(ethereum_types::U256::from(0x100)),
  1119. ];
  1120. runtime.function("f", &[ethabi::Token::FixedArray(array), index]);
  1121. }
  1122. #[test]
  1123. #[should_panic]
  1124. fn array_bounds_int_neg() {
  1125. array_bounds_int(ethabi::Token::Int(ethereum_types::U256::from(-1)))
  1126. }
  1127. #[test]
  1128. #[should_panic]
  1129. fn array_bounds_int_pos() {
  1130. array_bounds_int(ethabi::Token::Int(ethereum_types::U256::from(4)))
  1131. }
  1132. #[test]
  1133. fn array_array() {
  1134. let mut runtime = build_solidity(
  1135. r##"
  1136. contract foo {
  1137. function f(int a, uint i1, uint i2) public returns (int) {
  1138. int[4][2] memory bar = [ [ int(1), 2, 3, 4 ], [ 5, 6, 7, a ] ];
  1139. return bar[i1][i2];
  1140. }
  1141. }"##,
  1142. );
  1143. runtime.constructor(&[]);
  1144. for i1 in 0..2 {
  1145. for i2 in 0..4 {
  1146. let val = runtime.function(
  1147. "f",
  1148. &[
  1149. ethabi::Token::Int(ethereum_types::U256::from(8)),
  1150. ethabi::Token::Uint(ethereum_types::U256::from(i1)),
  1151. ethabi::Token::Uint(ethereum_types::U256::from(i2)),
  1152. ],
  1153. );
  1154. println!("i1:{} i2:{}: {:?}", i1, i2, val);
  1155. assert_eq!(
  1156. val,
  1157. [ethabi::Token::Int(ethereum_types::U256::from(
  1158. 1 + 4 * i1 + i2
  1159. ))]
  1160. );
  1161. }
  1162. }
  1163. }
  1164. #[test]
  1165. fn arrays_are_refs() {
  1166. // verified on remix
  1167. let mut runtime = build_solidity(
  1168. r##"
  1169. pragma solidity >=0.4.22 <0.6.0;
  1170. contract refs {
  1171. function f2(int[4] memory foo) private {
  1172. foo[2] = 2;
  1173. }
  1174. function f1(int[4] memory foo) private {
  1175. foo[1] = 2;
  1176. }
  1177. function bar() public returns (int[4] memory) {
  1178. int[4] memory x = [ int(0), 0, 0, 0 ];
  1179. f1(x);
  1180. f2(x);
  1181. return x;
  1182. }
  1183. }
  1184. "##,
  1185. );
  1186. runtime.constructor(&[]);
  1187. let val = runtime.function("bar", &[]);
  1188. assert_eq!(
  1189. val,
  1190. &[ethabi::Token::FixedArray(vec!(
  1191. ethabi::Token::Int(ethereum_types::U256::from(0)),
  1192. ethabi::Token::Int(ethereum_types::U256::from(2)),
  1193. ethabi::Token::Int(ethereum_types::U256::from(2)),
  1194. ethabi::Token::Int(ethereum_types::U256::from(0))
  1195. ))],
  1196. );
  1197. }
  1198. #[test]
  1199. fn storage_structs() {
  1200. // verified on remix
  1201. let mut runtime = build_solidity(
  1202. r##"
  1203. /**
  1204. * This is a doccomment
  1205. */
  1206. pragma solidity 0;
  1207. pragma experimental ABIEncoderV2;
  1208. contract test_struct_parsing {
  1209. struct foo {
  1210. bool x;
  1211. uint32 y;
  1212. }
  1213. foo f;
  1214. function test() public {
  1215. f.x = true;
  1216. f.y = 64;
  1217. assert(f.x == true);
  1218. assert(f.y == 64);
  1219. }
  1220. }"##,
  1221. );
  1222. runtime.constructor(&[]);
  1223. runtime.function("test", &[]);
  1224. }
  1225. #[test]
  1226. fn struct_encode() {
  1227. let mut runtime = build_solidity(
  1228. r##"
  1229. contract structs {
  1230. struct foo {
  1231. bool x;
  1232. uint32 y;
  1233. }
  1234. function test(foo memory f) public {
  1235. assert(f.x == true);
  1236. assert(f.y == 64);
  1237. }
  1238. }
  1239. "##,
  1240. );
  1241. runtime.constructor(&[]);
  1242. runtime.function(
  1243. "test",
  1244. &[ethabi::Token::Tuple(vec![
  1245. ethabi::Token::Bool(true),
  1246. ethabi::Token::Uint(ethereum_types::U256::from(64)),
  1247. ])],
  1248. );
  1249. }
  1250. #[test]
  1251. fn struct_dynamic_array_encode() {
  1252. let mut runtime = build_solidity(
  1253. r##"
  1254. contract structs {
  1255. struct foo {
  1256. bool x;
  1257. uint32 y;
  1258. }
  1259. function test() public returns (foo[]) {
  1260. foo[] x = new foo[](3);
  1261. x[0] = foo({x: true,y: 64});
  1262. x[1] = foo({x: false,y: 102});
  1263. x[2] = foo({x: true,y: 0x800});
  1264. return x;
  1265. }
  1266. }"##,
  1267. );
  1268. runtime.constructor(&[]);
  1269. let ret = runtime.function("test", &[]);
  1270. assert_eq!(
  1271. ret,
  1272. vec![ethabi::Token::Array(vec![
  1273. ethabi::Token::Tuple(vec![
  1274. ethabi::Token::Bool(true),
  1275. ethabi::Token::Uint(ethereum_types::U256::from(64))
  1276. ]),
  1277. ethabi::Token::Tuple(vec![
  1278. ethabi::Token::Bool(false),
  1279. ethabi::Token::Uint(ethereum_types::U256::from(102))
  1280. ]),
  1281. ethabi::Token::Tuple(vec![
  1282. ethabi::Token::Bool(true),
  1283. ethabi::Token::Uint(ethereum_types::U256::from(0x800)),
  1284. ])
  1285. ])],
  1286. );
  1287. }
  1288. #[test]
  1289. fn struct_decode() {
  1290. let mut runtime = build_solidity(
  1291. r##"
  1292. contract structs {
  1293. struct foo {
  1294. bool x;
  1295. uint32 y;
  1296. }
  1297. function test() public returns (foo) {
  1298. foo f;
  1299. f.x = true;
  1300. f.y = 64;
  1301. return f;
  1302. }
  1303. }
  1304. "##,
  1305. );
  1306. runtime.constructor(&[]);
  1307. let val = runtime.function("test", &[]);
  1308. assert_eq!(
  1309. val,
  1310. &[ethabi::Token::Tuple(vec![
  1311. ethabi::Token::Bool(true),
  1312. ethabi::Token::Uint(ethereum_types::U256::from(64)),
  1313. ])],
  1314. );
  1315. }
  1316. /* TODO: find out why this test fails.
  1317. #[test]
  1318. fn struct_in_struct_decode() {
  1319. let mut runtime = build_solidity(
  1320. r##"
  1321. contract structs {
  1322. enum suit { club, diamonds, hearts, spades }
  1323. enum value { two, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace }
  1324. struct card {
  1325. value v;
  1326. suit s;
  1327. }
  1328. struct hand {
  1329. card card1;
  1330. card card2;
  1331. card card3;
  1332. card card4;
  1333. card card5;
  1334. }
  1335. function test() public returns (hand) {
  1336. hand h = hand({
  1337. card1: card({ s: suit.hearts, v: value.two }),
  1338. card2: card({ s: suit.diamonds, v: value.three }),
  1339. card3: card({ s: suit.club, v: value.four }),
  1340. card4: card({ s: suit.diamonds, v: value.ten }),
  1341. card5: card({ s: suit.hearts, v: value.jack })
  1342. });
  1343. return h;
  1344. }
  1345. }
  1346. "##,
  1347. );
  1348. runtime.constructor(&[]);
  1349. let val = runtime.function("test", &[]);
  1350. assert_eq!(
  1351. val,
  1352. &[ethabi::Token::Tuple(vec![
  1353. ethabi::Token::Tuple(vec![
  1354. ethabi::Token::Uint(ethereum_types::U256::from(0)),
  1355. ethabi::Token::Uint(ethereum_types::U256::from(2)),
  1356. ]),
  1357. ethabi::Token::Tuple(vec![
  1358. ethabi::Token::Uint(ethereum_types::U256::from(1)),
  1359. ethabi::Token::Uint(ethereum_types::U256::from(1)),
  1360. ]),
  1361. ethabi::Token::Tuple(vec![
  1362. ethabi::Token::Uint(ethereum_types::U256::from(2)),
  1363. ethabi::Token::Uint(ethereum_types::U256::from(0)),
  1364. ]),
  1365. ethabi::Token::Tuple(vec![
  1366. ethabi::Token::Uint(ethereum_types::U256::from(8)),
  1367. ethabi::Token::Uint(ethereum_types::U256::from(1)),
  1368. ]),
  1369. ethabi::Token::Tuple(vec![
  1370. ethabi::Token::Uint(ethereum_types::U256::from(9)),
  1371. ethabi::Token::Uint(ethereum_types::U256::from(2)),
  1372. ]),
  1373. ])],
  1374. );
  1375. }*/
  1376. #[test]
  1377. fn struct_in_struct_encode() {
  1378. let mut runtime = build_solidity(
  1379. r##"
  1380. contract structs {
  1381. enum suit { club, diamonds, hearts, spades }
  1382. enum value { two, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace }
  1383. struct card {
  1384. value v;
  1385. suit s;
  1386. }
  1387. struct hand {
  1388. card card1;
  1389. card card2;
  1390. card card3;
  1391. card card4;
  1392. card card5;
  1393. }
  1394. function test(hand h) public {
  1395. assert(h.card1.s == suit.hearts);
  1396. assert(h.card1.v == value.two);
  1397. assert(h.card2.s == suit.diamonds);
  1398. assert(h.card2.v == value.three);
  1399. assert(h.card3.s == suit.club);
  1400. assert(h.card3.v == value.four);
  1401. assert(h.card4.s == suit.diamonds);
  1402. assert(h.card4.v == value.ten);
  1403. assert(h.card5.s == suit.hearts);
  1404. assert(h.card5.v == value.jack);
  1405. }
  1406. }
  1407. "##,
  1408. );
  1409. runtime.constructor(&[]);
  1410. runtime.function(
  1411. "test",
  1412. &[ethabi::Token::Tuple(vec![
  1413. ethabi::Token::Tuple(vec![
  1414. ethabi::Token::Uint(ethereum_types::U256::from(0)),
  1415. ethabi::Token::Uint(ethereum_types::U256::from(2)),
  1416. ]),
  1417. ethabi::Token::Tuple(vec![
  1418. ethabi::Token::Uint(ethereum_types::U256::from(1)),
  1419. ethabi::Token::Uint(ethereum_types::U256::from(1)),
  1420. ]),
  1421. ethabi::Token::Tuple(vec![
  1422. ethabi::Token::Uint(ethereum_types::U256::from(2)),
  1423. ethabi::Token::Uint(ethereum_types::U256::from(0)),
  1424. ]),
  1425. ethabi::Token::Tuple(vec![
  1426. ethabi::Token::Uint(ethereum_types::U256::from(8)),
  1427. ethabi::Token::Uint(ethereum_types::U256::from(1)),
  1428. ]),
  1429. ethabi::Token::Tuple(vec![
  1430. ethabi::Token::Uint(ethereum_types::U256::from(9)),
  1431. ethabi::Token::Uint(ethereum_types::U256::from(2)),
  1432. ]),
  1433. ])],
  1434. );
  1435. }
  1436. #[test]
  1437. fn array_push_delete() {
  1438. // ensure that structs and fixed arrays are wiped by delete
  1439. let mut runtime = build_solidity(
  1440. r#"
  1441. pragma solidity 0;
  1442. contract foo {
  1443. uint32[] bar;
  1444. function setup() public {
  1445. for (uint32 i = 0; i < 105; i++) {
  1446. bar.push(i + 0x8000);
  1447. }
  1448. }
  1449. function clear() public {
  1450. delete bar;
  1451. }
  1452. }"#,
  1453. );
  1454. runtime.constructor(&[]);
  1455. runtime.function("setup", &[]);
  1456. assert_eq!(runtime.store.len(), 106);
  1457. runtime.function("clear", &[]);
  1458. assert_eq!(runtime.store.len(), 0);
  1459. }
  1460. #[test]
  1461. fn encode_string() {
  1462. let mut runtime = build_solidity(
  1463. r##"
  1464. contract foo {
  1465. function f() public returns (string) {
  1466. return "Hello, World!";
  1467. }
  1468. }"##,
  1469. );
  1470. runtime.constructor(&[]);
  1471. let ret = runtime.function("f", &[]);
  1472. assert_eq!(ret, vec!(ethabi::Token::String("Hello, World!".to_owned())));
  1473. let mut runtime = build_solidity(
  1474. r##"
  1475. contract foo {
  1476. function f() public returns (int32, string, int64) {
  1477. return (105, "the quick brown dog jumps over the lazy fox", -563);
  1478. }
  1479. }"##,
  1480. );
  1481. runtime.constructor(&[]);
  1482. let ret = runtime.function("f", &[]);
  1483. let n563 = ethereum_types::U256::from(0)
  1484. .overflowing_sub(ethereum_types::U256::from(563))
  1485. .0;
  1486. assert_eq!(
  1487. ret,
  1488. vec!(
  1489. ethabi::Token::Int(ethereum_types::U256::from(105)),
  1490. ethabi::Token::String("the quick brown dog jumps over the lazy fox".to_owned()),
  1491. ethabi::Token::Int(n563),
  1492. )
  1493. );
  1494. }
  1495. #[test]
  1496. fn decode_string() {
  1497. let mut runtime = build_solidity(
  1498. r##"
  1499. contract foo {
  1500. function f(string a) public returns (string) {
  1501. return a + " ";
  1502. }
  1503. }"##,
  1504. );
  1505. runtime.constructor(&[]);
  1506. let ret = runtime.function("f", &[ethabi::Token::String("Hello, World!".to_owned())]);
  1507. assert_eq!(
  1508. ret,
  1509. vec!(ethabi::Token::String("Hello, World! ".to_owned()))
  1510. );
  1511. }
  1512. #[test]
  1513. fn revert() {
  1514. let mut runtime = build_solidity(
  1515. r##"
  1516. contract foo {
  1517. function f() public {
  1518. revert("Hello, World!");
  1519. }
  1520. }"##,
  1521. );
  1522. runtime.constructor(&[]);
  1523. let ret = runtime.function_revert("f", &[]);
  1524. assert_eq!(ret, Some("Hello, World!".to_owned()));
  1525. }
  1526. #[test]
  1527. fn constructor_args() {
  1528. let mut runtime = build_solidity(
  1529. r##"
  1530. contract foo {
  1531. int64 v;
  1532. constructor(int64 a) public {
  1533. v = a;
  1534. }
  1535. function f() public returns (int64) {
  1536. return v;
  1537. }
  1538. }"##,
  1539. );
  1540. let v = ethabi::Token::Int(ethereum_types::U256::from(105));
  1541. runtime.constructor(&[v.clone()]);
  1542. let ret = runtime.function("f", &[]);
  1543. assert_eq!(ret, vec!(v));
  1544. }
  1545. #[test]
  1546. fn create() {
  1547. let mut runtime = build_solidity(
  1548. r##"
  1549. contract a {
  1550. int32 x;
  1551. constructor() public {
  1552. }
  1553. function test() public {
  1554. x = 102;
  1555. }
  1556. }
  1557. contract b {
  1558. function x() public {
  1559. a r = new a();
  1560. }
  1561. }
  1562. "##,
  1563. );
  1564. runtime.constructor(&[]);
  1565. runtime.function("x", &[]);
  1566. }
  1567. #[test]
  1568. fn decode_complexish() {
  1569. let mut runtime = build_solidity(
  1570. r##"
  1571. pragma solidity 0;
  1572. struct foo1 {
  1573. int32 f1;
  1574. string f2;
  1575. int64[2] f3;
  1576. int64[] f4;
  1577. }
  1578. contract c {
  1579. function test(foo1[] a) public {
  1580. assert(a.length == 1);
  1581. assert(a[0].f2 == "Hello, World!");
  1582. assert(a[0].f3[0] == 55);
  1583. assert(a[0].f3[1] == 59);
  1584. assert(a[0].f4.length == 1);
  1585. assert(a[0].f4[0] == 102);
  1586. }
  1587. }"##,
  1588. );
  1589. runtime.constructor(&[]);
  1590. runtime.function(
  1591. "test",
  1592. &[ethabi::Token::Array(vec![ethabi::Token::Tuple(vec![
  1593. ethabi::Token::Int(ethereum_types::U256::from(102)),
  1594. ethabi::Token::String("Hello, World!".to_owned()),
  1595. ethabi::Token::FixedArray(vec![
  1596. ethabi::Token::Int(ethereum_types::U256::from(55)),
  1597. ethabi::Token::Int(ethereum_types::U256::from(59)),
  1598. ]),
  1599. ethabi::Token::Array(vec![ethabi::Token::Int(ethereum_types::U256::from(102))]),
  1600. ])])],
  1601. );
  1602. }
  1603. #[test]
  1604. fn decode_bad_abi() {
  1605. let mut runtime = build_solidity(
  1606. r##"
  1607. contract c {
  1608. function test(string a) public {
  1609. }
  1610. }"##,
  1611. );
  1612. runtime.constructor(&[]);
  1613. // patch offset to be garbage
  1614. runtime.function_abi_fail(
  1615. "test",
  1616. &[ethabi::Token::String("Hello, World!".to_owned())],
  1617. |x| x[30] = 2,
  1618. );
  1619. // patch offset to overflow
  1620. runtime.function_abi_fail(
  1621. "test",
  1622. &[ethabi::Token::String("Hello, World!".to_owned())],
  1623. |x| {
  1624. x[31] = 0xff;
  1625. x[30] = 0xff;
  1626. x[29] = 0xff;
  1627. x[28] = 0xe0;
  1628. },
  1629. );
  1630. // patch length to be garbage
  1631. runtime.function_abi_fail(
  1632. "test",
  1633. &[ethabi::Token::String("Hello, World!".to_owned())],
  1634. |x| x[62] = 2,
  1635. );
  1636. // patch length to overflow
  1637. runtime.function_abi_fail(
  1638. "test",
  1639. &[ethabi::Token::String("Hello, World!".to_owned())],
  1640. |x| {
  1641. x[63] = 0xff;
  1642. x[62] = 0xff;
  1643. x[61] = 0xff;
  1644. x[60] = 0xe0;
  1645. },
  1646. );
  1647. }
  1648. #[test]
  1649. fn external_call() {
  1650. let mut runtime = build_solidity(
  1651. r##"
  1652. contract b {
  1653. int32 x;
  1654. constructor(int32 a) public {
  1655. x = a;
  1656. }
  1657. function get_x() public returns (int32) {
  1658. return 200 * x;
  1659. }
  1660. }
  1661. contract c {
  1662. b x;
  1663. constructor() public {
  1664. x = new b(102);
  1665. }
  1666. function test() public returns (int32) {
  1667. return x.get_x();
  1668. }
  1669. function enc() public returns (bytes) {
  1670. return abi.encodeWithSignature("get_x()");
  1671. }
  1672. }"##,
  1673. );
  1674. runtime.constructor(&[]);
  1675. let ret = runtime.function("enc", &[]);
  1676. assert_eq!(
  1677. ret,
  1678. vec!(ethabi::Token::Bytes(0x3829050au32.to_be_bytes().into()))
  1679. );
  1680. let ret = runtime.function("test", &[]);
  1681. assert_eq!(
  1682. ret,
  1683. vec!(ethabi::Token::Int(ethereum_types::U256::from(20400)))
  1684. );
  1685. let mut runtime = build_solidity(
  1686. r##"
  1687. contract b {
  1688. int32 x;
  1689. constructor(int32 a) public {
  1690. x = a;
  1691. }
  1692. function get_x(int32 t) public returns (int32) {
  1693. return x * t;
  1694. }
  1695. }
  1696. contract c {
  1697. b x;
  1698. constructor() public {
  1699. x = new b(102);
  1700. }
  1701. function test() public returns (int32) {
  1702. return x.get_x({ t: 10 });
  1703. }
  1704. }"##,
  1705. );
  1706. runtime.constructor(&[]);
  1707. let ret = runtime.function("test", &[]);
  1708. assert_eq!(
  1709. ret,
  1710. vec!(ethabi::Token::Int(ethereum_types::U256::from(1020)))
  1711. );
  1712. }
  1713. #[test]
  1714. fn try_catch() {
  1715. let mut runtime = build_solidity(
  1716. r##"
  1717. contract b {
  1718. int32 x;
  1719. constructor(int32 a) public {
  1720. x = a;
  1721. }
  1722. function get_x(int32 t) public returns (int32) {
  1723. if (t == 0) {
  1724. revert("cannot be zero");
  1725. }
  1726. return x * t;
  1727. }
  1728. }
  1729. contract c {
  1730. b x;
  1731. constructor() public {
  1732. x = new b(102);
  1733. }
  1734. function test() public returns (int32) {
  1735. int32 state = 0;
  1736. try x.get_x(0) returns (int32 l) {
  1737. state = 1;
  1738. } catch Error(string err) {
  1739. if (err == "cannot be zero") {
  1740. state = 2;
  1741. } else {
  1742. state = 3;
  1743. }
  1744. } catch (bytes ) {
  1745. state = 4;
  1746. }
  1747. return state;
  1748. }
  1749. }"##,
  1750. );
  1751. runtime.constructor(&[]);
  1752. let ret = runtime.function("test", &[]);
  1753. assert_eq!(ret, vec!(ethabi::Token::Int(ethereum_types::U256::from(2))));
  1754. }
  1755. #[test]
  1756. fn payables() {
  1757. // no contructors means can't send value
  1758. let mut runtime = build_solidity(
  1759. r##"
  1760. contract c {
  1761. function test(string a) public {
  1762. }
  1763. }"##,
  1764. );
  1765. runtime.value = 1;
  1766. runtime.constructor_expect_revert(&[]);
  1767. // contructors w/o payable means can't send value
  1768. let mut runtime = build_solidity(
  1769. r##"
  1770. contract c {
  1771. constructor() public {
  1772. int32 a = 0;
  1773. }
  1774. function test(string a) public {
  1775. }
  1776. }"##,
  1777. );
  1778. runtime.value = 1;
  1779. runtime.constructor_expect_revert(&[]);
  1780. // contructors w/ payable means can send value
  1781. let mut runtime = build_solidity(
  1782. r##"
  1783. contract c {
  1784. constructor() public payable {
  1785. int32 a = 0;
  1786. }
  1787. function test(string a) public {
  1788. }
  1789. }"##,
  1790. );
  1791. runtime.value = 1;
  1792. runtime.constructor(&[]);
  1793. // function w/o payable means can't send value
  1794. let mut runtime = build_solidity(
  1795. r##"
  1796. contract c {
  1797. function test() public {
  1798. }
  1799. }"##,
  1800. );
  1801. runtime.constructor(&[]);
  1802. runtime.value = 1;
  1803. runtime.function_revert("test", &[]);
  1804. // test both
  1805. let mut runtime = build_solidity(
  1806. r##"
  1807. contract c {
  1808. function test() payable public {
  1809. }
  1810. function test2() public {
  1811. }
  1812. }"##,
  1813. );
  1814. runtime.constructor(&[]);
  1815. runtime.value = 1;
  1816. runtime.function_revert("test2", &[]);
  1817. runtime.value = 1;
  1818. runtime.function("test", &[]);
  1819. }
  1820. #[test]
  1821. fn balance() {
  1822. let mut runtime = build_solidity(
  1823. r##"
  1824. contract c {
  1825. function test() public returns (uint128) {
  1826. return address(this).balance;
  1827. }
  1828. }"##,
  1829. );
  1830. runtime.constructor(&[]);
  1831. runtime.accounts.get_mut(&runtime.vm.cur).unwrap().1 = 512;
  1832. let ret = runtime.function("test", &[]);
  1833. assert_eq!(
  1834. ret,
  1835. vec!(ethabi::Token::Uint(ethereum_types::U256::from(512)))
  1836. );
  1837. }
  1838. #[test]
  1839. fn selfdestruct() {
  1840. let mut runtime = build_solidity(
  1841. r##"
  1842. contract other {
  1843. function goaway(address payable recipient) public returns (bool) {
  1844. selfdestruct(recipient);
  1845. }
  1846. }
  1847. contract c {
  1848. other o;
  1849. function step1() public {
  1850. o = new other{value: 511}();
  1851. }
  1852. function step2() public {
  1853. bool foo = o.goaway(payable(address(this)));
  1854. }
  1855. }"##,
  1856. );
  1857. runtime.constructor(&[]);
  1858. runtime.function("step1", &[]);
  1859. runtime.accounts.get_mut(&runtime.vm.cur).unwrap().1 = 0;
  1860. runtime.function_revert("step2", &[]);
  1861. runtime.accounts.get_mut(&runtime.vm.cur).unwrap().1 = 511;
  1862. }
  1863. #[test]
  1864. fn event() {
  1865. let mut runtime = build_solidity(
  1866. r##"
  1867. contract c {
  1868. event foo (
  1869. bool indexed y,
  1870. int32 x
  1871. ) anonymous;
  1872. function func() public {
  1873. emit foo(true, 102);
  1874. }
  1875. }"##,
  1876. );
  1877. runtime.constructor(&[]);
  1878. runtime.function("func", &[]);
  1879. assert_eq!(runtime.events.len(), 1);
  1880. let event = &runtime.abi.events_by_name("foo").unwrap()[0];
  1881. for log in runtime.events() {
  1882. let decoded = event.parse_log(log).unwrap();
  1883. for log in &decoded.params {
  1884. match log.name.as_str() {
  1885. "y" => assert_eq!(log.value, ethabi::Token::Bool(true)),
  1886. "x" => assert_eq!(
  1887. log.value,
  1888. ethabi::Token::Int(ethereum_types::U256::from(102))
  1889. ),
  1890. _ => panic!("unexpected field {}", log.name),
  1891. }
  1892. }
  1893. }
  1894. let mut runtime = build_solidity(
  1895. r##"
  1896. contract c {
  1897. event foo (
  1898. bool indexed y,
  1899. string indexed x,
  1900. int[2] indexed z
  1901. );
  1902. function func() public {
  1903. emit foo(true, "foobar", [1, 2]);
  1904. }
  1905. }"##,
  1906. );
  1907. runtime.constructor(&[]);
  1908. runtime.function("func", &[]);
  1909. assert_eq!(runtime.events.len(), 1);
  1910. let event = &runtime.abi.events_by_name("foo").unwrap()[0];
  1911. for log in runtime.events() {
  1912. let decoded = event.parse_log(log).unwrap();
  1913. for log in &decoded.params {
  1914. match log.name.as_str() {
  1915. "y" => assert_eq!(log.value, ethabi::Token::Bool(true)),
  1916. "x" => assert_eq!(
  1917. log.value,
  1918. ethabi::Token::FixedBytes(
  1919. hex::decode(
  1920. "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e"
  1921. )
  1922. .unwrap()
  1923. )
  1924. ),
  1925. "z" => assert_eq!(
  1926. log.value,
  1927. ethabi::Token::FixedBytes(
  1928. hex::decode(
  1929. "e90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0"
  1930. )
  1931. .unwrap()
  1932. )
  1933. ),
  1934. _ => panic!("unexpected field {}", log.name),
  1935. }
  1936. }
  1937. }
  1938. }