contracts.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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. assert_eq!(runtime.output().len(), 0);
  88. }
  89. #[test]
  90. fn external_datatypes() {
  91. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  92. struct Ret(u64);
  93. let mut runtime = build_solidity(
  94. r##"
  95. contract c {
  96. b x;
  97. constructor() public {
  98. x = new b(102);
  99. }
  100. function test() public returns (int64) {
  101. strukt k = x.get_x(10, "foobar", true, strukt({ f1: "abcd", f2: address(555555), f3: -1 }));
  102. assert(k.f1 == "1234");
  103. assert(k.f2 == address(102));
  104. return int64(k.f3);
  105. }
  106. }
  107. contract b {
  108. int x;
  109. constructor(int a) public {
  110. x = a;
  111. }
  112. function get_x(int t, string s, bool y, strukt k) public returns (strukt) {
  113. assert(y == true);
  114. assert(t == 10);
  115. assert(s == "foobar");
  116. assert(k.f1 == "abcd");
  117. return strukt({ f1: "1234", f2: address(102), f3: x * t });
  118. }
  119. }
  120. struct strukt {
  121. bytes4 f1;
  122. address f2;
  123. int f3;
  124. }"##,
  125. );
  126. runtime.constructor(0, Vec::new());
  127. runtime.function("test", Vec::new());
  128. assert_eq!(runtime.output(), Ret(1020).encode());
  129. }
  130. #[test]
  131. fn creation_code() {
  132. let mut runtime = build_solidity(
  133. r##"
  134. contract c {
  135. function test() public returns (bytes) {
  136. bytes runtime = type(b).runtimeCode;
  137. assert(runtime[0] == 0);
  138. assert(runtime[1] == 0x61); // a
  139. assert(runtime[2] == 0x73); // s
  140. assert(runtime[3] == 0x6d); // m
  141. bytes creation = type(b).creationCode;
  142. // on Substrate, they are the same
  143. assert(creation == runtime);
  144. return creation;
  145. }
  146. }
  147. contract b {
  148. int public x;
  149. constructor(int a) public {
  150. x = a;
  151. }
  152. }"##,
  153. );
  154. runtime.function("test", Vec::new());
  155. assert_eq!(runtime.output(), runtime.contracts()[1].code.blob.encode());
  156. }
  157. #[test]
  158. fn issue666() {
  159. let mut runtime = build_solidity(
  160. r##"
  161. contract Flipper {
  162. function flip () pure public {
  163. print("flip");
  164. }
  165. }
  166. contract Inc {
  167. Flipper _flipper;
  168. constructor (Flipper _flipperContract) {
  169. _flipper = _flipperContract;
  170. }
  171. function superFlip () pure public {
  172. _flipper.flip();
  173. }
  174. }"##,
  175. );
  176. runtime.constructor(0, Vec::new());
  177. let flipper_address = runtime.caller();
  178. println!("flipper_address={}", hex::encode(flipper_address));
  179. runtime.set_account(1);
  180. runtime.constructor(0, flipper_address.to_vec());
  181. runtime.function("superFlip", Vec::new());
  182. assert!(runtime.output().is_empty());
  183. }
  184. #[test]
  185. fn mangle_function_names_in_abi() {
  186. let runtime = build_solidity(
  187. r##"
  188. enum E { v1, v2 }
  189. struct S { int256 i; bool b; address a; }
  190. contract C {
  191. // foo_
  192. function foo() public pure {}
  193. // foo_uint256_addressArray2Array
  194. function foo(uint256 i, address[2][] memory a) public pure {}
  195. // foo_uint8Array2__int256_bool_address
  196. function foo(E[2] memory e, S memory s) public pure {}
  197. }"##,
  198. );
  199. let _ = runtime.contracts()[0].code.messages["foo_"];
  200. let _ = runtime.contracts()[0].code.messages["foo_uint256_addressArray2Array"];
  201. let _ = runtime.contracts()[0].code.messages["foo_uint8Array2__int256_bool_address"];
  202. assert!(runtime.contracts()[0].code.messages.get("foo").is_none());
  203. }
  204. #[test]
  205. fn mangle_overloaded_function_names_in_abi() {
  206. let runtime = build_solidity(
  207. r##"
  208. contract A {
  209. function foo(bool x) public {}
  210. }
  211. contract B is A {
  212. function foo(int x) public {}
  213. }"##,
  214. );
  215. let _ = runtime.contracts()[0].code.messages["foo"];
  216. assert!(runtime.contracts()[0]
  217. .code
  218. .messages
  219. .get("foo_bool")
  220. .is_none());
  221. let _ = runtime.contracts()[1].code.messages["foo_bool"];
  222. assert!(runtime.contracts()[1].code.messages.get("foo").is_none());
  223. }