contracts.rs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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.vm.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.vm.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.vm.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.constructor(0, Vec::new());
  155. runtime.function("test", Vec::new());
  156. #[derive(Debug, PartialEq, Eq, Encode, Decode)]
  157. struct Ret(Vec<u8>);
  158. // return value should be the code for the second contract
  159. assert_eq!(
  160. runtime.vm.output,
  161. Ret(runtime.programs[1].code.clone()).encode()
  162. );
  163. }
  164. #[test]
  165. fn issue666() {
  166. let mut runtime = build_solidity(
  167. r##"
  168. contract Flipper {
  169. function flip () pure public {
  170. print("flip");
  171. }
  172. }
  173. contract Inc {
  174. Flipper _flipper;
  175. constructor (Flipper _flipperContract) {
  176. _flipper = _flipperContract;
  177. }
  178. function superFlip () pure public {
  179. _flipper.flip();
  180. }
  181. }"##,
  182. );
  183. runtime.constructor(0, Vec::new());
  184. let flipper_address = runtime.vm.account;
  185. println!("flipper_address={}", hex::encode(flipper_address));
  186. runtime.set_program(1);
  187. runtime.constructor(0, flipper_address.to_vec());
  188. runtime.function("superFlip", Vec::new());
  189. assert!(runtime.vm.output.is_empty());
  190. }
  191. #[test]
  192. fn mangle_function_names_in_abi() {
  193. let runtime = build_solidity(
  194. r##"
  195. enum E { v1, v2 }
  196. struct S { int256 i; bool b; address a; }
  197. contract C {
  198. // foo_
  199. function foo() public pure {}
  200. // foo_uint256_addressArray2Array
  201. function foo(uint256 i, address[2][] memory a) public pure {}
  202. // foo_uint8Array2__int256_bool_address
  203. function foo(E[2] memory e, S memory s) public pure {}
  204. }"##,
  205. );
  206. let messages: Vec<String> = runtime
  207. .programs
  208. .get(0)
  209. .unwrap()
  210. .abi
  211. .spec()
  212. .messages()
  213. .iter()
  214. .map(|m| m.label().clone())
  215. .collect();
  216. assert!(!messages.contains(&"foo".to_string()));
  217. assert!(messages.contains(&"foo_".to_string()));
  218. assert!(messages.contains(&"foo_uint256_addressArray2Array".to_string()));
  219. assert!(messages.contains(&"foo_uint8Array2__int256_bool_address".to_string()));
  220. }
  221. #[test]
  222. fn mangle_overloaded_function_names_in_abi() {
  223. let runtime = build_solidity(
  224. r##"
  225. contract A {
  226. function foo(bool x) public {}
  227. }
  228. contract B is A {
  229. function foo(int x) public {}
  230. }"##,
  231. );
  232. let messages_a: Vec<String> = runtime
  233. .programs
  234. .get(0)
  235. .unwrap()
  236. .abi
  237. .spec()
  238. .messages()
  239. .iter()
  240. .map(|m| m.label().clone())
  241. .collect();
  242. assert!(messages_a.contains(&"foo".to_string()));
  243. assert!(!messages_a.contains(&"foo_bool".to_string()));
  244. let messages_b: Vec<String> = runtime
  245. .programs
  246. .get(1)
  247. .unwrap()
  248. .abi
  249. .spec()
  250. .messages()
  251. .iter()
  252. .map(|m| m.label().clone())
  253. .collect();
  254. assert!(!messages_b.contains(&"foo".to_string()));
  255. assert!(messages_b.contains(&"foo_bool".to_string()));
  256. }