diff --git a/packages/config/src/configDefaults.ts b/packages/config/src/configDefaults.ts index 6b927679103..fe8a91e68ae 100644 --- a/packages/config/src/configDefaults.ts +++ b/packages/config/src/configDefaults.ts @@ -37,7 +37,7 @@ export const getInitialConfig = ({ ipfsProtocol: "https", ipfsPort: "5001", registry: { - address: "0xD230Dd91A049284a236f6ccba4412F647BDAAD9e", + address: "0x0bd0200357D26A0bB5d1D1c1Fd56C317B68d15d5", network: "ropsten" }, version: "3" diff --git a/packages/core/index.js b/packages/core/index.js index 1943ffd3492..89c37c0a918 100644 --- a/packages/core/index.js +++ b/packages/core/index.js @@ -7,8 +7,8 @@ module.exports = { console: require("./lib/repl"), // TODO: update this to non-legacy the next breaking change contracts: require("@truffle/workflow-compile/legacy"), - package: require("./lib/package"), test: require("./lib/testing/Test"), + package: require("@truffle/ethpm-v3"), version: pkg.version, ganache: require("ganache-core/public-exports") }; diff --git a/packages/core/lib/commands/install.js b/packages/core/lib/commands/install.js index 0602fd363f6..7457c80cd57 100644 --- a/packages/core/lib/commands/install.js +++ b/packages/core/lib/commands/install.js @@ -13,7 +13,7 @@ const command = { }, { option: "--alias", - description: "A different name under which to install this package." + description: "An alternate name under which to install this package." } ] }, @@ -31,7 +31,9 @@ const command = { } if (options._ && options._.length > 1) { done( - new Error(`Only one package identifier can be installed at a time.`) + new Error( + `Multiple package identifiers detected. Only one package can be installed at a time.` + ) ); } options.packageIdentifier = options._[0]; diff --git a/packages/ethpm-v1/lib/ethpm-v1.js b/packages/ethpm-v1/lib/ethpm-v1.js index 2237e37fc15..ef0ad3b396d 100644 --- a/packages/ethpm-v1/lib/ethpm-v1.js +++ b/packages/ethpm-v1/lib/ethpm-v1.js @@ -12,6 +12,9 @@ const OS = require("os"); const PackageV1 = { packages: async options => { + options.logger.log( + `ethpmV1 is deprecated. Please consider updating your packages to ethpmV3.` + ); try { expect.options(options, [ "ethpm", @@ -65,6 +68,9 @@ const PackageV1 = { }, install: async function (options, callback) { + options.logger.log( + `ethpmV1 is deprecated. Please consider updating your packages to ethpmV3.` + ); const callbackPassed = typeof callback === "function"; expect.options(options, ["working_directory", "ethpm"]); @@ -167,6 +173,9 @@ const PackageV1 = { }, publish: async function (options, callback) { + options.logger.log( + `ethpmV1 is deprecated. Please consider updating your packages to ethpmV3.` + ); const callbackPassed = typeof callback === "function"; var self = this; diff --git a/packages/ethpm-v1/package.json b/packages/ethpm-v1/package.json index fa7d165949f..7cbea10561e 100644 --- a/packages/ethpm-v1/package.json +++ b/packages/ethpm-v1/package.json @@ -8,9 +8,11 @@ ], "homepage": "http://www.ethpm.com", "license": "MIT", - "main": "lib/ethpm-v1.js", + "main": "./lib/ethpm-v1.js", "dependencies": { - "ethpm-registry": "0.1.0-next.3" + "@truffle/error": "^0.0.9", + "ethpm": "0.0.19", + "ethpm-registry": "0.1.0-next.3" }, "directories": { "lib": "lib", diff --git a/packages/ethpm-v1/tests/ethpm-v1.js b/packages/ethpm-v1/tests/ethpm-v1.js index eefcf2d298d..c9931f3555c 100644 --- a/packages/ethpm-v1/tests/ethpm-v1.js +++ b/packages/ethpm-v1/tests/ethpm-v1.js @@ -4,7 +4,8 @@ var fs = require("fs-extra"); var glob = require("glob"); var path = require("path"); var Contracts = require("@truffle/workflow-compile"); -var PackageV1 = require("../lib/package.js"); +var PackageV1 = require("../lib/ethpm-v1.js"); +var GithubExamples = require("ethpm/lib/indexes/github-examples"); var Blockchain = require("@truffle/blockchain-utils"); var Ganache = require("ganache-core"); var Resolver = require("@truffle/resolver"); @@ -29,35 +30,24 @@ describe.skip("EthPM integration", function () { ); } - beforeEach("Create a Ganache provider and get a blockchain uri", function ( - done - ) { + beforeEach("Create a Ganache provider and get a blockchain uri", async () => { provider = Ganache.provider(); - - Blockchain.asURI(provider, function (err, uri) { - if (err) return done(err); - blockchain_uri = uri; - done(); - }); + blockchain_uri = await Blockchain.asURI(provider); }); // Super slow doing these in a beforeEach, but it ensures nothing conflicts. - beforeEach("Create a sandbox", function (done) { + beforeEach("Create a sandbox", async () => { this.timeout(20000); - Box.sandbox(function (err, result) { - if (err) return done(err); - config = result; - config.resolver = new Resolver(config); - config.artifactor = new Artifactor(config.contracts_build_directory); - config.networks = { - development: { - network_id: blockchain_uri, - provider: provider - } - }; - config.network = "development"; - done(); - }); + config = await Box.sandbox("default"); + config.resolver = new Resolver(config); + config.artifactor = new Artifactor(config.contracts_build_directory); + config.networks = { + development: { + network_id: blockchain_uri, + provider: provider + } + }; + config.network = "development"; }); beforeEach("Create a fake EthPM host and memory registry", function (done) { diff --git a/packages/ethpm-v3/lib/ethpm-v3.js b/packages/ethpm-v3/lib/ethpm-v3.js index 535343d994f..7a39e443e14 100644 --- a/packages/ethpm-v3/lib/ethpm-v3.js +++ b/packages/ethpm-v3/lib/ethpm-v3.js @@ -38,6 +38,8 @@ const PackageV3 = { ); } + var provider = utils.pluckProviderFromConfig(options); + let targetRegistry; if (!isAddress(options.ethpm.registry.address)) { targetRegistry = await utils.resolveEnsName( @@ -49,8 +51,6 @@ const PackageV3 = { targetRegistry = options.ethpm.registry.address; } - var provider = utils.pluckProviderFromConfig(options); - // Create an ethpm instance let ethpm; try { @@ -74,11 +74,16 @@ const PackageV3 = { options.logger.log( `Searching for packages published on registry located at: ${targetRegistry}` ); - const owner = await ethpm.registries.registry.methods.owner().call(); - options.logger.log(`Registry controlled by account: ${owner}`); + + // display owner / warning about unauthorized registries + await utils.displayRegistryPermissions(options, ethpm); // Display all packages from connected registry const allPackages = await ethpm.registries.packages(); + if (allPackages.length == 0) { + options.logger.log(`0 packages found on this registry.`); + } + for (var i = 0; i < allPackages.length; i++) { const packageName = allPackages[i]; const allReleases = await ethpm.registries @@ -123,6 +128,7 @@ const PackageV3 = { options.logger.log( `! Please use caution when interacting with installed packages.\n! Only use packages that are published on trusted registries, or whose assets you've verified directly.` ); + options.logger.log("Fetching package manifest..."); var targetNetwork = options.ethpm.registry.network; var targetNetworkId = options.networks[targetNetwork].network_id; @@ -160,6 +166,9 @@ const PackageV3 = { throw new TruffleError(`Unable to configure ethpm: ${err.message}`); } + // display owner / warning about unauthorized registries + await utils.displayRegistryPermissions(options, ethpm); + let manifestUri; let targetPackageName; let targetVersion; @@ -242,11 +251,10 @@ const PackageV3 = { const allReleases = await ethpm.registries .package(targetPackageName) .releases(); - try { - targetVersion = semver.maxSatisfying(Object.keys(allReleases), "*"); - } catch (err) { + targetVersion = semver.maxSatisfying(Object.keys(allReleases), "*"); + if (!targetVersion) { throw new TruffleError( - `Releases on active version do not look like semver. Please specify a version of the package you want to install.` + `Releases for specified package (${targetPackageName}) do not look like semver. Please specify the version of the package you want to install.` ); } } @@ -308,7 +316,6 @@ const PackageV3 = { if (deployment.contractType === contractType) { contractDeployments[networkId] = { address: deployment.address - // links && events }; } } diff --git a/packages/ethpm-v3/lib/utils.js b/packages/ethpm-v3/lib/utils.js index 51b30c04d3f..4307abcb61f 100644 --- a/packages/ethpm-v3/lib/utils.js +++ b/packages/ethpm-v3/lib/utils.js @@ -54,24 +54,33 @@ async function getPublishableArtifacts(options, ethpm) { }); } + const requiredNetworkIds = Object.keys(detectedNetworkIdsToBlockchainUris); + const availableNetworkIds = Object.keys(options.networks).map(n => + options.networks[n].network_id.toString() + ); + for (let networkId of requiredNetworkIds) { + if (!availableNetworkIds.includes(networkId)) { + throw new TruffleError( + `Detected a deployment for network id: ${networkId}, but missing a provider for this network. Please make sure there is an available provider for this network id in your truffle-config.` + ); + } + } + // generate blockchainURI for each detected networkId - for (let networkId of Object.keys(detectedNetworkIdsToBlockchainUris)) { + for (let networkId of requiredNetworkIds) { let targetProvider; for (let provider of Object.keys(options.networks)) { - if ( - options.networks[provider].network_id == networkId && - options.networks[provider].provider - ) { - targetProvider = pluckProviderFromConfig(options); + if (options.networks[provider].network_id == networkId) { + // handle ganache provider from tests + if ( + options.networks[provider].provider.constructor.name == "Function" + ) { + targetProvider = options.networks[provider].provider(); + } else { + targetProvider = options.networks[provider].provider; + } } } - - if (!targetProvider) { - throw new TruffleError( - `Missing provider for network id: ${networkId}. Please make sure there is an available provider in your truffle-config` - ); - } - const blockchainUri = await getBlockchainUriForProvider(targetProvider); detectedNetworkIdsToBlockchainUris[networkId] = blockchainUri; } @@ -79,14 +88,12 @@ async function getPublishableArtifacts(options, ethpm) { // replace network ids with blockchain uri in detected artifacts for (let artifactPath of Object.keys(detectedArtifacts)) { var artifactDeployments = detectedArtifacts[artifactPath].networks; - if (Object.keys(artifactDeployments).length > 0) { - Object.keys(artifactDeployments).forEach(id => { - var matchingUri = detectedNetworkIdsToBlockchainUris[id]; - artifactDeployments[matchingUri] = artifactDeployments[id]; - delete artifactDeployments[id]; - }); - detectedArtifacts[artifactPath].networks = artifactDeployments; - } + var updatedDeployments = {}; + Object.keys(artifactDeployments).forEach(id => { + var matchingUri = detectedNetworkIdsToBlockchainUris[id]; + updatedDeployments[matchingUri] = artifactDeployments[id]; + }); + detectedArtifacts[artifactPath].networks = updatedDeployments; } const normalizedArtifacts = Object.keys(detectedArtifacts).map( @@ -270,13 +277,25 @@ function pluckProviderFromConfig(config) { } } +async function displayRegistryPermissions(options, ethpm) { + try { + const owner = await ethpm.registries.registry.methods.owner().call(); + options.logger.log(`Registry controlled by account: ${owner}`); + } catch (err) { + options.logger.log( + `This registry does not appear to have permissioned releases. This means that anybody can publish a package to this registry. Please be very careful before installing and interacting with packages on this registry.` + ); + } +} + module.exports = { - getPublishableArtifacts, - resolveEthpmUri, - resolveEnsName, convertContractTypeToContractSchema, + displayRegistryPermissions, + getPublishableArtifacts, fetchInstalledBuildDependencies, pluckProviderFromConfig, + resolveEthpmUri, + resolveEnsName, SUPPORTED_CHAIN_IDS, SUPPORTED_GENESIS_BLOCKS }; diff --git a/packages/ethpm-v3/package.json b/packages/ethpm-v3/package.json index f7e6b1dc8ef..9ad309cf14a 100644 --- a/packages/ethpm-v3/package.json +++ b/packages/ethpm-v3/package.json @@ -8,18 +8,19 @@ ], "homepage": "http://www.ethpm.com", "license": "MIT", - "main": "lib/ethpm-v3.js", + "main": "./lib/ethpm-v3.js", "scripts": { "test": "mocha ./tests/* --timeout 10000 --exit" }, "dependencies": { - "ethpm": "0.1.0-next.26", - "ethpm-spec": "3.0.0", - "ethereum-ens": "0.8.0", - "semver": "7.3.2" + "@truffle/error": "^0.0.10", + "ethpm": "0.1.0-next.30", + "ethpm-spec": "^3.0.0", + "ethereum-ens": "^0.8.0", + "semver": "^7.3.2" }, "devDependencies": { - "mocha": "8.0.1" + "mocha": "^8.0.1" }, "directories": { "lib": "lib", diff --git a/packages/resolver/lib/sources/ethpm-v1.ts b/packages/resolver/lib/sources/ethpm-v1.ts new file mode 100644 index 00000000000..4c462e98320 --- /dev/null +++ b/packages/resolver/lib/sources/ethpm-v1.ts @@ -0,0 +1,132 @@ +import path from "path"; +import fs from "fs"; + +import { ContractObject } from "@truffle/contract-schema/spec"; +import { ResolverSource } from "../source"; + +export class EthPMv1 implements ResolverSource { + workingDirectory: string; + + constructor(workingDirectory: string) { + this.workingDirectory = workingDirectory; + } + + require(importPath: string) { + if (importPath.indexOf(".") === 0 || importPath.indexOf("/") === 0) { + return null; + } + + // Look to see if we've compiled our own version first. + var contract_name = path.basename(importPath, ".sol"); + + // We haven't compiled our own version. Assemble from data in the lockfile. + var separator = importPath.indexOf("/"); + var package_name = importPath.substring(0, separator); + + var install_directory = path.join( + this.workingDirectory, + "installed_contracts" + ); + var lockfile: any = path.join(install_directory, package_name, "lock.json"); + + try { + lockfile = fs.readFileSync(lockfile, "utf8"); + } catch (e) { + return null; + } + + lockfile = JSON.parse(lockfile); + + // TODO: contracts that reference other types + // TODO: contract types that specify a hash as their key + // TODO: imported name doesn't match type but matches deployment name + var contract_types = lockfile.contract_types || {}; + var type = contract_types[contract_name]; + + // No contract name of the type asked. + if (!type) return null; + + var json: ContractObject = { + abi: type.abi, + contract_name: contract_name, + networks: {}, + unlinked_binary: type.bytecode + }; + + // Go through deployments and save all of them + Object.keys(lockfile.deployments || {}).forEach(function (blockchain) { + var deployments = lockfile.deployments[blockchain]; + + Object.keys(deployments).forEach(function (name) { + var deployment = deployments[name]; + if (deployment.contract_type === contract_name) { + json.networks[blockchain] = { + events: {}, + links: {}, + address: deployment.address + }; + } + }); + }); + + return json; + } + + async resolve(importPath: string) { + var separator = importPath.indexOf("/"); + var package_name = importPath.substring(0, separator); + var internal_path = importPath.substring(separator + 1); + var installDir = this.workingDirectory; + + // If nothing's found, body returns `undefined` + var body; + + while (true) { + var file_path = path.join(installDir, "installed_contracts", importPath); + + try { + body = fs.readFileSync(file_path, { encoding: "utf8" }); + break; + } catch (err) {} + + file_path = path.join( + installDir, + "installed_contracts", + package_name, + "contracts", + internal_path + ); + + try { + body = fs.readFileSync(file_path, { encoding: "utf8" }); + break; + } catch (err) {} + + // Recurse outwards until impossible + var oldInstallDir = installDir; + installDir = path.join(installDir, ".."); + if (installDir === oldInstallDir) { + break; + } + } + return { body, filePath: importPath }; + } + + // We're resolving package paths to other package paths, not absolute paths. + // This will ensure the source fetcher conintues to use the correct sources for packages. + // i.e., if some_module/contracts/MyContract.sol imported "./AnotherContract.sol", + // we're going to resolve it to some_module/contracts/AnotherContract.sol, ensuring + // that when this path is evaluated this source is used again. + resolveDependencyPath(importPath: string, dependencyPath: string) { + var dirname = path.dirname(importPath); + var resolved_dependency_path = path.join(dirname, dependencyPath); + + // Note: We use `path.join()` here to take care of path idiosyncrasies + // like joining "something/" and "./something_else.sol". However, this makes + // paths OS dependent, and on Windows, makes the separator "\". Solidity + // needs the separator to be a forward slash. Let's massage that here. + resolved_dependency_path = resolved_dependency_path.replace(/\\/g, "/"); + + return resolved_dependency_path; + } +} diff --git a/packages/resolver/lib/sources/ethpm-v3.ts b/packages/resolver/lib/sources/ethpm-v3.ts index 9d0c1b6cb9c..3073e0ade96 100644 --- a/packages/resolver/lib/sources/ethpm-v3.ts +++ b/packages/resolver/lib/sources/ethpm-v3.ts @@ -12,7 +12,7 @@ export class EthPMv3 implements ResolverSource { constructor(workingDirectory: string) { this.workingDirectory = workingDirectory; this.allEthpmFiles = glob.sync("**/*", { - cwd: path.join(this.workingDirectory, "_ethpm_packages"), + cwd: path.join(this.workingDirectory, "_ethpm_packages") }); } @@ -56,7 +56,7 @@ export class EthPMv3 implements ResolverSource { abi: type.abi, contractName: contractName, networks: {}, - unlinked_binary: type.deploymentBytecode.bytecode, + unlinked_binary: type.deploymentBytecode.bytecode }; // Go through deployments and save all of them @@ -69,7 +69,7 @@ export class EthPMv3 implements ResolverSource { json.networks[blockchain] = { events: {}, links: {}, - address: deployment.address, + address: deployment.address }; } }); @@ -116,7 +116,6 @@ export class EthPMv3 implements ResolverSource { break; } catch (err) {} - // DOES NOT SUPPORT DUPLICATE IMPORT PATHS W/IN AGGREGATED PKGS if (matches.length > 0) { if (matches.length === 1) { try { diff --git a/packages/truffle/test/scenarios/commands/ethpm.js b/packages/truffle/test/scenarios/commands/ethpm.js index 658a017788f..eb359603549 100644 --- a/packages/truffle/test/scenarios/commands/ethpm.js +++ b/packages/truffle/test/scenarios/commands/ethpm.js @@ -4,60 +4,64 @@ var fs = require("fs"); var path = require("path"); var assert = require("assert"); var Server = require("../server"); -var Reporter = require("../reporter"); var sandbox = require("../sandbox"); var log = console.log; -describe("truffle publish", function() { - var config; - var project = path.join(__dirname, '../../sources/ethpm'); - var logger = new MemoryLogger(); +function processErr(err, output) { + if (err) { + log(output); + throw new Error(err); + } +} - before("set up the server", function(done) { - Server.start(done); - }); +describe("truffle publish", () => { + let config, projectPath; + var logger = new MemoryLogger(); - after("stop server", function(done) { - Server.stop(done); + before("before all setup", done => { + projectPath = path.join(__dirname, "../../sources/ethpm"); + sandbox + .create(projectPath) + .then(conf => { + config = conf; + config.network = "ropsten"; + config.logger = logger; + }) + .then(() => Server.start(done)); }); - before("set up sandbox", function() { - this.timeout(10000); - return sandbox.create(project).then(conf => { - config = conf; - config.network = "development"; - config.logger = logger; - config.mocha = { - reporter: new Reporter(logger) - }; - }); - }); + after(done => Server.stop(done)); // This test only validates package assembly. We expect it to run logic up to the attempt to // publish to the network and fail. - it.skip("Can locate all the sources to publish", function(done) { - this.timeout(30000); + describe("With an ethpm package installed", () => { + it.skip("Can locate all the sources to publish", async () => { + await CommandRunner.run("compile", config); - CommandRunner.run("compile", config, function(err) { - if (err) { - log(logger.contents()); - return done(err); - } - assert(fs.existsSync(path.join(config.contracts_build_directory, "PLCRVoting.json"))); - assert(fs.existsSync(path.join(config.contracts_build_directory, "EIP20.json"))); - assert(fs.existsSync(path.join(config.contracts_build_directory, "Local.json"))); + assert( + fs.existsSync( + path.join(config.contracts_build_directory, "PLCRVoting.json") + ) + ); + assert( + fs.existsSync(path.join(config.contracts_build_directory, "EIP20.json")) + ); + assert( + fs.existsSync(path.join(config.contracts_build_directory, "Local.json")) + ); - CommandRunner.run("publish", config, function(err) { + try { + await CommandRunner.run("publish", config); + } catch (error) { var output = logger.contents(); + processErr(error, output); + } - // We expect publication to be rejected by the client. - if (!err) { - log(output); - done(err); - } - assert(output.includes('Uploading sources and publishing'), 'Should have found sources'); - done(); - }); - }); + assert( + output.includes("Uploading sources and publishing"), + "Should have found sources" + ); + done(); + }).timeout(30000); }); }); diff --git a/packages/truffle/test/scenarios/commands/install.js b/packages/truffle/test/scenarios/commands/install.js index c9fd5a2be62..50e53b21715 100644 --- a/packages/truffle/test/scenarios/commands/install.js +++ b/packages/truffle/test/scenarios/commands/install.js @@ -1,22 +1,34 @@ const CommandRunner = require("../commandrunner"); +const MemoryLogger = require("../memorylogger"); const sandbox = require("../sandbox"); const assert = require("assert"); -const fse = require("fs-extra"); const path = require("path"); let config; -describe("truffle install [standalone]", () => { +describe("truffle install [ @standalone ]", () => { + var logger = new MemoryLogger(); + before(async () => { config = await sandbox.create( path.join(__dirname, "../../sources/install/init") ); - config.logger = { log: () => {} }; + config.logger = logger; }); it("unboxes successfully", async () => { - await CommandRunner.run("install owned", config); - const theInstallDirExists = fse.pathExistsSync( - path.join(config.working_directory, "_ethpm_packages") + try { + // throws an error since there is no valid provider in truffle-config + await CommandRunner.run( + "install ipfs://QmcxvhkJJVpbxEAa6cgW3B6XwPJb79w9GpNUv2P2THUzZR", + config + ); + } catch (err) { + var output = logger.contents(); + } + + assert( + output.includes("Fetching package manifest"), + "Should have started locating manifest" ); assert(theInstallDirExists); }).timeout(30000); diff --git a/packages/truffle/test/scenarios/library/api.js b/packages/truffle/test/scenarios/library/api.js index 6511ec30c7a..d8a26c262ca 100644 --- a/packages/truffle/test/scenarios/library/api.js +++ b/packages/truffle/test/scenarios/library/api.js @@ -52,13 +52,9 @@ describe("Truffle Library APIs [ @standalone ]", () => { }); it("truffle.package API definition", () => { - assert(truffle.package.publish, "package.publish undefined"); assert(truffle.package.install, "package.install undefined"); - assert(truffle.package.digest, "package.digest undefined"); - assert( - truffle.package.publishable_artifacts, - "package.publishable_artifacts undefined" - ); + assert(truffle.package.packages, "package.packages undefined"); + assert(truffle.package.publish, "package.publish undefined"); }); it("truffle.test API", () => { diff --git a/packages/truffle/test/scenarios/resolver/resolver.js b/packages/truffle/test/scenarios/resolver/resolver.js index 522922d1961..ef3e68fb4ad 100644 --- a/packages/truffle/test/scenarios/resolver/resolver.js +++ b/packages/truffle/test/scenarios/resolver/resolver.js @@ -6,7 +6,7 @@ var Server = require("../server"); var Reporter = require("../reporter"); var sandbox = require("../sandbox"); -describe("Solidity Imports [ @standalone ]", function() { +describe("Solidity Imports [ @standalone ]", function () { var config; var project = path.join(__dirname, "../../sources/monorepo"); var logger = new MemoryLogger(); @@ -23,9 +23,10 @@ describe("Solidity Imports [ @standalone ]", function() { * | |-- ImportOfImport.sol # Local import for NodeImport.sol * | |-- NodeImport.sol * | - * + installed_contracts/ + * + _ethpm_packages/ * |-- ethpmpkg/ - * | |-- EthPMImport.sol + * | |-- _src/ + * | |-- EthPMImport.sol * | * + truffleproject/ * |-- contracts/ @@ -41,8 +42,8 @@ describe("Solidity Imports [ @standalone ]", function() { * | */ - describe("success", function() { - before(function() { + describe("success", function () { + before(function () { this.timeout(10000); return sandbox.create(project, "truffleproject").then(conf => { config = conf; @@ -54,7 +55,7 @@ describe("Solidity Imports [ @standalone ]", function() { }); }); - it("resolves solidity imports located outside the working directory", async function() { + it("resolves solidity imports located outside the working directory", async function () { this.timeout(30000); await CommandRunner.run("compile", config); @@ -68,8 +69,8 @@ describe("Solidity Imports [ @standalone ]", function() { }); }); - describe("failure", function() { - before(function() { + describe("failure", function () { + before(function () { this.timeout(10000); return sandbox.create(project, "errorproject").then(conf => { config = conf; @@ -81,7 +82,7 @@ describe("Solidity Imports [ @standalone ]", function() { }); }); - it("fails gracefully if an import is not found", async function() { + it("fails gracefully if an import is not found", async function () { this.timeout(30000); try { diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/ethpm.lock b/packages/truffle/test/sources/ethpm/_ethpm_packages/ethpm.lock new file mode 100644 index 00000000000..7d751b2d46a --- /dev/null +++ b/packages/truffle/test/sources/ethpm/_ethpm_packages/ethpm.lock @@ -0,0 +1,11 @@ +{ + "tokens": { + "alias": "tokens", + "install_uri": "ipfs://QmUFjXUiz86LNhpMZV8v2rnK6vVhXHcMZqbTuQyd2RZ2ib", + "registry_address": null, + "resolved_content_hash": "QmUFjXUiz86LNhpMZV8v2rnK6vVhXHcMZqbTuQyd2RZ2ib", + "resolved_package_name": "tokens", + "resolved_uri": "ipfs://QmUFjXUiz86LNhpMZV8v2rnK6vVhXHcMZqbTuQyd2RZ2ib", + "resolved_version": "1.0.0" + } +} diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/Migrations.sol b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/Migrations.sol similarity index 100% rename from packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/Migrations.sol rename to packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/Migrations.sol diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/eip20/EIP20.sol b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/eip20/EIP20.sol similarity index 93% rename from packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/eip20/EIP20.sol rename to packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/eip20/EIP20.sol index de6cfbc872f..fa200b7f975 100644 --- a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/eip20/EIP20.sol +++ b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/eip20/EIP20.sol @@ -21,9 +21,9 @@ contract EIP20 is EIP20Interface { constructor( uint256 _initialAmount, - string _tokenName, + string memory _tokenName, uint8 _decimalUnits, - string _tokenSymbol + string memory _tokenSymbol ) public { balances[msg.sender] = _initialAmount; // Give the creator all initial tokens totalSupply = _initialAmount; // Update total supply @@ -40,7 +40,7 @@ contract EIP20 is EIP20Interface { require(balances[msg.sender] >= _value); balances[msg.sender] -= _value; balances[_to] += _value; - Transfer(msg.sender, _to, _value); + emit Transfer(msg.sender, _to, _value); return true; } @@ -54,7 +54,7 @@ contract EIP20 is EIP20Interface { if (allowance < MAX_UINT256) { allowed[_from][msg.sender] -= _value; } - Transfer(_from, _to, _value); + emit Transfer(_from, _to, _value); return true; } @@ -64,7 +64,7 @@ contract EIP20 is EIP20Interface { function approve(address _spender, uint256 _value) public returns (bool success) { allowed[msg.sender][_spender] = _value; - Approval(msg.sender, _spender, _value); + emit Approval(msg.sender, _spender, _value); return true; } diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/eip20/EIP20Factory.sol b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/eip20/EIP20Factory.sol similarity index 100% rename from packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/eip20/EIP20Factory.sol rename to packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/eip20/EIP20Factory.sol diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/eip20/EIP20Interface.sol b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/eip20/EIP20Interface.sol similarity index 100% rename from packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/contracts/eip20/EIP20Interface.sol rename to packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/_src/contracts/eip20/EIP20Interface.sol diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/ethpm.json b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/ethpm.json deleted file mode 100644 index 31b790d4046..00000000000 --- a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/ethpm.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "authors": [ - "Simon de la Rouviere ", - "Joseph Chow " - ], - "license": "MIT", - "description": "Ethereum Token Contracts", - "keywords": [ - "tokens", - "consensys" - ], - "links": {}, - "sources": [ - "./contracts/Migrations.sol", - "./contracts/eip20/EIP20.sol", - "./contracts/eip20/EIP20Factory.sol", - "./contracts/eip20/EIP20Interface.sol" - ], - "dependencies": {}, - "name": "tokens", - "version": "1.0.0" -} diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/lock.json b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/lock.json deleted file mode 100644 index 171fb927e9c..00000000000 --- a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/lock.json +++ /dev/null @@ -1 +0,0 @@ -{"lockfile_version":"1","package_name":"tokens","meta":{"authors":["Simon de la Rouviere ","Joseph Chow "],"license":"MIT","description":"Ethereum Token Contracts","keywords":["tokens","consensys"],"links":{}},"version":"1.0.0","contract_types":{"undefined":{"abi":[{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]}},"deployments":{},"sources":{"./contracts/Migrations.sol":"ipfs://QmZ72TqAAmZA1fBze7HBpRP6XspG7g62JzTbAb1pAX8AVs","./contracts/eip20/EIP20.sol":"ipfs://QmZL1B4nzrFLhpKepmKWtLeLhRc7mP1zDWXA1vd2oA46rL","./contracts/eip20/EIP20Factory.sol":"ipfs://QmSxZrx5QPEeoKKUxE3DCd9ZHPUr1NzVziZ7FoA5mA1sdC","./contracts/eip20/EIP20Interface.sol":"ipfs://Qmd6HweneNKWybsiXWGiQ4hvzPuV8Gm58sBncvsGRP7Y29"},"build_dependencies":{}} \ No newline at end of file diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/lock.uri b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/lock.uri deleted file mode 100644 index 3a51d96602b..00000000000 --- a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/lock.uri +++ /dev/null @@ -1 +0,0 @@ -ipfs://QmZKeKhJdrfkP5MiPPddNaLMUxyt9YdKb7UaBPLsA4QUs8 \ No newline at end of file diff --git a/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/manifest.json b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/manifest.json new file mode 100644 index 00000000000..c2beeaca8fd --- /dev/null +++ b/packages/truffle/test/sources/ethpm/_ethpm_packages/tokens/manifest.json @@ -0,0 +1 @@ +{"manifest":"ethpm/3","name":"tokens","meta":{"authors":["Simon de la Rouviere ","Joseph Chow "],"license":"MIT","description":"Ethereum Token Contracts","keywords":["tokens","consensys"],"links":{}},"version":"1.0.0","contractTypes":{"undefined":{"abi":[{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}]}},"deployments":{},"sources":{"./contracts/Migrations.sol":{"urls":["ipfs://QmZ72TqAAmZA1fBze7HBpRP6XspG7g62JzTbAb1pAX8AVs"]},"./contracts/eip20/EIP20.sol":{"urls":["ipfs://QmZL1B4nzrFLhpKepmKWtLeLhRc7mP1zDWXA1vd2oA46rL"]},"./contracts/eip20/EIP20Factory.sol":{"urls":"ipfs://QmSxZrx5QPEeoKKUxE3DCd9ZHPUr1NzVziZ7FoA5mA1sdC"]},"./contracts/eip20/EIP20Interface.sol":{"urls":["ipfs://Qmd6HweneNKWybsiXWGiQ4hvzPuV8Gm58sBncvsGRP7Y29"]}}} diff --git a/packages/truffle/test/sources/ethpm/contracts/PLCRVoting.sol b/packages/truffle/test/sources/ethpm/contracts/PLCRVoting.sol index e226113ef1f..c760c334484 100644 --- a/packages/truffle/test/sources/ethpm/contracts/PLCRVoting.sol +++ b/packages/truffle/test/sources/ethpm/contracts/PLCRVoting.sol @@ -1,6 +1,6 @@ pragma solidity ^0.5.0; -import "tokens/eip20/EIP20.sol"; +import "tokens/contracts/eip20/EIP20.sol"; import "./Local.sol"; contract PLCRVoting is EIP20, Local { @@ -10,6 +10,6 @@ contract PLCRVoting is EIP20, Local { } function attrUUID(address _user, uint _pollID) public pure returns (bytes32 UUID) { - return keccak256(_user, _pollID); + return keccak256(abi.encodePacked(_user, _pollID)); } } diff --git a/packages/truffle/test/sources/ethpm/ethpm.json b/packages/truffle/test/sources/ethpm/ethpm.json index a26b32d0abf..576ebe01ae4 100644 --- a/packages/truffle/test/sources/ethpm/ethpm.json +++ b/packages/truffle/test/sources/ethpm/ethpm.json @@ -1,19 +1,18 @@ { - "package_name": "plcrvoting", + "name": "plcrvoting", "version": "1.0.0", - "description": "PLCR voting for ERC20 tokens", - "authors": [ - "Yorke Rhodes", - "Cem Ozer", - "Aspyn Palatnick" - ], - "keywords": [ - "tokens", - "consensys", - "plcr" - ], - "dependencies": { - "tokens": "1.0.0" - }, - "license": "Apache 2.0" + "meta": { + "description": "PLCR voting for ERC20 tokens", + "authors": [ + "Yorke Rhodes", + "Cem Ozer", + "Aspyn Palatnick" + ], + "keywords": [ + "tokens", + "consensys", + "plcr" + ], + "license": "Apache 2.0" + } } diff --git a/packages/truffle/test/sources/ethpm/truffle-config.js b/packages/truffle/test/sources/ethpm/truffle-config.js index 5413666a818..f27f04f2148 100644 --- a/packages/truffle/test/sources/ethpm/truffle-config.js +++ b/packages/truffle/test/sources/ethpm/truffle-config.js @@ -1,6 +1,17 @@ module.exports = { + ethpm: { + ipfsHost: "ipfs.infura.io", + ipfsProtocol: "https", + ipfsPort: "5001", + version: "3", + registry: { + address: "0x0bd0200357D26A0bB5d1D1c1Fd56C317B68d15d5", + network: "ropsten" + } + }, networks: { ropsten: { + provider: "", host: "127.0.0.1", port: 8545, network_id: "*", diff --git a/packages/truffle/test/sources/install/init/truffle-config.js b/packages/truffle/test/sources/install/init/truffle-config.js index 7fb92004ded..dfa9911a95a 100644 --- a/packages/truffle/test/sources/install/init/truffle-config.js +++ b/packages/truffle/test/sources/install/init/truffle-config.js @@ -1,8 +1,19 @@ module.exports = { // See // to customize your Truffle configuration! + ethpm: { + ipfsHost: "ipfs.infura.io", + ipfsProtocol: "https", + ipfsPort: "5001", + version: "3", + registry: { + address: "0x0bd0200357D26A0bB5d1D1c1Fd56C317B68d15d5", + network: "development" + } + }, networks: { development: { + provider: "", host: "127.0.0.1", port: 8545, network_id: "*", diff --git a/packages/truffle/test/sources/monorepo/installed_contracts/ethpmpkg/EthPMImport.sol b/packages/truffle/test/sources/monorepo/truffleproject/_ethpm_packages/ethpmpkg/_src/EthPMImport.sol similarity index 100% rename from packages/truffle/test/sources/monorepo/installed_contracts/ethpmpkg/EthPMImport.sol rename to packages/truffle/test/sources/monorepo/truffleproject/_ethpm_packages/ethpmpkg/_src/EthPMImport.sol