From 6b2989d142c2e5686a6a359d32aa0073f7ca5cf6 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 26 Feb 2018 15:14:07 +0100 Subject: [PATCH 1/3] fix deploy and link libraries --- remix-lib/package.json | 1 + remix-lib/src/execution/txFormat.js | 48 ++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/remix-lib/package.json b/remix-lib/package.json index 263a38ea42..938e28cce3 100644 --- a/remix-lib/package.json +++ b/remix-lib/package.json @@ -14,6 +14,7 @@ ], "main": "./index.js", "dependencies": { + "async": "^2.1.2", "babel-preset-es2015": "^6.24.0", "babel-plugin-transform-object-assign": "^6.22.0", "babel-eslint": "^7.1.1", diff --git a/remix-lib/src/execution/txFormat.js b/remix-lib/src/execution/txFormat.js index 8959de4215..d32e5ad3fc 100644 --- a/remix-lib/src/execution/txFormat.js +++ b/remix-lib/src/execution/txFormat.js @@ -2,6 +2,7 @@ var ethJSABI = require('ethereumjs-abi') var helper = require('./txHelper') var executionContext = require('./execution-context') +var asyncJS = require('async') module.exports = { @@ -99,10 +100,37 @@ module.exports = { atAddress: function () {}, - linkBytecode: function (contract, contracts, udapp, callback, callbackStep) { - if (contract.evm.bytecode.object.indexOf('_') < 0) { - return callback(null, contract.evm.bytecode.object) - } + linkBytecodeStandard: function (contract, contracts, udapp, callback, callbackStep) { + asyncJS.eachOfSeries(contract.evm.bytecode.linkReferences, (libs, file, cbFile) => { + asyncJS.eachOfSeries(contract.evm.bytecode.linkReferences[file], (libRef, libName, cbLibDeployed) => { + var library = contracts[file][libName] + if (library) { + this.deployLibrary(file + ':' + libName, libName, library, contracts, udapp, (error, address) => { + if (error) { + return cbLibDeployed(error) + } + var hexAddress = address.toString('hex') + if (hexAddress.slice(0, 2) === '0x') { + hexAddress = hexAddress.slice(2) + } + contract.evm.bytecode.object = this.linkLibraryStandard(libName, hexAddress, contract) + cbLibDeployed() + }, callbackStep) + } else { + cbLibDeployed('Cannot find compilation data of library ' + libName) + } + }, (error) => { + cbFile(error) + }) + }, (error) => { + if (error) { + callbackStep(error) + } + callback(error, contract.evm.bytecode.object) + }) + }, + + linkBytecodeLegacy: function (contract, contracts, udapp, callback, callbackStep) { var libraryRefMatch = contract.evm.bytecode.object.match(/__([^_]{1,36})__/) if (!libraryRefMatch) { return callback('Invalid bytecode format.') @@ -129,12 +157,22 @@ module.exports = { if (hexAddress.slice(0, 2) === '0x') { hexAddress = hexAddress.slice(2) } - contract.evm.bytecode.object = this.linkLibraryStandard(libraryShortName, hexAddress, contract) contract.evm.bytecode.object = this.linkLibrary(libraryName, hexAddress, contract.evm.bytecode.object) this.linkBytecode(contract, contracts, udapp, callback, callbackStep) }, callbackStep) }, + linkBytecode: function (contract, contracts, udapp, callback, callbackStep) { + if (contract.evm.bytecode.object.indexOf('_') < 0) { + return callback(null, contract.evm.bytecode.object) + } + if (contract.evm.bytecode.linkReferences && Object.keys(contract.evm.bytecode.linkReferences).length) { + this.linkBytecodeStandard(contract, contracts, udapp, callback, callbackStep) + } else { + this.linkBytecodeLegacy(contract, contracts, udapp, callback, callbackStep) + } + }, + deployLibrary: function (libraryName, libraryShortName, library, contracts, udapp, callback, callbackStep) { var address = library.address if (address) { From 16281dfe869f4e2bdb5c7eb4c4cd0b996daf6425 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 26 Feb 2018 15:14:25 +0100 Subject: [PATCH 2/3] add tests: deploy / link librairies --- remix-lib/test/txFormat.js | 70 +++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/remix-lib/test/txFormat.js b/remix-lib/test/txFormat.js index 9644d6ab9e..fed299a778 100644 --- a/remix-lib/test/txFormat.js +++ b/remix-lib/test/txFormat.js @@ -3,9 +3,10 @@ var tape = require('tape') var txFormat = require('../src/execution/txFormat') var compiler = require('solc') var compilerInput = require('../src/helpers/compilerHelper').compilerInput +var executionContext = require('../src/execution/execution-context') var context -tape('ContractParameters - (TxFormat.buildData)', function (t) { +tape('ContractParameters - (TxFormat.buildData) - format input parameters', function (t) { var output = compiler.compileStandardWrapper(compilerInput(uintContract)) output = JSON.parse(output) var contract = output.contracts['test.sol']['uintContractTest'] @@ -30,6 +31,51 @@ function testWithInput (st, params, expected) { }, () => {}) } +tape('ContractParameters - (TxFormat.buildData) - link Libraries', function (t) { + executionContext.setContext('vm') + var output = compiler.compileStandardWrapper(compilerInput(deploySimpleLib)) + output = JSON.parse(output) + var contract = output.contracts['test.sol']['testContractLinkLibrary'] + var fakeDeployedContracts = { + lib1: '0xf7a10e525d4b168f45f74db1b61f63d3e7619e11', + lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2: '0xf7a10e525d4b168f45f74db1b61f63d3e7619e33', + testContractLinkLibrary: '0xf7a10e525d4b168f45f74db1b61f63d3e7619e22' + } + var udapp = { runTx: (param, callback) => { + callback(null, { + result: { + createdAddress: fakeDeployedContracts[param.data.contractName] + } + }) + } } // fake + context = { output, contract, udapp } + t.test('(TxFormat.buildData and link library (standard way))', function (st) { + st.plan(6) + testLinkLibrary(st, fakeDeployedContracts) + }) +}) + +function testLinkLibrary (st, fakeDeployedContracts) { + var deployMsg = ['creation of library test.sol:lib1 pending...', + 'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...'] + txFormat.buildData('testContractLinkLibrary', context.contract, context.output.contracts, true, context.contract.abi[0], '', context.udapp + , (error, data) => { + if (error) { return st.fails(error) } + console.log(data) + var linkedbyteCode = data.dataHex + var libReference = context.contract.evm.bytecode.linkReferences['test.sol']['lib1'] + st.equal(linkedbyteCode.substr(2 * libReference[0].start, 40), fakeDeployedContracts['lib1'].replace('0x', '')) + st.equal(linkedbyteCode.substr(2 * libReference[1].start, 40), fakeDeployedContracts['lib1'].replace('0x', '')) + + libReference = context.contract.evm.bytecode.linkReferences['test.sol']['lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2'] + st.equal(linkedbyteCode.substr(2 * libReference[0].start, 40), fakeDeployedContracts['lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2'].replace('0x', '')) + st.equal(linkedbyteCode.substr(2 * libReference[1].start, 40), fakeDeployedContracts['lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2'].replace('0x', '')) + }, (msg) => { + st.equal(msg, deployMsg[0]) + deployMsg.shift() + }) +} + var uintContract = `contract uintContractTest { uint _tp; address _ap; @@ -38,3 +84,25 @@ var uintContract = `contract uintContractTest { _ap = _a; } }` + +var deploySimpleLib = `pragma solidity ^0.4.4; + +library lib1 { + function getEmpty () { + } +} + +library lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 { + function getEmpty () { + } +} + +contract testContractLinkLibrary { + function get () { + lib1.getEmpty(); + lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2.getEmpty(); + lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2.getEmpty(); + lib1.getEmpty(); + } + }` + From 5f2d45b6f3f37d72c8ced8d33c604412736be277 Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 26 Feb 2018 15:42:07 +0100 Subject: [PATCH 3/3] use same test config as remix-ide --- remix-debugger/nightwatch.js | 4 ++-- remix-debugger/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/remix-debugger/nightwatch.js b/remix-debugger/nightwatch.js index 259ba280bc..6fd4a0bda9 100644 --- a/remix-debugger/nightwatch.js +++ b/remix-debugger/nightwatch.js @@ -62,8 +62,8 @@ module.exports = { 'desiredCapabilities': { 'browserName': 'safari', 'javascriptEnabled': true, - 'platform': 'OS X 10.10', - 'version': '8.0', + 'platform': 'OS X 10.11', + 'version': '10.0', 'acceptSslCerts': true, 'build': 'build-' + TRAVIS_JOB_NUMBER, 'tunnel-identifier': 'remix_tests_' + TRAVIS_JOB_NUMBER diff --git a/remix-debugger/package.json b/remix-debugger/package.json index 86aad2b8a1..4faeb77aa3 100644 --- a/remix-debugger/package.json +++ b/remix-debugger/package.json @@ -56,7 +56,7 @@ "nightwatch_remote_chrome": "nightwatch --config nightwatch.js --env chrome", "nightwatch_remote_firefox": "nightwatch --config nightwatch.js --env default", "nightwatch_remote_ie": "nightwatch --config nightwatch.js --env ie", - "nightwatch_remote_parallel": "nightwatch --config nightwatch.js --env ie,safari,chrome,default", + "nightwatch_remote_parallel": "nightwatch --config nightwatch.js --env safari,chrome,default", "nightwatch_remote_safari": "nightwatch --config nightwatch.js --env safari", "onchange": "onchange build/app.js -- npm run lint", "selenium": "selenium-standalone start",