mappings.rs 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::{account_new, build_solidity, BorshToken};
  3. use num_bigint::BigInt;
  4. use num_traits::{One, Zero};
  5. #[test]
  6. fn simple_mapping() {
  7. let mut vm = build_solidity(
  8. r#"
  9. contract foo {
  10. mapping (uint64 => uint64) map;
  11. function set(uint64 index, uint64 val) public {
  12. map[index] = val;
  13. }
  14. function get(uint64 index) public returns (uint64) {
  15. return map[index];
  16. }
  17. function rm(uint64 index) public {
  18. delete map[index];
  19. }
  20. }"#,
  21. );
  22. vm.constructor(&[]);
  23. for i in 0..10 {
  24. vm.function(
  25. "set",
  26. &[
  27. BorshToken::Uint {
  28. width: 64,
  29. value: BigInt::from(102 + i),
  30. },
  31. BorshToken::Uint {
  32. width: 64,
  33. value: BigInt::from(300331 + i),
  34. },
  35. ],
  36. );
  37. }
  38. for i in 0..10 {
  39. let returns = vm
  40. .function(
  41. "get",
  42. &[BorshToken::Uint {
  43. width: 64,
  44. value: BigInt::from(102 + i),
  45. }],
  46. )
  47. .unwrap();
  48. assert_eq!(
  49. returns,
  50. BorshToken::Uint {
  51. width: 64,
  52. value: BigInt::from(300331 + i)
  53. }
  54. );
  55. }
  56. let returns = vm
  57. .function(
  58. "get",
  59. &[BorshToken::Uint {
  60. width: 64,
  61. value: BigInt::from(101u8),
  62. }],
  63. )
  64. .unwrap();
  65. assert_eq!(
  66. returns,
  67. BorshToken::Uint {
  68. width: 64,
  69. value: BigInt::zero()
  70. }
  71. );
  72. vm.function(
  73. "rm",
  74. &[BorshToken::Uint {
  75. width: 64,
  76. value: BigInt::from(104u8),
  77. }],
  78. );
  79. for i in 0..10 {
  80. let returns = vm
  81. .function(
  82. "get",
  83. &[BorshToken::Uint {
  84. width: 64,
  85. value: BigInt::from(102 + i),
  86. }],
  87. )
  88. .unwrap();
  89. if 102 + i != 104 {
  90. assert_eq!(
  91. returns,
  92. BorshToken::Uint {
  93. width: 64,
  94. value: BigInt::from(300331 + i)
  95. }
  96. );
  97. } else {
  98. assert_eq!(
  99. returns,
  100. BorshToken::Uint {
  101. width: 64,
  102. value: BigInt::zero(),
  103. }
  104. );
  105. }
  106. }
  107. }
  108. #[test]
  109. fn less_simple_mapping() {
  110. let mut vm = build_solidity(
  111. r#"
  112. struct S {
  113. string f1;
  114. int64[] f2;
  115. }
  116. contract foo {
  117. mapping (uint => S) map;
  118. function set_string(uint index, string s) public {
  119. map[index].f1 = s;
  120. }
  121. function add_int(uint index, int64 n) public {
  122. map[index].f2.push(n);
  123. }
  124. function get(uint index) public returns (S) {
  125. return map[index];
  126. }
  127. function rm(uint index) public {
  128. delete map[index];
  129. }
  130. }"#,
  131. );
  132. vm.constructor(&[]);
  133. vm.function(
  134. "set_string",
  135. &[
  136. BorshToken::Uint {
  137. width: 256,
  138. value: BigInt::from(12313132131321312311213131u128)
  139. },
  140. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  141. ],
  142. );
  143. vm.function(
  144. "add_int",
  145. &[
  146. BorshToken::Uint {
  147. width: 256,
  148. value: BigInt::from(12313132131321312311213131u128),
  149. },
  150. BorshToken::Int {
  151. width: 64,
  152. value: BigInt::from(102u8),
  153. },
  154. ],
  155. );
  156. let returns = vm
  157. .function(
  158. "get",
  159. &[BorshToken::Uint {
  160. width: 256,
  161. value: BigInt::from(12313132131321312311213131u128),
  162. }],
  163. )
  164. .unwrap();
  165. assert_eq!(
  166. returns,
  167. BorshToken::Tuple(vec![
  168. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  169. BorshToken::Array(vec![
  170. BorshToken::Int{
  171. width: 64,
  172. value: BigInt::from(102u8)
  173. },
  174. ]),
  175. ])
  176. );
  177. }
  178. #[test]
  179. fn string_mapping() {
  180. let mut vm = build_solidity(
  181. r#"
  182. struct S {
  183. string f1;
  184. int64[] f2;
  185. }
  186. contract foo {
  187. mapping (string => S) map;
  188. function set_string(string index, string s) public {
  189. map[index].f1 = s;
  190. }
  191. function add_int(string index, int64 n) public {
  192. map[index].f2.push(n);
  193. }
  194. function get(string index) public returns (S) {
  195. return map[index];
  196. }
  197. function rm(string index) public {
  198. delete map[index];
  199. }
  200. }"#,
  201. );
  202. vm.constructor(&[]);
  203. vm.function(
  204. "set_string",
  205. &[
  206. BorshToken::String(String::from("a")),
  207. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  208. ],
  209. );
  210. vm.function(
  211. "add_int",
  212. &[
  213. BorshToken::String(String::from("a")),
  214. BorshToken::Int {
  215. width: 64,
  216. value: BigInt::from(102u8),
  217. },
  218. ],
  219. );
  220. let returns = vm
  221. .function("get", &[BorshToken::String(String::from("a"))])
  222. .unwrap();
  223. assert_eq!(
  224. returns,
  225. BorshToken::Tuple(vec![
  226. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  227. BorshToken::Array(vec![
  228. BorshToken::Int{
  229. width: 64,
  230. value: BigInt::from(102u8)
  231. },
  232. ]),
  233. ])
  234. );
  235. }
  236. #[test]
  237. fn contract_mapping() {
  238. let mut vm = build_solidity(
  239. r#"
  240. interface I {}
  241. contract foo {
  242. mapping (I => string) public map;
  243. function set(I index, string s) public {
  244. map[index] = s;
  245. }
  246. function get(I index) public returns (string) {
  247. return map[index];
  248. }
  249. function rm(I index) public {
  250. delete map[index];
  251. }
  252. }"#,
  253. );
  254. vm.constructor(&[]);
  255. let index = BorshToken::Address(account_new());
  256. vm.function(
  257. "set",
  258. &[
  259. index.clone(),
  260. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  261. ], );
  262. let returns = vm.function("get", &[index.clone()]).unwrap();
  263. assert_eq!(
  264. returns,
  265. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder"))
  266. );
  267. vm.function("rm", &[index.clone()]);
  268. let returns = vm.function("get", &[index]).unwrap();
  269. assert_eq!(returns, BorshToken::String(String::from("")));
  270. }
  271. #[test]
  272. fn mapping_in_mapping() {
  273. let mut vm = build_solidity(
  274. r#"
  275. contract foo {
  276. mapping (string => mapping(int64 => byte)) public map;
  277. function set(string s, int64 n, bytes1 v) public {
  278. map[s][n] = v;
  279. }
  280. }"#,
  281. );
  282. vm.constructor(&[]);
  283. vm.function(
  284. "set",
  285. &[
  286. BorshToken::String(String::from("a")),
  287. BorshToken::Int {
  288. width: 64,
  289. value: BigInt::from(102u8),
  290. },
  291. BorshToken::FixedBytes(vec![0x98]),
  292. ],
  293. );
  294. let returns = vm
  295. .function(
  296. "map",
  297. &[
  298. BorshToken::String(String::from("a")),
  299. BorshToken::Int {
  300. width: 64,
  301. value: BigInt::from(102u8),
  302. },
  303. ],
  304. )
  305. .unwrap();
  306. assert_eq!(returns, BorshToken::uint8_fixed_array(vec![0x98]));
  307. let returns = vm
  308. .function(
  309. "map",
  310. &[
  311. BorshToken::String(String::from("a")),
  312. BorshToken::Int {
  313. width: 64,
  314. value: BigInt::from(103u8),
  315. },
  316. ],
  317. )
  318. .unwrap();
  319. assert_eq!(returns, BorshToken::uint8_fixed_array(vec![0]));
  320. let returns = vm
  321. .function(
  322. "map",
  323. &[
  324. BorshToken::String(String::from("b")),
  325. BorshToken::Int {
  326. width: 64,
  327. value: BigInt::from(102u8),
  328. },
  329. ],
  330. )
  331. .unwrap();
  332. assert_eq!(returns, BorshToken::uint8_fixed_array(vec![0]));
  333. }
  334. #[test]
  335. fn sparse_array() {
  336. let mut vm = build_solidity(
  337. r#"
  338. struct S {
  339. string f1;
  340. int64[] f2;
  341. }
  342. contract foo {
  343. S[1e9] map;
  344. function set_string(uint index, string s) public {
  345. map[index].f1 = s;
  346. }
  347. function add_int(uint index, int64 n) public {
  348. map[index].f2.push(n);
  349. }
  350. function get(uint index) public returns (S) {
  351. return map[index];
  352. }
  353. function rm(uint index) public {
  354. delete map[index];
  355. }
  356. }"#,
  357. );
  358. vm.constructor(&[]);
  359. vm.function(
  360. "set_string",
  361. &[
  362. BorshToken::Uint{
  363. width: 256,
  364. value: BigInt::from(909090909u64)
  365. },
  366. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  367. ], );
  368. vm.function(
  369. "add_int",
  370. &[
  371. BorshToken::Uint {
  372. width: 256,
  373. value: BigInt::from(909090909u64),
  374. },
  375. BorshToken::Int {
  376. width: 64,
  377. value: BigInt::from(102u8),
  378. },
  379. ],
  380. );
  381. let returns = vm
  382. .function(
  383. "get",
  384. &[BorshToken::Uint {
  385. width: 256,
  386. value: BigInt::from(909090909u64),
  387. }],
  388. )
  389. .unwrap();
  390. assert_eq!(
  391. returns,
  392. BorshToken::Tuple(vec![
  393. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  394. BorshToken::Array(vec![
  395. BorshToken::Int{
  396. width: 64,
  397. value: BigInt::from(102u8)
  398. },
  399. ]),
  400. ])
  401. );
  402. }
  403. #[test]
  404. fn massive_sparse_array() {
  405. let mut vm = build_solidity(
  406. r#"
  407. struct S {
  408. string f1;
  409. int64[] f2;
  410. }
  411. contract foo {
  412. S[1e24] map;
  413. function set_string(uint index, string s) public {
  414. map[index].f1 = s;
  415. }
  416. function add_int(uint index, int64 n) public {
  417. map[index].f2.push(n);
  418. }
  419. function get(uint index) public returns (S) {
  420. return map[index];
  421. }
  422. function rm(uint index) public {
  423. delete map[index];
  424. }
  425. }"#,
  426. );
  427. vm.constructor(&[]);
  428. vm.function(
  429. "set_string",
  430. &[
  431. BorshToken::Uint {
  432. width: 256,
  433. value: BigInt::from(786868768768678687686877u128)
  434. },
  435. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  436. ], );
  437. vm.function(
  438. "add_int",
  439. &[
  440. BorshToken::Uint {
  441. width: 256,
  442. value: BigInt::from(786868768768678687686877u128),
  443. },
  444. BorshToken::Int {
  445. width: 64,
  446. value: BigInt::from(102u8),
  447. },
  448. ],
  449. );
  450. let returns = vm
  451. .function(
  452. "get",
  453. &[BorshToken::Uint {
  454. width: 256,
  455. value: BigInt::from(786868768768678687686877u128),
  456. }],
  457. )
  458. .unwrap();
  459. assert_eq!(
  460. returns,
  461. BorshToken::Tuple(vec![
  462. BorshToken::String(String::from("This is a string which should be a little longer than 32 bytes so we the the abi encoder")),
  463. BorshToken::Array(vec![
  464. BorshToken::Int {
  465. width: 64,
  466. value: BigInt::from(102u8)
  467. },
  468. ]),
  469. ])
  470. );
  471. }
  472. #[test]
  473. fn mapping_in_dynamic_array() {
  474. let mut vm = build_solidity(
  475. r#"
  476. contract foo {
  477. mapping (uint64 => uint64)[] public map;
  478. int64 public number;
  479. function set(uint64 array_no, uint64 index, uint64 val) public {
  480. map[array_no][index] = val;
  481. }
  482. function rm(uint64 array_no, uint64 index) public {
  483. delete map[array_no][index];
  484. }
  485. function push() public {
  486. map.push();
  487. }
  488. function pop() public {
  489. map.pop();
  490. }
  491. function setNumber(int64 x) public {
  492. number = x;
  493. }
  494. function length() public returns (uint64) {
  495. return map.length;
  496. }
  497. }"#,
  498. );
  499. vm.constructor(&[]);
  500. vm.function(
  501. "setNumber",
  502. &[BorshToken::Int {
  503. width: 64,
  504. value: BigInt::from(2147483647),
  505. }],
  506. );
  507. vm.function("push", &[]);
  508. vm.function("push", &[]);
  509. for array_no in 0..2 {
  510. for i in 0..10 {
  511. vm.function(
  512. "set",
  513. &[
  514. BorshToken::Uint {
  515. width: 64,
  516. value: BigInt::from(array_no),
  517. },
  518. BorshToken::Uint {
  519. width: 64,
  520. value: BigInt::from(102 + i + array_no * 500),
  521. },
  522. BorshToken::Uint {
  523. width: 64,
  524. value: BigInt::from(300331 + i),
  525. },
  526. ],
  527. );
  528. }
  529. }
  530. for array_no in 0..2 {
  531. for i in 0..10 {
  532. let returns = vm
  533. .function(
  534. "map",
  535. &[
  536. BorshToken::Uint {
  537. width: 256,
  538. value: BigInt::from(array_no),
  539. },
  540. BorshToken::Uint {
  541. width: 64,
  542. value: BigInt::from(102 + i + array_no * 500),
  543. },
  544. ],
  545. )
  546. .unwrap();
  547. assert_eq!(
  548. returns,
  549. BorshToken::Uint {
  550. width: 64,
  551. value: BigInt::from(300331 + i)
  552. },
  553. );
  554. }
  555. }
  556. let returns = vm
  557. .function(
  558. "map",
  559. &[
  560. BorshToken::Uint {
  561. width: 256,
  562. value: BigInt::zero(),
  563. },
  564. BorshToken::Uint {
  565. width: 64,
  566. value: BigInt::from(101u8),
  567. },
  568. ],
  569. )
  570. .unwrap();
  571. assert_eq!(
  572. returns,
  573. BorshToken::Uint {
  574. width: 64,
  575. value: BigInt::zero()
  576. }
  577. );
  578. vm.function(
  579. "rm",
  580. &[
  581. BorshToken::Uint {
  582. width: 64,
  583. value: BigInt::zero(),
  584. },
  585. BorshToken::Uint {
  586. width: 64,
  587. value: BigInt::from(104u8),
  588. },
  589. ],
  590. );
  591. for i in 0..10 {
  592. let returns = vm
  593. .function(
  594. "map",
  595. &[
  596. BorshToken::Uint {
  597. width: 256,
  598. value: BigInt::zero(),
  599. },
  600. BorshToken::Uint {
  601. width: 64,
  602. value: BigInt::from(102 + i),
  603. },
  604. ],
  605. )
  606. .unwrap();
  607. if 102 + i != 104 {
  608. assert_eq!(
  609. returns,
  610. BorshToken::Uint {
  611. width: 64,
  612. value: BigInt::from(300331 + i)
  613. },
  614. );
  615. } else {
  616. assert_eq!(
  617. returns,
  618. BorshToken::Uint {
  619. width: 64,
  620. value: BigInt::zero()
  621. }
  622. );
  623. }
  624. }
  625. let returns = vm.function("length", &[]).unwrap();
  626. assert_eq!(
  627. returns,
  628. BorshToken::Uint {
  629. width: 64,
  630. value: BigInt::from(2u8)
  631. }
  632. );
  633. vm.function("pop", &[]);
  634. let returns = vm.function("length", &[]).unwrap();
  635. assert_eq!(
  636. returns,
  637. BorshToken::Uint {
  638. width: 64,
  639. value: BigInt::one()
  640. }
  641. );
  642. vm.function("pop", &[]);
  643. let returns = vm.function("length", &[]).unwrap();
  644. assert_eq!(
  645. returns,
  646. BorshToken::Uint {
  647. width: 64,
  648. value: BigInt::zero()
  649. }
  650. );
  651. let returns = vm.function("number", &[]).unwrap();
  652. assert_eq!(
  653. returns,
  654. BorshToken::Int {
  655. width: 64,
  656. value: BigInt::from(2147483647u64)
  657. }
  658. );
  659. }
  660. #[test]
  661. fn mapping_in_struct_in_dynamic_array() {
  662. let mut vm = build_solidity(
  663. r#"
  664. contract foo {
  665. struct A {
  666. mapping(uint256 => uint256) a;
  667. }
  668. A[] private map;
  669. int64 public number;
  670. function set(uint64 array_no, uint64 index, uint64 val) public {
  671. map[array_no].a[index] = val;
  672. }
  673. function get(uint64 array_no, uint64 index) public returns (uint256) {
  674. return map[array_no].a[index];
  675. }
  676. function rm(uint64 array_no, uint64 index) public {
  677. delete map[array_no].a[index];
  678. }
  679. function push() public {
  680. map.push();
  681. }
  682. function pop() public {
  683. map.pop();
  684. }
  685. function setNumber(int64 x) public {
  686. number = x;
  687. }
  688. }"#,
  689. );
  690. vm.constructor(&[]);
  691. vm.function(
  692. "setNumber",
  693. &[BorshToken::Int {
  694. width: 64,
  695. value: BigInt::from(2147483647),
  696. }],
  697. );
  698. vm.function("push", &[]);
  699. vm.function("push", &[]);
  700. for array_no in 0..2 {
  701. for i in 0..10 {
  702. vm.function(
  703. "set",
  704. &[
  705. BorshToken::Uint {
  706. width: 64,
  707. value: BigInt::from(array_no),
  708. },
  709. BorshToken::Uint {
  710. width: 64,
  711. value: BigInt::from(102 + i + array_no * 500),
  712. },
  713. BorshToken::Uint {
  714. width: 64,
  715. value: BigInt::from(300331 + i),
  716. },
  717. ],
  718. );
  719. }
  720. }
  721. for array_no in 0..2 {
  722. for i in 0..10 {
  723. let returns = vm
  724. .function(
  725. "get",
  726. &[
  727. BorshToken::Uint {
  728. width: 64,
  729. value: BigInt::from(array_no),
  730. },
  731. BorshToken::Uint {
  732. width: 64,
  733. value: BigInt::from(102 + i + array_no * 500),
  734. },
  735. ],
  736. )
  737. .unwrap();
  738. assert_eq!(
  739. returns,
  740. BorshToken::Uint {
  741. width: 256,
  742. value: BigInt::from(300331 + i)
  743. },
  744. );
  745. }
  746. }
  747. let returns = vm
  748. .function(
  749. "get",
  750. &[
  751. BorshToken::Uint {
  752. width: 64,
  753. value: BigInt::zero(),
  754. },
  755. BorshToken::Uint {
  756. width: 64,
  757. value: BigInt::from(101u8),
  758. },
  759. ],
  760. )
  761. .unwrap();
  762. assert_eq!(
  763. returns,
  764. BorshToken::Uint {
  765. width: 256,
  766. value: BigInt::zero(),
  767. },
  768. );
  769. vm.function(
  770. "rm",
  771. &[
  772. BorshToken::Uint {
  773. width: 64,
  774. value: BigInt::zero(),
  775. },
  776. BorshToken::Uint {
  777. width: 64,
  778. value: BigInt::from(104u8),
  779. },
  780. ],
  781. );
  782. for i in 0..10 {
  783. let returns = vm
  784. .function(
  785. "get",
  786. &[
  787. BorshToken::Uint {
  788. width: 64,
  789. value: BigInt::zero(),
  790. },
  791. BorshToken::Uint {
  792. width: 64,
  793. value: BigInt::from(102 + i),
  794. },
  795. ],
  796. )
  797. .unwrap();
  798. if 102 + i != 104 {
  799. assert_eq!(
  800. returns,
  801. BorshToken::Uint {
  802. width: 256,
  803. value: BigInt::from(300331 + i)
  804. }
  805. );
  806. } else {
  807. assert_eq!(
  808. returns,
  809. BorshToken::Uint {
  810. width: 256,
  811. value: BigInt::zero()
  812. }
  813. );
  814. }
  815. }
  816. vm.function("pop", &[]);
  817. vm.function("pop", &[]);
  818. let returns = vm.function("number", &[]).unwrap();
  819. assert_eq!(
  820. returns,
  821. BorshToken::Int {
  822. width: 64,
  823. value: BigInt::from(2147483647u64),
  824. }
  825. );
  826. }
  827. #[test]
  828. fn mapping_delete() {
  829. let mut vm = build_solidity(
  830. r#"
  831. contract DeleteTest {
  832. struct data_struct {
  833. address addr1;
  834. address addr2;
  835. }
  836. mapping(uint => data_struct) example;
  837. function addData(address sender) public {
  838. data_struct dt = data_struct({addr1: address(this), addr2: sender});
  839. uint id = 1;
  840. example[id] = dt;
  841. }
  842. function deltest() external {
  843. uint id = 1;
  844. delete example[id];
  845. }
  846. function get() public view returns (data_struct calldata) {
  847. uint id = 1;
  848. return example[id];
  849. }
  850. }
  851. "#,
  852. );
  853. let sender = account_new();
  854. vm.constructor(&[]);
  855. let _ = vm.function("addData", &[BorshToken::Address(sender)]);
  856. let _ = vm.function("deltest", &[]);
  857. let returns = vm.function("get", &[]).unwrap();
  858. assert_eq!(
  859. returns,
  860. BorshToken::Tuple(vec![
  861. BorshToken::Address([
  862. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  863. 0, 0, 0, 0
  864. ]),
  865. BorshToken::Address([
  866. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  867. 0, 0, 0, 0
  868. ])
  869. ]),
  870. );
  871. }
  872. #[test]
  873. fn mapping_within_struct() {
  874. let mut vm = build_solidity(
  875. r#"
  876. contract CrowdFunding {
  877. struct Funder {
  878. address addr;
  879. uint amount;
  880. }
  881. struct Campaign {
  882. mapping(uint => Funder)[2] arr_mp;
  883. mapping (uint => Funder) funders;
  884. }
  885. uint numCampaigns;
  886. mapping (uint => Campaign) campaigns;
  887. function newCampaign(address sender) public returns (uint campaignID) {
  888. campaignID = numCampaigns++;
  889. Campaign storage _campaign = campaigns[campaignID];
  890. _campaign.funders[0] = Funder(sender, 100);
  891. _campaign.arr_mp[1][0] = Funder(sender, 105);
  892. }
  893. function getAmt() public view returns (uint) {
  894. Campaign storage _campaign = campaigns[numCampaigns - 1];
  895. return _campaign.funders[0].amount;
  896. }
  897. function getArrAmt() public view returns (uint) {
  898. Campaign storage _campaign = campaigns[numCampaigns - 1];
  899. return _campaign.arr_mp[1][0].amount;
  900. }
  901. }
  902. "#,
  903. );
  904. let sender = account_new();
  905. vm.constructor(&[]);
  906. let ret = vm
  907. .function("newCampaign", &[BorshToken::Address(sender)])
  908. .unwrap();
  909. assert_eq!(
  910. ret,
  911. BorshToken::Uint {
  912. width: 256,
  913. value: BigInt::zero(),
  914. }
  915. );
  916. let ret = vm.function("getAmt", &[]).unwrap();
  917. assert_eq!(
  918. ret,
  919. BorshToken::Uint {
  920. width: 256,
  921. value: BigInt::from(100u8),
  922. }
  923. );
  924. let ret = vm.function("getArrAmt", &[]).unwrap();
  925. assert_eq!(
  926. ret,
  927. BorshToken::Uint {
  928. width: 256,
  929. value: BigInt::from(105u8),
  930. }
  931. );
  932. }