Skip to content

Commit

Permalink
Add Verification API 2
Browse files Browse the repository at this point in the history
  • Loading branch information
FabijanC committed Jan 4, 2021
1 parent 9fa11ca commit 18d8e94
Show file tree
Hide file tree
Showing 21 changed files with 1,137 additions and 559 deletions.
54 changes: 54 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,23 @@
},
"homepage": "https://github.com/ethereum/sourcify#readme",
"dependencies": {
"@ethereum-sourcify/core": "*",
"@ethereum-sourcify/validation": "*",
"@ethereum-sourcify/verification": "*",
"bunyan": "^1.8.12",
"cors": "^2.8.5",
"death": "^1.1.0",
"dotenv": "^8.2.0",
"ethers": "^5.0.14",
"express": "^4.17.1",
"express-fileupload": "^1.2.0",
"express-session": "^1.17.1",
"express-validator": "^6.6.1",
"http-status-codes": "^2.1.4",
"it-concat": "^1.0.1",
"multihashes": "^3.0.1",
"request-promise-native": "^1.0.9",
"serve-index": "^1.9.1",
"@ethereum-sourcify/core": "*",
"@ethereum-sourcify/validation": "*",
"@ethereum-sourcify/verification": "*",
"web3": "^1.2.11"
},
"devDependencies": {
Expand All @@ -71,6 +72,7 @@
"@types/dotenv": "^8.2.0",
"@types/express": "^4.17.8",
"@types/express-fileupload": "^1.1.4",
"@types/express-session": "^1.17.3",
"@types/fs-extra": "^9.0.1",
"@types/node": "^14.11.2",
"@types/request-promise-native": "^1.0.17",
Expand Down
67 changes: 37 additions & 30 deletions services/core/src/utils/CheckedContract.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Web3 from 'web3';
import { StringMap, SourceMap } from './types';
import { StringMap, SourceMap, Metadata } from './types';
import { isEmpty } from './utils';
import bunyan from 'bunyan';
import fetch from 'node-fetch';

Expand All @@ -11,11 +12,14 @@ const IPFS_PREFIX = "dweb:/ipfs/";

/**
* Abstraction of a checked solidity contract. With metadata and source (solidity) files.
* The info property contains the information about compilation or errors encountered while validating the metadata.
* The getInfo method returns the information about compilation or errors encountered while validating the metadata.
*/
export class CheckedContract {
/** The raw string representation of the contract's metadata. */
metadataRaw: string;

/** Object containing contract metadata keys and values. */
metadata: any;
metadata: Metadata;

/** SourceMap mapping the original compilation path to PathContent. */
solidity: StringMap;
Expand All @@ -26,26 +30,23 @@ export class CheckedContract {
/** Contains the invalid source files. */
invalid: StringMap;

/**
* Contains the message about compilation or errors encountered while validating the metadata.
* Should be without a trailing newline.
*/
info: string;

/** Object containing input for solc when used with the --standard-json flag. */
standardJson: any;

/** The path of the contract during compile-time. */
compiledPath: string;

/** The version of the Solidity compiler to use for compilation. */
compilerVersion?: string;

/** The name of the contract. */
name: string;

/** Checks whether this contract is valid or not.
* @returns true if no sources are missing or are invalid (malformed); false otherwise
*/
public isValid(): boolean {
return isEmpty(this.missing) && isEmpty(this.invalid);
public static isValid(contract: CheckedContract): boolean {
return isEmpty(contract.missing) && isEmpty(contract.invalid);
}

private sourceMapToStringMap(input: SourceMap) {
Expand All @@ -57,6 +58,7 @@ export class CheckedContract {
}

public constructor(metadata: any, solidity: SourceMap, missing: any, invalid: StringMap) {
this.metadataRaw = JSON.stringify(metadata);
this.metadata = JSON.parse(JSON.stringify(metadata));
this.solidity = this.sourceMapToStringMap(solidity);
this.missing = missing;
Expand All @@ -72,11 +74,12 @@ export class CheckedContract {
delete metadataSource.license;
}

if (metadata.compiler && metadata.compiler.version) {
this.compilerVersion = metadata.compiler.version;
}
const { contractPath, contractName } = this.getPathAndName();
this.compiledPath = contractPath;
this.name = contractName;

this.info = this.isValid() ? this.composeSuccessMessage() : this.composeErrorMessage();
}

/**
Expand Down Expand Up @@ -105,8 +108,9 @@ export class CheckedContract {
standardJson.settings = {};
standardJson.settings.outputSelection = { "*": { "*": [ "evm.bytecode", "abi" ] } };
for (const key of STANDARD_JSON_SETTINGS_KEYS) {
if (Object.prototype.hasOwnProperty.call(this.metadata.settings, key)) {
standardJson.settings[key] = this.metadata.settings[key];
const settings: any = this.metadata.settings; // has to be of type any, does not compile if calling this.metadata.settings
if (Object.prototype.hasOwnProperty.call(settings, key)) {
standardJson.settings[key] = settings[key];
}
}
}
Expand All @@ -119,14 +123,13 @@ export class CheckedContract {
* of source files related to the provided metadata file.
*/
private composeSuccessMessage(): string {
const compilerVersionDetailed = this.metadata.compiler.version;
const compilerVersion = compilerVersionDetailed.split("+")[0];
const simpleCompilerVersion = this.compilerVersion.split("+")[0];
const msgLines: string[] = [];
msgLines.push(`${this.name} (${this.compiledPath}):`);
msgLines.push(" Success!");
msgLines.push(` Compiled with Solidity ${compilerVersion}`);
msgLines.push(` https://solc-bin.ethereum.org/wasm/soljson-v${compilerVersionDetailed}.js`);
msgLines.push(` https://solc-bin.ethereum.org/linux-amd64/solc-linux-amd64-v${compilerVersionDetailed}`);
msgLines.push(` Compiled with Solidity ${simpleCompilerVersion}`);
msgLines.push(` https://solc-bin.ethereum.org/wasm/soljson-v${this.compilerVersion}.js`);
msgLines.push(` https://solc-bin.ethereum.org/linux-amd64/solc-linux-amd64-v${this.compilerVersion}`);
return msgLines.join("\n");
}

Expand Down Expand Up @@ -181,6 +184,10 @@ export class CheckedContract {
msgLines.push(` ${foundSourcesNumber} other source files found successfully.`);
}

if (!this.compilerVersion) {
msgLines.push(" No compiler version provided.");
}

return msgLines.join("\n");
}

Expand Down Expand Up @@ -219,8 +226,6 @@ export class CheckedContract {
this.solidity[fileName] = retrieved[fileName];
}

this.info = this.isValid() ? this.composeSuccessMessage() : this.composeErrorMessage();

const missingFiles = Object.keys(this.missing);
if (missingFiles.length) {
log.error({ loc: "[FETCH]", contractName: this.name, missingFiles });
Expand Down Expand Up @@ -248,13 +253,15 @@ export class CheckedContract {
return null;
}
}
}

/**
* Checks whether the provided object contains any keys or not.
* @param obj The object whose emptiness is tested.
* @returns true if any keys present; false otherwise
*/
function isEmpty(obj: object): boolean {
return !Object.keys(obj).length;

/**
* Returns a message describing the errors encountered while validating the metadata.
* Does not include a trailing newline.
*
* @returns the validation info message
*/
public getInfo() {
return CheckedContract.isValid(this) ? this.composeSuccessMessage() : this.composeErrorMessage();
}
}
20 changes: 18 additions & 2 deletions services/core/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,25 @@ export interface FileObject {
export interface InputData {
chain: string,
addresses: string[],
contracts?: CheckedContract[],
contract?: CheckedContract,
bytecode?: string;
}

export interface CompilationSettings {
compilationTarget: any;
outputSelection: any;
}

export interface CompilerInfo {
version: string;
}

export interface Metadata {
sources: any;
settings: CompilationSettings;
compiler: CompilerInfo;
}

export declare interface StringMap {
[key: string]: string;
}
Expand All @@ -34,7 +49,8 @@ export interface SourceMap {

export interface Match {
address: string | null,
status: 'perfect' | 'partial' | null
status: 'perfect' | 'partial' | null,
message?: string
}

/**
Expand Down
9 changes: 9 additions & 0 deletions services/core/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,13 @@ export function cborDecode(bytecode: number[]): any {
const cborLength: number = bytecode[bytecode.length - 2] * 0x100 + bytecode[bytecode.length - 1];
const bytecodeBuffer = Buffer.from(bytecode.slice(bytecode.length - 2 - cborLength, -2));
return cbor.decodeFirstSync(bytecodeBuffer);
}

/**
* Checks whether the provided object contains any keys or not.
* @param obj The object whose emptiness is tested.
* @returns true if any keys present; false otherwise
*/
export function isEmpty(obj: object): boolean {
return !Object.keys(obj).length && obj.constructor === Object;
}
3 changes: 2 additions & 1 deletion services/validation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ Migrations (/home/user/dir/truffle-example/contracts/Migrations.sol):
* `npm install @ethereum-sourcify/validation`
#### Process paths
```typescript
import { CheckedContract } from '@ethereum-sourcify/core';
import { ValidationService } from '@ethereum-sourcify/validation';

const validationService = new ValidationService();
Expand All @@ -211,7 +212,7 @@ function work(files) {
}

checkedContracts.forEach(contract => {
if (contract.isValid()) {
if (CheckedContract.isValid(contract)) {
console.log(`Contract ${contract.name} is valid!`);
} else {
console.log(`Contract ${contract.name} is not valid!`);
Expand Down
Loading

0 comments on commit 18d8e94

Please sign in to comment.