Merge pull request #6 from embarklabs/feat/lib
Make verifier usable as a library
This commit is contained in:
commit
1cef9b67b5
49
README.md
49
README.md
|
@ -1,9 +1,9 @@
|
|||
Embark-etherscan-verifier
|
||||
======
|
||||
|
||||
Plugin for [Embark](https://github.com/embark-framework/embark) to flatten and verify contracts on Etherscan
|
||||
Plugin for [Embark](https://github.com/embark-framework/embark) and library to flatten and verify contracts on Etherscan.
|
||||
|
||||
## Installation
|
||||
## Plugin installation
|
||||
|
||||
In your Embark dapp directory:
|
||||
|
||||
|
@ -19,16 +19,16 @@ then add embark-etherscan-verifier to the plugins section in `embark.json`:
|
|||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
### Usage
|
||||
|
||||
### Flatten
|
||||
#### Flatten
|
||||
In the console, type `flatten` or `flatten ContractName(s)`
|
||||
|
||||
- `flatten`: Flattens all contracts
|
||||
- `flatten ContractName(s)`: Flattens the specified contract(s). For multiple contracts, separate them using a comma.
|
||||
- Example: `flatten SimpleStorage,Token`
|
||||
|
||||
### Verify
|
||||
#### Verify
|
||||
You can also automatically verify on a valid network (mainnet, ropsten, rinkeby, kovan)
|
||||
|
||||
In the console:
|
||||
|
@ -37,7 +37,44 @@ In the console:
|
|||
- You need an Etherscan API key. You can find a simple tutorial [here](https://etherscancom.freshdesk.com/support/solutions/articles/35000022163-i-need-an-api-key)
|
||||
- Example: `verify YOUR_KEY SimpleStorage`
|
||||
|
||||
## Requirements
|
||||
### Requirements
|
||||
|
||||
- Embark 4.0.0 or higher
|
||||
|
||||
## Library usage
|
||||
|
||||
You can use the flattener and verifier standalone.
|
||||
|
||||
```
|
||||
import FlattenerVerifier from 'embark-etherscan-verifier/lib/FlattenerVerifier`;
|
||||
|
||||
const flattenerVerifier = new FlattenerVerifier({
|
||||
optimize: true,
|
||||
optimizeRuns: 200,
|
||||
contractsFiles: [...],
|
||||
solcVersion: '0.5.2',
|
||||
getWeb3DeployObject: (contract, cb) => {},
|
||||
getAllContracts: (cb) => {},
|
||||
getContractByName: (contractName, cb) => {},
|
||||
getNetworkId: (cb) => {}
|
||||
});
|
||||
```
|
||||
|
||||
### Parameters
|
||||
- `optimize`: bool: if the contract is optimized
|
||||
- `optimizeRuns`: int: Number of optimize passes
|
||||
- `contractsFiles`: Array of contract files objects. Must contain:
|
||||
- `originalPath`: Original path to the contract (relative path)
|
||||
- `path`: Absolute path to the contract object
|
||||
- `importRemappings`: Array of remapping objects (for imports). Must contain:
|
||||
- `target`: Absolute path to the imported contract
|
||||
- `solcVersion`: string: solc version used to compile
|
||||
- `getWeb3DeployObject`: Function to get a [web3 deploy object](https://web3js.readthedocs.io/en/v1.2.0/web3-eth-contract.html#deploy)
|
||||
- `getAllContracts`: Function that returns all contract objects. Contract object must contain: linkReferences(from solc output contract.evm.bytecode.linkReferences)}
|
||||
- `className`: string: Class name of the contract
|
||||
- `originalFilename`: string: Original file name of the file (relative path)
|
||||
- `filename`: string: Complete absolute file path
|
||||
- `deployedAddress`: string: Address where the contract is deployed
|
||||
- `linkReferences`: object: Library link references. You can get it from the solc output as `contract.evm.bytecode.linkReferences`
|
||||
- `getContractByName`: Function to get a contract object by name. Contains the same as all contracts above
|
||||
- `getNetworkId`: Function that returns the current networkId
|
||||
|
|
30
index.js
30
index.js
|
@ -3,7 +3,30 @@
|
|||
const FlattenerVerifier = require('./lib/FlattenerVerifier');
|
||||
|
||||
module.exports = (embark) => {
|
||||
const flattenerVerifier = new FlattenerVerifier(embark);
|
||||
function createVerifier() {
|
||||
return new FlattenerVerifier({
|
||||
optimize: embark.config.embarkConfig.options.solc.optimize,
|
||||
optimizeRuns: embark.config.embarkConfig.options.solc['optimize-runs'],
|
||||
contractsFiles: embark.config.contractsFiles,
|
||||
solcVersion: embark.config.embarkConfig.versions.solc,
|
||||
getWeb3DeployObject: (contract, cb) => {
|
||||
embark.events.request('deploy:contract:object', contract, cb);
|
||||
},
|
||||
getAllContracts: (cb) => {
|
||||
embark.events.request('contracts:all', cb);
|
||||
},
|
||||
getContractByName: (contractName, cb) => {
|
||||
embark.events.request("contracts:contract", contractName, (contract) => {
|
||||
cb(null, contract);
|
||||
});
|
||||
},
|
||||
getNetworkId: (cb) => {
|
||||
embark.events.request("blockchain:networkId", (networkId) => {
|
||||
cb(null, networkId);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
embark.registerConsoleCommand({
|
||||
description: "Flattens all or some of your contracts so that they can be verified on Etherscan\n\t\tYou can specify which contract to flatten by using their contract name. For multiple contracts, separate them using a comma",
|
||||
|
@ -21,8 +44,7 @@ module.exports = (embark) => {
|
|||
embark.logger.info('Flattening all contracts');
|
||||
}
|
||||
|
||||
|
||||
flattenerVerifier.flatten(contractNames, callback);
|
||||
createVerifier().flatten(contractNames, callback);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -47,7 +69,7 @@ module.exports = (embark) => {
|
|||
return callback(null, 'solc version not present in embarkjs.json. Please add it to versions.solc'.red);
|
||||
}
|
||||
|
||||
flattenerVerifier.verify(apiKey, contractName, callback);
|
||||
createVerifier().verify(apiKey, contractName, callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -26,10 +26,9 @@ function sleep(ms) {
|
|||
}
|
||||
|
||||
class FlattenerVerifier {
|
||||
constructor(embark) {
|
||||
this.embark = embark;
|
||||
this.events = embark.events;
|
||||
this.logger = embark.logger;
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
this.logger = options.logger || console;
|
||||
}
|
||||
|
||||
_doFlatten(contracts, callback) {
|
||||
|
@ -103,7 +102,10 @@ class FlattenerVerifier {
|
|||
libNames = Array.from(new Set(libNames));
|
||||
|
||||
async.eachOf(libNames, (libName, index, eachCb) => {
|
||||
this.events.request("contracts:contract", libName, (lib) => {
|
||||
this.options.getContractByName(libName, (err, lib) => {
|
||||
if (err) {
|
||||
return eachCb(err);
|
||||
}
|
||||
if (!this._isContractValid(lib, libName)) {
|
||||
return eachCb('Make sure the library is not set as `deploy: false`');
|
||||
}
|
||||
|
@ -131,11 +133,11 @@ class FlattenerVerifier {
|
|||
sourceCode: flattenedCode,
|
||||
contractname: contract.className,
|
||||
compilerversion: solcVersion,
|
||||
optimizationUsed: this.embark.config.embarkConfig.options.solc.optimize ? 1 : 0,
|
||||
runs: this.embark.config.embarkConfig.options.solc['optimize-runs']
|
||||
optimizationUsed: this.options.optimize ? 1 : 0,
|
||||
runs: this.options.optimizeRuns
|
||||
};
|
||||
|
||||
this.events.request('deploy:contract:object', contract, (err, deployObject) => {
|
||||
this.options.getWeb3DeployObject(contract, (err, deployObject) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
@ -219,7 +221,10 @@ class FlattenerVerifier {
|
|||
}
|
||||
|
||||
verify(apiKey, contractName, callback) {
|
||||
this.events.request("contracts:contract", contractName, (contract) => {
|
||||
this.options.getContractByName(contractName, (err, contract) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (!this._isContractValid(contract, contractName)) {
|
||||
return callback(null, 'Please make sure you specify the contract name as the class name. E.g. SimpleStorage instead of simple_storage.sol');
|
||||
}
|
||||
|
@ -236,7 +241,7 @@ class FlattenerVerifier {
|
|||
if (flattenedFileExists) {
|
||||
return next();
|
||||
}
|
||||
const file = this.embark.config.contractsFiles.find(file => path.normalize(file.path) === path.normalize(contract.filename));
|
||||
const file = this.options.contractsFiles.find(file => path.normalize(file.path) === path.normalize(contract.filename));
|
||||
this._doFlatten([file], next);
|
||||
},
|
||||
(next) => { // Read the flattened contract
|
||||
|
@ -250,14 +255,17 @@ class FlattenerVerifier {
|
|||
(content, next) => { // Get supported versions list
|
||||
axios.get(solcVersionsListLink)
|
||||
.then((response) => {
|
||||
const solcVersion = response.data.split('\n').find(version => version.indexOf(this.embark.config.embarkConfig.versions.solc) > -1 && version.indexOf('nightly') === -1);
|
||||
const solcVersion = response.data.split('\n')
|
||||
.find(version => {
|
||||
return version.indexOf(this.options.solcVersion) > -1 && version.indexOf('nightly') === -1;
|
||||
});
|
||||
next(null, content, solcVersion.replace('soljson-', '').replace('.js', ''));
|
||||
})
|
||||
.catch(next);
|
||||
},
|
||||
(content, solcVersion, next) => {
|
||||
this.events.request("blockchain:networkId", (networkId) => {
|
||||
next(null, content, solcVersion, networkId);
|
||||
this.options.getNetworkId((err, networkId) => {
|
||||
next(err, content, solcVersion, networkId);
|
||||
});
|
||||
}
|
||||
], (err, content, solcVersion, networkId) => {
|
||||
|
@ -271,10 +279,10 @@ class FlattenerVerifier {
|
|||
|
||||
flatten(contractNames, callback) {
|
||||
if (!contractNames) {
|
||||
return this._doFlatten(this.embark.config.contractsFiles, callback);
|
||||
return this._doFlatten(this.options.contractsFiles, callback);
|
||||
}
|
||||
|
||||
this.events.request('contracts:all', (err, contracts) => {
|
||||
this.options.getAllContracts((err, contracts) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
@ -287,7 +295,7 @@ class FlattenerVerifier {
|
|||
if (!contract) {
|
||||
throw new Error('No contract named ' + contractName);
|
||||
}
|
||||
return this.embark.config.contractsFiles.find(file => path.normalize(file.originalPath) === path.normalize(contract.originalFilename));
|
||||
return this.options.contractsFiles.find(file => path.normalize(file.originalPath) === path.normalize(contract.originalFilename));
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(null, e.message.red);
|
||||
|
|
Loading…
Reference in New Issue