abi_encode.rs 24 KB

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