abi_encode.rs 28 KB

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