Skip to content

Commit 642714b

Browse files
authored
Merge pull request #6 from tintinweb/fix/remoteCompiler
prep v0.0.7 - better remote compiler handling; new keywords
2 parents adae89c + fe8a283 commit 642714b

File tree

9 files changed

+1017
-841
lines changed

9 files changed

+1017
-841
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
# Change Log
22
All notable changes will be documented in this file.
33

4+
5+
## v0.0.7
6+
- fix: rework remote compiler
7+
- added a remoteCompiler wrapper
8+
- fix: always use latest compiler shipped with this package by default
9+
- new: ship with solc 0.8.10
10+
- preference: use solc shipped with package by default, else check static solcVersions list and fetch remote compiler, else update solcVersions list and fetch remote compiler.
11+
- fix: better error handling when changing compiler version
12+
- new: support `error` keyword and fix memory/storage type declarations
13+
414
## v0.0.6
515
- fix: handle interface declarations
616

package-lock.json

Lines changed: 776 additions & 815 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"name": "solidity-shell",
3-
"version": "0.0.6",
3+
"version": "0.0.7",
44
"description": "",
55
"main": "src/index.js",
66
"bin": {
77
"solidity-shell": "bin/main.js"
88
},
99
"scripts": {
10-
"test": "echo \"Error: no test specified\" && exit 1"
10+
"updateCompilerList": "node scripts/UpdateCompilerList.js > src/solcVersions.js"
1111
},
1212
"author": {
1313
"name": "tintinweb",
@@ -26,7 +26,8 @@
2626
"license": "MIT",
2727
"dependencies": {
2828
"readline-sync": "^1.4.10",
29-
"solc": "^0.8.7-fixed",
29+
"request": "^2.88.2",
30+
"solc": "^0.8.10",
3031
"vorpal": "^1.12.0",
3132
"web3": "^1.5.2"
3233
}

scripts/updateCompilerList.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env node
2+
'use strict'
3+
/**
4+
* @author github.com/tintinweb
5+
* @license MIT
6+
* */
7+
const { getSolcJsCompilerList } = require('../src/remoteCompiler');
8+
9+
10+
getSolcJsCompilerList({nightly:false}).then(compilers => {
11+
console.log(`'use strict'
12+
/**
13+
* @author github.com/tintinweb
14+
* @license MIT
15+
* */
16+
17+
//autogenerated with # npm run updateCompilerList
18+
module.exports.solcVersions = ${JSON.stringify(compilers, null, 4)}`);
19+
})
20+

src/handler.js

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
/** IMPORT */
77
const Web3 = require('web3')
88
const solc = require('solc')
9-
const { solcVersions } = require('./solcVersions.js')
9+
const { getRemoteCompiler } = require('./remoteCompiler.js')
1010

1111
/** CONST */
1212
const rexTypeError = /Return argument type (.*) is not implicitly convertible to expected type \(type of first return variable\)/;
13-
const rexAssign = /[^=]=[^=]/;
13+
const rexAssign = /[^=]=[^=];?/;
14+
const rexTypeDecl = /^([\w\[\]]+\s(memory|storage)?\s*\w+);?$/
1415
const IGNORE_WARNINGS = [
1516
"Statement has no effect.",
1617
"Function state mutability can be restricted to ",
@@ -45,15 +46,19 @@ class SolidityStatement {
4546

4647
constructor(rawCommand, scope) {
4748
this.rawCommand = rawCommand ? rawCommand.trim() : "";
48-
this.hasNoReturnValue = (rexAssign.test(this.rawCommand)) || (this.rawCommand.startsWith('delete')) || (this.rawCommand.startsWith('assembly')) || (this.rawCommand.startsWith('revert'))
49+
this.hasNoReturnValue = (rexAssign.test(this.rawCommand))
50+
|| (this.rawCommand.startsWith('delete'))
51+
|| (this.rawCommand.startsWith('assembly'))
52+
|| (this.rawCommand.startsWith('revert'))
53+
|| (rexTypeDecl.test(this.rawCommand))
4954

5055
if (scope) {
5156
this.scope = scope
5257
} else {
5358
if (this.rawCommand.startsWith('function ') || this.rawCommand.startsWith('modifier ')) {
5459
this.scope = SCOPE.CONTRACT;
5560
this.hasNoReturnValue = true;
56-
} else if (this.rawCommand.startsWith('mapping ') || this.rawCommand.startsWith('event ')) {
61+
} else if (this.rawCommand.startsWith('mapping ') || this.rawCommand.startsWith('event ') || this.rawCommand.startsWith('error ')) {
5762
this.scope = SCOPE.CONTRACT;
5863
this.hasNoReturnValue = true;
5964
} else if (this.rawCommand.startsWith('pragma solidity ')) {
@@ -111,7 +116,7 @@ class InteractiveSolidityShell {
111116
const defaults = {
112117
templateContractName: 'MainContract',
113118
templateFuncMain: 'main',
114-
installedSolidityVersion: require('../package.json').dependencies.solc.split("-", 1)[0],
119+
installedSolidityVersion: null, // overridden after merging settings; never use configured value
115120
providerUrl: 'http://localhost:8545',
116121
autostartGanache: true,
117122
ganacheCmd: 'ganache-cli',
@@ -122,6 +127,8 @@ class InteractiveSolidityShell {
122127
...defaults, ... (settings || {})
123128
};
124129

130+
this.settings.installedSolidityVersion = require('../package.json').dependencies.solc.split("-", 1)[0];
131+
125132
this.cache = {
126133
compiler: {} /** compilerVersion:object */
127134
}
@@ -203,35 +210,38 @@ contract ${this.settings.templateContractName} {
203210

204211

205212
loadCachedCompiler(solidityVersion) {
206-
solidityVersion = solidityVersion.startsWith("^") ? solidityVersion.substring(1) : solidityVersion; //strip leading ^
207-
/** load remote version - (maybe cache?) */
208-
if(this.cache.compiler[solidityVersion]){
209-
return new Promise((resolve, reject) => {
210-
return resolve(this.cache.compiler[solidityVersion]);
211-
});
212-
}
213-
214-
var remoteSolidityVersion = solcVersions.find(
215-
(e) => !e.includes('nightly') && e.includes(`v${solidityVersion}`)
216-
)
217213

214+
solidityVersion = solidityVersion.startsWith("^") ? solidityVersion.substring(1) : solidityVersion; //strip leading ^
218215
var that = this;
216+
/** load remote version - (maybe cache?) */
219217

220218
return new Promise((resolve, reject) => {
221-
solc.loadRemoteVersion(remoteSolidityVersion, function (err, solcSnapshot) {
222-
that.cache.compiler[solidityVersion] = solcSnapshot;
223-
return resolve(solcSnapshot)
224-
})
219+
if(that.cache.compiler[solidityVersion]){
220+
return resolve(that.cache.compiler[solidityVersion]);
221+
}
222+
223+
getRemoteCompiler(solidityVersion)
224+
.then(remoteSolidityVersion => {
225+
solc.loadRemoteVersion(remoteSolidityVersion, function (err, solcSnapshot) {
226+
that.cache.compiler[solidityVersion] = solcSnapshot;
227+
return resolve(solcSnapshot)
228+
})
229+
})
230+
.catch(err => {
231+
return reject(err)
232+
})
225233
});
226234

227235
}
228236

229237
compile(source, cbWarning) {
230-
231238
let solidityVersion = getBestSolidityVersion(source);
232239

233240
return new Promise((resolve, reject) => {
234241

242+
if(!solidityVersion){
243+
return reject(new Error(`No valid solidity version found in source code (e.g. pragma solidity 0.8.10).`));
244+
}
235245
this.loadCachedCompiler(solidityVersion).then(solcSelected => {
236246

237247
let input = {
@@ -263,6 +273,9 @@ contract ${this.settings.templateContractName} {
263273

264274
}
265275
return resolve(ret);
276+
})
277+
.catch(err => {
278+
return reject(err);
266279
});
267280

268281

@@ -296,6 +309,11 @@ contract ${this.settings.templateContractName} {
296309
})
297310
}).catch(errors => {
298311
// frownie face
312+
313+
if(!Array.isArray(errors)){ //handle single error
314+
this.revert();
315+
return reject(errors);
316+
}
299317
//get last typeError to detect return type:
300318
let lastTypeError = errors.slice().reverse().find(err => err.type === "TypeError");
301319
if (!lastTypeError) {

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
'use strict'
12
/**
23
* @author github.com/tintinweb
34
* @license MIT

src/remoteCompiler.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'use strict'
2+
/**
3+
* @author github.com/tintinweb
4+
* @license MIT
5+
* */
6+
/** IMPORT */
7+
const { solcVersions } = require('./solcVersions.js')
8+
const request = require('request');
9+
10+
function normalizeSolcVersion(version) {
11+
return version.replace('soljson-', '').replace('.js', '');
12+
}
13+
14+
function getSolcJsCompilerList(options){
15+
options = options || {};
16+
return new Promise((resolve, reject) => {
17+
request.get('https://solc-bin.ethereum.org/bin/list.json', (err, res, body) => {
18+
if(err){
19+
return reject(err)
20+
}else{
21+
let data = JSON.parse(body);
22+
let releases = Object.values(data.releases)
23+
24+
if(options.nightly){
25+
releases = Array.from(new Set([...releases, ...data.builds.map(b => b.path)]));
26+
}
27+
return resolve(releases.map(normalizeSolcVersion))
28+
}
29+
})
30+
});
31+
}
32+
33+
function getRemoteCompiler(solidityVersion) {
34+
return new Promise((resolve, reject) => {
35+
36+
//check if version is in static list (avoid http requests)
37+
let remoteSolidityVersion = solcVersions.find(
38+
(e) => !e.includes('nightly') && e.includes(`v${solidityVersion}`)
39+
)
40+
41+
if (remoteSolidityVersion) {
42+
return resolve(remoteSolidityVersion);
43+
}
44+
//download remote compiler list and check again.
45+
getSolcJsCompilerList().then(solcJsCompilerList => {
46+
let found = solcJsCompilerList.find(
47+
(e) => !e.includes('nightly') && e.includes(`v${solidityVersion}`)
48+
)
49+
if (found) {
50+
return resolve(found);
51+
}
52+
return reject(new Error(`No compiler found for version ${solidityVersion}`));
53+
})
54+
55+
});
56+
}
57+
58+
59+
module.exports = {
60+
getRemoteCompiler,
61+
getSolcJsCompilerList
62+
}
63+

src/solcVersions.js

Lines changed: 101 additions & 1 deletion
Large diffs are not rendered by default.

src/utils.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
'use strict'
12
/**
23
* @author github.com/tintinweb
34
* @license MIT
45
* */
56

6-
77
function convert(str){
88
switch(str){
99
case '': return undefined;
@@ -33,6 +33,8 @@ function multilineInput(command){
3333
return command;
3434
}
3535

36+
37+
3638
module.exports = {
3739
convert,
3840
multilineInput

0 commit comments

Comments
 (0)