abi_encode.rs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. use crate::build_solidity;
  2. use borsh::BorshDeserialize;
  3. use ethabi::Token;
  4. #[test]
  5. fn integers_bool_enum() {
  6. #[derive(BorshDeserialize, PartialEq, Debug)]
  7. enum WeekDay {
  8. Sunday,
  9. Monday,
  10. Tuesday,
  11. Wednesday,
  12. Thursday,
  13. Friday,
  14. Saturday,
  15. }
  16. #[derive(BorshDeserialize, Debug)]
  17. struct Res1 {
  18. a: u8,
  19. b: u64,
  20. c: u128,
  21. d: i16,
  22. e: i32,
  23. day: WeekDay,
  24. h: bool,
  25. }
  26. #[derive(BorshDeserialize, Debug)]
  27. struct Res2 {
  28. sunday: WeekDay,
  29. elem: WeekDay,
  30. vec_2: WeekDay,
  31. }
  32. let mut vm = build_solidity(
  33. r#"
  34. contract Testing {
  35. enum weekday{
  36. sunday, monday, tuesday, wednesday, thursday, friday, saturday
  37. }
  38. function getThis() public pure returns (bytes memory) {
  39. uint8 a = 45;
  40. uint64 b = 9965956609890;
  41. uint128 c = 88;
  42. int16 d = -29;
  43. int32 e = -88;
  44. weekday f = weekday.wednesday;
  45. bool h = false;
  46. bytes memory g = abi.encode(a, b, c, d, e, f, h);
  47. return g;
  48. }
  49. function encodeEnum() public pure returns (bytes memory) {
  50. weekday[3] memory vec = [weekday.sunday, weekday.tuesday, weekday.friday];
  51. weekday elem = weekday.saturday;
  52. bytes memory b = abi.encode(weekday.sunday, elem, vec[2]);
  53. return b;
  54. }
  55. }
  56. "#,
  57. );
  58. vm.constructor("Testing", &[]);
  59. let returns = vm.function("getThis", &[], &[], None);
  60. let encoded = returns[0].clone().into_bytes().unwrap();
  61. let decoded = Res1::try_from_slice(&encoded).unwrap();
  62. assert_eq!(decoded.a, 45);
  63. assert_eq!(decoded.b, 9965956609890);
  64. assert_eq!(decoded.c, 88);
  65. assert_eq!(decoded.d, -29);
  66. assert_eq!(decoded.e, -88);
  67. assert_eq!(decoded.day, WeekDay::Wednesday);
  68. assert!(!decoded.h);
  69. let returns = vm.function("encodeEnum", &[], &[], None);
  70. let encoded = returns[0].clone().into_bytes().unwrap();
  71. let decoded = Res2::try_from_slice(&encoded).unwrap();
  72. assert_eq!(decoded.sunday, WeekDay::Sunday);
  73. assert_eq!(decoded.elem, WeekDay::Saturday);
  74. assert_eq!(decoded.vec_2, WeekDay::Friday);
  75. }
  76. #[test]
  77. fn encode_address() {
  78. #[derive(BorshDeserialize, Debug)]
  79. struct Response {
  80. address: [u8; 32],
  81. this: [u8; 32],
  82. }
  83. let mut vm = build_solidity(
  84. r#"
  85. contract Testing {
  86. function getThis() public view returns (bytes memory) {
  87. bytes memory b = abi.encode(address(this), this);
  88. return b;
  89. }
  90. }
  91. "#,
  92. );
  93. vm.constructor("Testing", &[]);
  94. let returns = vm.function("getThis", &[], &[], None);
  95. let encoded = returns[0].clone().into_bytes().unwrap();
  96. let decoded = Response::try_from_slice(&encoded).unwrap();
  97. assert_eq!(decoded.address, vm.programs[0].data);
  98. assert_eq!(decoded.this, vm.programs[0].data);
  99. }
  100. #[test]
  101. fn string_and_bytes() {
  102. #[derive(BorshDeserialize, Debug)]
  103. struct MyStruct {
  104. a: String,
  105. b: Vec<u8>,
  106. }
  107. let mut vm = build_solidity(
  108. r#"
  109. contract Testing {
  110. function getThis() public pure returns (bytes memory) {
  111. string memory a = "coffe";
  112. bytes memory b = "tea";
  113. bytes memory c = abi.encode(a, b);
  114. return c;
  115. }
  116. }
  117. "#,
  118. );
  119. vm.constructor("Testing", &[]);
  120. let returns = vm.function("getThis", &[], &[], None);
  121. let encoded = returns[0].clone().into_bytes().unwrap();
  122. let decoded = MyStruct::try_from_slice(&encoded).unwrap();
  123. assert_eq!(decoded.a, "coffe");
  124. assert_eq!(decoded.b, b"tea");
  125. }
  126. #[test]
  127. fn primitive_structs() {
  128. #[derive(Debug, BorshDeserialize)]
  129. struct NoPadStruct {
  130. a: u32,
  131. b: u32,
  132. }
  133. #[derive(Debug, BorshDeserialize)]
  134. struct PaddedStruct {
  135. a: u128,
  136. b: u8,
  137. c: [u8; 32],
  138. }
  139. let mut vm = build_solidity(
  140. r#"
  141. contract Testing {
  142. struct noPadStruct {
  143. uint32 a;
  144. uint32 b;
  145. }
  146. struct PaddedStruct {
  147. uint128 a;
  148. uint8 b;
  149. bytes32 c;
  150. }
  151. function getThis() public pure returns (bytes memory) {
  152. noPadStruct memory a = noPadStruct(1238, 87123);
  153. bytes memory b = abi.encode(a);
  154. return b;
  155. }
  156. function getThat() public pure returns (bytes memory) {
  157. PaddedStruct memory a = PaddedStruct(12998, 240, "tea_is_good");
  158. bytes memory b = abi.encode(a);
  159. return b;
  160. }
  161. }
  162. "#,
  163. );
  164. vm.constructor("Testing", &[]);
  165. let returns = vm.function("getThis", &[], &[], None);
  166. let encoded = returns[0].clone().into_bytes().unwrap();
  167. let decoded = NoPadStruct::try_from_slice(&encoded).unwrap();
  168. assert_eq!(decoded.a, 1238);
  169. assert_eq!(decoded.b, 87123);
  170. let returns = vm.function("getThat", &[], &[], None);
  171. let encoded = returns[0].clone().into_bytes().unwrap();
  172. let decoded = PaddedStruct::try_from_slice(&encoded).unwrap();
  173. assert_eq!(decoded.a, 12998);
  174. assert_eq!(decoded.b, 240);
  175. let mut b: [u8; 11] = b"tea_is_good".to_owned();
  176. b.reverse();
  177. assert_eq!(&decoded.c[21..32], b);
  178. }
  179. #[test]
  180. fn argument_string() {
  181. #[derive(Debug, BorshDeserialize)]
  182. struct Response {
  183. rr: String,
  184. }
  185. let mut vm = build_solidity(
  186. r#"
  187. contract Testing {
  188. function testStruct(string memory rr) public pure returns (bytes memory) {
  189. bytes memory b1 = abi.encode(rr);
  190. return b1;
  191. }
  192. }
  193. "#,
  194. );
  195. vm.constructor("Testing", &[]);
  196. let returns = vm.function(
  197. "testStruct",
  198. &[Token::String("nihao".to_string())],
  199. &[],
  200. None,
  201. );
  202. let encoded = returns[0].clone().into_bytes().unwrap();
  203. let decoded = Response::try_from_slice(&encoded).unwrap();
  204. assert_eq!(decoded.rr, "nihao");
  205. }
  206. #[test]
  207. fn test_string_array() {
  208. #[derive(Debug, BorshDeserialize)]
  209. struct Response {
  210. a: Vec<String>,
  211. }
  212. let mut vm = build_solidity(
  213. r#"
  214. contract Testing {
  215. string[] string_vec;
  216. function encode() public view returns (bytes memory) {
  217. string[] memory mem_vec = string_vec;
  218. bytes memory b = abi.encode(mem_vec);
  219. return b;
  220. }
  221. function insertStrings() public {
  222. string_vec.push("tea");
  223. string_vec.push("coffee");
  224. }
  225. }
  226. "#,
  227. );
  228. vm.constructor("Testing", &[]);
  229. let returns = vm.function("encode", &[], &[], None);
  230. let encoded = returns[0].clone().into_bytes().unwrap();
  231. let decoded = Response::try_from_slice(&encoded).unwrap();
  232. assert_eq!(decoded.a.len(), 0);
  233. let _ = vm.function("insertStrings", &[], &[], None);
  234. let returns = vm.function("encode", &[], &[], None);
  235. let encoded = returns[0].clone().into_bytes().unwrap();
  236. let decoded = Response::try_from_slice(&encoded).unwrap();
  237. assert_eq!(decoded.a.len(), 2);
  238. assert_eq!(decoded.a[0], "tea");
  239. assert_eq!(decoded.a[1], "coffee");
  240. }
  241. #[test]
  242. fn struct_within_struct() {
  243. #[derive(Debug, BorshDeserialize)]
  244. struct NoPadStruct {
  245. a: u32,
  246. b: u32,
  247. }
  248. #[derive(Debug, BorshDeserialize)]
  249. struct PaddedStruct {
  250. a: u128,
  251. b: u8,
  252. c: [u8; 32],
  253. }
  254. #[derive(Debug, BorshDeserialize)]
  255. struct NonConstantStruct {
  256. a: u64,
  257. b: Vec<String>,
  258. no_pad: NoPadStruct,
  259. pad: PaddedStruct,
  260. }
  261. let mut vm = build_solidity(
  262. r#"
  263. contract Testing {
  264. struct noPadStruct {
  265. uint32 a;
  266. uint32 b;
  267. }
  268. struct PaddedStruct {
  269. uint128 a;
  270. uint8 b;
  271. bytes32 c;
  272. }
  273. struct NonConstantStruct {
  274. uint64 a;
  275. string[] b;
  276. noPadStruct noPad;
  277. PaddedStruct pad;
  278. }
  279. string[] string_vec;
  280. NonConstantStruct to_encode;
  281. function testStruct() public returns (bytes memory) {
  282. noPadStruct memory noPad = noPadStruct(89123, 12354);
  283. PaddedStruct memory padded = PaddedStruct(988834, 129, "tea_is_good");
  284. string_vec.push("tea");
  285. string_vec.push("coffee");
  286. to_encode = NonConstantStruct(890234, string_vec, noPad, padded);
  287. bytes memory b1 = abi.encode(to_encode);
  288. return b1;
  289. }
  290. }
  291. "#,
  292. );
  293. vm.constructor("Testing", &[]);
  294. let returns = vm.function("testStruct", &[], &[], None);
  295. let encoded = returns[0].clone().into_bytes().unwrap();
  296. let decoded = NonConstantStruct::try_from_slice(&encoded).unwrap();
  297. assert_eq!(decoded.a, 890234);
  298. assert_eq!(decoded.b.len(), 2);
  299. assert_eq!(decoded.b[0], "tea");
  300. assert_eq!(decoded.b[1], "coffee");
  301. assert_eq!(decoded.no_pad.a, 89123);
  302. assert_eq!(decoded.no_pad.b, 12354);
  303. assert_eq!(decoded.pad.a, 988834);
  304. assert_eq!(decoded.pad.b, 129);
  305. let mut b: [u8; 11] = b"tea_is_good".to_owned();
  306. b.reverse();
  307. assert_eq!(&decoded.pad.c[21..32], b);
  308. }
  309. #[test]
  310. fn struct_in_array() {
  311. #[derive(Debug, BorshDeserialize, PartialEq, Copy, Default, Clone)]
  312. struct NoPadStruct {
  313. a: u32,
  314. b: u32,
  315. }
  316. #[derive(Debug, BorshDeserialize)]
  317. struct PaddedStruct {
  318. a: u128,
  319. b: u8,
  320. c: [u8; 32],
  321. }
  322. #[derive(Debug, BorshDeserialize)]
  323. struct Res1 {
  324. item_1: NoPadStruct,
  325. item_2: PaddedStruct,
  326. }
  327. #[derive(Debug, BorshDeserialize)]
  328. struct Res2 {
  329. item_1: Vec<NoPadStruct>,
  330. item_2: [i32; 4],
  331. item_3: [NoPadStruct; 2],
  332. }
  333. let mut vm = build_solidity(
  334. r#"
  335. contract Testing {
  336. struct noPadStruct {
  337. uint32 a;
  338. uint32 b;
  339. }
  340. struct PaddedStruct {
  341. uint128 a;
  342. uint8 b;
  343. bytes32 c;
  344. }
  345. noPadStruct[] test_vec_1;
  346. function addData() public {
  347. noPadStruct memory mm = noPadStruct(1623, 43279);
  348. test_vec_1.push(mm);
  349. mm.a = 41234;
  350. mm.b = 98375;
  351. test_vec_1.push(mm);
  352. mm.a = 945;
  353. mm.b = 7453;
  354. test_vec_1.push(mm);
  355. }
  356. function encodeStruct() public view returns (bytes memory) {
  357. PaddedStruct memory ss = PaddedStruct(1, 3, "there_is_padding_here");
  358. bytes memory b = abi.encode(test_vec_1[2], ss);
  359. return b;
  360. }
  361. function primitiveStruct() public view returns (bytes memory) {
  362. int32[4] memory mem_vec = [int32(1), -298, 3, -434];
  363. noPadStruct[2] memory str_vec = [noPadStruct(1,2), noPadStruct(3, 4)];
  364. bytes memory b1 = abi.encode(test_vec_1, mem_vec, str_vec);
  365. return b1;
  366. }
  367. }
  368. "#,
  369. );
  370. vm.constructor("Testing", &[]);
  371. let _ = vm.function("addData", &[], &[], None);
  372. let returns = vm.function("encodeStruct", &[], &[], None);
  373. let encoded = returns[0].clone().into_bytes().unwrap();
  374. let decoded = Res1::try_from_slice(&encoded).unwrap();
  375. assert_eq!(decoded.item_1.a, 945);
  376. assert_eq!(decoded.item_1.b, 7453);
  377. assert_eq!(decoded.item_2.a, 1);
  378. assert_eq!(decoded.item_2.b, 3);
  379. let mut b: [u8; 21] = b"there_is_padding_here".to_owned();
  380. b.reverse();
  381. assert_eq!(&decoded.item_2.c[11..32], b);
  382. let returns = vm.function("primitiveStruct", &[], &[], None);
  383. let encoded = returns[0].clone().into_bytes().unwrap();
  384. let decoded = Res2::try_from_slice(&encoded).unwrap();
  385. assert_eq!(decoded.item_1.len(), 3);
  386. assert_eq!(decoded.item_1[0], NoPadStruct { a: 1623, b: 43279 });
  387. assert_eq!(decoded.item_1[1], NoPadStruct { a: 41234, b: 98375 });
  388. assert_eq!(decoded.item_1[2], NoPadStruct { a: 945, b: 7453 });
  389. assert_eq!(decoded.item_2, [1, -298, 3, -434]);
  390. assert_eq!(decoded.item_3[0], NoPadStruct { a: 1, b: 2 });
  391. assert_eq!(decoded.item_3[1], NoPadStruct { a: 3, b: 4 });
  392. }
  393. #[test]
  394. fn arrays() {
  395. #[derive(Debug, BorshDeserialize)]
  396. struct Res1 {
  397. vec_1: Vec<i16>,
  398. }
  399. #[derive(Debug, BorshDeserialize, Default, Clone)]
  400. struct NonConstantStruct {
  401. a: u64,
  402. b: Vec<String>,
  403. }
  404. #[derive(Debug, BorshDeserialize)]
  405. struct Res2 {
  406. complex_array: Vec<NonConstantStruct>,
  407. }
  408. #[derive(Debug, BorshDeserialize)]
  409. struct Res3 {
  410. multi_dim: [[i8; 2]; 3],
  411. }
  412. let mut vm = build_solidity(
  413. r#"
  414. contract Testing {
  415. int16[] vec_1;
  416. function addData() public {
  417. vec_1.push(-90);
  418. vec_1.push(5523);
  419. vec_1.push(-89);
  420. }
  421. struct NonConstantStruct {
  422. uint64 a;
  423. string[] b;
  424. }
  425. function encodeComplex() public returns (bytes memory) {
  426. string[] vec_2 = new string[](2);
  427. vec_2[0] = "tea";
  428. vec_2[1] = "coffee";
  429. NonConstantStruct[] arr = new NonConstantStruct[](2);
  430. arr[0] = NonConstantStruct(897, vec_2);
  431. string[] vec_3 = new string[](2);
  432. vec_3[0] = "cortado";
  433. vec_3[1] = "cappuccino";
  434. arr[1] = NonConstantStruct(74123, vec_3);
  435. return abi.encode(arr);
  436. }
  437. function encodeArray() public view returns (bytes memory) {
  438. bytes memory b = abi.encode(vec_1);
  439. return b;
  440. }
  441. function multiDimArrays() public pure returns (bytes memory) {
  442. int8[2][3] memory vec = [[int8(1), 2], [int8(4), 5], [int8(6), 7]];
  443. bytes memory b = abi.encode(vec);
  444. return b;
  445. }
  446. }
  447. "#,
  448. );
  449. vm.constructor("Testing", &[]);
  450. let _ = vm.function("addData", &[], &[], None);
  451. let returns = vm.function("encodeArray", &[], &[], None);
  452. let encoded = returns[0].clone().into_bytes().unwrap();
  453. let decoded = Res1::try_from_slice(&encoded).unwrap();
  454. assert_eq!(decoded.vec_1.len(), 3);
  455. assert_eq!(decoded.vec_1[0], -90);
  456. assert_eq!(decoded.vec_1[1], 5523);
  457. assert_eq!(decoded.vec_1[2], -89);
  458. let returns = vm.function("encodeComplex", &[], &[], None);
  459. let encoded = returns[0].clone().into_bytes().unwrap();
  460. let decoded = Res2::try_from_slice(&encoded).unwrap();
  461. assert_eq!(decoded.complex_array.len(), 2);
  462. assert_eq!(decoded.complex_array[0].a, 897);
  463. assert_eq!(
  464. decoded.complex_array[0].b,
  465. vec!["tea".to_string(), "coffee".to_string()]
  466. );
  467. assert_eq!(decoded.complex_array[1].a, 74123);
  468. assert_eq!(
  469. decoded.complex_array[1].b,
  470. vec!["cortado".to_string(), "cappuccino".to_string()]
  471. );
  472. let returns = vm.function("multiDimArrays", &[], &[], None);
  473. let encoded = returns[0].clone().into_bytes().unwrap();
  474. let decoded = Res3::try_from_slice(&encoded).unwrap();
  475. assert_eq!(decoded.multi_dim[0], [1, 2]);
  476. assert_eq!(decoded.multi_dim[1], [4, 5]);
  477. assert_eq!(decoded.multi_dim[2], [6, 7]);
  478. }
  479. #[test]
  480. fn multi_dimensional_array() {
  481. #[derive(Debug, BorshDeserialize, Default, Copy, Clone, PartialEq)]
  482. struct PaddedStruct {
  483. a: u128,
  484. b: u8,
  485. c: [u8; 32],
  486. }
  487. #[derive(Debug, BorshDeserialize)]
  488. struct Res1 {
  489. item_1: Vec<[[PaddedStruct; 2]; 3]>,
  490. item_2: u16,
  491. }
  492. #[derive(Debug, BorshDeserialize)]
  493. struct Res2 {
  494. item: Vec<[[u16; 4]; 2]>,
  495. }
  496. #[derive(Debug, BorshDeserialize)]
  497. struct Res3 {
  498. item: Vec<u16>,
  499. }
  500. let mut vm = build_solidity(
  501. r#"
  502. contract Testing {
  503. struct PaddedStruct {
  504. uint128 a;
  505. uint8 b;
  506. bytes32 c;
  507. }
  508. function getThis() public pure returns (bytes memory) {
  509. PaddedStruct memory a = PaddedStruct(56, 1, "oi");
  510. PaddedStruct memory b = PaddedStruct(78, 6, "bc");
  511. PaddedStruct memory c = PaddedStruct(89, 4, "sn");
  512. PaddedStruct memory d = PaddedStruct(42, 56, "cn");
  513. PaddedStruct memory e = PaddedStruct(23, 78, "fr");
  514. PaddedStruct memory f = PaddedStruct(445, 46, "br");
  515. PaddedStruct[2][3] memory vec = [[a, b], [c, d], [e, f]];
  516. PaddedStruct[2][3][] memory arr2 = new PaddedStruct[2][3][](1);
  517. arr2[0] = vec;
  518. uint16 g = 5;
  519. bytes memory b1 = abi.encode(arr2, g);
  520. return b1;
  521. }
  522. function multiDim() public pure returns (bytes memory) {
  523. uint16[4][2] memory vec = [[uint16(1), 2, 3, 4], [uint16(5), 6, 7, 8]];
  524. uint16[4][2][] memory simple_arr = new uint16[4][2][](1);
  525. simple_arr[0] = vec;
  526. bytes memory b = abi.encode(simple_arr);
  527. return b;
  528. }
  529. function uniqueDim() public pure returns (bytes memory) {
  530. uint16[] memory vec = new uint16[](5);
  531. vec[0] = 9;
  532. vec[1] = 3;
  533. vec[2] = 4;
  534. vec[3] = 90;
  535. vec[4] = 834;
  536. bytes memory b = abi.encode(vec);
  537. return b;
  538. }
  539. }
  540. "#,
  541. );
  542. vm.constructor("Testing", &[]);
  543. let returns = vm.function("getThis", &[], &[], None);
  544. let encoded = returns[0].clone().into_bytes().unwrap();
  545. let decoded = Res1::try_from_slice(&encoded).unwrap();
  546. assert_eq!(decoded.item_1.len(), 1);
  547. let mut res1_c: Vec<u8> = Vec::new();
  548. res1_c.resize(32, 0);
  549. assert_eq!(
  550. decoded.item_1[0][0][0],
  551. PaddedStruct {
  552. a: 56,
  553. b: 1,
  554. c: create_response(&mut res1_c, b"oi")
  555. }
  556. );
  557. assert_eq!(
  558. decoded.item_1[0][0][1],
  559. PaddedStruct {
  560. a: 78,
  561. b: 6,
  562. c: create_response(&mut res1_c, b"bc")
  563. }
  564. );
  565. assert_eq!(
  566. decoded.item_1[0][1][0],
  567. PaddedStruct {
  568. a: 89,
  569. b: 4,
  570. c: create_response(&mut res1_c, b"sn")
  571. }
  572. );
  573. assert_eq!(
  574. decoded.item_1[0][1][1],
  575. PaddedStruct {
  576. a: 42,
  577. b: 56,
  578. c: create_response(&mut res1_c, b"cn")
  579. }
  580. );
  581. assert_eq!(
  582. decoded.item_1[0][2][0],
  583. PaddedStruct {
  584. a: 23,
  585. b: 78,
  586. c: create_response(&mut res1_c, b"fr")
  587. }
  588. );
  589. assert_eq!(
  590. decoded.item_1[0][2][1],
  591. PaddedStruct {
  592. a: 445,
  593. b: 46,
  594. c: create_response(&mut res1_c, b"br")
  595. }
  596. );
  597. assert_eq!(decoded.item_2, 5);
  598. let returns = vm.function("multiDim", &[], &[], None);
  599. let encoded = returns[0].clone().into_bytes().unwrap();
  600. let decoded = Res2::try_from_slice(&encoded).unwrap();
  601. assert_eq!(decoded.item.len(), 1);
  602. assert_eq!(decoded.item[0][0], [1, 2, 3, 4]);
  603. assert_eq!(decoded.item[0][1], [5, 6, 7, 8]);
  604. let returns = vm.function("uniqueDim", &[], &[], None);
  605. let encoded = returns[0].clone().into_bytes().unwrap();
  606. let decoded = Res3::try_from_slice(&encoded).unwrap();
  607. assert_eq!(decoded.item.len(), 5);
  608. assert_eq!(decoded.item, vec![9, 3, 4, 90, 834]);
  609. }
  610. fn create_response(vec: &mut [u8], string: &[u8; 2]) -> [u8; 32] {
  611. vec[30] = string[1];
  612. vec[31] = string[0];
  613. <[u8; 32]>::try_from(vec.to_owned()).unwrap()
  614. }
  615. #[test]
  616. fn null_pointer() {
  617. #[derive(Debug, BorshDeserialize)]
  618. struct S {
  619. f1: i64,
  620. f2: String,
  621. }
  622. #[derive(Debug, BorshDeserialize)]
  623. struct Res1 {
  624. item: Vec<S>,
  625. }
  626. #[derive(Debug, BorshDeserialize)]
  627. struct Res2 {
  628. item: Vec<String>,
  629. }
  630. let mut vm = build_solidity(
  631. r#"
  632. contract Testing {
  633. struct S {
  634. int64 f1;
  635. string f2;
  636. }
  637. function test1() public pure returns (bytes memory) {
  638. S[] memory s = new S[](5);
  639. return abi.encode(s);
  640. }
  641. function test2() public pure returns (bytes memory) {
  642. string[] memory x = new string[](5);
  643. return abi.encode(x);
  644. }
  645. }
  646. "#,
  647. );
  648. vm.constructor("Testing", &[]);
  649. let returns = vm.function("test1", &[], &[], None);
  650. let encoded = returns[0].clone().into_bytes().unwrap();
  651. let decoded = Res1::try_from_slice(&encoded).unwrap();
  652. assert_eq!(decoded.item.len(), 5);
  653. for i in 0..5 {
  654. assert_eq!(decoded.item[i].f1, 0);
  655. assert!(decoded.item[i].f2.is_empty())
  656. }
  657. let returns = vm.function("test2", &[], &[], None);
  658. let encoded = returns[0].clone().into_bytes().unwrap();
  659. let decoded = Res2::try_from_slice(&encoded).unwrap();
  660. assert_eq!(decoded.item.len(), 5);
  661. for i in 0..5 {
  662. assert!(decoded.item[i].is_empty());
  663. }
  664. }
  665. #[test]
  666. fn external_function() {
  667. #[derive(Debug, BorshDeserialize)]
  668. struct Res {
  669. item_1: [u8; 4],
  670. item_2: [u8; 32],
  671. }
  672. let mut vm = build_solidity(
  673. r#"
  674. contract Testing {
  675. function doThis(int64 a, int64 b) public pure returns (int64) {
  676. return a+b;
  677. }
  678. function doThat() public view returns (bytes4, address, bytes memory) {
  679. function (int64, int64) external returns (int64) fPtr = this.doThis;
  680. bytes memory b = abi.encode(fPtr);
  681. return (fPtr.selector, fPtr.address, b);
  682. }
  683. }
  684. "#,
  685. );
  686. vm.constructor("Testing", &[]);
  687. let returns = vm.function("doThat", &[], &[], None);
  688. let encoded = returns[2].clone().into_bytes().unwrap();
  689. let decoded = Res::try_from_slice(&encoded).unwrap();
  690. let mut selector = returns[0].clone().into_fixed_bytes().unwrap();
  691. selector.reverse();
  692. let address = returns[1].clone().into_fixed_bytes().unwrap();
  693. assert_eq!(decoded.item_1, &selector[..]);
  694. assert_eq!(decoded.item_2, &address[..]);
  695. }