Merge branch 'master' into bunsenstraat-patch-4

pull/5370/head
bunsenstraat 3 years ago committed by GitHub
commit fe34674348
  1. 63
      .circleci/config.yml
  2. 2
      .eslintrc
  3. 2
      apps/remix-ide-e2e/nightwatch.ts
  4. 15
      apps/remix-ide-e2e/src/commands/clickElementAtPosition.ts
  5. 4
      apps/remix-ide-e2e/src/local-plugin/.babelrc
  6. 16
      apps/remix-ide-e2e/src/local-plugin/.browserslistrc
  7. 248
      apps/remix-ide-e2e/src/local-plugin/.eslintrc
  8. 128
      apps/remix-ide-e2e/src/local-plugin/src/app/app.css
  9. 39
      apps/remix-ide-e2e/src/local-plugin/src/app/app.tsx
  10. 17
      apps/remix-ide-e2e/src/local-plugin/src/app/logo.svg
  11. 11
      apps/remix-ide-e2e/src/local-plugin/src/app/star.svg
  12. 0
      apps/remix-ide-e2e/src/local-plugin/src/assets/.gitkeep
  13. 3
      apps/remix-ide-e2e/src/local-plugin/src/environments/environment.prod.ts
  14. 6
      apps/remix-ide-e2e/src/local-plugin/src/environments/environment.ts
  15. BIN
      apps/remix-ide-e2e/src/local-plugin/src/favicon.ico
  16. 14
      apps/remix-ide-e2e/src/local-plugin/src/index.html
  17. 11
      apps/remix-ide-e2e/src/local-plugin/src/main.tsx
  18. 7
      apps/remix-ide-e2e/src/local-plugin/src/polyfills.ts
  19. 1
      apps/remix-ide-e2e/src/local-plugin/src/styles.css
  20. 13
      apps/remix-ide-e2e/src/local-plugin/tsconfig.app.json
  21. 16
      apps/remix-ide-e2e/src/local-plugin/tsconfig.json
  22. 6
      apps/remix-ide-e2e/src/tests/ballot.test.ts
  23. 41
      apps/remix-ide-e2e/src/tests/pluginManager.ts
  24. 63
      apps/remix-ide-e2e/src/tests/solidityUnittests.spec.ts
  25. 63
      apps/remix-ide-e2e/src/tests/terminal.test.ts
  26. 6
      apps/remix-ide-e2e/src/types/index.d.ts
  27. 21
      apps/remix-ide/ci/browser_tests_plugin_manager.sh
  28. 14
      apps/remix-ide/src/app/tabs/test-tab.js
  29. 18
      apps/solidity-compiler/webpack.config.js
  30. 8
      jest.config.js
  31. 8
      libs/remix-analyzer/package.json
  32. 4
      libs/remix-astwalker/package.json
  33. 2
      libs/remix-astwalker/src/@types/remix-lib/index.d.ts
  34. 3
      libs/remix-debug/package.json
  35. 2
      libs/remix-debug/src/code/codeUtils.ts
  36. 2
      libs/remix-debug/src/source/sourceMappingDecoder.ts
  37. 2
      libs/remix-debug/src/storage/storageResolver.ts
  38. 2
      libs/remix-debug/src/trace/traceHelper.ts
  39. 24
      libs/remix-debug/test/debugger.ts
  40. 19
      libs/remix-debug/test/decoder/localDecoder.ts
  41. 19
      libs/remix-debug/test/decoder/localsTests/calldata.ts
  42. 14
      libs/remix-debug/test/decoder/localsTests/int.ts
  43. 16
      libs/remix-debug/test/decoder/localsTests/misc.ts
  44. 14
      libs/remix-debug/test/decoder/localsTests/misc2.ts
  45. 14
      libs/remix-debug/test/decoder/localsTests/structArray.ts
  46. 34
      libs/remix-debug/test/decoder/stateTests/mapping.ts
  47. 76
      libs/remix-debug/test/decoder/vmCall.ts
  48. 2
      libs/remix-debug/test/tests.ts
  49. 73
      libs/remix-debug/test/vmCall.ts
  50. 25
      libs/remix-lib/src/execution/logsManager.ts
  51. 40
      libs/remix-lib/src/execution/txFormat.ts
  52. 8
      libs/remix-lib/src/execution/txHelper.ts
  53. 1
      libs/remix-lib/src/execution/txRunnerVM.ts
  54. 2
      libs/remix-lib/src/helpers/uiHelper.ts
  55. 4
      libs/remix-lib/src/init.ts
  56. 20
      libs/remix-lib/src/util.ts
  57. 12
      libs/remix-lib/src/web3Provider/web3VmProvider.ts
  58. 5
      libs/remix-simulator/src/methods/blocks.ts
  59. 20
      libs/remix-simulator/src/methods/misc.ts
  60. 6
      libs/remix-simulator/src/methods/net.ts
  61. 32
      libs/remix-simulator/src/methods/transactions.ts
  62. 31
      libs/remix-simulator/src/utils/logs.ts
  63. 46
      libs/remix-simulator/src/vm-context.ts
  64. 26
      libs/remix-simulator/test/blocks.ts
  65. 6
      libs/remix-solidity/package.json
  66. 9
      libs/remix-tests/src/testRunner.ts
  67. 4
      libs/remix-ui/plugin-manager/.eslintrc
  68. 90
      libs/remix-ui/plugin-manager/src/types.d.ts
  69. 6
      libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx
  70. 6
      libs/remix-url-resolver/package.json
  71. 4
      libs/remixd/src/bin/remixd.ts
  72. 13
      nx.json
  73. 94885
      package-lock.json
  74. 57
      package.json
  75. 8
      tsconfig.base.json
  76. 76
      workspace.json

@ -7,7 +7,7 @@ jobs:
lint: lint:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -35,7 +35,7 @@ jobs:
remix-libs: remix-libs:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -56,7 +56,7 @@ jobs:
remix-ide-chrome-1: remix-ide-chrome-1:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -89,7 +89,7 @@ jobs:
remix-ide-chrome-2: remix-ide-chrome-2:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -123,7 +123,7 @@ jobs:
remix-ide-firefox-1: remix-ide-firefox-1:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -156,7 +156,7 @@ jobs:
remix-ide-firefox-2: remix-ide-firefox-2:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -190,7 +190,7 @@ jobs:
remix-ide-run-deploy: remix-ide-run-deploy:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -220,11 +220,45 @@ jobs:
- store_artifacts: - store_artifacts:
path: ./reports/screenshots path: ./reports/screenshots
remix-ide-plugin-manager:
docker:
# specify the version you desire here
- image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
resource_class: xlarge
# - image: circleci/mongo:3.4.4
environment:
- COMMIT_AUTHOR_EMAIL: "yann@ethereum.org"
- COMMIT_AUTHOR: "Circle CI"
- FILES_TO_PACKAGE: "dist/apps/remix-ide/assets dist/apps/remix-ide/index.html dist/apps/remix-ide/main.js dist/apps/remix-ide/polyfills.js dist/apps/remix-ide/runtime.js dist/apps/remix-ide/vendor.js dist/apps/remix-ide/favicon.ico"
working_directory: ~/remix-project
steps:
- checkout
- run: npm install
- run: npx nx build remix-ide --with-deps
- run: npx nx build remix-ide-e2e-src-local-plugin
- run:
name: Download Selenium
command: ./node_modules/.bin/selenium-standalone install --drivers.chrome.version=2.39 --drivers.chrome.baseURL=https://chromedriver.storage.googleapis.com
- run:
name: Start Selenium
command: ./node_modules/.bin/selenium-standalone start --drivers.chrome.version=2.39 --drivers.chrome.baseURL=https://chromedriver.storage.googleapis.com
background: true
- run: ./apps/remix-ide/ci/browser_tests_plugin_manager.sh
- store_test_results:
path: ./reports/tests
- store_artifacts:
path: ./reports/screenshots
deploy-remix-live: deploy-remix-live:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -252,7 +286,7 @@ jobs:
publish: publish:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.19.0-buster - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -278,7 +312,7 @@ jobs:
deploy-remix-alpha: deploy-remix-alpha:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -306,7 +340,7 @@ jobs:
deploy-remix-beta: deploy-remix-beta:
docker: docker:
# specify the version you desire here # specify the version you desire here
- image: circleci/node:10.18.0-browsers - image: circleci/node:14.17.6-browsers
# Specify service dependencies here if necessary # Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images # CircleCI maintains a library of pre-built images
@ -355,6 +389,9 @@ workflows:
- remix-ide-run-deploy: - remix-ide-run-deploy:
requires: requires:
- lint - lint
- remix-ide-plugin-manager:
requires:
- lint
- publish: - publish:
requires: requires:
- lint - lint
@ -365,6 +402,7 @@ workflows:
- remix-ide-firefox-1 - remix-ide-firefox-1
- remix-ide-firefox-2 - remix-ide-firefox-2
- remix-ide-run-deploy - remix-ide-run-deploy
- remix-ide-plugin-manager
filters: filters:
branches: branches:
only: remix_live only: remix_live
@ -375,6 +413,7 @@ workflows:
- remix-ide-firefox-1 - remix-ide-firefox-1
- remix-ide-firefox-2 - remix-ide-firefox-2
- remix-ide-run-deploy - remix-ide-run-deploy
- remix-ide-plugin-manager
filters: filters:
branches: branches:
only: master only: master
@ -385,6 +424,8 @@ workflows:
- remix-ide-firefox-1 - remix-ide-firefox-1
- remix-ide-firefox-2 - remix-ide-firefox-2
- remix-ide-run-deploy - remix-ide-run-deploy
- remix-ide-plugin-manager
filters: filters:
branches: branches:
only: remix_beta only: remix_beta

@ -4,7 +4,7 @@
"parserOptions": { "parserOptions": {
"ecmaVersion": 2018, "ecmaVersion": 2018,
"sourceType": "module", "sourceType": "module",
"project": "./tsconfig.json" "project": "./tsconfig.base.json"
}, },
"plugins": ["@typescript-eslint", "@nrwl/nx"], "plugins": ["@typescript-eslint", "@nrwl/nx"],
"extends": "standard", "extends": "standard",

@ -30,7 +30,7 @@ module.exports = {
javascriptEnabled: true, javascriptEnabled: true,
acceptSslCerts: true acceptSslCerts: true
}, },
exclude: ['dist/apps/remix-ide-e2e/src/tests/runAndDeploy.js'] exclude: ['dist/apps/remix-ide-e2e/src/tests/runAndDeploy.js', 'dist/apps/remix-ide-e2e/src/tests/pluginManager.spec.ts']
}, },
chrome: { chrome: {

@ -2,9 +2,9 @@ import { NightwatchBrowser } from 'nightwatch'
import EventEmitter from 'events' import EventEmitter from 'events'
class ClickElement extends EventEmitter { class ClickElement extends EventEmitter {
command (this: NightwatchBrowser, cssSelector: string, index = 0): NightwatchBrowser { command (this: NightwatchBrowser, cssSelector: string, index = 0, opt = { forceSelectIfUnselected: false }): NightwatchBrowser {
this.api.perform((done) => { this.api.perform((done) => {
_clickElement(this.api, cssSelector, index, () => { _clickElement(this.api, cssSelector, index, opt.forceSelectIfUnselected, () => {
done() done()
this.emit('complete') this.emit('complete')
}) })
@ -13,13 +13,14 @@ class ClickElement extends EventEmitter {
} }
} }
function _clickElement (browser: NightwatchBrowser, cssSelector: string, index: number, cb: VoidFunction) { function _clickElement (browser: NightwatchBrowser, cssSelector: string, index: number, forceSelectIfUnselected: boolean, cb: VoidFunction) {
browser.waitForElementPresent(cssSelector) browser.waitForElementPresent(cssSelector)
.execute(function (cssSelector: string, index: number) { .execute(function (cssSelector: string, index: number, forceSelectIfUnselected: boolean) {
const elem = document.querySelectorAll(cssSelector)[index] as HTMLElement const elem = document.querySelectorAll(cssSelector)[index] as HTMLElement
if (forceSelectIfUnselected) {
elem.click() if (!(elem as any).checked) elem.click()
}, [cssSelector, index], function () { } else elem.click()
}, [cssSelector, index, forceSelectIfUnselected], function () {
cb() cb()
}) })
} }

@ -0,0 +1,4 @@
{
"presets": ["@nrwl/react/babel"],
"plugins": []
}

@ -0,0 +1,16 @@
# This file is used by:
# 1. autoprefixer to adjust CSS to support the below specified browsers
# 2. babel preset-env to adjust included polyfills
#
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
#
# If you need to support different browsers in production, you may tweak the list below.
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major version
last 2 iOS major versions
Firefox ESR
not IE 9-11 # For IE 9-11 support, remove 'not'.

@ -0,0 +1,248 @@
{
"rules": {
"array-callback-return": "warn",
"dot-location": ["warn", "property"],
"eqeqeq": ["warn", "smart"],
"new-parens": "warn",
"no-caller": "warn",
"no-cond-assign": ["warn", "except-parens"],
"no-const-assign": "warn",
"no-control-regex": "warn",
"no-delete-var": "warn",
"no-dupe-args": "warn",
"no-dupe-keys": "warn",
"no-duplicate-case": "warn",
"no-empty-character-class": "warn",
"no-empty-pattern": "warn",
"no-eval": "warn",
"no-ex-assign": "warn",
"no-extend-native": "warn",
"no-extra-bind": "warn",
"no-extra-label": "warn",
"no-fallthrough": "warn",
"no-func-assign": "warn",
"no-implied-eval": "warn",
"no-invalid-regexp": "warn",
"no-iterator": "warn",
"no-label-var": "warn",
"no-labels": ["warn", { "allowLoop": true, "allowSwitch": false }],
"no-lone-blocks": "warn",
"no-loop-func": "warn",
"no-mixed-operators": [
"warn",
{
"groups": [
["&", "|", "^", "~", "<<", ">>", ">>>"],
["==", "!=", "===", "!==", ">", ">=", "<", "<="],
["&&", "||"],
["in", "instanceof"]
],
"allowSamePrecedence": false
}
],
"no-multi-str": "warn",
"no-native-reassign": "warn",
"no-negated-in-lhs": "warn",
"no-new-func": "warn",
"no-new-object": "warn",
"no-new-symbol": "warn",
"no-new-wrappers": "warn",
"no-obj-calls": "warn",
"no-octal": "warn",
"no-octal-escape": "warn",
"no-redeclare": "warn",
"no-regex-spaces": "warn",
"no-restricted-syntax": ["warn", "WithStatement"],
"no-script-url": "warn",
"no-self-assign": "warn",
"no-self-compare": "warn",
"no-sequences": "warn",
"no-shadow-restricted-names": "warn",
"no-sparse-arrays": "warn",
"no-template-curly-in-string": "warn",
"no-this-before-super": "warn",
"no-throw-literal": "warn",
"no-restricted-globals": [
"error",
"addEventListener",
"blur",
"close",
"closed",
"confirm",
"defaultStatus",
"defaultstatus",
"event",
"external",
"find",
"focus",
"frameElement",
"frames",
"history",
"innerHeight",
"innerWidth",
"length",
"location",
"locationbar",
"menubar",
"moveBy",
"moveTo",
"name",
"onblur",
"onerror",
"onfocus",
"onload",
"onresize",
"onunload",
"open",
"opener",
"opera",
"outerHeight",
"outerWidth",
"pageXOffset",
"pageYOffset",
"parent",
"print",
"removeEventListener",
"resizeBy",
"resizeTo",
"screen",
"screenLeft",
"screenTop",
"screenX",
"screenY",
"scroll",
"scrollbars",
"scrollBy",
"scrollTo",
"scrollX",
"scrollY",
"self",
"status",
"statusbar",
"stop",
"toolbar",
"top"
],
"no-unexpected-multiline": "warn",
"no-unreachable": "warn",
"no-unused-expressions": [
"error",
{
"allowShortCircuit": true,
"allowTernary": true,
"allowTaggedTemplates": true
}
],
"no-unused-labels": "warn",
"no-useless-computed-key": "warn",
"no-useless-concat": "warn",
"no-useless-escape": "warn",
"no-useless-rename": [
"warn",
{
"ignoreDestructuring": false,
"ignoreImport": false,
"ignoreExport": false
}
],
"no-with": "warn",
"no-whitespace-before-property": "warn",
"react-hooks/exhaustive-deps": "warn",
"require-yield": "warn",
"rest-spread-spacing": ["warn", "never"],
"strict": ["warn", "never"],
"unicode-bom": ["warn", "never"],
"use-isnan": "warn",
"valid-typeof": "warn",
"no-restricted-properties": [
"error",
{
"object": "require",
"property": "ensure",
"message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
},
{
"object": "System",
"property": "import",
"message": "Please use import() instead. More info: https://facebook.github.io/create-react-app/docs/code-splitting"
}
],
"getter-return": "warn",
"import/first": "error",
"import/no-amd": "error",
"import/no-webpack-loader-syntax": "error",
"react/forbid-foreign-prop-types": ["warn", { "allowInPropTypes": true }],
"react/jsx-no-comment-textnodes": "warn",
"react/jsx-no-duplicate-props": "warn",
"react/jsx-no-target-blank": "warn",
"react/jsx-no-undef": "error",
"react/jsx-pascal-case": ["warn", { "allowAllCaps": true, "ignore": [] }],
"react/jsx-uses-react": "warn",
"react/jsx-uses-vars": "warn",
"react/no-danger-with-children": "warn",
"react/no-direct-mutation-state": "warn",
"react/no-is-mounted": "warn",
"react/no-typos": "error",
"react/react-in-jsx-scope": "error",
"react/require-render-return": "error",
"react/style-prop-object": "warn",
"react/jsx-no-useless-fragment": "warn",
"jsx-a11y/accessible-emoji": "warn",
"jsx-a11y/alt-text": "warn",
"jsx-a11y/anchor-has-content": "warn",
"jsx-a11y/anchor-is-valid": [
"warn",
{ "aspects": ["noHref", "invalidHref"] }
],
"jsx-a11y/aria-activedescendant-has-tabindex": "warn",
"jsx-a11y/aria-props": "warn",
"jsx-a11y/aria-proptypes": "warn",
"jsx-a11y/aria-role": "warn",
"jsx-a11y/aria-unsupported-elements": "warn",
"jsx-a11y/heading-has-content": "warn",
"jsx-a11y/iframe-has-title": "warn",
"jsx-a11y/img-redundant-alt": "warn",
"jsx-a11y/no-access-key": "warn",
"jsx-a11y/no-distracting-elements": "warn",
"jsx-a11y/no-redundant-roles": "warn",
"jsx-a11y/role-has-required-aria-props": "warn",
"jsx-a11y/role-supports-aria-props": "warn",
"jsx-a11y/scope": "warn",
"react-hooks/rules-of-hooks": "error",
"default-case": "off",
"no-dupe-class-members": "off",
"no-undef": "off",
"@typescript-eslint/consistent-type-assertions": "warn",
"no-array-constructor": "off",
"@typescript-eslint/no-array-constructor": "warn",
"@typescript-eslint/no-namespace": "error",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": [
"warn",
{
"functions": false,
"classes": false,
"variables": false,
"typedefs": false
}
],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{ "args": "none", "ignoreRestSiblings": true }
],
"no-useless-constructor": "off",
"@typescript-eslint/no-useless-constructor": "warn"
},
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"jest": true,
"node": true
},
"settings": { "react": { "version": "detect" } },
"plugins": ["import", "jsx-a11y", "react", "react-hooks"],
"extends": ["../../../../.eslintrc"],
"ignorePatterns": ["!**/*"]
}

@ -0,0 +1,128 @@
.app {
font-family: sans-serif;
min-width: 300px;
max-width: 600px;
margin: 50px auto;
}
.app .gutter-left {
margin-left: 9px;
}
.app .col-span-2 {
grid-column: span 2;
}
.app .flex {
display: flex;
align-items: center;
justify-content: center;
}
.app header {
background-color: #143055;
color: white;
padding: 5px;
border-radius: 3px;
}
.app main {
padding: 0 36px;
}
.app p {
text-align: center;
}
.app h1 {
text-align: center;
margin-left: 18px;
font-size: 24px;
}
.app h2 {
text-align: center;
font-size: 20px;
margin: 40px 0 10px 0;
}
.app .resources {
text-align: center;
list-style: none;
padding: 0;
display: grid;
grid-gap: 9px;
grid-template-columns: 1fr 1fr;
}
.app .resource {
color: #0094ba;
height: 36px;
background-color: rgba(0, 0, 0, 0);
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 4px;
padding: 3px 9px;
text-decoration: none;
}
.app .resource:hover {
background-color: rgba(68, 138, 255, 0.04);
}
.app pre {
padding: 9px;
border-radius: 4px;
background-color: black;
color: #eee;
}
.app details {
border-radius: 4px;
color: #333;
background-color: rgba(0, 0, 0, 0);
border: 1px solid rgba(0, 0, 0, 0.12);
padding: 3px 9px;
margin-bottom: 9px;
}
.app summary {
outline: none;
height: 36px;
line-height: 36px;
}
.app .github-star-container {
margin-top: 12px;
line-height: 20px;
}
.app .github-star-container a {
display: flex;
align-items: center;
text-decoration: none;
color: #333;
}
.app .github-star-badge {
color: #24292e;
display: flex;
align-items: center;
font-size: 12px;
padding: 3px 10px;
border: 1px solid rgba(27, 31, 35, 0.2);
border-radius: 3px;
background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
margin-left: 4px;
font-weight: 600;
}
.app .github-star-badge:hover {
background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
border-color: rgba(27, 31, 35, 0.35);
background-position: -0.5em;
}
.app .github-star-badge .material-icons {
height: 16px;
width: 16px;
margin-right: 4px;
}

@ -0,0 +1,39 @@
import React, { useEffect, useState } from 'react'
import { PluginClient } from '@remixproject/plugin'
import { createClient } from '@remixproject/plugin-webview'
import './app.css'
import { ReactComponent as Logo } from './logo.svg'
export const App = () => {
const [remixClient, setRemixClient] = useState(null)
useEffect(() => {
(async () => {
const client = createClient(new PluginClient())
await client.onload()
console.log('Local plugin loaded')
setRemixClient(client)
})()
}, [])
const handleClick = () => {
remixClient.call('manager', 'activatePlugin', 'LearnEth')
}
return (
<div className="app">
<header className="flex">
<Logo width="75" height="75" />
<h1>Welcome to local-plugin!</h1>
</header>
<main>
<button data-id="btnActivateRemixd" onClick={handleClick}>Activate Learneth</button>
</main>
</div>
)
}
export default App

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="262px" height="163px" viewBox="0 0 262 163" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Styles-&amp;-Quick-Wins" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Nx---Quick-Wins" transform="translate(-476.000000, -1284.000000)" fill-rule="nonzero">
<g id="Logos" transform="translate(-11.000000, 782.000000)">
<g id="Nx_Flat_White" transform="translate(487.000000, 502.000000)">
<polygon id="Path" fill="#FFFFFF" points="130.68 104.59 97.49 52.71 97.44 96.3 40.24 0 0 0 0 162.57 39.79 162.57 39.92 66.39 96.53 158.26"></polygon>
<polygon id="Path" fill="#FFFFFF" points="97.5 41.79 137.24 41.79 137.33 41.33 137.33 0 97.54 0 97.49 41.33"></polygon>
<path d="M198.66,86.86 C189.139872,86.6795216 180.538723,92.516445 177.19,101.43 C182.764789,93.0931021 193.379673,89.7432211 202.73,93.37 C207.05,95.13 212.73,97.97 217.23,96.45 C212.950306,90.4438814 206.034895,86.8725952 198.66,86.86 L198.66,86.86 Z" id="Path" fill="#96D8E9"></path>
<path d="M243.75,106.42 C243.75,101.55 241.1,100.42 235.6,98.42 C231.52,97 226.89,95.4 223.52,91 C222.86,90.13 222.25,89.15 221.6,88.11 C220.14382,85.4164099 218.169266,83.037429 215.79,81.11 C212.58,78.75 208.37,77.6 202.91,77.6 C191.954261,77.6076705 182.084192,84.2206169 177.91,94.35 C183.186964,87.0278244 191.956716,83.0605026 200.940147,83.9314609 C209.923578,84.8024193 217.767888,90.3805017 221.54,98.58 C223.424615,101.689762 227.141337,103.174819 230.65,102.22 C236.02,101.07 235.65,106.15 243.76,107.87 L243.75,106.42 Z" id="Path" fill="#48C4E5"></path>
<path d="M261.46,105.38 L261.46,105.27 C261.34,73.03 235.17,45.45 202.91,45.45 C183.207085,45.4363165 164.821777,55.3450614 154,71.81 L153.79,71.45 L137.23,45.45 L97.5,45.4499858 L135.25,104.57 L98.41,162.57 L137,162.57 L153.79,136.78 L170.88,162.57 L209.48,162.57 L174.48,107.49 C173.899005,106.416838 173.583536,105.220114 173.56,104 C173.557346,96.2203871 176.64661,88.7586448 182.147627,83.2576275 C187.648645,77.7566101 195.110387,74.6673462 202.89,74.67 C219.11,74.67 221.82,84.37 225.32,88.93 C232.23,97.93 246.03,93.99 246.03,105.73 L246.03,105.73 C246.071086,108.480945 247.576662,111.001004 249.979593,112.340896 C252.382524,113.680787 255.317747,113.636949 257.679593,112.225896 C260.041438,110.814842 261.471086,108.250945 261.43,105.5 L261.43,105.5 L261.43,105.38 L261.46,105.38 Z" id="Path" fill="#FFFFFF"></path>
<path d="M261.5,113.68 C261.892278,116.421801 261.504116,119.218653 260.38,121.75 C258.18,126.84 254.51,125.14 254.51,125.14 C254.51,125.14 251.35,123.6 253.27,120.65 C255.4,117.36 259.61,117.74 261.5,113.68 Z" id="Path" fill="#FFFFFF"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg
className="material-icons"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path d="M0 0h24v24H0z" fill="none" />
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" />
</svg>

After

Width:  |  Height:  |  Size: 347 B

@ -0,0 +1,3 @@
export const environment = {
production: true
}

@ -0,0 +1,6 @@
// This file can be replaced during build by using the `fileReplacements` array.
// When building for production, this file is replaced with `environment.prod.ts`.
export const environment = {
production: false
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>LocalPlugin</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<div id="root"></div>
</body>
</html>

@ -0,0 +1,11 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from './app/app'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
)

@ -0,0 +1,7 @@
/**
* Polyfill stable language features. These imports will be optimized by `@babel/preset-env`.
*
* See: https://github.com/zloirock/core-js#babel
*/
import 'core-js/stable'
import 'regenerator-runtime/runtime'

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

@ -0,0 +1,13 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

@ -0,0 +1,16 @@
{
"extends": "../../../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
}
]
}

@ -56,7 +56,8 @@ module.exports = {
.waitForElementVisible('#stepdetail') .waitForElementVisible('#stepdetail')
.goToVMTraceStep(144) .goToVMTraceStep(144)
.pause(2000) .pause(2000)
.checkVariableDebug('soliditystate', stateCheck) // Should be uncommented while fixing https://github.com/ethereum/remix-project/issues/1644
// .checkVariableDebug('soliditystate', stateCheck)
.checkVariableDebug('soliditylocals', localsCheck) .checkVariableDebug('soliditylocals', localsCheck)
}, },
@ -116,7 +117,7 @@ const localsCheck = {
type: 'address' type: 'address'
} }
} }
/*
const stateCheck = { const stateCheck = {
chairperson: { chairperson: {
value: '0xCA35B7D915458EF540ADE6068DFE2F44E8FA733C', value: '0xCA35B7D915458EF540ADE6068DFE2F44E8FA733C',
@ -174,6 +175,7 @@ const stateCheck = {
immutable: false immutable: false
} }
} }
*/
const ballotABI = `[ const ballotABI = `[
{ {

@ -12,6 +12,13 @@ const testData = {
pluginUrl: 'https://zokrates.github.io/zokrates-remix-plugin/' pluginUrl: 'https://zokrates.github.io/zokrates-remix-plugin/'
} }
const localPluginData = {
pluginName: 'localPlugin',
pluginDisplayName: 'Local Plugin',
pluginCanActivate: 'LearnEth',
pluginUrl: 'http://localhost:2020'
}
module.exports = { module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) { before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, 'http://127.0.0.1:8080', false) init(browser, done, 'http://127.0.0.1:8080', false)
@ -147,8 +154,38 @@ module.exports = {
.assert.containsText('*[data-shared="tooltipPopup"]', 'Cannot create Plugin : This name has already been used') .assert.containsText('*[data-shared="tooltipPopup"]', 'Cannot create Plugin : This name has already been used')
}, },
'Local plugin should activate LearnEth plugin': function (browser: NightwatchBrowser) {
browser
.waitForElementVisible('*[data-id="pluginManagerComponentPluginManager"]')
.click('*[data-id="pluginManagerComponentPluginSearchButton"]')
.waitForElementVisible('*[data-id="pluginManagerLocalPluginModalDialogModalDialogContainer-react"]')
.click('*[data-id="pluginManagerLocalPluginModalDialogModalDialogModalBody-react"]')
.waitForElementVisible('*[data-id="localPluginName"]')
.clearValue('*[data-id="localPluginName"]').setValue('*[data-id="localPluginName"]', localPluginData.pluginName)
.clearValue('*[data-id="localPluginDisplayName"]').setValue('*[data-id="localPluginDisplayName"]', localPluginData.pluginDisplayName)
.clearValue('*[data-id="localPluginCanActivate"]').setValue('*[data-id="localPluginCanActivate"]', localPluginData.pluginCanActivate)
.clearValue('*[data-id="localPluginUrl"]').setValue('*[data-id="localPluginUrl"]', localPluginData.pluginUrl)
.click('*[data-id="localPluginRadioButtoniframe"]')
.click('*[data-id="localPluginRadioButtonsidePanel"]')
.click('*[data-id="pluginManagerLocalPluginModalDialogModalDialogModalFooter-react"]')
.click('*[data-id="pluginManagerLocalPluginModalDialog-modal-footer-ok-react')
.waitForElementVisible('[data-id="verticalIconsKindlocalPlugin"]')
.click('[data-id="verticalIconsKindlocalPlugin"]')
.waitForElementNotPresent('[data-id="verticalIconsKindLearnEth"]')
.pause(2000)
// @ts-ignore
.frame('plugin-localPlugin')
.useXpath().click("//button[text()='Activate Learneth']")
.pause(2000)
.frameParent()
.useCss().waitForElementPresent('[data-id="verticalIconsKindLearnEth"]')
},
'Should load back installed plugins after reload': function (browser: NightwatchBrowser) { 'Should load back installed plugins after reload': function (browser: NightwatchBrowser) {
browser.waitForElementVisible('*[data-id="pluginManagerComponentPluginManager"]') browser
.waitForElementVisible('*[data-id="remixIdeSidePanel"]')
.click('*[plugin="pluginManager"]')
.waitForElementVisible('*[data-id="pluginManagerComponentPluginManager"]')
.getInstalledPlugins((plugins) => { .getInstalledPlugins((plugins) => {
browser.refresh() browser.refresh()
.waitForElementVisible('*[data-id="remixIdeSidePanel"]') .waitForElementVisible('*[data-id="remixIdeSidePanel"]')
@ -156,7 +193,7 @@ module.exports = {
.perform((done) => { .perform((done) => {
// const filtered = plugins.filter(plugin => plugin !== 'testremixIde') // remove this when localplugin bug is resolved // const filtered = plugins.filter(plugin => plugin !== 'testremixIde') // remove this when localplugin bug is resolved
plugins.forEach(plugin => { plugins.forEach(plugin => {
if (plugin !== testData.pluginName && plugin !== 'testremixIde') { if ((plugin !== testData.pluginName) && plugin !== localPluginData.pluginName) {
browser.waitForElementVisible(`[plugin="${plugin}"`) browser.waitForElementVisible(`[plugin="${plugin}"`)
} }
}) })

@ -90,11 +90,10 @@ module.exports = {
.waitForElementContainsText('*[data-id="testTabTestsExecutionStopped"]', 'The test execution has been stopped', 60000) .waitForElementContainsText('*[data-id="testTabTestsExecutionStopped"]', 'The test execution has been stopped', 60000)
}, },
'Should fail on compilation': function (browser: NightwatchBrowser) { 'Should fail on compilation, open file on error click, not disappear error': function (browser: NightwatchBrowser) {
browser.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]') browser.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]')
.addFile('tests/compilationError_test.sol', sources[0]['compilationError_test.sol']) .addFile('tests/compilationError_test.sol', sources[0]['compilationError_test.sol'])
.clickLaunchIcon('filePanel') .click('div[title="default_workspace/tests/compilationError_test.sol"] span[class="close"]')
.openFile('tests/compilationError_test.sol')
.clickLaunchIcon('solidityUnitTesting') .clickLaunchIcon('solidityUnitTesting')
.pause(2000) .pause(2000)
.click('*[data-id="testTabCheckAllTests"]') .click('*[data-id="testTabCheckAllTests"]')
@ -102,6 +101,12 @@ module.exports = {
.scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]') .scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]')
.waitForElementContainsText('*[data-id="testTabSolidityUnitTestsOutput"]', 'SyntaxError: No visibility specified', 120000) .waitForElementContainsText('*[data-id="testTabSolidityUnitTestsOutput"]', 'SyntaxError: No visibility specified', 120000)
.waitForElementContainsText('*[data-id="testTabTestsExecutionStoppedError"]', 'The test execution has been stopped because of error(s) in your test file', 120000) .waitForElementContainsText('*[data-id="testTabTestsExecutionStoppedError"]', 'The test execution has been stopped because of error(s) in your test file', 120000)
.click('*[data-id="tests/compilationError_test.sol"]')
.pause(1000)
.getEditorValue((content) => browser.assert.ok(content.indexOf('contract failOnCompilation {') !== -1))
// Verify that compilation error is still present after a file is opened
// usually, tests result is cleared on opening a new file
.verify.elementPresent('*[data-id="tests/compilationError_test.sol"]')
}, },
'Should fail on deploy': function (browser: NightwatchBrowser) { 'Should fail on deploy': function (browser: NightwatchBrowser) {
@ -135,7 +140,7 @@ module.exports = {
.clickLaunchIcon('solidityUnitTesting') .clickLaunchIcon('solidityUnitTesting')
.setValue('*[data-id="uiPathInput"]', 'myTests') .setValue('*[data-id="uiPathInput"]', 'myTests')
.click('*[data-id="testTabGenerateTestFolder"]') .click('*[data-id="testTabGenerateTestFolder"]')
.clickElementAtPosition('.singleTestLabel', 0) .clickElementAtPosition('.singleTest', 0, { forceSelectIfUnselected: true })
.scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]') .scrollAndClick('*[data-id="testTabRunTestsTabRunAction"]')
.waitForElementPresent('*[data-id="testTabSolidityUnitTestsOutputheader"]', 60000) .waitForElementPresent('*[data-id="testTabSolidityUnitTestsOutputheader"]', 60000)
.waitForElementPresent('*[data-id="testTabSolidityUnitTestsOutput"]') .waitForElementPresent('*[data-id="testTabSolidityUnitTestsOutput"]')
@ -207,6 +212,23 @@ module.exports = {
.removeFile('tests/hhLogs_test.sol', 'workspace_new') .removeFile('tests/hhLogs_test.sol', 'workspace_new')
}, },
'Solidity Unit tests with hardhat console log for EVM revert': function (browser: NightwatchBrowser) {
browser
.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]')
.addFile('tests/ballotFailedLog_test.sol', sources[0]['tests/ballotFailedLog_test.sol'])
.clickLaunchIcon('solidityUnitTesting')
.waitForElementVisible('*[id="singleTesttests/4_Ballot_test.sol"]', 60000)
.click('*[id="singleTesttests/4_Ballot_test.sol"]')
.click('#runTestsTabRunAction')
.pause(2000)
.waitForElementVisible('*[data-id="testTabSolidityUnitTestsOutputheader"]', 120000)
.waitForElementContainsText('#solidityUnittestsOutput', 'tests/ballotFailedLog_test.sol', 60000)
.assert.containsText('#journal > div:nth-child(6) > span > div', 'Check winning proposal:')
.assert.containsText('#journal > div:nth-child(6) > span > div', 'Inside checkWinningProposal')
.openFile('tests/ballotFailedLog_test.sol')
.removeFile('tests/ballotFailedLog_test.sol', 'workspace_new')
},
'Debug failed test using debugger': function (browser: NightwatchBrowser) { 'Debug failed test using debugger': function (browser: NightwatchBrowser) {
browser browser
.waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]') .waitForElementPresent('*[data-id="verticalIconsKindfilePanel"]')
@ -230,7 +252,8 @@ module.exports = {
.waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposal()', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'checkWinningProposal()', 60000)
.waitForElementContainsText('*[data-id="functionPanel"]', 'vote(proposal)', 60000) .waitForElementContainsText('*[data-id="functionPanel"]', 'vote(proposal)', 60000)
.pause(2000) .pause(2000)
.checkVariableDebug('soliditylocals', locals) // Should be uncommented while fixing https://github.com/ethereum/remix-project/issues/1644
// .checkVariableDebug('soliditylocals', locals)
.clickLaunchIcon('filePanel') .clickLaunchIcon('filePanel')
.pause(2000) .pause(2000)
.openFile('tests/ballotFailedDebug_test.sol') .openFile('tests/ballotFailedDebug_test.sol')
@ -424,7 +447,7 @@ const sources = [
}, },
'compilationError_test.sol': { 'compilationError_test.sol': {
content: ` content: `
pragma solidity ^0.7.0; pragma solidity ^0.8.0;
contract failOnCompilation { contract failOnCompilation {
fallback() { fallback() {
@ -483,6 +506,31 @@ const sources = [
} }
}` }`
}, },
'tests/ballotFailedLog_test.sol': {
content: `// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "remix_tests.sol"; // this import is automatically injected by Remix.
import "../contracts/3_Ballot.sol";
import "hardhat/console.sol";
contract BallotTest {
bytes32[] proposalNames;
Ballot ballotToTest;
function beforeAll () public {
proposalNames.push(bytes32("candidate1"));
ballotToTest = new Ballot(proposalNames);
}
function checkWinningProposal () public {
console.log("Inside checkWinningProposal");
ballotToTest.vote(1); // This will revert the transaction
}
}`
},
'tests/hhLogs_test.sol': { 'tests/hhLogs_test.sol': {
content: `// SPDX-License-Identifier: GPL-3.0 content: `// SPDX-License-Identifier: GPL-3.0
@ -510,7 +558,7 @@ const sources = [
} }
} }
] ]
/*
const locals = { const locals = {
sender: { sender: {
value: { value: {
@ -538,3 +586,4 @@ const locals = {
type: 'uint256' type: 'uint256'
} }
} }
*/

@ -107,6 +107,32 @@ module.exports = {
.executeScript('remix.execute(\'resolveExternalUrlAndSaveToaPath.js\')') .executeScript('remix.execute(\'resolveExternalUrlAndSaveToaPath.js\')')
.waitForElementContainsText('*[data-id="terminalJournal"]', 'abstract contract ERC20Burnable', 60000) .waitForElementContainsText('*[data-id="terminalJournal"]', 'abstract contract ERC20Burnable', 60000)
.openFile('.deps/github/newFile.sol') .openFile('.deps/github/newFile.sol')
},
'Deploy "Owner" using an ether.js script, listen to event and check event are logged in the terminal': function (browser: NightwatchBrowser) {
browser
.clickLaunchIcon('settings')
.clickLaunchIcon('udapp')
.click('*[data-id="settingsVMLondonMode"]')
.click('*[data-id="terminalClearConsole"]') // clear the terminal
.clickLaunchIcon('filePanel')
.click('*[data-id="treeViewDivtreeViewItem"]') // make sure we create the file at the root folder
.addFile('deployWithEthersJs.js', { content: deployWithEthersJs })
.openFile('deployWithEthersJs.js')
.pause(1000)
.openFile('contracts/2_Owner.sol')
.clickLaunchIcon('solidity')
.click('*[data-id="compilerContainerCompileBtn"]') // compile Owner
.executeScript('remix.execute(\'deployWithEthersJs.js\')')
.waitForElementContainsText('*[data-id="terminalJournal"]', 'Contract Address: 0xd9145CCE52D386f254917e481eB44e9943F39138', 60000)
.waitForElementContainsText('*[data-id="terminalJournal"]', 'Deployment successful.', 60000)
.addAtAddressInstance('0xd9145CCE52D386f254917e481eB44e9943F39138', true, true)
.click('*[data-id="terminalClearConsole"]') // clear the terminal
.waitForElementPresent('*[data-id="universalDappUiContractActionWrapper"]', 60000)
.click('*[data-id="universalDappUiTitleExpander"]')
.clickFunction('changeOwner - transact (not payable)', { types: 'address newOwner', values: '0xd9145CCE52D386f254917e481eB44e9943F39138' }) // execute the "changeOwner" function
.waitForElementContainsText('*[data-id="terminalJournal"]', 'previousOwner0x5B38Da6a701c568545dCfcB03FcB875f56beddC4', 60000) // check that the script is logging the event
.waitForElementContainsText('*[data-id="terminalJournal"]', 'newOwner0xd9145CCE52D386f254917e481eB44e9943F39138', 60000)
.end() .end()
} }
} }
@ -180,3 +206,40 @@ const resolveUrl = `
} }
})() })()
` `
const deployWithEthersJs = `
// Right click on the script name and hit "Run" to execute
(async () => {
try {
console.log('Running deployWithEthers script...')
const constructorArgs = [] // Put constructor args (if any) here for your contract
// Note that the script needs the ABI which is generated from the compilation artifact.
// Make sure contract is compiled and artifacts are generated
const artifactsPath = 'contracts/artifacts/Owner.json' // Change this for different path
const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
// 'web3Provider' is a remix global variable object
const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner()
let factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer);
let contract = await factory.deploy(...constructorArgs);
console.log('Contract Address: ', contract.address);
// The contract is NOT deployed yet; we must wait until it is mined
await contract.deployed()
console.log('Deployment successful.')
contract.on('OwnerSet', (previousOwner, newOwner) => {
console.log('previousOwner' , previousOwner)
console.log('newOwner' , newOwner)
})
console.log('ok')
} catch (e) {
console.log(e.message)
}
})()`

@ -1,8 +1,8 @@
// Merge custom command types with nightwatch types // Merge custom command types with nightwatch types
import { NightwatchBrowser, NightwatchBrowser, NightwatchBrowser } from "nightwatch"; import { NightwatchBrowser } from 'nightwatch'
declare module "nightwatch" { declare module 'nightwatch' {
export interface NightwatchCustomCommands { export interface NightwatchCustomCommands {
clickLaunchIcon(icon: string): NightwatchBrowser, clickLaunchIcon(icon: string): NightwatchBrowser,
switchBrowserTab(index: number): NightwatchBrowser, switchBrowserTab(index: number): NightwatchBrowser,
@ -46,7 +46,7 @@ declare module "nightwatch" {
setupMetamask(passphrase: string, password: string): NightwatchBrowser, setupMetamask(passphrase: string, password: string): NightwatchBrowser,
signMessage(msg: string, callback: (hash: { value: string }, signature: { value: string }) => void): NightwatchBrowser, signMessage(msg: string, callback: (hash: { value: string }, signature: { value: string }) => void): NightwatchBrowser,
setSolidityCompilerVersion(version: string): NightwatchBrowser, setSolidityCompilerVersion(version: string): NightwatchBrowser,
clickElementAtPosition(cssSelector: string, index: number): NightwatchBrowser, clickElementAtPosition(cssSelector: string, index: number, opt?: { forceSelectIfUnselected: boolean }): NightwatchBrowser,
notContainsText(cssSelector: string, text: string): NightwatchBrowser, notContainsText(cssSelector: string, text: string): NightwatchBrowser,
sendLowLevelTx(address: string, value: string, callData: string): NightwatchBrowser, sendLowLevelTx(address: string, value: string, callData: string): NightwatchBrowser,
journalLastChild(val: string): NightwatchBrowser, journalLastChild(val: string): NightwatchBrowser,

@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -e
BUILD_ID=${CIRCLE_BUILD_NUM:-${TRAVIS_JOB_NUMBER}}
echo "$BUILD_ID"
TEST_EXITCODE=0
npm run serve &
npx nx serve remix-ide-e2e-src-local-plugin &
sleep 5
npm run build:e2e
npm run nightwatch_local_pluginManager || TEST_EXITCODE=1
echo "$TEST_EXITCODE"
if [ "$TEST_EXITCODE" -eq 1 ]
then
exit 1
fi

@ -44,6 +44,7 @@ module.exports = class TestTab extends ViewPlugin {
this.offsetToLineColumnConverter = offsetToLineColumnConverter this.offsetToLineColumnConverter = offsetToLineColumnConverter
this.allFilesInvolved = [] this.allFilesInvolved = []
this.isDebugging = false this.isDebugging = false
this.currentErrors = []
appManager.event.on('activate', (name) => { appManager.event.on('activate', (name) => {
if (name === 'solidity') this.updateRunAction() if (name === 'solidity') this.updateRunAction()
@ -117,6 +118,14 @@ module.exports = class TestTab extends ViewPlugin {
} }
async updateForNewCurrent (file) { async updateForNewCurrent (file) {
// Ensure that when someone clicks on compilation error and that opens a new file
// Test result, which is compilation error in this case, is not cleared
if (this.currentErrors) {
if (Array.isArray(this.currentErrors) && this.currentErrors.length > 0) {
const errFiles = this.currentErrors.map(err => { if (err.sourceLocation && err.sourceLocation.file) return err.sourceLocation.file })
if (errFiles.includes(file)) return
} else if (this.currentErrors.sourceLocation && this.currentErrors.sourceLocation.file && this.currentErrors.sourceLocation.file === file) return
}
// if current file is changed while debugging and one of the files imported in test file are opened // if current file is changed while debugging and one of the files imported in test file are opened
// do not clear the test results in SUT plugin // do not clear the test results in SUT plugin
if (this.isDebugging && this.allFilesInvolved.includes(file)) return if (this.isDebugging && this.allFilesInvolved.includes(file)) return
@ -377,12 +386,13 @@ module.exports = class TestTab extends ViewPlugin {
this.testsOutput.hidden = false this.testsOutput.hidden = false
if (!result && (_errors && (_errors.errors || (Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage))))) { if (!result && (_errors && (_errors.errors || (Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage))))) {
this.testCallback({ type: 'contract', filename }) this.testCallback({ type: 'contract', filename })
this.currentErrors = _errors.errors
this.setHeader(false) this.setHeader(false)
} }
if (_errors && _errors.errors) { if (_errors && _errors.errors) {
_errors.errors.forEach((err) => this.renderer.error(err.formattedMessage || err.message, this.testsOutput, { type: err.severity })) _errors.errors.forEach((err) => this.renderer.error(err.formattedMessage || err.message, this.testsOutput, { type: err.severity, errorType: err.type }))
} else if (_errors && Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage)) { } else if (_errors && Array.isArray(_errors) && (_errors[0].message || _errors[0].formattedMessage)) {
_errors.forEach((err) => this.renderer.error(err.formattedMessage || err.message, this.testsOutput, { type: err.severity })) _errors.forEach((err) => this.renderer.error(err.formattedMessage || err.message, this.testsOutput, { type: err.severity, errorType: err.type }))
} else if (_errors && !_errors.errors && !Array.isArray(_errors)) { } else if (_errors && !_errors.errors && !Array.isArray(_errors)) {
// To track error like this: https://github.com/ethereum/remix/pull/1438 // To track error like this: https://github.com/ethereum/remix/pull/1438
this.renderer.error(_errors.formattedMessage || _errors.message, this.testsOutput, { type: 'error' }) this.renderer.error(_errors.formattedMessage || _errors.message, this.testsOutput, { type: 'error' })

@ -1,9 +1,9 @@
const nxWebpack = require('@nrwl/react/plugins/webpack') const nxWebpack = require('@nrwl/react/plugins/webpack')
const TerserPlugin = require('terser-webpack-plugin')
module.exports = config => { module.exports = config => {
const nxWebpackConfig = nxWebpack(config) const nxWebpackConfig = nxWebpack(config)
const webpackConfig = {
return {
...nxWebpackConfig, ...nxWebpackConfig,
node: { node: {
fs: 'empty', fs: 'empty',
@ -14,4 +14,18 @@ module.exports = config => {
child_process: 'empty' child_process: 'empty'
} }
} }
if (process.env.NODE_ENV === 'production') {
return {
...webpackConfig,
mode: 'production',
devtool: 'source-map',
optimization: {
minimize: true,
minimizer: [new TerserPlugin()]
}
}
} else {
return webpackConfig
}
} }

@ -7,15 +7,15 @@ module.exports = {
moduleFileExtensions: ['ts', 'js', 'html'], moduleFileExtensions: ['ts', 'js', 'html'],
coverageReporters: ['html'], coverageReporters: ['html'],
moduleNameMapper:{ moduleNameMapper:{
"@remix-project/remix-analyzer": "<rootDir>/../../dist/libs/remix-analyzer/index.js", "@remix-project/remix-analyzer": "<rootDir>/../../dist/libs/remix-analyzer/src/index.js",
"@remix-project/remix-astwalker": "<rootDir>/../../dist/libs/remix-astwalker/index.js", "@remix-project/remix-astwalker": "<rootDir>/../../dist/libs/remix-astwalker/src/index.js",
"@remix-project/remix-debug": "<rootDir>/../../dist/libs/remix-debug/src/index.js", "@remix-project/remix-debug": "<rootDir>/../../dist/libs/remix-debug/src/index.js",
"@remix-project/remix-lib": "<rootDir>/../../dist/libs/remix-lib/src/index.js", "@remix-project/remix-lib": "<rootDir>/../../dist/libs/remix-lib/src/index.js",
"@remix-project/remix-simulator": "<rootDir>/../../dist/libs/remix-simulator/src/index.js", "@remix-project/remix-simulator": "<rootDir>/../../dist/libs/remix-simulator/src/index.js",
"@remix-project/remix-solidity": "<rootDir>/../../dist/libs/remix-solidity/index.js", "@remix-project/remix-solidity": "<rootDir>/../../dist/libs/remix-solidity/src/index.js",
"@remix-project/remix-tests": "<rootDir>/../../dist/libs/remix-tests/src/index.js", "@remix-project/remix-tests": "<rootDir>/../../dist/libs/remix-tests/src/index.js",
"@remix-project/remix-url-resolver": "@remix-project/remix-url-resolver":
"<rootDir>/../../dist/libs/remix-url-resolver/index.js" "<rootDir>/../../dist/libs/remix-url-resolver/src/index.js"
, ,
"@remix-project/remixd": "<rootDir>/../../dist/libs/remixd/index.js" "@remix-project/remixd": "<rootDir>/../../dist/libs/remixd/index.js"
} }

@ -2,8 +2,8 @@
"name": "@remix-project/remix-analyzer", "name": "@remix-project/remix-analyzer",
"version": "0.5.16", "version": "0.5.16",
"description": "Tool to perform static analysis on Solidity smart contracts", "description": "Tool to perform static analysis on Solidity smart contracts",
"main": "index.js", "main": "src/index.js",
"types": ".index.d.ts", "types": "src/index.d.ts",
"contributors": [ "contributors": [
{ {
"name": "Alex Beregszaszi", "name": "Alex Beregszaszi",
@ -22,7 +22,7 @@
"@ethereumjs/block": "^3.4.0", "@ethereumjs/block": "^3.4.0",
"@ethereumjs/tx": "^3.3.0", "@ethereumjs/tx": "^3.3.0",
"@ethereumjs/vm": "^5.5.0", "@ethereumjs/vm": "^5.5.0",
"@remix-project/remix-astwalker": "^0.0.26", "@remix-project/remix-astwalker": "^0.0.37",
"@remix-project/remix-lib": "^0.5.7", "@remix-project/remix-lib": "^0.5.7",
"async": "^2.6.2", "async": "^2.6.2",
"ethereumjs-util": "^7.0.10", "ethereumjs-util": "^7.0.10",
@ -50,6 +50,6 @@
"ts-node": "^8.6.2", "ts-node": "^8.6.2",
"typescript": "^3.7.5" "typescript": "^3.7.5"
}, },
"typings": "index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4705cbc4d1761f75267992552da9db6cff2f3ed5" "gitHead": "4705cbc4d1761f75267992552da9db6cff2f3ed5"
} }

@ -2,7 +2,7 @@
"name": "@remix-project/remix-astwalker", "name": "@remix-project/remix-astwalker",
"version": "0.0.37", "version": "0.0.37",
"description": "Tool to walk through Solidity AST", "description": "Tool to walk through Solidity AST",
"main": "index.js", "main": "src/index.js",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"test": "./../../node_modules/.bin/nyc --reporter=lcov --require ts-node/register --require tsconfig-paths/register ./../../node_modules/.bin/tape ./tests/*.ts | ./../../node_modules/.bin/tap-spec; ./../../node_modules/.bin/nyc report ---reporter=text" "test": "./../../node_modules/.bin/nyc --reporter=lcov --require ts-node/register --require tsconfig-paths/register ./../../node_modules/.bin/tape ./tests/*.ts | ./../../node_modules/.bin/tap-spec; ./../../node_modules/.bin/nyc report ---reporter=text"
@ -52,6 +52,6 @@
"devDependencies": { "devDependencies": {
"tap-spec": "^5.0.0" "tap-spec": "^5.0.0"
}, },
"typings": "index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4705cbc4d1761f75267992552da9db6cff2f3ed5" "gitHead": "4705cbc4d1761f75267992552da9db6cff2f3ed5"
} }

@ -1,6 +1,6 @@
// Type definitions for the things we need from remix-lib // Type definitions for the things we need from remix-lib
declare module "remix-lib" { declare module 'remix-lib' {
export module util { export module util {
export function findLowerBound(target: number, array: Array<number>): number; export function findLowerBound(target: number, array: Array<number>): number;
} }

@ -22,8 +22,9 @@
"@ethereumjs/common": "^2.2.0", "@ethereumjs/common": "^2.2.0",
"@ethereumjs/tx": "^3.3.0", "@ethereumjs/tx": "^3.3.0",
"@ethereumjs/vm": "^5.5.0", "@ethereumjs/vm": "^5.5.0",
"@remix-project/remix-astwalker": "^0.0.26", "@remix-project/remix-astwalker": "^0.0.37",
"@remix-project/remix-lib": "^0.5.7", "@remix-project/remix-lib": "^0.5.7",
"@remix-project/remix-simulator": "^0.2.7",
"async": "^2.6.2", "async": "^2.6.2",
"commander": "^2.19.0", "commander": "^2.19.0",
"deep-equal": "^1.0.1", "deep-equal": "^1.0.1",

@ -29,7 +29,7 @@ export function nameOpCodes (raw, hardfork) {
const data = (pushData as any).toString('hex') !== '' ? ' ' + (pushData as any).toString('hex') : '' const data = (pushData as any).toString('hex') !== '' ? ' ' + (pushData as any).toString('hex') : ''
code.push(this.pad(pc, this.roundLog(raw.length, 10)) + ' ' + curOpCode + data) code.push(pad(pc, roundLog(raw.length, 10)) + ' ' + curOpCode + data)
pushData = '' pushData = ''
} }
return [code, codeMap] return [code, codeMap]

@ -108,7 +108,7 @@ function sourceLocationFromAstNode (astNode) {
* @param {Object} ast - ast given by the compilation result * @param {Object} ast - ast given by the compilation result
*/ */
export function findNodeAtInstructionIndex (astNodeType, instIndex, sourceMap, ast) { export function findNodeAtInstructionIndex (astNodeType, instIndex, sourceMap, ast) {
const sourceLocation = this.atIndex(instIndex, sourceMap) const sourceLocation = atIndex(instIndex, sourceMap)
return findNodeAtSourceLocation(astNodeType, sourceLocation, ast) return findNodeAtSourceLocation(astNodeType, sourceLocation, ast)
} }

@ -133,7 +133,7 @@ export class StorageResolver {
resolve([{}, null]) resolve([{}, null])
} else { } else {
this.web3.debug.storageRangeAt( this.web3.debug.storageRangeAt(
tx.blockHash, tx.transactionIndex === undefined ? tx.hash : tx.transactionIndex, tx.blockHash, tx.hash,
address, address,
start, start,
maxSize, maxSize,

@ -53,7 +53,7 @@ export function newContextStorage (step) {
export function isCallToPrecompiledContract (index, trace) { export function isCallToPrecompiledContract (index, trace) {
// if stack empty => this is not a precompiled contract // if stack empty => this is not a precompiled contract
const step = trace[index] const step = trace[index]
if (this.isCallInstruction(step)) { if (isCallInstruction(step)) {
return index + 1 < trace.length && trace[index + 1].stack.length !== 0 return index + 1 < trace.length && trace[index + 1].stack.length !== 0
} }
return false return false

@ -7,7 +7,6 @@ import { BreakpointManager } from '../src/code/breakpointManager'
var compiler = require('solc') var compiler = require('solc')
var vmCall = require('./vmCall') var vmCall = require('./vmCall')
var remixLib = require('@remix-project/remix-lib')
var ballot = `pragma solidity >=0.4.22 <0.8.0; var ballot = `pragma solidity >=0.4.22 <0.8.0;
@ -151,19 +150,17 @@ contract Ballot {
`; `;
(async () => { (async () => {
var privateKey = Buffer.from('dae9801649ba2d95a21e688b56f77905e5667c44ce868ec83f82e838712a2c7a', 'hex') var privateKey = Buffer.from('503f38a9c967ed597e47fe25643985f032b072db8075426a92110f82df48dfcb', 'hex')
var vm = await vmCall.initVM(privateKey)
var output = compiler.compile(compilerInput(ballot)) var output = compiler.compile(compilerInput(ballot))
output = JSON.parse(output) output = JSON.parse(output)
var web3VM = new remixLib.vm.Web3VMProvider()
web3VM.setVM(vm)
const param = '0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000148656c6c6f20576f726c64210000000000000000000000000000000000000000' const param = '0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000148656c6c6f20576f726c64210000000000000000000000000000000000000000'
vmCall.sendTx(vm, {nonce: 0, privateKey: privateKey}, null, 0, output.contracts['test.sol']['Ballot'].evm.bytecode.object + param, (error, txHash) => { const web3 = await vmCall.getWeb3()
console.log(error, txHash) vmCall.sendTx(web3, {nonce: 0, privateKey: privateKey}, null, 0, output.contracts['test.sol']['Ballot'].evm.bytecode.object + param, (error, hash) => {
console.log(error, hash)
if (error) { if (error) {
throw error throw error
} else { } else {
web3VM.eth.getTransaction(txHash, (error, tx) => { web3.eth.getTransaction(hash, (error, tx) => {
if (error) { if (error) {
throw error throw error
} else { } else {
@ -171,7 +168,7 @@ contract Ballot {
compilationResult: function () { compilationResult: function () {
return { data: output } return { data: output }
}, },
web3: web3VM web3: web3
}) })
debugManager.callTree.event.register('callTreeReady', () => { debugManager.callTree.event.register('callTreeReady', () => {
@ -230,7 +227,7 @@ function testDebugging (debugManager) {
var storageView = debugManager.storageViewAt(196, address) var storageView = debugManager.storageViewAt(196, address)
storageView.storageRange().then((storage) => { storageView.storageRange().then((storage) => {
t.equal(JSON.stringify(storage), JSON.stringify({ '0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563': { key: '0x0000000000000000000000000000000000000000000000000000000000000000', value: '0x0000000000000000000000004b0897b0513fdc7c541b6d9d7e929c4e5364d2db' } })) t.equal(JSON.stringify(storage), JSON.stringify({ '0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563': { key: '0x0000000000000000000000000000000000000000000000000000000000000000', value: '0x0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4' } }))
}).catch((error) => { }).catch((error) => {
if (error) return t.end(error) if (error) return t.end(error)
}) })
@ -245,7 +242,7 @@ function testDebugging (debugManager) {
const state = await debugManager.extractStateAt(312) const state = await debugManager.extractStateAt(312)
const decodedState = await debugManager.decodeStateAt(312, state) const decodedState = await debugManager.decodeStateAt(312, state)
console.log(decodedState) console.log(decodedState)
t.equal(decodedState['chairperson'].value, '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB') t.equal(decodedState['chairperson'].value, '0x5B38DA6A701C568545DCFCB03FCB875F56BEDDC4')
t.equal(decodedState['chairperson'].type, 'address') t.equal(decodedState['chairperson'].type, 'address')
t.equal(decodedState['proposals'].value[0].value.voteCount.value, '0') t.equal(decodedState['proposals'].value[0].value.voteCount.value, '0')
t.equal(decodedState['proposals'].value[0].value.voteCount.type, 'uint256') t.equal(decodedState['proposals'].value[0].value.voteCount.type, 'uint256')
@ -259,13 +256,14 @@ function testDebugging (debugManager) {
tape('traceManager.decodeLocalsAt', async (t) => { tape('traceManager.decodeLocalsAt', async (t) => {
t.plan(1) t.plan(1)
const tested = JSON.parse('{"proposalNames":{"value":[{"value":"0x48656C6C6F20576F726C64210000000000000000000000000000000000000000","type":"bytes32"}],"length":"0x1","type":"bytes32[]","cursor":1,"hasNext":false},"p":{"value":"45","type":"uint256"},"addressLocal":{"value":"0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB","type":"address"},"i":{"value":"2","type":"uint256"},"proposalsLocals":{"value":[{"value":{"name":{"value":"0x48656C6C6F20576F726C64210000000000000000000000000000000000000000","type":"bytes32"},"voteCount":{"value":"0","type":"uint256"}},"type":"struct Ballot.Proposal"}],"length":"0x1","type":"struct Ballot.Proposal[]"}}') const tested = JSON.parse('{"proposalNames":{"value":[{"value":"0x48656C6C6F20576F726C64210000000000000000000000000000000000000000","type":"bytes32"}],"length":"0x1","type":"bytes32[]","cursor":1,"hasNext":false},"p":{"value":"45","type":"uint256"},"addressLocal":{"value":"0x5B38DA6A701C568545DCFCB03FCB875F56BEDDC4","type":"address"},"i":{"value":"2","type":"uint256"},"proposalsLocals":{"value":[{"value":{"name":{"value":"0x48656C6C6F20576F726C64210000000000000000000000000000000000000000","type":"bytes32"},"voteCount":{"value":"0","type":"uint256"}},"type":"struct Ballot.Proposal"}],"length":"0x1","type":"struct Ballot.Proposal[]"}}')
try { try {
const address = debugManager.traceManager.getCurrentCalledAddressAt(327) const address = debugManager.traceManager.getCurrentCalledAddressAt(327)
const location = await debugManager.sourceLocationFromVMTraceIndex(address, 327) const location = await debugManager.sourceLocationFromVMTraceIndex(address, 327)
debugManager.decodeLocalsAt(327, location, (error, decodedlocals) => { debugManager.decodeLocalsAt(327, location, (error, decodedlocals) => {
if (error) return t.end(error) if (error) return t.end(error)
t.ok(deepequal(decodedlocals, tested), `locals does not match. expected: ${JSON.stringify(tested)} - current: ${decodedlocals}`) const res = deepequal(decodedlocals, tested)
t.ok(res, `test if locals does match. expected: ${JSON.stringify(tested)} - current: ${JSON.stringify(decodedlocals)}`)
}) })
} catch (error) { } catch (error) {
return t.end(error) return t.end(error)

@ -5,7 +5,7 @@ var intLocal = require('./contracts/intLocal')
var miscLocal = require('./contracts/miscLocal') var miscLocal = require('./contracts/miscLocal')
var structArrayLocal = require('./contracts/structArrayLocal') var structArrayLocal = require('./contracts/structArrayLocal')
var calldataLocal = require('./contracts/calldata') var calldataLocal = require('./contracts/calldata')
var vmCall = require('./vmCall') var vmCall = require('../vmCall')
var intLocalTest = require('./localsTests/int') var intLocalTest = require('./localsTests/int')
var miscLocalTest = require('./localsTests/misc') var miscLocalTest = require('./localsTests/misc')
var misc2LocalTest = require('./localsTests/misc2') var misc2LocalTest = require('./localsTests/misc2')
@ -15,29 +15,28 @@ var compilerInput = require('../helpers/compilerHelper').compilerInput
tape('solidity', function (t) { tape('solidity', function (t) {
t.test('local decoder', async function (st) { t.test('local decoder', async function (st) {
var privateKey = Buffer.from('dae9801649ba2d95a21e688b56f77905e5667c44ce868ec83f82e838712a2c7a', 'hex') var privateKey = Buffer.from('503f38a9c967ed597e47fe25643985f032b072db8075426a92110f82df48dfcb', 'hex')
var vm = await vmCall.initVM(st, privateKey) await test(st, privateKey)
await test(st, vm, privateKey)
}) })
}) })
async function test (st, vm, privateKey) { async function test (st, privateKey) {
var output = compiler.compile(compilerInput(intLocal.contract)) var output = compiler.compile(compilerInput(intLocal.contract))
output = JSON.parse(output) output = JSON.parse(output)
await intLocalTest(st, vm, privateKey, output.contracts['test.sol']['intLocal'].evm.bytecode.object, output) await intLocalTest(st, privateKey, output.contracts['test.sol']['intLocal'].evm.bytecode.object, output)
output = compiler.compile(compilerInput(miscLocal.contract)) output = compiler.compile(compilerInput(miscLocal.contract))
output = JSON.parse(output) output = JSON.parse(output)
await miscLocalTest(st, vm, privateKey, output.contracts['test.sol']['miscLocal'].evm.bytecode.object, output) await miscLocalTest(st, privateKey, output.contracts['test.sol']['miscLocal'].evm.bytecode.object, output)
output = compiler.compile(compilerInput(miscLocal.contract)) output = compiler.compile(compilerInput(miscLocal.contract))
output = JSON.parse(output) output = JSON.parse(output)
await misc2LocalTest(st, vm, privateKey, output.contracts['test.sol']['miscLocal2'].evm.bytecode.object, output) await misc2LocalTest(st, privateKey, output.contracts['test.sol']['miscLocal2'].evm.bytecode.object, output)
output = compiler.compile(compilerInput(structArrayLocal.contract)) output = compiler.compile(compilerInput(structArrayLocal.contract))
output = JSON.parse(output) output = JSON.parse(output)
await structArrayLocalTest(st, vm, privateKey, output.contracts['test.sol']['structArrayLocal'].evm.bytecode.object, output) await structArrayLocalTest(st, privateKey, output.contracts['test.sol']['structArrayLocal'].evm.bytecode.object, output)
output = compiler.compile(compilerInput(calldataLocal.contract)) output = compiler.compile(compilerInput(calldataLocal.contract))
output = JSON.parse(output) output = JSON.parse(output)
await calldataLocalTest(st, vm, privateKey, output.contracts['test.sol']['calldataLocal'].evm.bytecode.object, output) await calldataLocalTest(st, privateKey, output.contracts['test.sol']['calldataLocal'].evm.bytecode.object, output)
st.end() st.end()
} }

@ -1,7 +1,7 @@
'use strict' 'use strict'
import deepequal from 'deep-equal' import deepequal from 'deep-equal'
import { sendTx } from '../vmCall' import * as vmCall from '../../vmCall'
import { TraceManager } from '../../../src/trace/traceManager' import { TraceManager } from '../../../src/trace/traceManager'
import { CodeManager } from '../../../src/code/codeManager' import { CodeManager } from '../../../src/code/codeManager'
import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy' import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy'
@ -9,23 +9,26 @@ import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree
import { EventManager } from '../../../src/eventManager' import { EventManager } from '../../../src/eventManager'
import * as helper from './helper' import * as helper from './helper'
module.exports = async function (st, vm, privateKey, contractBytecode, compilationResult) { module.exports = async function (st, privateKey, contractBytecode, compilationResult) {
let txHash let txHash
let web3
try { try {
let data = await sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode) web3 = await (vmCall as any).getWeb3()
const to = (data as any).result.createdAddress.toString() let hash = await (vmCall as any).sendTx(web3, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode)
const receipt = await web3.eth.getTransactionReceipt(hash)
const to = receipt.contractAddress
console.log('to', to)
// call to level11 // call to level11
data = await sendTx(vm, { nonce: 1, privateKey: privateKey }, to, 0, 'a372a595000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015400000000000000000000000000000000000000000000000000000000000000') txHash = await (vmCall as any).sendTx(web3, { nonce: 1, privateKey: privateKey }, to, 0, 'a372a595000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015400000000000000000000000000000000000000000000000000000000000000')
txHash = (data as any).hash
} catch (e) { } catch (e) {
return st.fail(e) return st.fail(e)
} }
return new Promise((resolve) => { return new Promise((resolve) => {
vm.web3.eth.getTransaction(txHash, function (error, tx) { web3.eth.getTransaction(txHash, function (error, tx) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
var traceManager = new TraceManager({ web3: vm.web3 }) var traceManager = new TraceManager({ web3 })
var codeManager = new CodeManager(traceManager) var codeManager = new CodeManager(traceManager)
codeManager.clear() codeManager.clear()
var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) })

@ -1,6 +1,6 @@
'use strict' 'use strict'
import { sendTx } from '../vmCall' import * as vmCall from '../../vmCall'
import { TraceManager } from '../../../src/trace/traceManager' import { TraceManager } from '../../../src/trace/traceManager'
import { CodeManager } from '../../../src/code/codeManager' import { CodeManager } from '../../../src/code/codeManager'
import { contractCreationToken } from '../../../src/trace/traceHelper' import { contractCreationToken } from '../../../src/trace/traceHelper'
@ -9,19 +9,19 @@ import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree
import { EventManager } from '../../../src/eventManager' import { EventManager } from '../../../src/eventManager'
import * as helper from './helper' import * as helper from './helper'
module.exports = function (st, vm, privateKey, contractBytecode, compilationResult) { module.exports = function (st, privateKey, contractBytecode, compilationResult) {
return new Promise((resolve) => { return new Promise(async (resolve) => {
sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, data) { let web3 = await (vmCall as any).getWeb3();
(vmCall as any).sendTx(web3, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, hash) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
const txHash = data.hash web3.eth.getTransaction(hash, function (error, tx) {
vm.web3.eth.getTransaction(txHash, function (error, tx) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
tx.to = contractCreationToken('0') tx.to = contractCreationToken('0')
var traceManager = new TraceManager({ web3: vm.web3 }) var traceManager = new TraceManager({ web3 })
var codeManager = new CodeManager(traceManager) var codeManager = new CodeManager(traceManager)
codeManager.clear() codeManager.clear()
var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) })

@ -1,5 +1,5 @@
'use strict' 'use strict'
import { sendTx } from '../vmCall' import * as vmCall from '../../vmCall'
import { contractCreationToken } from '../../../src/trace/traceHelper' import { contractCreationToken } from '../../../src/trace/traceHelper'
import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy' import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy'
import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree' import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree'
@ -8,19 +8,19 @@ import * as helper from './helper'
import { TraceManager } from '../../../src/trace/traceManager' import { TraceManager } from '../../../src/trace/traceManager'
import { CodeManager } from '../../../src/code/codeManager' import { CodeManager } from '../../../src/code/codeManager'
module.exports = function (st, vm, privateKey, contractBytecode, compilationResult) { module.exports = function (st, privateKey, contractBytecode, compilationResult) {
return new Promise((resolve) => { return new Promise(async (resolve) => {
sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, data) { const web3 = await (vmCall as any).getWeb3();
(vmCall as any).sendTx(web3, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, hash) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
const txHash = data.hash web3.eth.getTransaction(hash, function (error, tx) {
vm.web3.eth.getTransaction(txHash, function (error, tx) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
tx.to = contractCreationToken('0') tx.to = contractCreationToken('0')
var traceManager = new TraceManager({ web3: vm.web3 }) var traceManager = new TraceManager({ web3 })
var codeManager = new CodeManager(traceManager) var codeManager = new CodeManager(traceManager)
codeManager.clear() codeManager.clear()
var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) })
@ -36,7 +36,7 @@ module.exports = function (st, vm, privateKey, contractBytecode, compilationResu
st.equals(locals['boolFalse'].value, false) st.equals(locals['boolFalse'].value, false)
st.equals(locals['boolTrue'].value, true) st.equals(locals['boolTrue'].value, true)
st.equals(locals['testEnum'].value, 'three') st.equals(locals['testEnum'].value, 'three')
st.equals(locals['sender'].value, '0x4B0897B0513FDC7C541B6D9D7E929C4E5364D2DB') st.equals(locals['sender'].value, '0x5B38DA6A701C568545DCFCB03FCB875F56BEDDC4')
st.equals(locals['_bytes1'].value, '0x99') st.equals(locals['_bytes1'].value, '0x99')
st.equals(locals['__bytes1'].value, '0x99') st.equals(locals['__bytes1'].value, '0x99')
st.equals(locals['__bytes2'].value, '0x99AB') st.equals(locals['__bytes2'].value, '0x99AB')

@ -1,5 +1,5 @@
'use strict' 'use strict'
import { sendTx } from '../vmCall' import * as vmCall from '../../vmCall'
import { contractCreationToken } from '../../../src/trace/traceHelper' import { contractCreationToken } from '../../../src/trace/traceHelper'
import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy' import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy'
import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree' import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree'
@ -8,19 +8,19 @@ import * as helper from './helper'
import { TraceManager } from '../../../src/trace/traceManager' import { TraceManager } from '../../../src/trace/traceManager'
import { CodeManager } from '../../../src/code/codeManager' import { CodeManager } from '../../../src/code/codeManager'
module.exports = function (st, vm, privateKey, contractBytecode, compilationResult) { module.exports = function (st, privateKey, contractBytecode, compilationResult) {
return new Promise((resolve) => { return new Promise(async (resolve) => {
sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, data) { const web3 = await (vmCall as any).getWeb3();
(vmCall as any).sendTx(web3, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, hash) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
const txHash = data.hash web3.eth.getTransaction(hash, function (error, tx) {
vm.web3.eth.getTransaction(txHash, function (error, tx) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
tx.to = contractCreationToken('0') tx.to = contractCreationToken('0')
var traceManager = new TraceManager({ web3: vm.web3 }) var traceManager = new TraceManager({ web3 })
var codeManager = new CodeManager(traceManager) var codeManager = new CodeManager(traceManager)
codeManager.clear() codeManager.clear()
var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) })

@ -1,5 +1,5 @@
'use strict' 'use strict'
import { sendTx } from '../vmCall' import * as vmCall from '../../vmCall'
import { contractCreationToken } from '../../../src/trace/traceHelper' import { contractCreationToken } from '../../../src/trace/traceHelper'
import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy' import { SolidityProxy } from '../../../src/solidity-decoder/solidityProxy'
import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree' import { InternalCallTree } from '../../../src/solidity-decoder/internalCallTree'
@ -8,19 +8,19 @@ import * as helper from './helper'
import { TraceManager } from '../../../src/trace/traceManager' import { TraceManager } from '../../../src/trace/traceManager'
import { CodeManager } from '../../../src/code/codeManager' import { CodeManager } from '../../../src/code/codeManager'
module.exports = function (st, vm, privateKey, contractBytecode, compilationResult) { module.exports = function (st, privateKey, contractBytecode, compilationResult) {
return new Promise((resolve) => { return new Promise(async (resolve) => {
sendTx(vm, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, data) { const web3 = await (vmCall as any).getWeb3();
(vmCall as any).sendTx(web3, { nonce: 0, privateKey: privateKey }, null, 0, contractBytecode, function (error, hash) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
const txHash = data.hash web3.eth.getTransaction(hash, function (error, tx) {
vm.web3.eth.getTransaction(txHash, function (error, tx) {
if (error) { if (error) {
return st.fail(error) return st.fail(error)
} }
tx.to = contractCreationToken('0') tx.to = contractCreationToken('0')
var traceManager = new TraceManager({ web3: vm.web3 }) var traceManager = new TraceManager({ web3 })
var codeManager = new CodeManager(traceManager) var codeManager = new CodeManager(traceManager)
codeManager.clear() codeManager.clear()
var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) }) var solidityProxy = new SolidityProxy({ getCurrentCalledAddressAt: traceManager.getCurrentCalledAddressAt.bind(traceManager), getCode: codeManager.getCode.bind(codeManager) })

@ -2,57 +2,59 @@ import { compilerInput } from '../../helpers/compilerHelper'
import { TraceManager } from '../../../src/trace/traceManager' import { TraceManager } from '../../../src/trace/traceManager'
import { compile } from 'solc' import { compile } from 'solc'
import * as stateDecoder from '../../../src/solidity-decoder/stateDecoder' import * as stateDecoder from '../../../src/solidity-decoder/stateDecoder'
import { sendTx, initVM } from '../vmCall' import * as vmCall from '../../vmCall'
import { StorageResolver } from '../../../src/storage/storageResolver' import { StorageResolver } from '../../../src/storage/storageResolver'
import { StorageViewer } from '../../../src/storage/storageViewer' import { StorageViewer } from '../../../src/storage/storageViewer'
import { Address, bufferToHex } from 'ethereumjs-util'
module.exports = async function testMappingStorage (st, cb) { module.exports = async function testMappingStorage (st, cb) {
var mappingStorage = require('../contracts/mappingStorage') var mappingStorage = require('../contracts/mappingStorage')
var privateKey = Buffer.from('dae9801649ba2d95a21e688b56f77905e5667c44ce868ec83f82e838712a2c7a', 'hex') var privateKey = Buffer.from('503f38a9c967ed597e47fe25643985f032b072db8075426a92110f82df48dfcb', 'hex')
var vm = await initVM(st, privateKey)
var output = compile(compilerInput(mappingStorage.contract)) var output = compile(compilerInput(mappingStorage.contract))
output = JSON.parse(output) output = JSON.parse(output);
sendTx(vm, {nonce: 0, privateKey: privateKey}, null, 0, output.contracts['test.sol']['SimpleMappingState'].evm.bytecode.object, function (error, data) { const web3 = await (vmCall as any).getWeb3();
(vmCall as any).sendTx(web3, {nonce: 0, privateKey: privateKey}, null, 0, output.contracts['test.sol']['SimpleMappingState'].evm.bytecode.object, function (error, hash) {
if (error) { if (error) {
console.log(error) console.log(error)
st.end(error) st.end(error)
} else { } else {
const txHash = data.hash web3.eth.getTransactionReceipt(hash, (error, tx) => {
vm.web3.eth.getTransaction(txHash, (error, tx) => {
if (error) { if (error) {
console.log(error) console.log(error)
st.end(error) st.end(error)
} else { } else {
testMapping(st, vm, privateKey, tx.contractAddress, output, cb) // const storage = await this.vm.stateManager.dumpStorage(data.to)
// (vmCall as any).web3().eth.getCode(tx.contractAddress).then((code) => console.log('code:', code))
// (vmCall as any).web3().debug.traceTransaction(hash).then((code) => console.log('trace:', code))
testMapping(st, privateKey, tx.contractAddress, output, web3, cb)
// st.end()
} }
}) })
} }
}) })
} }
function testMapping (st, vm, privateKey, contractAddress, output, cb) { function testMapping (st, privateKey, contractAddress, output, web3, cb) {
sendTx(vm, {nonce: 1, privateKey: privateKey}, contractAddress, 0, '2fd0a83a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001074686973206973206120737472696e6700000000000000000000000000000000', (vmCall as any).sendTx(web3, {nonce: 1, privateKey: privateKey}, contractAddress, 0, '2fd0a83a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001074686973206973206120737472696e6700000000000000000000000000000000',
function (error, data) { function (error, hash) {
if (error) { if (error) {
console.log(error) console.log(error)
st.end(error) st.end(error)
} else { } else {
const txHash = data.hash web3.eth.getTransaction(hash, (error, tx) => {
vm.web3.eth.getTransaction(txHash, (error, tx) => {
if (error) { if (error) {
console.log(error) console.log(error)
st.end(error) st.end(error)
} else { } else {
var traceManager = new TraceManager({web3: vm.web3}) var traceManager = new TraceManager({web3})
traceManager.resolveTrace(tx).then(() => { traceManager.resolveTrace(tx).then(() => {
var storageViewer = new StorageViewer({ var storageViewer = new StorageViewer({
stepIndex: 268, stepIndex: 268,
tx: tx, tx: tx,
address: contractAddress address: contractAddress
}, new StorageResolver({web3: vm.web3}), traceManager) }, new StorageResolver({web3}), traceManager)
var stateVars = stateDecoder.extractStateVariables('SimpleMappingState', output.sources) var stateVars = stateDecoder.extractStateVariables('SimpleMappingState', output.sources)
stateDecoder.decodeState(stateVars, storageViewer).then((result) => { stateDecoder.decodeState(stateVars, storageViewer).then((result) => {
console.log('ok', JSON.stringify(result))
st.equal(result['_num'].value, '1') st.equal(result['_num'].value, '1')
st.equal(result['_num'].type, 'uint256') st.equal(result['_num'].type, 'uint256')
st.equal(result['_iBreakSolidityState'].type, 'mapping(string => uint256)') st.equal(result['_iBreakSolidityState'].type, 'mapping(string => uint256)')

@ -1,76 +0,0 @@
'use strict'
import { Transaction as Tx } from '@ethereumjs/tx'
import { Block } from '@ethereumjs/block'
import { BN, bufferToHex, Address } from 'ethereumjs-util'
import { vm as remixlibVM } from '@remix-project/remix-lib'
import VM from '@ethereumjs/vm'
import Common from '@ethereumjs/common'
export function sendTx (vm, from, to, value, data, cb?) {
cb = cb || (() => {})
return new Promise ((resolve, reject) => {
var tx = new Tx({
nonce: new BN(from.nonce++),
// gasPrice: new BN(1),
gasLimit: new BN(3000000, 10),
to: to,
value: new BN(value, 10),
data: Buffer.from(data, 'hex')
})
tx = tx.sign(from.privateKey)
var block = Block.fromBlockData({
header: {
timestamp: new Date().getTime() / 1000 | 0,
number: 0
}
}) // still using default common
try {
vm.runTx({block: block, tx: tx, skipBalance: true, skipNonce: true}).then(function (result) {
setTimeout(() => {
const hash = bufferToHex(tx.hash())
cb(null, { hash, result })
resolve({ hash, result })
}, 500)
}).catch((error) => {
console.error(error)
cb(error)
reject(error)
})
} catch (e) {
console.error(e)
}
})
}
async function createVm (hardfork) {
const common = new Common({ chain: 'mainnet', hardfork })
const vm = new VM({ common })
await vm.init()
return { vm, stateManager: vm.stateManager }
}
/*
Init VM / Send Transaction
*/
export async function initVM (st, privateKey) {
var VM = await createVm('berlin')
const vm = VM.vm
var address = Address.fromPrivateKey(privateKey)
try {
let account = await vm.stateManager.getAccount(address)
account.balance = new BN('f00000000000000001', 16)
await vm.stateManager.putAccount(address, account)
} catch (error) {
console.log(error)
}
var web3Provider = new remixlibVM.Web3VMProvider()
web3Provider.setVM(vm)
vm.web3 = web3Provider
return vm
}

@ -1,5 +1,5 @@
'use strict' 'use strict'
require('./vmCall')
require('./traceManager') require('./traceManager')
require('./codeManager') require('./codeManager')
require('./disassembler') require('./disassembler')

@ -1,63 +1,44 @@
'use strict' 'use strict'
import { Block } from '@ethereumjs/block' import { Block } from '@ethereumjs/block'
import { Transaction } from '@ethereumjs/tx'
import VM from '@ethereumjs/vm' import VM from '@ethereumjs/vm'
import { rlp, keccak, bufferToHex } from 'ethereumjs-util'
import { extendWeb3 } from '../src/init'
var utileth = require('ethereumjs-util') var utileth = require('ethereumjs-util')
var Tx = require('@ethereumjs/tx').Transaction var Tx = require('@ethereumjs/tx').Transaction
var BN = require('ethereumjs-util').BN var BN = require('ethereumjs-util').BN
var remixLib = require('@remix-project/remix-lib') var remixLib = require('@remix-project/remix-lib')
const { Provider, extend } = require('@remix-project/remix-simulator')
const Web3 = require('web3')
function sendTx (vm, from, to, value, data, cb) {
var tx = new Tx({
nonce: new BN(from.nonce++),
// gasPrice: new BN(1),
gasLimit: new BN(3000000, 10),
to: to,
value: new BN(value, 10),
data: Buffer.from(data, 'hex')
})
tx = tx.sign(from.privateKey)
var block = Block.fromBlockData({ async function getWeb3 () {
header: { const remixSimulatorProvider = new Provider({ fork: 'berlin' })
timestamp: new Date().getTime() / 1000 | 0, await remixSimulatorProvider.init()
number: 0 await remixSimulatorProvider.Accounts.resetAccounts()
} const web3 = new Web3(remixSimulatorProvider)
}) // still using default common extendWeb3(web3)
vm.runTx({block: block, tx: tx, skipBalance: true, skipNonce: true}).then(function (result) { return web3
setTimeout(() => {
cb(null, utileth.bufferToHex(tx.hash()))
}, 500)
}).catch((error) => {
console.error(error)
cb(error)
})
} }
/* async function sendTx (web3, from, to, value, data, cb) {
Init VM / Send Transaction
*/
async function initVM (privateKey) {
var address = utileth.Address.fromPrivateKey(privateKey)
var vm = new VM({
activatePrecompiles: true
})
await vm.init()
try { try {
let account = await vm.stateManager.getAccount(address) cb = cb || (() => {})
account.balance = new BN('f00000000000000001', 16) const receipt = await web3.eth.sendTransaction({
await vm.stateManager.putAccount(address, account) from: utileth.Address.fromPrivateKey(from.privateKey).toString('hex'),
} catch (error) { to,
console.log(error) value,
data,
gas: 7000000
})
cb(null, receipt.transactionHash)
return receipt.transactionHash
} catch (e) {
cb(e)
} }
var web3Provider = new remixLib.vm.Web3VMProvider()
web3Provider.setVM(vm)
vm.web3 = web3Provider
return vm
} }
module.exports = { module.exports = {
sendTx: sendTx, sendTx,
initVM: initVM getWeb3
} }

@ -55,10 +55,10 @@ export class LogsManager {
if (queryFilter.topics.filter((logTopic) => changeEvent.log.topics.indexOf(logTopic) >= 0).length === 0) return false if (queryFilter.topics.filter((logTopic) => changeEvent.log.topics.indexOf(logTopic) >= 0).length === 0) return false
if (queryType === 'logs') { if (queryType === 'logs') {
if ((queryFilter.address === ('0x' + changeEvent.tx.to.toString('hex'))) && (queryFilter.address === ('0x' + changeEvent.tx.from.toString('hex')))) { const fromBlock = queryFilter.fromBlock || '0x0'
if (!queryFilter.toBlock) { const toBlock = queryFilter.toBlock || this.oldLogs.length ? this.oldLogs[this.oldLogs.length - 1].blockNumber : '0x0'
return true if ((queryFilter.address === (changeEvent.tx.to || '').toString()) || queryFilter.address === (changeEvent.tx.getSenderAddress().toString())) {
} else if (parseInt(queryFilter.toBlock) > parseInt(changeEvent.blockNumber)) { if ((parseInt(toBlock) >= parseInt(changeEvent.blockNumber)) && (parseInt(fromBlock) <= parseInt(changeEvent.blockNumber))) {
return true return true
} }
} }
@ -144,6 +144,23 @@ export class LogsManager {
} }
} }
getLogsByTxHash (hash) {
return this.oldLogs.filter((log) => '0x' + log.tx.hash().toString('hex') === hash)
.map((log) => {
return {
logIndex: '0x1', // 1
blockNumber: log.blockNumber,
blockHash: ('0x' + log.block.hash().toString('hex')),
transactionHash: ('0x' + log.tx.hash().toString('hex')),
transactionIndex: '0x' + log.txNumber.toString(16),
// TODO: if it's a contract deploy, it should be that address instead
address: log.log.address,
data: log.log.data,
topics: log.log.topics
}
})
}
getLogsFor (params) { getLogsFor (params) {
const results = [] const results = []
for (const log of this.oldLogs) { for (const log of this.oldLogs) {

@ -77,7 +77,7 @@ export function encodeParams (params, funAbi, callback) {
* @param {Function} callback - callback * @param {Function} callback - callback
*/ */
export function encodeFunctionCall (params, funAbi, callback) { export function encodeFunctionCall (params, funAbi, callback) {
this.encodeParams(params, funAbi, (error, encodedParam) => { encodeParams(params, funAbi, (error, encodedParam) => {
if (error) return callback(error) if (error) return callback(error)
callback(null, { dataHex: encodeFunctionId(funAbi) + encodedParam.dataHex, funAbi, funArgs: encodedParam.funArgs }) callback(null, { dataHex: encodeFunctionId(funAbi) + encodedParam.dataHex, funAbi, funArgs: encodedParam.funArgs })
}) })
@ -94,7 +94,7 @@ export function encodeFunctionCall (params, funAbi, callback) {
* @param {Function} callback - callback * @param {Function} callback - callback
*/ */
export function encodeConstructorCallAndLinkLibraries (contract, params, funAbi, linkLibraries, linkReferences, callback) { export function encodeConstructorCallAndLinkLibraries (contract, params, funAbi, linkLibraries, linkReferences, callback) {
this.encodeParams(params, funAbi, (error, encodedParam) => { encodeParams(params, funAbi, (error, encodedParam) => {
if (error) return callback(error) if (error) return callback(error)
let bytecodeToDeploy = contract.evm.bytecode.object let bytecodeToDeploy = contract.evm.bytecode.object
if (bytecodeToDeploy.indexOf('_') >= 0) { if (bytecodeToDeploy.indexOf('_') >= 0) {
@ -103,7 +103,7 @@ export function encodeConstructorCallAndLinkLibraries (contract, params, funAbi,
for (const lib in linkLibraries[libFile]) { for (const lib in linkLibraries[libFile]) {
const address = linkLibraries[libFile][lib] const address = linkLibraries[libFile][lib]
if (!isValidAddress(address)) return callback(address + ' is not a valid address. Please check the provided address is valid.') if (!isValidAddress(address)) return callback(address + ' is not a valid address. Please check the provided address is valid.')
bytecodeToDeploy = this.linkLibraryStandardFromlinkReferences(lib, address.replace('0x', ''), bytecodeToDeploy, linkReferences) bytecodeToDeploy = linkLibraryStandardFromlinkReferences(lib, address.replace('0x', ''), bytecodeToDeploy, linkReferences)
} }
} }
} }
@ -129,13 +129,13 @@ export function encodeConstructorCallAndLinkLibraries (contract, params, funAbi,
* @param {Function} callback - callback * @param {Function} callback - callback
*/ */
export function encodeConstructorCallAndDeployLibraries (contractName, contract, contracts, params, funAbi, callback, callbackStep, callbackDeployLibrary) { export function encodeConstructorCallAndDeployLibraries (contractName, contract, contracts, params, funAbi, callback, callbackStep, callbackDeployLibrary) {
this.encodeParams(params, funAbi, (error, encodedParam) => { encodeParams(params, funAbi, (error, encodedParam) => {
if (error) return callback(error) if (error) return callback(error)
let dataHex = '' let dataHex = ''
const contractBytecode = contract.evm.bytecode.object const contractBytecode = contract.evm.bytecode.object
let bytecodeToDeploy = contract.evm.bytecode.object let bytecodeToDeploy = contract.evm.bytecode.object
if (bytecodeToDeploy.indexOf('_') >= 0) { if (bytecodeToDeploy.indexOf('_') >= 0) {
this.linkBytecode(contract, contracts, (err, bytecode) => { linkBytecode(contract, contracts, (err, bytecode) => {
if (err) { if (err) {
callback('Error deploying required libraries: ' + err) callback('Error deploying required libraries: ' + err)
} else { } else {
@ -176,7 +176,7 @@ export function buildData (contractName, contract, contracts, isConstructor, fun
} else { } else {
try { try {
if (params.length > 0) { if (params.length > 0) {
funArgs = this.parseFunctionParams(params) funArgs = parseFunctionParams(params)
} }
} catch (e) { } catch (e) {
return callback('Error encoding arguments: ' + e) return callback('Error encoding arguments: ' + e)
@ -199,7 +199,7 @@ export function buildData (contractName, contract, contracts, isConstructor, fun
contractBytecode = contract.evm.bytecode.object contractBytecode = contract.evm.bytecode.object
let bytecodeToDeploy = contract.evm.bytecode.object let bytecodeToDeploy = contract.evm.bytecode.object
if (bytecodeToDeploy.indexOf('_') >= 0) { if (bytecodeToDeploy.indexOf('_') >= 0) {
this.linkBytecode(contract, contracts, (err, bytecode) => { linkBytecode(contract, contracts, (err, bytecode) => {
if (err) { if (err) {
callback('Error deploying required libraries: ' + err) callback('Error deploying required libraries: ' + err)
} else { } else {
@ -225,7 +225,7 @@ export function linkBytecodeStandard (contract, contracts, callback, callbackSte
eachOfSeries(contract.evm.bytecode.linkReferences[file], (libRef, libName, cbLibDeployed) => { eachOfSeries(contract.evm.bytecode.linkReferences[file], (libRef, libName, cbLibDeployed) => {
const library = contracts[file][libName] const library = contracts[file][libName]
if (library) { if (library) {
this.deployLibrary(file + ':' + libName, libName, library, contracts, (error, address) => { deployLibrary(file + ':' + libName, libName, library, contracts, (error, address) => {
if (error) { if (error) {
return cbLibDeployed(error) return cbLibDeployed(error)
} }
@ -233,7 +233,7 @@ export function linkBytecodeStandard (contract, contracts, callback, callbackSte
if (hexAddress.slice(0, 2) === '0x') { if (hexAddress.slice(0, 2) === '0x') {
hexAddress = hexAddress.slice(2) hexAddress = hexAddress.slice(2)
} }
contractBytecode = this.linkLibraryStandard(libName, hexAddress, contractBytecode, contract) contractBytecode = linkLibraryStandard(libName, hexAddress, contractBytecode, contract)
cbLibDeployed() cbLibDeployed()
}, callbackStep, callbackDeployLibrary) }, callbackStep, callbackDeployLibrary)
} else { } else {
@ -269,7 +269,7 @@ export function linkBytecodeLegacy (contract, contracts, callback, callbackStep,
if (!library) { if (!library) {
return callback('Library ' + libraryName + ' not found.') return callback('Library ' + libraryName + ' not found.')
} }
this.deployLibrary(libraryName, libraryShortName, library, contracts, (err, address) => { deployLibrary(libraryName, libraryShortName, library, contracts, (err, address) => {
if (err) { if (err) {
return callback(err) return callback(err)
} }
@ -277,8 +277,8 @@ export function linkBytecodeLegacy (contract, contracts, callback, callbackStep,
if (hexAddress.slice(0, 2) === '0x') { if (hexAddress.slice(0, 2) === '0x') {
hexAddress = hexAddress.slice(2) hexAddress = hexAddress.slice(2)
} }
contract.evm.bytecode.object = this.linkLibrary(libraryName, hexAddress, contract.evm.bytecode.object) contract.evm.bytecode.object = linkLibrary(libraryName, hexAddress, contract.evm.bytecode.object)
this.linkBytecode(contract, contracts, callback, callbackStep, callbackDeployLibrary) linkBytecode(contract, contracts, callback, callbackStep, callbackDeployLibrary)
}, callbackStep, callbackDeployLibrary) }, callbackStep, callbackDeployLibrary)
} }
@ -287,9 +287,9 @@ export function linkBytecode (contract, contracts, callback?, callbackStep?, cal
return callback(null, contract.evm.bytecode.object) return callback(null, contract.evm.bytecode.object)
} }
if (contract.evm.bytecode.linkReferences && Object.keys(contract.evm.bytecode.linkReferences).length) { if (contract.evm.bytecode.linkReferences && Object.keys(contract.evm.bytecode.linkReferences).length) {
this.linkBytecodeStandard(contract, contracts, callback, callbackStep, callbackDeployLibrary) linkBytecodeStandard(contract, contracts, callback, callbackStep, callbackDeployLibrary)
} else { } else {
this.linkBytecodeLegacy(contract, contracts, callback, callbackStep, callbackDeployLibrary) linkBytecodeLegacy(contract, contracts, callback, callbackStep, callbackDeployLibrary)
} }
} }
@ -300,11 +300,11 @@ export function deployLibrary (libraryName, libraryShortName, library, contracts
} }
const bytecode = library.evm.bytecode.object const bytecode = library.evm.bytecode.object
if (bytecode.indexOf('_') >= 0) { if (bytecode.indexOf('_') >= 0) {
this.linkBytecode(library, contracts, (err, bytecode) => { linkBytecode(library, contracts, (err, bytecode) => {
if (err) callback(err) if (err) callback(err)
else { else {
library.evm.bytecode.object = bytecode library.evm.bytecode.object = bytecode
this.deployLibrary(libraryName, libraryShortName, library, contracts, callback, callbackStep, callbackDeployLibrary) deployLibrary(libraryName, libraryShortName, library, contracts, callback, callbackStep, callbackDeployLibrary)
} }
}, callbackStep, callbackDeployLibrary) }, callbackStep, callbackDeployLibrary)
} else { } else {
@ -325,7 +325,7 @@ export function linkLibraryStandardFromlinkReferences (libraryName, address, byt
for (const file in linkReferences) { for (const file in linkReferences) {
for (const libName in linkReferences[file]) { for (const libName in linkReferences[file]) {
if (libraryName === libName) { if (libraryName === libName) {
bytecode = this.setLibraryAddress(address, bytecode, linkReferences[file][libName]) bytecode = setLibraryAddress(address, bytecode, linkReferences[file][libName])
} }
} }
} }
@ -333,7 +333,7 @@ export function linkLibraryStandardFromlinkReferences (libraryName, address, byt
} }
export function linkLibraryStandard (libraryName, address, bytecode, contract) { export function linkLibraryStandard (libraryName, address, bytecode, contract) {
return this.linkLibraryStandardFromlinkReferences(libraryName, address, bytecode, contract.evm.bytecode.linkReferences) return linkLibraryStandardFromlinkReferences(libraryName, address, bytecode, contract.evm.bytecode.linkReferences)
} }
export function setLibraryAddress (address, bytecodeToLink, positions) { export function setLibraryAddress (address, bytecodeToLink, positions) {
@ -384,7 +384,7 @@ export function decodeResponse (response, fnabi) {
export function parseFunctionParams (params) { export function parseFunctionParams (params) {
let args = [] let args = []
// Check if parameter string starts with array or string // Check if parameter string starts with array or string
let startIndex = this.isArrayOrStringStart(params, 0) ? -1 : 0 let startIndex = isArrayOrStringStart(params, 0) ? -1 : 0
for (let i = 0; i < params.length; i++) { for (let i = 0; i < params.length; i++) {
// If a quote is received // If a quote is received
if (params.charAt(i) === '"') { if (params.charAt(i) === '"') {
@ -427,7 +427,7 @@ export function parseFunctionParams (params) {
args.push(params.substring(startIndex, i)) args.push(params.substring(startIndex, i))
} }
// Register start index of a parameter to parse // Register start index of a parameter to parse
startIndex = this.isArrayOrStringStart(params, i + 1) ? -1 : i + 1 startIndex = isArrayOrStringStart(params, i + 1) ? -1 : i + 1
} else if (startIndex >= 0 && i === params.length - 1) { } else if (startIndex >= 0 && i === params.length - 1) {
// If start index is registered and string is completed (To handle last parameter) // If start index is registered and string is completed (To handle last parameter)
args.push(params.substring(startIndex, params.length)) args.push(params.substring(startIndex, params.length))

@ -3,8 +3,8 @@ import { ethers } from 'ethers'
export function makeFullTypeDefinition (typeDef) { export function makeFullTypeDefinition (typeDef) {
if (typeDef && typeDef.type.indexOf('tuple') === 0 && typeDef.components) { if (typeDef && typeDef.type.indexOf('tuple') === 0 && typeDef.components) {
const innerTypes = typeDef.components.map((innerType) => { return this.makeFullTypeDefinition(innerType) }) const innerTypes = typeDef.components.map((innerType) => { return makeFullTypeDefinition(innerType) })
return `tuple(${innerTypes.join(',')})${this.extractSize(typeDef.type)}` return `tuple(${innerTypes.join(',')})${extractSize(typeDef.type)}`
} }
return typeDef.type return typeDef.type
} }
@ -19,7 +19,7 @@ export function encodeParams (funABI, args) {
if (type === 'bool' && args[i] === 'false') { if (type === 'bool' && args[i] === 'false') {
args[i] = false args[i] = false
} }
types.push(type.indexOf('tuple') === 0 ? this.makeFullTypeDefinition(funABI.inputs[i]) : type) types.push(type.indexOf('tuple') === 0 ? makeFullTypeDefinition(funABI.inputs[i]) : type)
if (args.length < types.length) { if (args.length < types.length) {
args.push('') args.push('')
} }
@ -107,7 +107,7 @@ export function getFunction (abi, fnName) {
const fn = abi[i] const fn = abi[i]
if (fn.type === 'function' && fnName === fn.name + '(' + fn.inputs.map((value) => { if (fn.type === 'function' && fnName === fn.name + '(' + fn.inputs.map((value) => {
if (value.components) { if (value.components) {
const fullType = this.makeFullTypeDefinition(value) const fullType = makeFullTypeDefinition(value)
return fullType.replace(/tuple/g, '') // return of makeFullTypeDefinition might contain `tuple`, need to remove it cause `methodIdentifier` (fnName) does not include `tuple` keyword return fullType.replace(/tuple/g, '') // return of makeFullTypeDefinition might contain `tuple`, need to remove it cause `methodIdentifier` (fnName) does not include `tuple` keyword
} else { } else {
return value.type return value.type

@ -13,7 +13,6 @@ export class TxRunnerVM {
vmaccounts vmaccounts
queusTxs queusTxs
blocks blocks
txs
logsManager logsManager
commonContext commonContext
getVMObject: () => any getVMObject: () => any

@ -11,7 +11,7 @@ export function formatMemory (mem, width) {
for (let k = 0; k < mem.length; k += (width * 2)) { for (let k = 0; k < mem.length; k += (width * 2)) {
const memory = mem.substr(k, width * 2) const memory = mem.substr(k, width * 2)
const content = this.tryConvertAsciiFormat(memory) const content = tryConvertAsciiFormat(memory)
ret['0x' + (k / 2).toString(16)] = content.raw + '\t' + content.ascii ret['0x' + (k / 2).toString(16)] = content.raw + '\t' + content.ascii
} }
return ret return ret

@ -4,12 +4,12 @@ import Web3 from 'web3'
export function loadWeb3 (url = 'http://localhost:8545') { export function loadWeb3 (url = 'http://localhost:8545') {
const web3 = new Web3() const web3 = new Web3()
web3.setProvider(new Web3.providers.HttpProvider(url)) web3.setProvider(new Web3.providers.HttpProvider(url))
this.extend(web3) extend(web3)
return web3 return web3
} }
export function extendWeb3 (web3) { export function extendWeb3 (web3) {
this.extend(web3) extend(web3)
} }
export function extend (web3) { export function extend (web3) {

@ -85,7 +85,7 @@ export function findLowerBound (target, array) {
return largest array[i] such that array[i] <= target; return null if array[0] > target || array is empty return largest array[i] such that array[i] <= target; return null if array[0] > target || array is empty
*/ */
export function findLowerBoundValue (target, array) { export function findLowerBoundValue (target, array) {
const index = this.findLowerBound(target, array) const index = findLowerBound(target, array)
return index >= 0 ? array[index] : null return index >= 0 ? array[index] : null
} }
@ -99,7 +99,7 @@ export function findClosestIndex (target, array): number {
if (array.length === 0) { if (array.length === 0) {
return -1 return -1
} }
const index = this.findLowerBound(target, array) const index = findLowerBound(target, array)
if (index < 0) { if (index < 0) {
return 0 return 0
} else if (index >= array.length - 1) { } else if (index >= array.length - 1) {
@ -185,13 +185,13 @@ export function cborEncodedValueExtraction () {
} }
export function extractcborMetadata (value) { export function extractcborMetadata (value) {
return value.replace(this.cborEncodedValueExtraction(), '') return value.replace(cborEncodedValueExtraction(), '')
} }
export function extractSwarmHash (value) { export function extractSwarmHash (value) {
value = value.replace(this.swarmHashExtraction(), '') value = value.replace(swarmHashExtraction(), '')
value = value.replace(this.swarmHashExtractionPOC31(), '') value = value.replace(swarmHashExtractionPOC31(), '')
value = value.replace(this.swarmHashExtractionPOC32(), '') value = value.replace(swarmHashExtractionPOC32(), '')
return value return value
} }
@ -218,10 +218,10 @@ export function compareByteCode (code1, code2) {
code2 = replaceLibReference(code2, pos) code2 = replaceLibReference(code2, pos)
code1 = replaceLibReference(code1, pos) code1 = replaceLibReference(code1, pos)
} }
code1 = this.extractSwarmHash(code1) code1 = extractSwarmHash(code1)
code1 = this.extractcborMetadata(code1) code1 = extractcborMetadata(code1)
code2 = this.extractSwarmHash(code2) code2 = extractSwarmHash(code2)
code2 = this.extractcborMetadata(code2) code2 = extractcborMetadata(code2)
if (code1 && code2) { if (code1 && code2) {
const compare = stringSimilarity.compareTwoStrings(code1, code2) const compare = stringSimilarity.compareTwoStrings(code1, code2)

@ -129,7 +129,11 @@ export class Web3VmProvider {
this.storageCache[this.processingHash] = {} this.storageCache[this.processingHash] = {}
if (data.to) { if (data.to) {
try { try {
const storage = await this.vm.stateManager.dumpStorage(data.to) // dumpStorage throws error as 'Missing Node in DB'
// This can be uncommented once that error is handled
// https://github.com/ethereum/remix-project/issues/1644
// const storage = await this.vm.stateManager.dumpStorage(data.to)
const storage = {}
this.storageCache[this.processingHash][tx['to']] = storage this.storageCache[this.processingHash][tx['to']] = storage
this.lastProcessedStorageTxHash[tx['to']] = this.processingHash this.lastProcessedStorageTxHash[tx['to']] = this.processingHash
} catch (e) { } catch (e) {
@ -245,7 +249,11 @@ export class Web3VmProvider {
if (!this.storageCache[this.processingHash][this.processingAddress]) { if (!this.storageCache[this.processingHash][this.processingAddress]) {
const account = Address.fromString(this.processingAddress) const account = Address.fromString(this.processingAddress)
try { try {
const storage = await this.vm.stateManager.dumpStorage(account) // dumpStorage throws error as 'Missing Node in DB'
// This can be uncommented once that error is handled
// https://github.com/ethereum/remix-project/issues/1644
// const storage = await this.vm.stateManager.dumpStorage(account)
const storage = {}
this.storageCache[this.processingHash][this.processingAddress] = storage this.storageCache[this.processingHash][this.processingAddress] = storage
this.lastProcessedStorageTxHash[this.processingAddress] = this.processingHash this.lastProcessedStorageTxHash[this.processingAddress] = this.processingHash
} catch (e) { } catch (e) {

@ -1,13 +1,10 @@
export class Blocks { export class Blocks {
vmContext vmContext
coinbase: string coinbase: string
blockNumber: number
constructor (vmContext, _options) { constructor (vmContext, _options) {
this.vmContext = vmContext this.vmContext = vmContext
const options = _options || {} const options = _options || {}
this.coinbase = options.coinbase || '0x0000000000000000000000000000000000000000' this.coinbase = options.coinbase || '0x0000000000000000000000000000000000000000'
this.blockNumber = 0
} }
methods (): Record<string, unknown> { methods (): Record<string, unknown> {
@ -107,7 +104,7 @@ export class Blocks {
} }
eth_blockNumber (payload, cb) { eth_blockNumber (payload, cb) {
cb(null, this.blockNumber) cb(null, parseInt(this.vmContext.latestBlockNumber))
} }
eth_getBlockTransactionCountByHash (payload, cb) { eth_getBlockTransactionCountByHash (payload, cb) {

@ -3,16 +3,16 @@ const version = require('../../package.json').version
export function methods () { export function methods () {
return { return {
web3_clientVersion: this.web3_clientVersion.bind(this), web3_clientVersion: web3_clientVersion,
eth_protocolVersion: this.eth_protocolVersion.bind(this), eth_protocolVersion: eth_protocolVersion,
eth_syncing: this.eth_syncing.bind(this), eth_syncing: eth_syncing,
eth_mining: this.eth_mining.bind(this), eth_mining: eth_mining,
eth_hashrate: this.eth_hashrate.bind(this), eth_hashrate: eth_hashrate,
web3_sha3: this.web3_sha3.bind(this), web3_sha3: web3_sha3,
eth_getCompilers: this.eth_getCompilers.bind(this), eth_getCompilers: eth_getCompilers,
eth_compileSolidity: this.eth_compileSolidity.bind(this), eth_compileSolidity: eth_compileSolidity,
eth_compileLLL: this.eth_compileLLL.bind(this), eth_compileLLL: eth_compileLLL,
eth_compileSerpent: this.eth_compileSerpent.bind(this) eth_compileSerpent: eth_compileSerpent
} }
} }

@ -1,8 +1,8 @@
export function methods (): Record<string, unknown> { export function methods (): Record<string, unknown> {
return { return {
net_version: this.net_version, net_version: net_version,
net_listening: this.net_listening, net_listening: net_listening,
net_peerCount: this.net_peerCount net_peerCount: net_peerCount
} }
} }

@ -11,6 +11,7 @@ export class Transactions {
tags tags
txRunnerVMInstance txRunnerVMInstance
txRunnerInstance txRunnerInstance
TX_INDEX = '0x0' // currently there's always only 1 tx per block, so the transaction index will always be 0x0
constructor (vmContext) { constructor (vmContext) {
this.vmContext = vmContext this.vmContext = vmContext
@ -71,7 +72,7 @@ export class Transactions {
if (!error && result) { if (!error && result) {
this.vmContext.addBlock(result.block) this.vmContext.addBlock(result.block)
const hash = '0x' + result.tx.hash().toString('hex') const hash = '0x' + result.tx.hash().toString('hex')
this.vmContext.trackTx(hash, result.block) this.vmContext.trackTx(hash, result.block, result.tx)
this.vmContext.trackExecResult(hash, result.result.execResult) this.vmContext.trackExecResult(hash, result.result.execResult)
return cb(null, result.transactionHash) return cb(null, result.transactionHash)
} }
@ -95,17 +96,19 @@ export class Transactions {
return cb(error) return cb(error)
} }
const txBlock = this.vmContext.txs[receipt.hash] const txBlock = this.vmContext.blockByTxHash[receipt.hash]
const logs = this.vmContext.logsManager.getLogsByTxHash(receipt.hash)
const r: Record <string, unknown> = { const r: Record <string, unknown> = {
transactionHash: receipt.hash, transactionHash: receipt.hash,
transactionIndex: '0x00', transactionIndex: this.TX_INDEX,
blockHash: '0x' + txBlock.hash().toString('hex'), blockHash: '0x' + txBlock.hash().toString('hex'),
blockNumber: '0x' + txBlock.header.number.toString('hex'), blockNumber: '0x' + txBlock.header.number.toString('hex'),
gasUsed: receipt.gasUsed, gasUsed: receipt.gasUsed,
cumulativeGasUsed: receipt.gasUsed, // only 1 tx per block cumulativeGasUsed: receipt.gasUsed, // only 1 tx per block
contractAddress: receipt.contractAddress, contractAddress: receipt.contractAddress,
logs: receipt.logs, logs,
status: receipt.status, status: receipt.status,
to: receipt.to to: receipt.to
} }
@ -151,7 +154,7 @@ export class Transactions {
if (!error && result) { if (!error && result) {
this.vmContext.addBlock(result.block) this.vmContext.addBlock(result.block)
const hash = '0x' + result.tx.hash().toString('hex') const hash = '0x' + result.tx.hash().toString('hex')
this.vmContext.trackTx(hash, result.block) this.vmContext.trackTx(hash, result.block, result.tx)
this.vmContext.trackExecResult(hash, result.result.execResult) this.vmContext.trackExecResult(hash, result.result.execResult)
this.tags[tag] = result.transactionHash this.tags[tag] = result.transactionHash
// calls are not supposed to return a transaction hash. we do this for keeping track of it and allowing debugging calls. // calls are not supposed to return a transaction hash. we do this for keeping track of it and allowing debugging calls.
@ -185,7 +188,8 @@ export class Transactions {
return cb(error) return cb(error)
} }
const txBlock = this.vmContext.txs[receipt.transactionHash] const txBlock = this.vmContext.blockByTxHash[receipt.transactionHash]
const tx = this.vmContext.txByHash[receipt.transactionHash]
// TODO: params to add later // TODO: params to add later
const r: Record<string, unknown> = { const r: Record<string, unknown> = {
@ -198,8 +202,8 @@ export class Transactions {
gasPrice: '0x4a817c800', // 20000000000 gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash, hash: receipt.transactionHash,
input: receipt.input, input: receipt.input,
nonce: 2, // 0x15 // the nonce should be updated nonce: '0x' + tx.nonce.toString('hex'),
// "transactionIndex": 0, transactionIndex: this.TX_INDEX,
value: receipt.value value: receipt.value
// "value":"0xf3dbb76162000" // 4290000000000000 // "value":"0xf3dbb76162000" // 4290000000000000
// "v": "0x25", // 37 // "v": "0x25", // 37
@ -234,6 +238,8 @@ export class Transactions {
return cb(error) return cb(error)
} }
const tx = this.vmContext.txByHash[receipt.transactionHash]
// TODO: params to add later // TODO: params to add later
const r: Record<string, unknown> = { const r: Record<string, unknown> = {
blockHash: '0x' + txBlock.hash().toString('hex'), blockHash: '0x' + txBlock.hash().toString('hex'),
@ -245,8 +251,8 @@ export class Transactions {
gasPrice: '0x4a817c800', // 20000000000 gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash, hash: receipt.transactionHash,
input: receipt.input, input: receipt.input,
nonce: 2, // 0x15 // the nonce should be updated nonce: '0x' + tx.nonce.toString('hex'),
// "transactionIndex": 0, transactionIndex: this.TX_INDEX,
value: receipt.value value: receipt.value
// "value":"0xf3dbb76162000" // 4290000000000000 // "value":"0xf3dbb76162000" // 4290000000000000
// "v": "0x25", // 37 // "v": "0x25", // 37
@ -277,6 +283,8 @@ export class Transactions {
return cb(error) return cb(error)
} }
const tx = this.vmContext.txByHash[receipt.transactionHash]
// TODO: params to add later // TODO: params to add later
const r: Record<string, unknown> = { const r: Record<string, unknown> = {
blockHash: '0x' + txBlock.hash().toString('hex'), blockHash: '0x' + txBlock.hash().toString('hex'),
@ -288,8 +296,8 @@ export class Transactions {
gasPrice: '0x4a817c800', // 20000000000 gasPrice: '0x4a817c800', // 20000000000
hash: receipt.transactionHash, hash: receipt.transactionHash,
input: receipt.input, input: receipt.input,
nonce: 2, // 0x15 // the nonce should be updated nonce: '0x' + tx.nonce.toString('hex'),
// "transactionIndex": 0, transactionIndex: this.TX_INDEX,
value: receipt.value value: receipt.value
// "value":"0xf3dbb76162000" // 4290000000000000 // "value":"0xf3dbb76162000" // 4290000000000000
// "v": "0x25", // 37 // "v": "0x25", // 37

@ -9,11 +9,11 @@ function hasFlag (flag) {
} }
function addColor (str) { function addColor (str) {
if (this.hasFlag('no-color')) { if (hasFlag('no-color')) {
return str return str
} }
if (this.hasFlag('color')) { if (hasFlag('color')) {
return gray(str) return gray(str)
} }
@ -35,41 +35,36 @@ function stderr (arg) {
} }
function getTimestamp () { function getTimestamp () {
const coloredTimestamp = this.addColor(timestamp('HH:mm:ss')) const coloredTimestamp = addColor(timestamp('HH:mm:ss'))
return '[' + coloredTimestamp + ']' return '[' + coloredTimestamp + ']'
} }
export function log (...args: any[]) { export function log (...args: any[]) {
const time = this.getTimestamp() const time = getTimestamp()
this.stdout(time + ' ') stdout(time + ' ')
console.log(args) console.log(args)
return this
} }
export function info (...args: any[]) { export function info (...args: any[]) {
const time = this.getTimestamp() const time = getTimestamp()
this.stdout(time + ' ') stdout(time + ' ')
console.info(args) console.info(args)
return this
} }
export function dir (...args: any[]) { export function dir (...args: any[]) {
const time = this.getTimestamp() const time = getTimestamp()
this.stdout(time + ' ') stdout(time + ' ')
console.dir(args) console.dir(args)
return this
} }
export function warn (...args: any[]) { export function warn (...args: any[]) {
const time = this.getTimestamp() const time = getTimestamp()
this.stderr(time + ' ') stderr(time + ' ')
console.warn(args) console.warn(args)
return this
} }
export function error (...args: any[]) { export function error (...args: any[]) {
const time = this.getTimestamp() const time = getTimestamp()
this.stderr(time + ' ') stderr(time + ' ')
console.error(args) console.error(args)
return this
} }

@ -24,18 +24,13 @@ class StateManagerCommonStorageDump extends StateManager {
return super.putContractStorage(address, key, value) return super.putContractStorage(address, key, value)
} }
async dumpStorage (address) { async dumpStorage (address): Promise<StorageDump> {
let trie return new Promise((resolve, reject) => {
try { this._getStorageTrie(address)
trie = await this._getStorageTrie(address) .then((trie) => {
} catch (e) {
console.log(e)
throw e
}
return new Promise<StorageDump>((resolve, reject) => {
try {
const storage = {} const storage = {}
const stream = trie.createReadStream() const stream = trie.createReadStream()
stream.on('data', (val) => { stream.on('data', (val) => {
const value = rlp.decode(val.value) const value = rlp.decode(val.value)
storage['0x' + val.key.toString('hex')] = { storage['0x' + val.key.toString('hex')] = {
@ -43,12 +38,13 @@ class StateManagerCommonStorageDump extends StateManager {
value: '0x' + value.toString('hex') value: '0x' + value.toString('hex')
} }
}) })
stream.on('end', function () { stream.on('end', () => {
resolve(storage) resolve(storage)
}) })
} catch (e) { })
.catch((e) => {
reject(e) reject(e)
} })
}) })
} }
@ -60,19 +56,18 @@ class StateManagerCommonStorageDump extends StateManager {
} }
async setStateRoot (stateRoot) { async setStateRoot (stateRoot) {
await this._cache.flush() if (this._checkpointCount !== 0) {
throw new Error('Cannot set state root with uncommitted checkpoints')
if (stateRoot === this._trie.EMPTY_TRIE_ROOT) {
this._trie.root = stateRoot
this._cache.clear()
this._storageTries = {}
return
} }
await this._cache.flush()
if (!stateRoot.equals(this._trie.EMPTY_TRIE_ROOT)) {
const hasRoot = await this._trie.checkRoot(stateRoot) const hasRoot = await this._trie.checkRoot(stateRoot)
if (!hasRoot) { if (!hasRoot) {
throw new Error('State trie does not contain state root') throw new Error('State trie does not contain state root')
} }
}
this._trie.root = stateRoot this._trie.root = stateRoot
this._cache.clear() this._cache.clear()
@ -90,7 +85,8 @@ export class VMContext {
customNetWorks customNetWorks
blocks blocks
latestBlockNumber latestBlockNumber
txs blockByTxHash
txByHash
currentVm currentVm
web3vm web3vm
logsManager logsManager
@ -103,7 +99,8 @@ export class VMContext {
this.currentVm = this.createVm(this.currentFork) this.currentVm = this.createVm(this.currentFork)
this.blocks = {} this.blocks = {}
this.latestBlockNumber = 0 this.latestBlockNumber = 0
this.txs = {} this.blockByTxHash = {}
this.txByHash = {}
this.exeResults = {} this.exeResults = {}
this.logsManager = new execution.LogsManager() this.logsManager = new execution.LogsManager()
} }
@ -156,8 +153,9 @@ export class VMContext {
this.logsManager.checkBlock(blockNumber, block, this.web3()) this.logsManager.checkBlock(blockNumber, block, this.web3())
} }
trackTx (tx, block) { trackTx (txHash, block, tx) {
this.txs[tx] = block this.blockByTxHash[txHash] = block
this.txByHash[txHash] = tx
} }
trackExecResult (tx, execReult) { trackExecResult (tx, execReult) {

@ -116,6 +116,7 @@ describe('blocks', () => {
}) })
}) })
/*
describe('eth_getStorageAt', () => { describe('eth_getStorageAt', () => {
it('should get storage at position at given address', async () => { it('should get storage at position at given address', async () => {
const abi: any = [ const abi: any = [
@ -200,28 +201,29 @@ describe('blocks', () => {
} }
] ]
const code = '0x608060405234801561001057600080fd5b506040516020806102018339810180604052602081101561003057600080fd5b810190808051906020019092919050505080600081905550506101a9806100586000396000f3fe60806040526004361061005c576000357c0100000000000000000000000000000000000000000000000000000000900480632a1afcd91461006157806360fe47b11461008c5780636d4ce63c146100c7578063ce01e1ec146100f2575b600080fd5b34801561006d57600080fd5b5061007661012d565b6040518082815260200191505060405180910390f35b34801561009857600080fd5b506100c5600480360360208110156100af57600080fd5b8101908080359060200190929190505050610133565b005b3480156100d357600080fd5b506100dc61013d565b6040518082815260200191505060405180910390f35b3480156100fe57600080fd5b5061012b6004803603602081101561011557600080fd5b8101908080359060200190929190505050610146565b005b60005481565b8060008190555050565b60008054905090565b80600081905550807f63a242a632efe33c0e210e04e4173612a17efa4f16aa4890bc7e46caece80de060405160405180910390a25056fea165627a7a7230582063160eb16dc361092a85ced1a773eed0b63738b83bea1e1c51cf066fa90e135d0029' // const code = '0x608060405234801561001057600080fd5b506040516020806102018339810180604052602081101561003057600080fd5b810190808051906020019092919050505080600081905550506101a9806100586000396000f3fe60806040526004361061005c576000357c0100000000000000000000000000000000000000000000000000000000900480632a1afcd91461006157806360fe47b11461008c5780636d4ce63c146100c7578063ce01e1ec146100f2575b600080fd5b34801561006d57600080fd5b5061007661012d565b6040518082815260200191505060405180910390f35b34801561009857600080fd5b506100c5600480360360208110156100af57600080fd5b8101908080359060200190929190505050610133565b005b3480156100d357600080fd5b506100dc61013d565b6040518082815260200191505060405180910390f35b3480156100fe57600080fd5b5061012b6004803603602081101561011557600080fd5b8101908080359060200190929190505050610146565b005b60005481565b8060008190555050565b60008054905090565b80600081905550807f63a242a632efe33c0e210e04e4173612a17efa4f16aa4890bc7e46caece80de060405160405180910390a25056fea165627a7a7230582063160eb16dc361092a85ced1a773eed0b63738b83bea1e1c51cf066fa90e135d0029'
const contract = new web3.eth.Contract(abi) // const contract = new web3.eth.Contract(abi)
const accounts = await web3.eth.getAccounts() // const accounts = await web3.eth.getAccounts()
const contractInstance: any = await contract.deploy({ data: code, arguments: [100] }).send({ from: accounts[0], gas: 400000 }) // const contractInstance: any = await contract.deploy({ data: code, arguments: [100] }).send({ from: accounts[0], gas: 400000 })
contractInstance.currentProvider = web3.eth.currentProvider // contractInstance.currentProvider = web3.eth.currentProvider
contractInstance.givenProvider = web3.eth.currentProvider // contractInstance.givenProvider = web3.eth.currentProvider
await contractInstance.methods.set(100).send({ from: accounts[0].toLowerCase(), gas: 400000 }) // await contractInstance.methods.set(100).send({ from: accounts[0].toLowerCase(), gas: 400000 })
let storage = await web3.eth.getStorageAt(contractInstance.options.address, 0) // let storage = await web3.eth.getStorageAt(contractInstance.options.address, 0)
assert.deepEqual(storage, '0x64') // assert.deepEqual(storage, '0x64')
await contractInstance.methods.set(200).send({ from: accounts[0], gas: 400000 }) // await contractInstance.methods.set(200).send({ from: accounts[0], gas: 400000 })
storage = await web3.eth.getStorageAt(contractInstance.options.address, 0) // storage = await web3.eth.getStorageAt(contractInstance.options.address, 0)
assert.deepEqual(storage, '0x64') // assert.deepEqual(storage, '0x64')
await contractInstance.methods.set(200).send({ from: accounts[0], gas: 400000 }) await contractInstance.methods.set(200).send({ from: accounts[0], gas: 400000 })
storage = await web3.eth.getStorageAt(contractInstance.options.address, 0) storage = await web3.eth.getStorageAt(contractInstance.options.address, 0)
assert.deepEqual(storage, '0xc8') assert.deepEqual(storage, '0xc8')
}) })
}) })
*/
describe('eth_call', () => { describe('eth_call', () => {
it('should get a value', async () => { it('should get a value', async () => {

@ -2,8 +2,8 @@
"name": "@remix-project/remix-solidity", "name": "@remix-project/remix-solidity",
"version": "0.4.7", "version": "0.4.7",
"description": "Tool to load and run Solidity compiler", "description": "Tool to load and run Solidity compiler",
"main": "index.js", "main": "src/index.js",
"types": "./index.d.ts", "types": "src/index.d.ts",
"contributors": [ "contributors": [
{ {
"name": "Yann Levreau", "name": "Yann Levreau",
@ -60,6 +60,6 @@
"url": "https://github.com/ethereum/remix-project/issues" "url": "https://github.com/ethereum/remix-project/issues"
}, },
"homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme", "homepage": "https://github.com/ethereum/remix-project/tree/master/libs/remix-solidity#readme",
"typings": "index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4705cbc4d1761f75267992552da9db6cff2f3ed5" "gitHead": "4705cbc4d1761f75267992552da9db6cff2f3ed5"
} }

@ -232,6 +232,7 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
testCallback(undefined, resp) testCallback(undefined, resp)
async.eachOfLimit(runList, 1, function (func, index, next) { async.eachOfLimit(runList, 1, function (func, index, next) {
let sender: string | null = null let sender: string | null = null
let hhLogs
if (func.signature) { if (func.signature) {
sender = getOverridedSender(contractDetails.userdoc, func.signature, contractDetails.evm.methodIdentifiers) sender = getOverridedSender(contractDetails.userdoc, func.signature, contractDetails.evm.methodIdentifiers)
if (opts.accounts && sender) { if (opts.accounts && sender) {
@ -293,7 +294,6 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
sendParams.gas = 10000000 * 8 sendParams.gas = 10000000 * 8
method.send(sendParams).on('receipt', async (receipt) => { method.send(sendParams).on('receipt', async (receipt) => {
try { try {
let hhLogs
if (web3.eth && web3.eth.getHHLogsForTx) hhLogs = await web3.eth.getHHLogsForTx(receipt.transactionHash) if (web3.eth && web3.eth.getHHLogsForTx) hhLogs = await web3.eth.getHHLogsForTx(receipt.transactionHash)
const time: number = (Date.now() - startTime) / 1000.0 const time: number = (Date.now() - startTime) / 1000.0
const assertionEventHashes = assertionEvents.map(e => Web3.utils.sha3(e.name + '(' + e.params.join() + ')')) const assertionEventHashes = assertionEvents.map(e => Web3.utils.sha3(e.name + '(' + e.params.join() + ')'))
@ -366,7 +366,7 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
console.error(err) console.error(err)
return next(err) return next(err)
} }
}).on('error', function (err: Error) { }).on('error', async (err: Error) => {
const time: number = (Date.now() - startTime) / 1000.0 const time: number = (Date.now() - startTime) / 1000.0
const resp: TestResultInterface = { const resp: TestResultInterface = {
type: 'testFailure', type: 'testFailure',
@ -377,6 +377,11 @@ export function runTest (testName: string, testObject: any, contractDetails: Com
context: testName, context: testName,
web3 web3
} }
if (err.message.includes('Transaction has been reverted by the EVM')) {
const txHash = JSON.parse(err.message.replace('Transaction has been reverted by the EVM:', '')).transactionHash
if (web3.eth && web3.eth.getHHLogsForTx) hhLogs = await web3.eth.getHHLogsForTx(txHash)
if (hhLogs) resp.hhLogs = hhLogs
}
testCallback(undefined, resp) testCallback(undefined, resp)
failureNum += 1 failureNum += 1
timePassed += time timePassed += time

@ -14,6 +14,8 @@
}, },
"rules": { "rules": {
"no-unused-vars": "off", "no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error" "@typescript-eslint/no-unused-vars": "error",
"no-useless-constructor": "off",
"@typescript-eslint/no-useless-constructor": "error"
} }
} }

@ -11,12 +11,12 @@ interface SetPluginOptionType {
} }
export class RemixEngine extends Engine { export class RemixEngine extends Engine {
event: EventEmitter; event: EventEmitter
setPluginOption ({ name, kind }) : SetPluginOptionType setPluginOption ({ name, kind }) : SetPluginOptionType
onRegistration (plugin) : void onRegistration (plugin) : void
} }
export function isNative(name: any): any; export function isNative(name: any): any
/** /**
* Checks if plugin caller 'from' is allowed to activate plugin 'to' * Checks if plugin caller 'from' is allowed to activate plugin 'to'
* The caller can have 'canActivate' as a optional property in the plugin profile. * The caller can have 'canActivate' as a optional property in the plugin profile.
@ -27,33 +27,33 @@ export function isNative(name: any): any;
* @param {any, any} * @param {any, any}
* @returns {boolean} * @returns {boolean}
*/ */
export function canActivate(from: any, to: any): boolean; export function canActivate(from: any, to: any): boolean
export class RemixAppManager extends PluginManager { export class RemixAppManager extends PluginManager {
constructor(); constructor()
event: EventEmitter; event: EventEmitter
pluginsDirectory: string; pluginsDirectory: string
pluginLoader: PluginLoader; pluginLoader: PluginLoader
permissionHandler: PermissionHandler; permissionHandler: PermissionHandler
getAll(): import('@remixproject/plugin-utils').Profile<any>[]; getAll(): import('@remixproject/plugin-utils').Profile<any>[]
getIds(): string[]; getIds(): string[]
isDependent(name: any): any; isDependent(name: any): any
isRequired(name: any): any; isRequired(name: any): any
registeredPlugins(): Promise<any>; registeredPlugins(): Promise<any>
turnPluginOn(name: string | string[]); turnPluginOn(name: string | string[])
turnPluginOff(name: string); turnPluginOff(name: string)
} }
export class PluginManagerSettings { export class PluginManagerSettings {
openDialog(): void; openDialog(): void
permissions: any; permissions: any
currentSetting: any; currentSetting: any
onValidation(): void; onValidation(): void
/** Clear one permission from a plugin */ /** Clear one permission from a plugin */
clearPersmission(from: string, to: string, method: string): void; clearPersmission(from: string, to: string, method: string): void
/** Clear all persmissions from a plugin */ /** Clear all persmissions from a plugin */
clearAllPersmission(to: string): void; clearAllPersmission(to: string): void
settings(): any; settings(): any
render(): any; render(): any
} }
export type PluginPermissions = { export type PluginPermissions = {
@ -94,7 +94,7 @@ export class PluginManagerComponent extends ViewPlugin extends Plugin implements
} }
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
export = LocalPlugin; export = LocalPlugin
declare class LocalPlugin { declare class LocalPlugin {
/** /**
* Open a modal to create a local plugin * Open a modal to create a local plugin
@ -102,34 +102,34 @@ declare class LocalPlugin {
* @returns {Promise<{api: any, profile: any}>} A promise with the new plugin profile * @returns {Promise<{api: any, profile: any}>} A promise with the new plugin profile
*/ */
open(plugins: any[]): Promise<{ open(plugins: any[]): Promise<{
api: any; api: any
profile: any; profile: any
}>; }>
profile: any; profile: any
/** /**
* Create the object to add to the plugin-list * Create the object to add to the plugin-list
*/ */
create(): any; create(): any
updateName({ target }: { updateName({ target }: {
target: any; target: any
}): void; }): void
updateUrl({ target }: { updateUrl({ target }: {
target: any; target: any
}): void; }): void
updateDisplayName({ target }: { updateDisplayName({ target }: {
target: any; target: any
}): void; }): void
updateProfile(key: any, e: any): void; updateProfile(key: any, e: any): void
updateMethods({ target }: { updateMethods({ target }: {
target: any; target: any
}): void; }): void
/** The form to create a local plugin */ /** The form to create a local plugin */
form(): any; form(): any
} }
export interface PluginManagerContextProviderProps { export interface PluginManagerContextProviderProps {
@ -146,12 +146,12 @@ export interface RemixUiPluginManagerProps {
* (localStorage, queryParams) * (localStorage, queryParams)
**/ **/
declare class PluginLoader { declare class PluginLoader {
get currentLoader(): any; get currentLoader(): any
donotAutoReload: string[]; donotAutoReload: string[]
loaders: {}; loaders: {}
current: string; current: string
set(plugin: any, actives: any): void; set(plugin: any, actives: any): void
get(): any; get(): any
} }
export type PluginManagerSettings = { export type PluginManagerSettings = {

@ -8,7 +8,7 @@ import ErrorRenderer from './ErrorRenderer' // eslint-disable-line
import { compilation } from './actions/staticAnalysisActions' import { compilation } from './actions/staticAnalysisActions'
import { initialState, analysisReducer } from './reducers/staticAnalysisReducer' import { initialState, analysisReducer } from './reducers/staticAnalysisReducer'
import { OverlayTrigger, Tooltip } from 'react-bootstrap'// eslint-disable-line import { OverlayTrigger, Tooltip } from 'react-bootstrap'// eslint-disable-line
const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis import { CodeAnalysis } from '@remix-project/remix-analyzer'
declare global { declare global {
interface Window { interface Window {
@ -25,7 +25,7 @@ export interface RemixUiStaticAnalyserProps {
} }
export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => { export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
const [runner] = useState(new StaticAnalysisRunner()) const [runner] = useState(new CodeAnalysis())
const preProcessModules = (arr: any) => { const preProcessModules = (arr: any) => {
return arr.map((Item, i) => { return arr.map((Item, i) => {
@ -196,7 +196,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
fileName = Object.keys(lastCompilationResult.sources)[file] fileName = Object.keys(lastCompilationResult.sources)[file]
} }
warningCount++ warningCount++
const msg = message(item.name, item.warning, item.more, fileName, locationString) const msg = message(result.name, item.warning, item.more, fileName, locationString)
const options = { const options = {
type: 'warning', type: 'warning',
useSpan: true, useSpan: true,

@ -2,8 +2,8 @@
"name": "@remix-project/remix-url-resolver", "name": "@remix-project/remix-url-resolver",
"version": "0.0.28", "version": "0.0.28",
"description": "Solidity import url resolver engine", "description": "Solidity import url resolver engine",
"main": "index.js", "main": "src/index.js",
"types": "./index.d.ts", "types": "src/index.d.ts",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"test": "./../../node_modules/.bin/mocha --require ts-node/register --require tsconfig-paths/register tests/*.ts -t 300000" "test": "./../../node_modules/.bin/mocha --require ts-node/register --require tsconfig-paths/register tests/*.ts -t 300000"
@ -41,6 +41,6 @@
"tslint": "^5.11.0", "tslint": "^5.11.0",
"typescript": "^3.1.6" "typescript": "^3.1.6"
}, },
"typings": "index.d.ts", "typings": "src/index.d.ts",
"gitHead": "4705cbc4d1761f75267992552da9db6cff2f3ed5" "gitHead": "4705cbc4d1761f75267992552da9db6cff2f3ed5"
} }

@ -12,7 +12,7 @@ import * as program from 'commander'
async function warnLatestVersion () { async function warnLatestVersion () {
const latest = await latestVersion('@remix-project/remixd') const latest = await latestVersion('@remix-project/remixd')
const pjson = require('../package.json') const pjson = require('../../package.json')
if (semver.eq(latest, pjson.version)) { if (semver.eq(latest, pjson.version)) {
console.log('\x1b[32m%s\x1b[0m', `[INFO] you are using the latest version ${latest}`) console.log('\x1b[32m%s\x1b[0m', `[INFO] you are using the latest version ${latest}`)
} else if (semver.gt(latest, pjson.version)) { } else if (semver.gt(latest, pjson.version)) {
@ -54,7 +54,7 @@ function errorHandler (error: any, service: string) {
} }
(async () => { (async () => {
const { version } = require('../package.json') const { version } = require('../../package.json')
program.version(version, '-v, --version') program.version(version, '-v, --version')
program program

@ -123,6 +123,17 @@
}, },
"solidity-compiler": { "solidity-compiler": {
"tags": [] "tags": []
},
"remix-ide-e2e-src-local-plugin": {
"tags": []
}
},
"targetDependencies": {
"build": [
{
"target": "build",
"projects": "dependencies"
}
]
} }
}
} }

94885
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -20,6 +20,10 @@
"bin": { "bin": {
"remix-ide": "./apps/remix-ide/bin/remix-ide" "remix-ide": "./apps/remix-ide/bin/remix-ide"
}, },
"engines": {
"node": "^14.17.6",
"npm": "^6.14.15"
},
"scripts": { "scripts": {
"nx": "nx", "nx": "nx",
"start": "nx start", "start": "nx start",
@ -42,7 +46,7 @@
"dep-graph": "nx dep-graph", "dep-graph": "nx dep-graph",
"help": "nx help", "help": "nx help",
"lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,remix-ui-plugin-manager", "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui,remix-ui-workspace,remix-ui-static-analyser,remix-ui-checkbox,remix-ui-settings,remix-core-plugin,remix-ui-renderer,remix-ui-publish-to-storage,remix-ui-solidity-compiler,remix-ui-plugin-manager",
"build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "build:libs": "nx run-many --target=build --parallel=false --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd",
"publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs", "publish:libs": "npm run build:libs && lerna publish --skip-git && npm run bumpVersion:libs",
"build:e2e": "tsc -p apps/remix-ide-e2e/tsconfig.e2e.json", "build:e2e": "tsc -p apps/remix-ide-e2e/tsconfig.e2e.json",
@ -53,7 +57,7 @@
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/solidity-compiler/src/assets/js/soljson.js", "downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/solidity-compiler/src/assets/js/soljson.js",
"make-mock-compiler": "node apps/remix-ide/ci/makeMockCompiler.js", "make-mock-compiler": "node apps/remix-ide/ci/makeMockCompiler.js",
"minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false", "minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false",
"build:production": "NODE_ENV=production npx nx build remix-ide --with-deps --skip-nx-cache", "build:production": "NODE_ENV=production nx build remix-ide --skip-nx-cache",
"serve:production": "npx http-server ./dist/apps/remix-ide", "serve:production": "npx http-server ./dist/apps/remix-ide",
"nightwatch_parallel": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome,firefox", "nightwatch_parallel": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=chrome,firefox",
"nightwatch_local_firefox": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=firefox", "nightwatch_local_firefox": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js --env=firefox",
@ -74,7 +78,7 @@
"nightwatch_local_gist": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.spec.js --env=chrome", "nightwatch_local_gist": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.spec.js --env=chrome",
"nightwatch_local_workspace": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/workspace.test.js --env=chrome", "nightwatch_local_workspace": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/workspace.test.js --env=chrome",
"nightwatch_local_defaultLayout": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/defaultLayout.test.js --env=chrome", "nightwatch_local_defaultLayout": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/defaultLayout.test.js --env=chrome",
"nightwatch_local_pluginManager": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/pluginManager.spec.js --env=chrome", "nightwatch_local_pluginManager": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/pluginManager.js --env=chrome",
"nightwatch_local_publishContract": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/publishContract.test.js --env=chrome", "nightwatch_local_publishContract": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/publishContract.test.js --env=chrome",
"nightwatch_local_generalSettings": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/generalSettings.test.js --env=chrome", "nightwatch_local_generalSettings": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/generalSettings.test.js --env=chrome",
"nightwatch_local_fileExplorer": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileExplorer.test.js --env=chrome", "nightwatch_local_fileExplorer": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/fileExplorer.test.js --env=chrome",
@ -132,10 +136,10 @@
}, },
"dependencies": { "dependencies": {
"@erebos/bzz-node": "^0.13.0", "@erebos/bzz-node": "^0.13.0",
"@ethereumjs/block": "^3.4.0", "@ethereumjs/block": "^3.5.1",
"@ethereumjs/common": "^2.4.0", "@ethereumjs/common": "^2.5.0",
"@ethereumjs/tx": "^3.3.0", "@ethereumjs/tx": "^3.3.2",
"@ethereumjs/vm": "^5.5.0", "@ethereumjs/vm": "^5.5.3",
"@remixproject/engine": "^0.3.20", "@remixproject/engine": "^0.3.20",
"@remixproject/engine-web": "^0.3.20", "@remixproject/engine-web": "^0.3.20",
"@remixproject/plugin": "^0.3.20", "@remixproject/plugin": "^0.3.20",
@ -168,10 +172,10 @@
"latest-version": "^5.1.0", "latest-version": "^5.1.0",
"merge": "^1.2.0", "merge": "^1.2.0",
"npm-install-version": "^6.0.2", "npm-install-version": "^6.0.2",
"react": "16.13.1", "react": "^17.0.2",
"react-beautiful-dnd": "^13.0.0", "react-beautiful-dnd": "^13.1.0",
"react-bootstrap": "^1.3.0", "react-bootstrap": "^1.6.4",
"react-dom": "16.13.1", "react-dom": "^17.0.2",
"selenium": "^2.20.0", "selenium": "^2.20.0",
"signale": "^1.4.0", "signale": "^1.4.0",
"string-similarity": "^4.0.4", "string-similarity": "^4.0.4",
@ -196,26 +200,27 @@
"@babel/preset-typescript": "7.9.0", "@babel/preset-typescript": "7.9.0",
"@babel/register": "^7.4.4", "@babel/register": "^7.4.4",
"@fortawesome/fontawesome-free": "^5.8.1", "@fortawesome/fontawesome-free": "^5.8.1",
"@nrwl/eslint-plugin-nx": "^10.0.6", "@nrwl/cli": "12.3.6",
"@nrwl/jest": "10.0.6", "@nrwl/eslint-plugin-nx": "12.3.6",
"@nrwl/linter": "^10.0.6", "@nrwl/jest": "12.3.6",
"@nrwl/node": "^10.0.6", "@nrwl/linter": "12.3.6",
"@nrwl/react": "10.0.6", "@nrwl/node": "12.3.6",
"@nrwl/web": "10.0.6", "@nrwl/react": "12.3.6",
"@nrwl/workspace": "10.0.6", "@nrwl/web": "12.3.6",
"@nrwl/workspace": "12.3.6",
"@testing-library/react": "10.4.1", "@testing-library/react": "10.4.1",
"@types/axios": "^0.14.0", "@types/axios": "^0.14.0",
"@types/chai": "^4.2.11", "@types/chai": "^4.2.11",
"@types/fs-extra": "^9.0.1", "@types/fs-extra": "^9.0.1",
"@types/jest": "25.1.4", "@types/jest": "^27.0.2",
"@types/lodash": "^4.14.172", "@types/lodash": "^4.14.172",
"@types/mocha": "^7.0.2", "@types/mocha": "^7.0.2",
"@types/nightwatch": "^1.1.6", "@types/nightwatch": "^1.1.6",
"@types/node": "~8.9.4", "@types/node": "~8.9.4",
"@types/react": "16.9.17", "@types/react": "^17.0.24",
"@types/react-beautiful-dnd": "^13.0.0", "@types/react-beautiful-dnd": "^13.1.2",
"@types/react-dom": "16.9.4", "@types/react-dom": "^17.0.9",
"@types/react-router-dom": "5.1.3", "@types/react-router-dom": "^5.3.0",
"@types/tape": "^4.13.0", "@types/tape": "^4.13.0",
"@types/ws": "^7.2.4", "@types/ws": "^7.2.4",
"@typescript-eslint/eslint-plugin": "^3.3.0", "@typescript-eslint/eslint-plugin": "^3.3.0",
@ -262,7 +267,7 @@
"ipfs-mini": "^1.1.5", "ipfs-mini": "^1.1.5",
"is-electron": "^2.2.0", "is-electron": "^2.2.0",
"javascript-serialize": "^1.6.1", "javascript-serialize": "^1.6.1",
"jest": "25.2.3", "jest": "^27.2.4",
"js-base64": "^2.1.9", "js-base64": "^2.1.9",
"js-beautify": "1.6.14", "js-beautify": "1.6.14",
"lerna": "^3.22.1", "lerna": "^3.22.1",
@ -289,10 +294,10 @@
"tap-spec": "^5.0.0", "tap-spec": "^5.0.0",
"tape": "^4.13.3", "tape": "^4.13.3",
"terser-webpack-plugin": "^4.2.3", "terser-webpack-plugin": "^4.2.3",
"ts-jest": "25.2.1", "ts-jest": "^27.0.5",
"ts-node": "^7.0.1", "ts-node": "^7.0.1",
"tslint": "~6.0.0", "tslint": "~6.0.0",
"typescript": "~3.8.3", "typescript": "^4.4.3",
"uglify-js": "^2.8.16", "uglify-js": "^2.8.16",
"vm-browserify": "0.0.4", "vm-browserify": "0.0.4",
"watchify": "^3.9.0", "watchify": "^3.9.0",

@ -16,14 +16,14 @@
"skipDefaultLibCheck": true, "skipDefaultLibCheck": true,
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@remix-project/remix-analyzer": ["dist/libs/remix-analyzer/index.js"], "@remix-project/remix-analyzer": ["dist/libs/remix-analyzer/src/index.js"],
"@remix-project/remix-astwalker": ["dist/libs/remix-astwalker/index.js"], "@remix-project/remix-astwalker": ["dist/libs/remix-astwalker/src/index.js"],
"@remix-project/remix-debug": ["dist/libs/remix-debug/src/index.js"], "@remix-project/remix-debug": ["dist/libs/remix-debug/src/index.js"],
"@remix-project/remix-lib": ["dist/libs/remix-lib/src/index.js"], "@remix-project/remix-lib": ["dist/libs/remix-lib/src/index.js"],
"@remix-project/remix-simulator": ["dist/libs/remix-simulator/src/index.js"], "@remix-project/remix-simulator": ["dist/libs/remix-simulator/src/index.js"],
"@remix-project/remix-solidity": ["dist/libs/remix-solidity/index.js"], "@remix-project/remix-solidity": ["dist/libs/remix-solidity/src/index.js"],
"@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"], "@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"],
"@remix-project/remix-url-resolver": ["dist/libs/remix-url-resolver/index.js"], "@remix-project/remix-url-resolver": ["dist/libs/remix-url-resolver/src/index.js"],
"@remixproject/debugger-plugin": ["apps/debugger/src/index.ts"], "@remixproject/debugger-plugin": ["apps/debugger/src/index.ts"],
"@remixproject/solidity-compiler-plugin": ["apps/solidity-compiler/src/index.ts"], "@remixproject/solidity-compiler-plugin": ["apps/solidity-compiler/src/index.ts"],
"@remix-project/remixd": ["dist/libs/remixd/index.js"], "@remix-project/remixd": ["dist/libs/remixd/index.js"],

@ -462,7 +462,7 @@
"options": { "options": {
"commands": [ "commands": [
{ {
"command": "SERVE_SCRIPT='chmod +x dist/libs/remixd/bin/remixd.js; dist/libs/remixd/bin/remixd.js '; if [ {args.folder} != undefined ]; then SERVE_SCRIPT=${SERVE_SCRIPT}' -s {args.folder}'; fi; if [ {args.remixide} != undefined ]; then SERVE_SCRIPT=${SERVE_SCRIPT}' --remix-ide {args.remixide}'; fi; eval $SERVE_SCRIPT;" "command": "SERVE_SCRIPT='chmod +x dist/libs/remixd/src/bin/remixd.js; dist/libs/remixd/src/bin/remixd.js '; if [ {args.folder} != undefined ]; then SERVE_SCRIPT=${SERVE_SCRIPT}' -s {args.folder}'; fi; if [ {args.remixide} != undefined ]; then SERVE_SCRIPT=${SERVE_SCRIPT}' --remix-ide {args.remixide}'; fi; eval $SERVE_SCRIPT;"
} }
] ]
} }
@ -945,6 +945,80 @@
} }
} }
} }
},
"remix-ide-e2e-src-local-plugin": {
"root": "apps/remix-ide-e2e/src/local-plugin",
"sourceRoot": "apps/remix-ide-e2e/src/local-plugin/src",
"projectType": "application",
"schematics": {},
"architect": {
"build": {
"builder": "@nrwl/web:build",
"options": {
"outputPath": "dist/apps/remix-ide-e2e/src/local-plugin",
"index": "apps/remix-ide-e2e/src/local-plugin/src/index.html",
"main": "apps/remix-ide-e2e/src/local-plugin/src/main.tsx",
"polyfills": "apps/remix-ide-e2e/src/local-plugin/src/polyfills.ts",
"tsConfig": "apps/remix-ide-e2e/src/local-plugin/tsconfig.app.json",
"assets": [
"apps/remix-ide-e2e/src/local-plugin/src/favicon.ico",
"apps/remix-ide-e2e/src/local-plugin/src/assets"
],
"styles": ["apps/remix-ide-e2e/src/local-plugin/src/styles.css"],
"scripts": [],
"webpackConfig": "@nrwl/react/plugins/webpack"
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "apps/remix-ide-e2e/src/local-plugin/src/environments/environment.ts",
"with": "apps/remix-ide-e2e/src/local-plugin/src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@nrwl/web:dev-server",
"options": {
"buildTarget": "remix-ide-e2e-src-local-plugin:build",
"port": 2020
},
"configurations": {
"production": {
"buildTarget": "remix-ide-e2e-src-local-plugin:build:production"
}
}
},
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": [
"apps/remix-ide-e2e/src/local-plugin/tsconfig.app.json"
],
"exclude": [
"**/node_modules/**",
"!apps/remix-ide-e2e/src/local-plugin/**/*"
]
}
}
}
} }
}, },
"cli": { "cli": {

Loading…
Cancel
Save