contracts.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::build_solidity;
  3. use parity_scale_codec::{Decode, Encode};
  4. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  5. struct RevertReturn(u32, String);
  6. #[test]
  7. fn external_call() {
  8. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  9. struct Ret(u32);
  10. let mut runtime = build_solidity(
  11. r##"
  12. contract c {
  13. b x;
  14. constructor() public {
  15. x = new b(102);
  16. }
  17. function test() public returns (int32) {
  18. return x.get_x({ t: 10 });
  19. }
  20. }
  21. contract b {
  22. int32 x;
  23. constructor(int32 a) public {
  24. x = a;
  25. }
  26. function get_x(int32 t) public returns (int32) {
  27. return x * t;
  28. }
  29. }"##,
  30. );
  31. runtime.constructor(0, Vec::new());
  32. runtime.function("test", Vec::new());
  33. assert_eq!(runtime.output(), Ret(1020).encode());
  34. }
  35. #[test]
  36. fn revert_external_call() {
  37. let mut runtime = build_solidity(
  38. r#"
  39. contract c {
  40. b x;
  41. constructor() public {
  42. x = new b(102);
  43. }
  44. function test() public returns (int32) {
  45. return x.get_x({ t: 10 });
  46. }
  47. }
  48. contract b {
  49. int32 x;
  50. constructor(int32 a) public {
  51. x = a;
  52. }
  53. function get_x(int32 t) public returns (int32) {
  54. revert("The reason why");
  55. }
  56. }"#,
  57. );
  58. runtime.constructor(0, Vec::new());
  59. runtime.function_expect_failure("test", Vec::new());
  60. }
  61. #[test]
  62. fn revert_constructor() {
  63. let mut runtime = build_solidity(
  64. r#"
  65. contract c {
  66. b x;
  67. constructor() public {
  68. }
  69. function test() public returns (int32) {
  70. x = new b(102);
  71. return x.get_x({ t: 10 });
  72. }
  73. }
  74. contract b {
  75. int32 x;
  76. constructor(int32 a) public {
  77. require(a == 0, "Hello,\
  78. World!");
  79. }
  80. function get_x(int32 t) public returns (int32) {
  81. return x * t;
  82. }
  83. }"#,
  84. );
  85. runtime.constructor(0, Vec::new());
  86. runtime.function_expect_failure("test", Vec::new());
  87. }
  88. #[test]
  89. fn external_datatypes() {
  90. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  91. struct Ret(u64);
  92. let mut runtime = build_solidity(
  93. r#"
  94. contract c {
  95. b x;
  96. constructor() public {
  97. x = new b(102);
  98. }
  99. function test() public returns (int64) {
  100. strukt k = x.get_x(10, "foobar", true, strukt({ f1: "abcd", f2: address(555555), f3: -1 }));
  101. assert(k.f1 == "1234");
  102. assert(k.f2 == address(102));
  103. return int64(k.f3);
  104. }
  105. }
  106. contract b {
  107. int x;
  108. constructor(int a) public {
  109. x = a;
  110. }
  111. function get_x(int t, string s, bool y, strukt k) public returns (strukt) {
  112. assert(y == true);
  113. assert(t == 10);
  114. assert(s == "foobar");
  115. assert(k.f1 == "abcd");
  116. return strukt({ f1: "1234", f2: address(102), f3: x * t });
  117. }
  118. }
  119. struct strukt {
  120. bytes4 f1;
  121. address f2;
  122. int f3;
  123. }"#,
  124. );
  125. runtime.constructor(0, Vec::new());
  126. runtime.function("test", Vec::new());
  127. assert_eq!(runtime.output(), Ret(1020).encode());
  128. }
  129. #[test]
  130. fn creation_code() {
  131. let mut runtime = build_solidity(
  132. r##"
  133. contract c {
  134. function test() public returns (bytes) {
  135. bytes runtime = type(b).runtimeCode;
  136. assert(runtime[0] == 0);
  137. assert(runtime[1] == 0x61); // a
  138. assert(runtime[2] == 0x73); // s
  139. assert(runtime[3] == 0x6d); // m
  140. bytes creation = type(b).creationCode;
  141. // on Polkadot, they are the same
  142. assert(creation == runtime);
  143. return creation;
  144. }
  145. }
  146. contract b {
  147. int public x;
  148. constructor(int a) public {
  149. x = a;
  150. }
  151. }"##,
  152. );
  153. runtime.function("test", Vec::new());
  154. assert_eq!(runtime.output(), runtime.contracts()[1].code.blob.encode());
  155. }
  156. #[test]
  157. fn issue666() {
  158. let mut runtime = build_solidity(
  159. r#"
  160. contract Flipper {
  161. function flip () pure public {
  162. print("flip");
  163. }
  164. }
  165. contract Inc {
  166. Flipper _flipper;
  167. constructor (Flipper _flipperContract) {
  168. _flipper = _flipperContract;
  169. }
  170. function superFlip () pure public {
  171. _flipper.flip();
  172. }
  173. }"#,
  174. );
  175. runtime.constructor(0, Vec::new());
  176. let flipper_address = runtime.caller();
  177. println!("flipper_address={}", hex::encode(flipper_address));
  178. runtime.set_account(1);
  179. runtime.constructor(0, flipper_address.to_vec());
  180. runtime.function("superFlip", Vec::new());
  181. assert!(runtime.output().is_empty());
  182. }
  183. #[test]
  184. fn mangle_function_names_in_abi() {
  185. let runtime = build_solidity(
  186. r##"
  187. enum E { v1, v2 }
  188. struct S { int256 i; bool b; address a; }
  189. contract C {
  190. // foo_
  191. function foo() public pure {}
  192. // foo_uint256_addressArray2Array
  193. function foo(uint256 i, address[2][] memory a) public pure {}
  194. // foo_uint8Array2__int256_bool_address
  195. function foo(E[2] memory e, S memory s) public pure {}
  196. }"##,
  197. );
  198. let _ = runtime.contracts()[0].code.messages["foo_"];
  199. let _ = runtime.contracts()[0].code.messages["foo_uint256_addressArray2Array"];
  200. let _ = runtime.contracts()[0].code.messages["foo_uint8Array2__int256_bool_address"];
  201. assert!(runtime.contracts()[0].code.messages.get("foo").is_none());
  202. }
  203. #[test]
  204. fn mangle_overloaded_function_names_in_abi() {
  205. let runtime = build_solidity(
  206. r##"
  207. contract A {
  208. function foo(bool x) public {}
  209. }
  210. contract B is A {
  211. function foo(int x) public {}
  212. }"##,
  213. );
  214. let _ = runtime.contracts()[0].code.messages["foo"];
  215. assert!(runtime.contracts()[0]
  216. .code
  217. .messages
  218. .get("foo_bool")
  219. .is_none());
  220. let _ = runtime.contracts()[1].code.messages["foo_bool"];
  221. assert!(runtime.contracts()[1].code.messages.get("foo").is_none());
  222. }