@theqrl/hypc 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +361 -0
  3. package/abi.js +80 -0
  4. package/bindings/compile.js +157 -0
  5. package/bindings/core.js +116 -0
  6. package/bindings/helpers.js +35 -0
  7. package/bindings/index.js +16 -0
  8. package/build/clean.js +6 -0
  9. package/build/pack-publish-block.js +10 -0
  10. package/build/postbuild.js +3 -0
  11. package/common/helpers.js +24 -0
  12. package/common/types.js +2 -0
  13. package/contractA_hyp_A.bin +1 -0
  14. package/contractB_hyp_B.bin +1 -0
  15. package/downloadCurrentVersion.js +93 -0
  16. package/formatters.js +17 -0
  17. package/hypc.js +259 -0
  18. package/hypjson.js +1733 -0
  19. package/importA_hyp_C.bin +1 -0
  20. package/importB_hyp_D.bin +1 -0
  21. package/index.js +7 -0
  22. package/libX_hyp_X.bin +1 -0
  23. package/libY_hyp_Y.bin +1 -0
  24. package/libZ_hyp_Z.bin +1 -0
  25. package/linker.js +156 -0
  26. package/package.json +74 -0
  27. package/smtchecker.js +39 -0
  28. package/smtsolver.js +89 -0
  29. package/test/abi.js +77 -0
  30. package/test/cli.js +245 -0
  31. package/test/compiler.js +791 -0
  32. package/test/index.js +36 -0
  33. package/test/linker.js +132 -0
  34. package/test/resources/fixtureAsmJson.hyp +8 -0
  35. package/test/resources/fixtureAsmJson.json +528 -0
  36. package/test/resources/fixtureAsmJson.output +101 -0
  37. package/test/resources/fixtureIncorrectSource.hyp +1 -0
  38. package/test/resources/fixtureSmoke.hyp +5 -0
  39. package/test/resources/importA.hyp +7 -0
  40. package/test/resources/importB.hyp +5 -0
  41. package/test/resources/importCallback/base/contractA.hyp +8 -0
  42. package/test/resources/importCallback/base/contractB.hyp +6 -0
  43. package/test/resources/importCallback/contractC.hyp +4 -0
  44. package/test/resources/importCallback/includeA/libX.hyp +4 -0
  45. package/test/resources/importCallback/includeA/libY.hyp +6 -0
  46. package/test/resources/importCallback/includeA/utils.hyp +4 -0
  47. package/test/resources/importCallback/includeB/libZ.hyp +4 -0
  48. package/test/resources/smtChecker/loop.hyp +8 -0
  49. package/test/resources/smtChecker/smoke.hyp +5 -0
  50. package/test/resources/smtChecker/smoke_with_engine.hyp +6 -0
  51. package/test/resources/smtChecker/smoke_with_multi_engine.hyp +8 -0
  52. package/test/smtcallback.js +221 -0
  53. package/test/smtchecker.js +83 -0
  54. package/test/translate.js +83 -0
  55. package/test_resources_fixtureSmoke_hyp_C.abi +1 -0
  56. package/test_resources_fixtureSmoke_hyp_C.bin +1 -0
  57. package/test_resources_importA_hyp_C.bin +1 -0
  58. package/test_resources_importB_hyp_D.bin +1 -0
  59. package/translate.js +186 -0
  60. package/tsconfig.json +25 -0
  61. package/utils_hyp_Utils.bin +1 -0
  62. package/verifyVersion.js +43 -0
  63. package/wrapper.js +143 -0
@@ -0,0 +1 @@
1
+ 6080604052348015600e575f80fd5b5060ab8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306044565b604051603b9190605e565b60405180910390f35b5f90565b5f819050919050565b6058816048565b82525050565b5f602082019050606f5f8301846051565b9291505056fea264697066735822122003aa2795a073c7ca2063308c3a8a13fb3a1ce6028c399f889636bd9eabe1f73f6468797063430000020033
@@ -0,0 +1 @@
1
+ 6080604052348015600e575f80fd5b5060ab8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c806326121ff014602a575b5f80fd5b60306044565b604051603b9190605e565b60405180910390f35b5f90565b5f819050919050565b6058816048565b82525050565b5f602082019050606f5f8301846051565b9291505056fea2646970667358221220f96d6c685f4fe201ee93ca17a8b69d8182984a86c16908f46d7becc54efcfb846468797063430000020033
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const wrapper_1 = __importDefault(require("./wrapper"));
6
+ const hypjson = require('./hypjson.js');
7
+ module.exports = (0, wrapper_1.default)(hypjson);
package/libX_hyp_X.bin ADDED
@@ -0,0 +1 @@
1
+ 6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220e78306f3d7dc80c45acbd51f639ead3e6f620f10144ea624b2c7e88c6c1504e96468797063430000020033
package/libY_hyp_Y.bin ADDED
@@ -0,0 +1 @@
1
+ 6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea2646970667358221220fe2cbe5e62e395650d519ac764d3d5271e9af30d3e271d1c291677812e14d7ce6468797063430000020033
package/libZ_hyp_Z.bin ADDED
@@ -0,0 +1 @@
1
+ 6055604b600b8282823980515f1a607314603f577f4e487b71000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b305f52607381538281f3fe730000000000000000000000000000000000000000301460806040525f80fdfea26469706673582212208cf9773d6268fc017aed7c3282d7e4ec482fd3b5d956250412103e5d65854bfc6468797063430000020033
package/linker.js ADDED
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const assert_1 = __importDefault(require("assert"));
6
+ const js_sha3_1 = require("js-sha3");
7
+ const helpers_1 = require("./common/helpers");
8
+ /**
9
+ * Generates a new-style library placeholder from a fully-qualified library name.
10
+ *
11
+ * Newer versions of the compiler use hashed names instead of just truncating the name
12
+ * before putting it in a placeholder.
13
+ *
14
+ * @param fullyQualifiedLibraryName Fully qualified library name.
15
+ */
16
+ function libraryHashPlaceholder(fullyQualifiedLibraryName) {
17
+ return `$${(0, js_sha3_1.keccak256)(fullyQualifiedLibraryName).slice(0, 34)}$`;
18
+ }
19
+ /**
20
+ * Finds all placeholders corresponding to the specified library label and replaces them
21
+ * with a concrete address. Works with both hex-encoded and binary bytecode as long as
22
+ * the address is in the same format.
23
+ *
24
+ * @param bytecode Bytecode string.
25
+ *
26
+ * @param label Library label, either old- or new-style. Must exactly match the part between `__` markers in the
27
+ * placeholders. Will be padded with `_` characters if too short or truncated if too long.
28
+ *
29
+ * @param address Address to replace placeholders with. Must be the right length.
30
+ * It will **not** be padded with zeros if too short.
31
+ */
32
+ function replacePlaceholder(bytecode, label, address) {
33
+ // truncate to 36 characters
34
+ const truncatedName = label.slice(0, 36);
35
+ const libLabel = `__${truncatedName.padEnd(36, '_')}__`;
36
+ while (bytecode.indexOf(libLabel) >= 0) {
37
+ bytecode = bytecode.replace(libLabel, address);
38
+ }
39
+ return bytecode;
40
+ }
41
+ /**
42
+ * Finds and all library placeholders in the provided bytecode and replaces them with actual addresses.
43
+ * Supports both old- and new-style placeholders (even both in the same file).
44
+ * See [Library Linking](https://docs.soliditylang.org/en/latest/using-the-compiler.html#library-linking)
45
+ * for a full explanation of the linking process.
46
+ *
47
+ * Example of a legacy placeholder: `__lib.hyp:L_____________________________`
48
+ * Example of a new-style placeholder: `__$7484607a72fb0587588e5a1e608f0b16de$__`
49
+ *
50
+ * @param bytecode Hex-encoded bytecode string. All 40-byte substrings starting and ending with
51
+ * `__` will be interpreted as placeholders.
52
+ *
53
+ * @param libraries Mapping between fully qualified library names and the hex-encoded
54
+ * addresses they should be replaced with. Addresses shorter than 40 characters are automatically padded with zeros.
55
+ *
56
+ * @returns bytecode Hex-encoded bytecode string with placeholders replaced with addresses.
57
+ * Note that some placeholders may remain in the bytecode if `libraries` does not provide addresses for all of them.
58
+ */
59
+ function linkBytecode(bytecode, libraries) {
60
+ (0, assert_1.default)(typeof bytecode === 'string');
61
+ (0, assert_1.default)(typeof libraries === 'object');
62
+ // NOTE: for backwards compatibility support old compiler which didn't use file names
63
+ const librariesComplete = {};
64
+ for (const [fullyQualifiedLibraryName, libraryObjectOrAddress] of Object.entries(libraries)) {
65
+ if ((0, helpers_1.isNil)(libraryObjectOrAddress)) {
66
+ throw new Error(`No address provided for library ${fullyQualifiedLibraryName}`);
67
+ }
68
+ // API compatible with the standard JSON i/o
69
+ // {"lib.hyp": {"L": "Z..."}}
70
+ if ((0, helpers_1.isObject)(libraryObjectOrAddress)) {
71
+ for (const [unqualifiedLibraryName, address] of Object.entries(libraryObjectOrAddress)) {
72
+ librariesComplete[unqualifiedLibraryName] = address;
73
+ librariesComplete[`${fullyQualifiedLibraryName}:${unqualifiedLibraryName}`] = address;
74
+ }
75
+ continue;
76
+ }
77
+ // backwards compatible API for early hypc-js versions
78
+ const parsed = fullyQualifiedLibraryName.match(/^(?<sourceUnitName>[^:]+):(?<unqualifiedLibraryName>.+)$/);
79
+ const libraryAddress = libraryObjectOrAddress;
80
+ if (!(0, helpers_1.isNil)(parsed)) {
81
+ const { unqualifiedLibraryName } = parsed.groups;
82
+ librariesComplete[unqualifiedLibraryName] = libraryAddress;
83
+ }
84
+ librariesComplete[fullyQualifiedLibraryName] = libraryAddress;
85
+ }
86
+ for (const libraryName in librariesComplete) {
87
+ let hexAddress = librariesComplete[libraryName];
88
+ if (!hexAddress.startsWith('Z') || hexAddress.length > 41) {
89
+ throw new Error(`Invalid address specified for ${libraryName}`);
90
+ }
91
+ // remove 0x prefix
92
+ hexAddress = hexAddress.slice(1).padStart(40, '0');
93
+ bytecode = replacePlaceholder(bytecode, libraryName, hexAddress);
94
+ bytecode = replacePlaceholder(bytecode, libraryHashPlaceholder(libraryName), hexAddress);
95
+ }
96
+ return bytecode;
97
+ }
98
+ /**
99
+ * Finds locations of all library address placeholders in the hex-encoded bytecode.
100
+ * Returns information in a format matching `zvm.bytecode.linkReferences` output
101
+ * in Standard JSON.
102
+ *
103
+ * See [Library Linking](https://docs.soliditylang.org/en/latest/using-the-compiler.html#library-linking)
104
+ * for a full explanation of library placeholders and linking process.
105
+ *
106
+ * WARNING: The output matches `zvm.bytecode.linkReferences` exactly only in
107
+ * case of old-style placeholders created from fully qualified library names
108
+ * of no more than 36 characters, and even then only if the name does not start
109
+ * or end with an underscore. This is different from
110
+ * `zvm.bytecode.linkReferences`, which uses fully qualified library names.
111
+ * This is a limitation of the placeholder format - the fully qualified names
112
+ * are not preserved in the compiled bytecode and cannot be reconstructed
113
+ * without external information.
114
+ *
115
+ * @param bytecode Hex-encoded bytecode string.
116
+ *
117
+ * @returns linkReferences A mapping between library labels and their locations
118
+ * in the bytecode. In case of old-style placeholders the label is a fully
119
+ * qualified library name truncated to 36 characters. For new-style placeholders
120
+ * it's the first 34 characters of the hex-encoded hash of the fully qualified
121
+ * library name, with a leading and trailing $ character added. Note that the
122
+ * offsets and lengths refer to the *binary* (not hex-encoded) bytecode, just
123
+ * like in `zvm.bytecode.linkReferences`.
124
+ */
125
+ function findLinkReferences(bytecode) {
126
+ (0, assert_1.default)(typeof bytecode === 'string');
127
+ // find 40 bytes in the pattern of __...<36 digits>...__
128
+ // e.g. __Lib.hyp:L_____________________________
129
+ const linkReferences = {};
130
+ let offset = 0;
131
+ while (true) {
132
+ const found = bytecode.match(/__(.{36})__/);
133
+ if (!found) {
134
+ break;
135
+ }
136
+ const start = found.index;
137
+ // trim trailing underscores
138
+ // NOTE: this has no way of knowing if the trailing underscore was part of the name
139
+ const libraryName = found[1].replace(/_+$/gm, '');
140
+ if (!linkReferences[libraryName]) {
141
+ linkReferences[libraryName] = [];
142
+ }
143
+ // offsets are in bytes in binary representation (and not hex)
144
+ linkReferences[libraryName].push({
145
+ start: (offset + start) / 2,
146
+ length: 20
147
+ });
148
+ offset += start + 20;
149
+ bytecode = bytecode.slice(start + 20);
150
+ }
151
+ return linkReferences;
152
+ }
153
+ module.exports = {
154
+ linkBytecode,
155
+ findLinkReferences
156
+ };
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@theqrl/hypc",
3
+ "version": "0.0.2",
4
+ "description": "Hyperion compiler",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "hypcjs": "hypc.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "postbuild": "node build/postbuild.js && cp README.md LICENSE dist/",
12
+ "lint": "eslint --ext .js,.ts .",
13
+ "lint:fix": "eslint --fix --ext .js,.ts .",
14
+ "updateBinary": "node build/clean.js && ts-node ./downloadCurrentVersion.ts && ts-node ./verifyVersion.ts",
15
+ "prepack": "node build/pack-publish-block.js",
16
+ "build:tarball": "npm run updateBinary && npm run build && BYPASS_SAFETY_CHECK=true npm pack ./dist",
17
+ "publish:tarball": "tarball=$(npm run --silent tarballName) && ls \"$tarball\" && BYPASS_SAFETY_CHECK=true npm publish --access public \"$tarball\"",
18
+ "tarballName": "jq --raw-output '.name + \"-\" + .version + \".tgz\"' package.json",
19
+ "copyTestFiles": "cp -r ./test/resources ./dist/test/",
20
+ "pretest": "npm run lint && npm run build && npm run copyTestFiles",
21
+ "test": "cd dist && tape ./test/index.js",
22
+ "coverage": "nyc npm run test",
23
+ "coveralls": "npm run coverage && coveralls <coverage/lcov.info"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/theQRL/hypc-js.git"
28
+ },
29
+ "keywords": [
30
+ "zond",
31
+ "hyperion",
32
+ "compiler"
33
+ ],
34
+ "author": "",
35
+ "license": "MIT",
36
+ "bugs": {
37
+ "url": "https://github.com/theQRL/hypc-js/issues"
38
+ },
39
+ "homepage": "https://github.com/theQRL/hypc-js#readme",
40
+ "dependencies": {
41
+ "command-exists": "^1.2.8",
42
+ "commander": "^8.1.0",
43
+ "follow-redirects": "^1.12.1",
44
+ "js-sha3": "0.8.0",
45
+ "memorystream": "^0.3.1",
46
+ "semver": "^5.5.0",
47
+ "tmp": "0.0.33"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^16.11.7",
51
+ "@types/semver": "^7.3.9",
52
+ "@types/tape": "^4.13.2",
53
+ "@types/tmp": "^0.2.3",
54
+ "@typescript-eslint/eslint-plugin": "^5.8.0",
55
+ "@typescript-eslint/parser": "^5.8.0",
56
+ "coveralls": "^3.0.0",
57
+ "eslint": "^7.32.0",
58
+ "eslint-config-standard": "^16.0.3",
59
+ "eslint-plugin-import": "^2.25.3",
60
+ "eslint-plugin-node": "^11.1.0",
61
+ "eslint-plugin-promise": "^5.1.1",
62
+ "nyc": "^15.1.0",
63
+ "tape": "^4.11.0",
64
+ "tape-spawn": "^1.4.2",
65
+ "ts-node": "^10.4.0",
66
+ "typescript": "^4.5.4"
67
+ },
68
+ "nyc": {
69
+ "exclude": [
70
+ "hypjson.js",
71
+ "dist"
72
+ ]
73
+ }
74
+ }
package/smtchecker.js ADDED
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ // This function checks the standard JSON output for auxiliaryInputRequested,
3
+ // where smtlib2queries represent the queries created by the SMTChecker.
4
+ // The function runs an SMT solver on each query and adjusts the input for
5
+ // another run.
6
+ // Returns null if no solving is requested.
7
+ function handleSMTQueries(inputJSON, outputJSON, solverFunction, solver) {
8
+ const auxInputReq = outputJSON.auxiliaryInputRequested;
9
+ if (!auxInputReq) {
10
+ return null;
11
+ }
12
+ const queries = auxInputReq.smtlib2queries;
13
+ if (!queries || Object.keys(queries).length === 0) {
14
+ return null;
15
+ }
16
+ const responses = {};
17
+ for (const query in queries) {
18
+ responses[query] = solverFunction(queries[query], solver);
19
+ }
20
+ // Note: all existing solved queries are replaced.
21
+ // This assumes that all necessary queries are quested above.
22
+ inputJSON.auxiliaryInput = { smtlib2responses: responses };
23
+ return inputJSON;
24
+ }
25
+ function smtCallback(solverFunction, solver) {
26
+ return function (query) {
27
+ try {
28
+ const result = solverFunction(query, solver);
29
+ return { contents: result };
30
+ }
31
+ catch (err) {
32
+ return { error: err };
33
+ }
34
+ };
35
+ }
36
+ module.exports = {
37
+ handleSMTQueries,
38
+ smtCallback
39
+ };
package/smtsolver.js ADDED
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ const command_exists_1 = require("command-exists");
26
+ const child_process_1 = require("child_process");
27
+ const fs = __importStar(require("fs"));
28
+ const tmp = __importStar(require("tmp"));
29
+ // Timeout in ms.
30
+ const timeout = 10000;
31
+ const potentialSolvers = [
32
+ {
33
+ name: 'z3',
34
+ command: 'z3',
35
+ params: '-smt2 rlimit=20000000 rewriter.pull_cheap_ite=true fp.spacer.q3.use_qgen=true fp.spacer.mbqi=false fp.spacer.ground_pobs=false'
36
+ },
37
+ {
38
+ name: 'Eldarica',
39
+ command: 'eld',
40
+ params: '-horn -t:' + (timeout / 1000) // Eldarica takes timeout in seconds.
41
+ },
42
+ {
43
+ name: 'cvc4',
44
+ command: 'cvc4',
45
+ params: '--lang=smt2 --tlimit=' + timeout
46
+ }
47
+ ];
48
+ const solvers = potentialSolvers.filter(solver => (0, command_exists_1.sync)(solver.command));
49
+ function solve(query, solver) {
50
+ if (solver === undefined) {
51
+ if (solvers.length === 0) {
52
+ throw new Error('No SMT solver available. Assertion checking will not be performed.');
53
+ }
54
+ else {
55
+ solver = solvers[0];
56
+ }
57
+ }
58
+ const tmpFile = tmp.fileSync({ postfix: '.smt2' });
59
+ fs.writeFileSync(tmpFile.name, query);
60
+ let solverOutput;
61
+ try {
62
+ solverOutput = (0, child_process_1.execSync)(solver.command + ' ' + solver.params + ' ' + tmpFile.name, {
63
+ encoding: 'utf8',
64
+ maxBuffer: 1024 * 1024 * 1024,
65
+ stdio: 'pipe',
66
+ timeout: timeout // Enforce timeout on the process, since solvers can sometimes go around it.
67
+ }).toString();
68
+ }
69
+ catch (e) {
70
+ // execSync throws if the process times out or returns != 0.
71
+ // The latter might happen with z3 if the query asks for a model
72
+ // for an UNSAT formula. We can still use stdout.
73
+ solverOutput = e.stdout.toString();
74
+ if (!solverOutput.startsWith('sat') &&
75
+ !solverOutput.startsWith('unsat') &&
76
+ !solverOutput.startsWith('unknown') &&
77
+ !solverOutput.startsWith('(error') && // Eldarica reports errors in an sexpr, for example: '(error "Failed to reconstruct array model")'
78
+ !solverOutput.startsWith('error')) {
79
+ throw new Error('Failed to solve SMT query. ' + e.toString());
80
+ }
81
+ }
82
+ // Trigger early manual cleanup
83
+ tmpFile.removeCallback();
84
+ return solverOutput;
85
+ }
86
+ module.exports = {
87
+ smtSolver: solve,
88
+ availableSolvers: solvers
89
+ };
package/test/abi.js ADDED
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const tape_1 = __importDefault(require("tape"));
7
+ const abi_1 = __importDefault(require("../abi"));
8
+ (0, tape_1.default)('ABI translator', function (t) {
9
+ t.test('Empty ABI', function (st) {
10
+ st.deepEqual(abi_1.default.update('0.4.0', []), []);
11
+ st.end();
12
+ });
13
+ t.test('0.1.1 (no constructor)', function (st) {
14
+ st.deepEqual(abi_1.default.update('0.1.1', []), [{ inputs: [], payable: true, stateMutability: 'payable', type: 'constructor' }, { payable: true, stateMutability: 'payable', type: 'fallback' }]);
15
+ st.end();
16
+ });
17
+ t.test('0.3.6 (constructor)', function (st) {
18
+ const input = [{ inputs: [], type: 'constructor' }];
19
+ st.deepEqual(abi_1.default.update('0.3.6', input), [{ inputs: [], payable: true, stateMutability: 'payable', type: 'constructor' }, { payable: true, stateMutability: 'payable', type: 'fallback' }]);
20
+ st.end();
21
+ });
22
+ t.test('0.3.6 (non-constant function)', function (st) {
23
+ const input = [{ inputs: [], type: 'function' }];
24
+ st.deepEqual(abi_1.default.update('0.3.6', input), [{ inputs: [], payable: true, stateMutability: 'payable', type: 'function' }, { payable: true, stateMutability: 'payable', type: 'fallback' }]);
25
+ st.end();
26
+ });
27
+ t.test('0.3.6 (constant function)', function (st) {
28
+ const input = [{ inputs: [], type: 'function', constant: true }];
29
+ st.deepEqual(abi_1.default.update('0.3.6', input), [{ inputs: [], constant: true, stateMutability: 'view', type: 'function' }, { payable: true, stateMutability: 'payable', type: 'fallback' }]);
30
+ st.end();
31
+ });
32
+ t.test('0.3.6 (event)', function (st) {
33
+ const input = [{ inputs: [], type: 'event' }];
34
+ st.deepEqual(abi_1.default.update('0.3.6', input), [{ inputs: [], type: 'event' }, { payable: true, stateMutability: 'payable', type: 'fallback' }]);
35
+ st.end();
36
+ });
37
+ t.test('0.3.6 (has no fallback)', function (st) {
38
+ const input = [{ inputs: [], type: 'constructor' }];
39
+ st.deepEqual(abi_1.default.update('0.3.6', input), [{ inputs: [], type: 'constructor', payable: true, stateMutability: 'payable' }, { type: 'fallback', payable: true, stateMutability: 'payable' }]);
40
+ st.end();
41
+ });
42
+ t.test('0.4.0 (has fallback)', function (st) {
43
+ const input = [{ inputs: [], type: 'constructor' }, { type: 'fallback' }];
44
+ st.deepEqual(abi_1.default.update('0.4.0', input), [{ inputs: [], type: 'constructor', payable: true, stateMutability: 'payable' }, { type: 'fallback', stateMutability: 'nonpayable' }]);
45
+ st.end();
46
+ });
47
+ t.test('0.4.0 (non-constant function)', function (st) {
48
+ const input = [{ inputs: [], type: 'function' }];
49
+ st.deepEqual(abi_1.default.update('0.4.0', input), [{ inputs: [], stateMutability: 'nonpayable', type: 'function' }]);
50
+ st.end();
51
+ });
52
+ t.test('0.4.0 (constant function)', function (st) {
53
+ const input = [{ inputs: [], type: 'function', constant: true }];
54
+ st.deepEqual(abi_1.default.update('0.4.0', input), [{ inputs: [], constant: true, stateMutability: 'view', type: 'function' }]);
55
+ st.end();
56
+ });
57
+ t.test('0.4.0 (payable function)', function (st) {
58
+ const input = [{ inputs: [], payable: true, type: 'function' }];
59
+ st.deepEqual(abi_1.default.update('0.4.0', input), [{ inputs: [], payable: true, stateMutability: 'payable', type: 'function' }]);
60
+ st.end();
61
+ });
62
+ t.test('0.4.1 (constructor not payable)', function (st) {
63
+ const input = [{ inputs: [], payable: false, type: 'constructor' }];
64
+ st.deepEqual(abi_1.default.update('0.4.1', input), [{ inputs: [], payable: true, stateMutability: 'payable', type: 'constructor' }]);
65
+ st.end();
66
+ });
67
+ t.test('0.4.5 (constructor payable)', function (st) {
68
+ const input = [{ inputs: [], payable: false, type: 'constructor' }];
69
+ st.deepEqual(abi_1.default.update('0.4.5', input), [{ inputs: [], payable: false, stateMutability: 'nonpayable', type: 'constructor' }]);
70
+ st.end();
71
+ });
72
+ t.test('0.4.16 (statemutability)', function (st) {
73
+ const input = [{ inputs: [], payable: false, stateMutability: 'pure', type: 'function' }];
74
+ st.deepEqual(abi_1.default.update('0.4.16', input), [{ inputs: [], payable: false, stateMutability: 'pure', type: 'function' }]);
75
+ st.end();
76
+ });
77
+ });