mod.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. use parity_scale_codec::Encode;
  2. use parity_scale_codec_derive::{Decode, Encode};
  3. use super::{build_solidity, first_error};
  4. use solang::{parse_and_resolve, Target};
  5. #[derive(Debug, PartialEq, Encode, Decode)]
  6. struct Val32(u32);
  7. #[derive(Debug, PartialEq, Encode, Decode)]
  8. struct Val8(u8);
  9. #[test]
  10. fn parse_structs() {
  11. let ns = parse_and_resolve(
  12. r#"
  13. contract test_struct_parsing {
  14. struct Foo {
  15. bool a;
  16. uint a;
  17. }
  18. }"#,
  19. Target::Substrate,
  20. );
  21. assert_eq!(
  22. first_error(ns.diagnostics),
  23. "struct ‘Foo’ has duplicate struct field ‘a’"
  24. );
  25. let ns = parse_and_resolve(
  26. r#"
  27. contract test_struct_parsing {
  28. struct Foo {
  29. bool a;
  30. uint storage b;
  31. }
  32. }"#,
  33. Target::Substrate,
  34. );
  35. assert_eq!(
  36. first_error(ns.diagnostics),
  37. "storage location ‘storage’ not allowed for struct field"
  38. );
  39. let ns = parse_and_resolve(
  40. r#"
  41. contract test_struct_parsing {
  42. struct Foo {
  43. bool a;
  44. uint calldata b;
  45. }
  46. }"#,
  47. Target::Substrate,
  48. );
  49. assert_eq!(
  50. first_error(ns.diagnostics),
  51. "storage location ‘calldata’ not allowed for struct field"
  52. );
  53. let ns = parse_and_resolve(
  54. r#"
  55. contract test_struct_parsing {
  56. struct Foo {
  57. bool memory a;
  58. uint calldata b;
  59. }
  60. }"#,
  61. Target::Substrate,
  62. );
  63. assert_eq!(
  64. first_error(ns.diagnostics),
  65. "storage location ‘memory’ not allowed for struct field"
  66. );
  67. let ns = parse_and_resolve(
  68. r#"
  69. contract test_struct_parsing {
  70. struct Foo {
  71. }
  72. }"#,
  73. Target::Substrate,
  74. );
  75. assert_eq!(
  76. first_error(ns.diagnostics),
  77. "struct definition for ‘Foo’ has no fields"
  78. );
  79. let ns = parse_and_resolve(
  80. r#"
  81. contract test_struct_parsing {
  82. struct Foo {
  83. boolean x;
  84. }
  85. }"#,
  86. Target::Substrate,
  87. );
  88. assert_eq!(first_error(ns.diagnostics), "type ‘boolean’ not found");
  89. // is it impossible to define recursive structs
  90. let ns = parse_and_resolve(
  91. r#"
  92. contract test_struct_parsing {
  93. struct Foo {
  94. bool x;
  95. Foo y;
  96. }
  97. }"#,
  98. Target::Substrate,
  99. );
  100. assert_eq!(
  101. first_error(ns.diagnostics),
  102. "struct ‘Foo’ has infinite size"
  103. );
  104. // is it impossible to define recursive structs
  105. let ns = parse_and_resolve(
  106. r#"
  107. contract c {
  108. s z;
  109. }
  110. struct s {
  111. bool f1;
  112. int32 f2;
  113. s2 f3;
  114. }
  115. struct s2 {
  116. bytes4 selector;
  117. s foo;
  118. }"#,
  119. Target::Substrate,
  120. );
  121. assert_eq!(first_error(ns.diagnostics), "struct ‘s’ has infinite size");
  122. // literal initializers
  123. let ns = parse_and_resolve(
  124. r#"
  125. contract test_struct_parsing {
  126. struct Foo {
  127. bool x;
  128. int32 y;
  129. }
  130. function f() private {
  131. Foo a = Foo();
  132. }
  133. }"#,
  134. Target::Substrate,
  135. );
  136. assert_eq!(
  137. first_error(ns.diagnostics),
  138. "struct ‘Foo’ has 2 fields, not 0"
  139. );
  140. // literal initializers
  141. let ns = parse_and_resolve(
  142. r#"
  143. contract test_struct_parsing {
  144. struct Foo {
  145. bool x;
  146. int32 y;
  147. }
  148. function f() private {
  149. Foo a = Foo(true, true, true);
  150. }
  151. }"#,
  152. Target::Substrate,
  153. );
  154. assert_eq!(
  155. first_error(ns.diagnostics),
  156. "struct ‘Foo’ has 2 fields, not 3"
  157. );
  158. // literal initializers
  159. let ns = parse_and_resolve(
  160. r#"
  161. contract test_struct_parsing {
  162. struct Foo {
  163. bool x;
  164. int32 y;
  165. }
  166. function f() private {
  167. Foo a = Foo({ });
  168. }
  169. }"#,
  170. Target::Substrate,
  171. );
  172. assert_eq!(
  173. first_error(ns.diagnostics),
  174. "struct ‘Foo’ has 2 fields, not 0"
  175. );
  176. // literal initializers
  177. let ns = parse_and_resolve(
  178. r#"
  179. contract test_struct_parsing {
  180. struct Foo {
  181. bool x;
  182. int32 y;
  183. }
  184. function f() private {
  185. Foo a = Foo({ x: true, y: 1, z: 2 });
  186. }
  187. }"#,
  188. Target::Substrate,
  189. );
  190. assert_eq!(
  191. first_error(ns.diagnostics),
  192. "struct ‘Foo’ has 2 fields, not 3"
  193. );
  194. // literal initializers
  195. let ns = parse_and_resolve(
  196. r#"
  197. contract test_struct_parsing {
  198. struct Foo {
  199. bool x;
  200. int32 y;
  201. }
  202. function f() private {
  203. Foo a = Foo({ x: true, z: 1 });
  204. }
  205. }"#,
  206. Target::Substrate,
  207. );
  208. assert_eq!(first_error(ns.diagnostics), "struct ‘Foo’ has no field ‘z’");
  209. }
  210. #[test]
  211. fn struct_members() {
  212. let mut runtime = build_solidity(
  213. r##"
  214. pragma solidity 0;
  215. pragma experimental ABIEncoderV2;
  216. contract test_struct_parsing {
  217. struct foo {
  218. bool x;
  219. uint32 y;
  220. bytes31 d;
  221. }
  222. function test() public {
  223. foo f;
  224. f.x = true;
  225. f.y = 64;
  226. assert(f.x == true);
  227. assert(f.y == 64);
  228. assert(f.d.length == 31);
  229. foo f2 = foo(false, 32168, hex"DEAD");
  230. assert(f2.x == false);
  231. assert(f2.y == 32168);
  232. assert(f2.d == hex"dead");
  233. foo f3 = foo({ x: true, y: 102, d: hex"00DEAD" });
  234. assert(f3.x == true);
  235. assert(f3.y == 102);
  236. assert(f3.d == hex"00dead");
  237. }
  238. }"##,
  239. );
  240. runtime.function("test", Vec::new());
  241. }
  242. #[test]
  243. fn structs_as_ref_args() {
  244. let mut runtime = build_solidity(
  245. r##"
  246. contract test_struct_parsing {
  247. struct foo {
  248. bool x;
  249. uint32 y;
  250. }
  251. function func(foo f) private {
  252. // assigning to f members dereferences f
  253. f.x = true;
  254. f.y = 64;
  255. // assigning to f changes the reference
  256. f = foo({ x: false, y: 256 });
  257. // f no longer point to f in caller function
  258. f.x = false;
  259. f.y = 98123;
  260. }
  261. function test() public {
  262. foo f;
  263. func(f);
  264. assert(f.x == true);
  265. assert(f.y == 64);
  266. }
  267. }"##,
  268. );
  269. runtime.function("test", Vec::new());
  270. }
  271. #[test]
  272. fn structs_encode() {
  273. #[derive(Debug, PartialEq, Encode, Decode)]
  274. struct Foo {
  275. f1: [u8; 3],
  276. f2: bool,
  277. };
  278. let mut runtime = build_solidity(
  279. r##"
  280. contract test_struct_parsing {
  281. struct foo {
  282. bytes3 f1;
  283. bool f2;
  284. }
  285. function test(foo f) public {
  286. assert(f.f1 == "ABC");
  287. assert(f.f2 == true);
  288. }
  289. }"##,
  290. );
  291. runtime.function(
  292. "test",
  293. Foo {
  294. f1: [0x41, 0x42, 0x43],
  295. f2: true,
  296. }
  297. .encode(),
  298. );
  299. }
  300. #[test]
  301. fn structs_decode() {
  302. #[derive(Debug, PartialEq, Encode, Decode)]
  303. struct Foo {
  304. f1: [u8; 3],
  305. f2: i32,
  306. };
  307. let mut runtime = build_solidity(
  308. r##"
  309. contract test_struct_parsing {
  310. struct foo {
  311. bytes3 f1;
  312. int32 f2;
  313. }
  314. function test() public returns (foo) {
  315. foo f;
  316. f.f1 = hex"f33ec3";
  317. f.f2 = 0xfd7f;
  318. return f;
  319. }
  320. }"##,
  321. );
  322. runtime.function("test", Vec::new());
  323. assert_eq!(
  324. runtime.vm.scratch,
  325. Foo {
  326. f1: [0xf3, 0x3e, 0xc3],
  327. f2: 0xfd7f,
  328. }
  329. .encode(),
  330. );
  331. }
  332. #[test]
  333. fn struct_in_struct() {
  334. let mut runtime = build_solidity(
  335. r##"
  336. pragma solidity 0;
  337. contract struct_in_struct {
  338. struct foo {
  339. bool x;
  340. uint32 y;
  341. }
  342. struct bar {
  343. address a;
  344. bytes7 b;
  345. foo c;
  346. }
  347. function test() public pure {
  348. bar memory f = bar({ a: address(0), b: hex"fe", c: foo({ x: true, y: 102 }) });
  349. foo memory m = foo(false, 50);
  350. f.c = m;
  351. f.c.y = 300;
  352. assert(m.y == 300);
  353. }
  354. }"##,
  355. );
  356. runtime.function("test", Vec::new());
  357. }
  358. #[test]
  359. fn structs_in_structs_decode() {
  360. #[derive(Debug, PartialEq, Encode, Decode)]
  361. struct Foo {
  362. f1: [u8; 3],
  363. f2: i32,
  364. };
  365. #[derive(Debug, PartialEq, Encode, Decode)]
  366. struct Bar {
  367. a: bool,
  368. b: Foo,
  369. c: Foo,
  370. };
  371. let mut runtime = build_solidity(
  372. r##"
  373. contract test_struct_parsing {
  374. struct foo {
  375. bytes3 f1;
  376. int32 f2;
  377. }
  378. struct bar {
  379. bool a;
  380. foo b;
  381. foo c;
  382. }
  383. function test() public returns (bar) {
  384. bar f = bar({ a: true, b: foo({ f1: hex"c30000", f2: 0xff7f}), c: foo({ f1: hex"f7f6f5", f2: 0x4002 })});
  385. return f;
  386. }
  387. }"##,
  388. );
  389. runtime.function("test", Vec::new());
  390. assert_eq!(
  391. runtime.vm.scratch,
  392. Bar {
  393. a: true,
  394. b: Foo {
  395. f1: [0xc3, 0x00, 0x00],
  396. f2: 0xff7f,
  397. },
  398. c: Foo {
  399. f1: [0xf7, 0xf6, 0xf5],
  400. f2: 0x4002,
  401. }
  402. }
  403. .encode(),
  404. );
  405. }
  406. #[test]
  407. fn structs_in_structs_encode() {
  408. #[derive(Debug, PartialEq, Encode, Decode)]
  409. struct Foo {
  410. f1: [u8; 3],
  411. f2: i32,
  412. };
  413. #[derive(Debug, PartialEq, Encode, Decode)]
  414. struct Bar {
  415. a: bool,
  416. b: Foo,
  417. c: Foo,
  418. };
  419. let mut runtime = build_solidity(
  420. r##"
  421. contract test_struct_parsing {
  422. struct foo {
  423. bytes3 f1;
  424. int32 f2;
  425. }
  426. function test(other.bar f) public {
  427. assert(f.c.f2 == 0x4002);
  428. assert(f.b.f1 == hex"c30000");
  429. }
  430. }
  431. contract other {
  432. struct bar {
  433. bool a;
  434. test_struct_parsing.foo b;
  435. test_struct_parsing.foo c;
  436. }
  437. }"##,
  438. );
  439. runtime.function(
  440. "test",
  441. Bar {
  442. a: true,
  443. b: Foo {
  444. f1: [0xc3, 0x00, 0x00],
  445. f2: 0xff7f,
  446. },
  447. c: Foo {
  448. f1: [0xf7, 0xf6, 0xf5],
  449. f2: 0x4002,
  450. },
  451. }
  452. .encode(),
  453. );
  454. }
  455. #[test]
  456. fn struct_storage_to_memory() {
  457. let mut runtime = build_solidity(
  458. r##"
  459. contract test_struct_parsing {
  460. struct foo {
  461. bytes3 f1;
  462. int64 f2;
  463. }
  464. foo bar;
  465. constructor() public {
  466. bar.f1 = hex"123456";
  467. bar.f2 = 0x0123456789abcdef;
  468. }
  469. function test() public {
  470. foo f = bar;
  471. assert(f.f1 == hex"123456");
  472. assert(f.f2 == 81985529216486895);
  473. }
  474. }"##,
  475. );
  476. runtime.constructor(0, Vec::new());
  477. runtime.function("test", Vec::new());
  478. }
  479. #[test]
  480. fn return_from_struct_storage() {
  481. #[derive(Debug, PartialEq, Encode, Decode)]
  482. struct Foo {
  483. f1: [u8; 3],
  484. f2: u32,
  485. };
  486. let mut runtime = build_solidity(
  487. r##"
  488. struct foo {
  489. bytes3 f1;
  490. uint32 f2;
  491. }
  492. contract test_struct_parsing {
  493. foo bar;
  494. constructor() public {
  495. bar.f1 = "png";
  496. bar.f2 = 0x89abcdef;
  497. }
  498. function test() public returns (foo) {
  499. return bar;
  500. }
  501. }"##,
  502. );
  503. runtime.constructor(0, Vec::new());
  504. runtime.function("test", Vec::new());
  505. assert_eq!(
  506. runtime.vm.scratch,
  507. Foo {
  508. f1: [0x70, 0x6e, 0x67],
  509. f2: 0x89ab_cdef,
  510. }
  511. .encode(),
  512. );
  513. }
  514. #[test]
  515. fn struct_in_init_return() {
  516. #[derive(Debug, PartialEq, Encode, Decode)]
  517. struct Card {
  518. value: u8,
  519. suit: u8,
  520. };
  521. #[derive(Debug, PartialEq, Encode, Decode)]
  522. struct Hand {
  523. card1: Card,
  524. card2: Card,
  525. card3: Card,
  526. card4: Card,
  527. card5: Card,
  528. };
  529. let mut runtime = build_solidity(
  530. r#"
  531. enum suit { club, diamonds, hearts, spades }
  532. enum value { two, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace }
  533. struct card {
  534. value v;
  535. suit s;
  536. }
  537. contract structs {
  538. card card1 = card({ s: suit.hearts, v: value.two });
  539. card card2 = card({ s: suit.diamonds, v: value.three });
  540. card card3 = card({ s: suit.club, v: value.four });
  541. card card4 = card({ s: suit.diamonds, v: value.ten });
  542. card card5 = card({ s: suit.hearts, v: value.jack });
  543. function test() public {
  544. assert(card1.s == suit.hearts);
  545. assert(card1.v == value.two);
  546. assert(card2.s == suit.diamonds);
  547. assert(card2.v == value.three);
  548. assert(card3.s == suit.club);
  549. assert(card3.v == value.four);
  550. assert(card4.s == suit.diamonds);
  551. assert(card4.v == value.ten);
  552. assert(card5.s == suit.hearts);
  553. assert(card5.v == value.jack);
  554. }
  555. }"#,
  556. );
  557. runtime.constructor(0, Vec::new());
  558. runtime.function("test", Vec::new());
  559. }
  560. #[test]
  561. fn struct_struct_in_init_and_return() {
  562. #[derive(Debug, PartialEq, Encode, Decode)]
  563. struct Card {
  564. v: u8,
  565. s: u8,
  566. };
  567. #[derive(Debug, PartialEq, Encode, Decode)]
  568. struct Hand {
  569. card1: Card,
  570. card2: Card,
  571. card3: Card,
  572. card4: Card,
  573. card5: Card,
  574. };
  575. let mut runtime = build_solidity(
  576. r#"
  577. contract structs {
  578. enum suit { club, diamonds, hearts, spades }
  579. enum value { two, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace }
  580. struct card {
  581. value v;
  582. suit s;
  583. }
  584. struct hand {
  585. card card1;
  586. card card2;
  587. card card3;
  588. card card4;
  589. card card5;
  590. }
  591. hand h = hand({
  592. card1: card({ s: suit.hearts, v: value.two }),
  593. card2: card({ s: suit.diamonds, v: value.three }),
  594. card3: card({ s: suit.club, v: value.four }),
  595. card4: card({ s: suit.diamonds, v: value.ten }),
  596. card5: card({ s: suit.hearts, v: value.jack })
  597. });
  598. function return_struct_from_storage(hand storage n) private returns (hand) {
  599. return n;
  600. }
  601. function test() public {
  602. hand l = return_struct_from_storage(h);
  603. assert(l.card1.s == suit.hearts);
  604. assert(l.card1.v == value.two);
  605. assert(l.card2.s == suit.diamonds);
  606. assert(l.card2.v == value.three);
  607. assert(l.card3.s == suit.club);
  608. assert(l.card3.v == value.four);
  609. assert(l.card4.s == suit.diamonds);
  610. assert(l.card4.v == value.ten);
  611. assert(l.card5.s == suit.hearts);
  612. assert(l.card5.v == value.jack);
  613. }
  614. }
  615. "#,
  616. );
  617. runtime.constructor(0, Vec::new());
  618. runtime.function("test", Vec::new());
  619. }