Merge branch 'master' of https://github.com/ethereum/remix-project into editorcontext

editorcontextDummy
filip mertens 2 years ago
commit 8b1da64bf2
  1. 4
      .eslintrc.json
  2. 16
      apps/remix-ide-e2e/src/commands/createContract.ts
  3. 10
      apps/remix-ide-e2e/src/tests/debugger.test.ts
  4. 8
      apps/remix-ide-e2e/src/tests/libraryDeployment.test.ts
  5. 6
      apps/remix-ide-e2e/src/tests/recorder.test.ts
  6. 2
      apps/remix-ide-e2e/src/tests/signingMessage.test.ts
  7. 12
      apps/remix-ide-e2e/src/tests/specialFunctions.test.ts
  8. 2
      apps/remix-ide-e2e/src/tests/terminal.test.ts
  9. 4
      apps/remix-ide-e2e/src/tests/transactionExecution.test.ts
  10. 2
      apps/remix-ide-e2e/src/types/index.d.ts
  11. 87
      apps/remix-ide/docs/FAQ.md
  12. 216
      apps/remix-ide/docs/Makefile
  13. 95
      apps/remix-ide/docs/assert_library.md
  14. 11
      apps/remix-ide/docs/code_contribution_guide.md
  15. 14
      apps/remix-ide/docs/community.md
  16. 34
      apps/remix-ide/docs/compile.md
  17. 305
      apps/remix-ide/docs/conf.py
  18. 183
      apps/remix-ide/docs/contract_metadata.md
  19. 107
      apps/remix-ide/docs/create_deploy.md
  20. 14
      apps/remix-ide/docs/debugger.md
  21. 59
      apps/remix-ide/docs/file_explorer.md
  22. BIN
      apps/remix-ide/docs/images/a-Runtab-deploy-atAddress.png
  23. BIN
      apps/remix-ide/docs/images/a-contract-inputs.png
  24. BIN
      apps/remix-ide/docs/images/a-debug1-deploy.png
  25. BIN
      apps/remix-ide/docs/images/a-debug2-udapp1.png
  26. BIN
      apps/remix-ide/docs/images/a-debug2-udapp1a.png
  27. BIN
      apps/remix-ide/docs/images/a-debug3-udapp2.png
  28. BIN
      apps/remix-ide/docs/images/a-debug4-value-loc.png
  29. BIN
      apps/remix-ide/docs/images/a-debug5-term-debug-but.png
  30. BIN
      apps/remix-ide/docs/images/a-debug6-term-txn-hash.png
  31. BIN
      apps/remix-ide/docs/images/a-debug7-debugger.png
  32. BIN
      apps/remix-ide/docs/images/a-debug8-top3.png
  33. BIN
      apps/remix-ide/docs/images/a-debug9-buttons.png
  34. BIN
      apps/remix-ide/docs/images/a-debugger.png
  35. BIN
      apps/remix-ide/docs/images/a-file-ex-rt-click-folder.png
  36. BIN
      apps/remix-ide/docs/images/a-file-ex-rt-click.png
  37. BIN
      apps/remix-ide/docs/images/a-file-explorer-buttons-big.png
  38. BIN
      apps/remix-ide/docs/images/a-file-explorer-buttons.png
  39. BIN
      apps/remix-ide/docs/images/a-file-explorer1.png
  40. BIN
      apps/remix-ide/docs/images/a-home-page.png
  41. BIN
      apps/remix-ide/docs/images/a-hometab.png
  42. BIN
      apps/remix-ide/docs/images/a-icon-swap.png
  43. BIN
      apps/remix-ide/docs/images/a-icons-at-load.png
  44. BIN
      apps/remix-ide/docs/images/a-jvm-calling-instance.png
  45. BIN
      apps/remix-ide/docs/images/a-jvm-instance.png
  46. BIN
      apps/remix-ide/docs/images/a-jvm.png
  47. BIN
      apps/remix-ide/docs/images/a-layout1.png
  48. BIN
      apps/remix-ide/docs/images/a-layout1c.png
  49. BIN
      apps/remix-ide/docs/images/a-old-tuto_basicimport.png
  50. BIN
      apps/remix-ide/docs/images/a-old-tuto_importgit.png
  51. BIN
      apps/remix-ide/docs/images/a-old-tuto_importswarm.png
  52. BIN
      apps/remix-ide/docs/images/a-plug.png
  53. BIN
      apps/remix-ide/docs/images/a-plugin-man-local.png
  54. BIN
      apps/remix-ide/docs/images/a-receive-fun.png
  55. BIN
      apps/remix-ide/docs/images/a-remixd-success.png
  56. BIN
      apps/remix-ide/docs/images/a-run-icon.png
  57. BIN
      apps/remix-ide/docs/images/a-runtab-recorder.png
  58. BIN
      apps/remix-ide/docs/images/a-runtab1a.png
  59. BIN
      apps/remix-ide/docs/images/a-sol-compiler.png
  60. BIN
      apps/remix-ide/docs/images/a-sol-editor.png
  61. BIN
      apps/remix-ide/docs/images/a-static-analysis.png
  62. BIN
      apps/remix-ide/docs/images/a-terminal-and-more.png
  63. BIN
      apps/remix-ide/docs/images/a-themes.png
  64. BIN
      apps/remix-ide/docs/images/a-udapp-inputs.png
  65. BIN
      apps/remix-ide/docs/images/a-udapp-multi-param-man.png
  66. BIN
      apps/remix-ide/docs/images/a-udapp1.png
  67. BIN
      apps/remix-ide/docs/images/a-udapp2.png
  68. BIN
      apps/remix-ide/docs/images/a-unit-testing-custom-compiler-config.png
  69. BIN
      apps/remix-ide/docs/images/a-unit-testing-feature.png
  70. BIN
      apps/remix-ide/docs/images/a-unit-testing-from-pm.png
  71. BIN
      apps/remix-ide/docs/images/a-unit-testing-run-result.png
  72. BIN
      apps/remix-ide/docs/images/a-user-testing-icon.png
  73. 74
      apps/remix-ide/docs/import.md
  74. 83
      apps/remix-ide/docs/index.rst
  75. 54
      apps/remix-ide/docs/layout.md
  76. 14
      apps/remix-ide/docs/locations.md
  77. 263
      apps/remix-ide/docs/make.bat
  78. 22
      apps/remix-ide/docs/plugin_manager.md
  79. 93
      apps/remix-ide/docs/remix_commands.md
  80. 37
      apps/remix-ide/docs/remix_tutorials_github.md
  81. 57
      apps/remix-ide/docs/remixd.md
  82. 309
      apps/remix-ide/docs/run.md
  83. 14
      apps/remix-ide/docs/settings.md
  84. 18
      apps/remix-ide/docs/solidity_editor.md
  85. 296
      apps/remix-ide/docs/static_analysis.md
  86. 9
      apps/remix-ide/docs/support.md
  87. 21
      apps/remix-ide/docs/terminal.md
  88. 225
      apps/remix-ide/docs/tutorial_debug.md
  89. 139
      apps/remix-ide/docs/udapp.md
  90. 100
      apps/remix-ide/docs/unittesting.md
  91. 329
      apps/remix-ide/docs/unittesting_examples.md
  92. 10
      apps/remix-ide/src/app/udapp/run-tab.js
  93. 160
      apps/remix-ide/src/blockchain/blockchain.js
  94. 91
      libs/remix-core-plugin/src/lib/constants/uups.ts
  95. 61
      libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts
  96. 137
      libs/remix-core-plugin/src/types/contract.ts
  97. 62
      libs/remix-lib/src/execution/txFormat.ts
  98. 10
      libs/remix-lib/test/txFormat.ts
  99. 10
      libs/remix-ui/helper/src/lib/helper-components.tsx
  100. 135
      libs/remix-ui/run-tab/src/lib/actions/account.ts
  101. Some files were not shown because too many files have changed in this diff Show More

@ -29,7 +29,9 @@
"@typescript-eslint/no-this-alias": "off",
"@typescript-eslint/no-empty-function": "off",
"eslint-disable-next-line no-empty": "off",
"no-empty": "off"
"no-empty": "off",
"jsx-a11y/anchor-is-valid": "off",
"@typescript-eslint/no-inferrable-types": "off"
}
},
{

@ -2,7 +2,7 @@ import { NightwatchBrowser } from 'nightwatch'
import EventEmitter from 'events'
class CreateContract extends EventEmitter {
command (this: NightwatchBrowser, inputParams: string): NightwatchBrowser {
command (this: NightwatchBrowser, inputParams: string[]): NightwatchBrowser {
this.api.perform((done) => {
createContract(this.api, inputParams, () => {
done()
@ -13,11 +13,19 @@ class CreateContract extends EventEmitter {
}
}
function createContract (browser: NightwatchBrowser, inputParams: string, callback: VoidFunction) {
if (inputParams) {
browser.setValue('.udapp_contractActionsContainerSingle > input', inputParams, function () {
function createContract (browser: NightwatchBrowser, inputParams: string[], callback: VoidFunction) {
if (inputParams.length === 1) {
browser.setValue('.udapp_contractActionsContainerSingle > input', inputParams[0], function () {
browser.click('.udapp_contractActionsContainerSingle > button').pause(500).perform(function () { callback() })
})
} else if (inputParams.length > 1) {
browser.perform((done) => {
for (let i = 0; i < inputParams.length; i++) {
browser.setValue(`div.udapp_multiArg:nth-child(${i + 1}) > input`, inputParams[i])
}
done()
})
.click('div.udapp_multiArg > button').pause(500).perform(function () { callback() })
} else {
browser
.click('.udapp_contractActionsContainerSingle > button')

@ -86,7 +86,7 @@ module.exports = {
.clickLaunchIcon('udapp')
.waitForElementPresent('*[title="Deploy - transact (not payable)"]', 35000)
.selectContract('ERC20')
.createContract('"tokenName", "symbol"')
.createContract(["tokenName", "symbol"])
.debugTransaction(0)
.pause(2000)
.waitForElementVisible('#stepdetail')
@ -115,7 +115,7 @@ module.exports = {
.testContracts('withABIEncoderV2.sol', sources[2]['withABIEncoderV2.sol'], ['test'])
.clickLaunchIcon('udapp')
.selectContract('test')
.createContract('')
.createContract([])
.clearConsole()
.clickInstance(0)
.clickFunction('test1 - transact (not payable)', { types: 'bytes userData', values: '0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000015b38da6a701c568545dcfcb03fcb875f56beddc4' })
@ -148,7 +148,7 @@ module.exports = {
.testContracts('locals.sol', sources[3]['locals.sol'], ['testLocals'])
.clickLaunchIcon('udapp')
.waitForElementPresent('*[title="Deploy - transact (not payable)"]', 40000)
.createContract('')
.createContract([])
.pause(2000)
.clearConsole()
.clickInstance(0)
@ -173,7 +173,7 @@ module.exports = {
.pause(2000)
.testContracts('withGeneratedSources.sol', sources[4]['withGeneratedSources.sol'], ['A'])
.clickLaunchIcon('udapp')
.createContract('')
.createContract([])
.clearConsole()
.clickInstance(0)
.clickFunction('f - transact (not payable)', { types: 'uint256[] ', values: '[]' })
@ -235,7 +235,7 @@ module.exports = {
.testContracts('reverted.sol', sources[6]['reverted.sol'], ['A', 'B', 'C'])
.clickLaunchIcon('udapp')
.selectContract('A')
.createContract('')
.createContract([])
.pause(500)
.clickInstance(0)
.clickFunction('callA - transact (not payable)')

@ -22,7 +22,7 @@ module.exports = {
browser.verifyContracts(['test'])
.clickLaunchIcon('udapp')
.selectContract('test')
.createContract('')
.createContract([])
.getAddressAtPosition(0, (address) => {
console.log('testAutoDeployLib ' + address)
addressRef = address
@ -46,7 +46,7 @@ module.exports = {
.verifyContracts(['test'])
.clickLaunchIcon('udapp')
.selectContract('lib') // deploy lib
.createContract('')
.createContract([])
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
console.log(address)
@ -74,7 +74,7 @@ function checkDeployShouldFail (browser: NightwatchBrowser, callback: VoidFuncti
.openFile('Untitled5.sol')
.clickLaunchIcon('udapp')
.selectContract('test') // deploy lib
.createContract('')
.createContract([])
.pause(2000)
.getText('div[class^="terminal"]', (value) => {
console.log('value: ', value)
@ -98,7 +98,7 @@ function checkDeployShouldSucceed (browser: NightwatchBrowser, address: string,
.openFile('Untitled5.sol')
.clickLaunchIcon('udapp')
.selectContract('test') // deploy lib
.createContract('')
.createContract([])
.getAddressAtPosition(1, (address) => {
addressRef = address
})

@ -39,7 +39,7 @@ module.exports = {
'Save scenario': function (browser: NightwatchBrowser) {
browser.testContracts('testRecorder.sol', sources[0]['testRecorder.sol'], ['testRecorder'])
.clickLaunchIcon('udapp')
.createContract('12')
.createContract(['12'])
.clickInstance(0)
.clickFunction('set - transact (not payable)', { types: 'uint256 _p', values: '34' })
.click('i.savetransaction')
@ -72,11 +72,11 @@ module.exports = {
.clickLaunchIcon('udapp')
.selectContract('t1est')
.pause(1000)
.createContract('')
.createContract([])
.clickInstance(0)
.selectContract('t2est')
.pause(1000)
.createContract('')
.createContract([])
.click('i.savetransaction')
.waitForElementVisible('[data-id="udappNotify-modal-footer-ok-react"]')
.execute(function () {

@ -33,7 +33,7 @@ module.exports = {
.clickLaunchIcon('udapp')
.pause(5000)
.selectContract('ECVerify')
.createContract('')
.createContract([])
.clickInstance(0)
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {

@ -24,7 +24,7 @@ module.exports = {
.clickLaunchIcon('udapp')
.selectAccount('0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c') // this account will be used for this test suite
.selectContract('CheckSpecials')
.createContract('') // deploy
.createContract([]) // deploy
.clickInstance(0)
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
@ -92,7 +92,7 @@ module.exports = {
.testContracts('receiveOnly.sol', sources[1]['receiveOnly.sol'], ['CheckSpecials'])
.clickLaunchIcon('udapp')
.selectContract('CheckSpecials')
.createContract('')
.createContract([])
.clickInstance(0)
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
@ -122,7 +122,7 @@ module.exports = {
.testContracts('fallbackOnlyPayable.sol', sources[2]['fallbackOnlyPayable.sol'], ['CheckSpecials'])
.clickLaunchIcon('udapp')
.selectContract('CheckSpecials')
.createContract('')
.createContract([])
.clickInstance(0)
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
@ -153,7 +153,7 @@ module.exports = {
.testContracts('fallbackOnlyNotPayable.sol', sources[3]['fallbackOnlyNotPayable.sol'], ['CheckSpecials'])
.clickLaunchIcon('udapp')
.selectContract('CheckSpecials')
.createContract('')
.createContract([])
.clickInstance(0)
.perform((done) => {
browser.getAddressAtPosition(0, (address) => {
@ -174,7 +174,7 @@ module.exports = {
.clearValue('#value')
.setValue('#value', '0')
.pause(2000)
.createContract('')
.createContract([])
.pause(1000)
.clickInstance(0).pause(1000)
.perform((done) => {
@ -208,7 +208,7 @@ module.exports = {
.waitForElementVisible('#value')
.clearValue('#value')
.setValue('#value', '0').pause(2000)
.createContract('')
.createContract([])
.clickInstance(0)
.pause(1000)
.perform((done) => {

@ -172,7 +172,7 @@ module.exports = {
.clickLaunchIcon('udapp')
.click('*[data-id="deployAndRunClearInstances"]')
.selectContract('OwnerTest')
.createContract('')
.createContract([])
.pause(1000)
.journalChildIncludes('constructor', { shouldHaveOnlyOneOccurence: true })
.pause(5000)

@ -202,10 +202,10 @@ module.exports = {
.addFile('Storage.sol', sources[6]['Storage.sol'])
.addFile('Owner.sol', sources[6]['Owner.sol'])
.clickLaunchIcon('udapp')
.createContract('42, 24')
.createContract(['42', '24'])
.openFile('Storage.sol')
.clickLaunchIcon('udapp')
.createContract('102') // this creation will fail if the component hasn't been properly reset.
.createContract(['102']) // this creation will fail if the component hasn't been properly reset.
.clickInstance(1)
.clickFunction('store - transact (not payable)', { types: 'uint256 num', values: '24' })
.testFunction('last', // we check if the contract is actually reachable.

@ -34,7 +34,7 @@ declare module 'nightwatch' {
getModalBody(callback: (value: string, cb: VoidFunction) => void): NightwatchBrowser,
modalFooterCancelClick(id?: string): NightwatchBrowser,
selectContract(contractName: string): NightwatchBrowser,
createContract(inputParams: string): NightwatchBrowser,
createContract(inputParams: string[]): NightwatchBrowser,
getAddressAtPosition(index: number, cb: (pos: string) => void): NightwatchBrowser,
testConstantFunction(address: string, fnFullName: string, expectedInput: NightwatchTestConstantFunctionExpectedInput | null, expectedOutput: string): NightwatchBrowser,
getEditorValue(callback: (content: string) => void): NightwatchBrowser,

@ -1,87 +0,0 @@
FAQ
===
### Solidity compiler
**Q: Error: compiler might be in a non-sane state**
```
error: "Uncaught JavaScript exception: RangeError: Maximum call stack size exceeded.
The compiler might be in a non-sane state, please be careful and do not use further compilation data to deploy to mainnet.
It is heavily recommended to use another browser not affected by this issue (Firefox is known to not be affected)."
```
**A:** Old versions of solidity compiler had this problem with chrome.
Please change the compiler version in Solidity Plugin to the newer one or use another browser.
**Q:** I’m getting an issue with Maximum call stack exceed and various other errors, can't compile.
**A:** Try a different browser or a newer solidity compiler version.
**Q:** How to verify a contract that imports other contracts?
**A:** The verification tool does not recursively go through the import statments in a contract. So can only verify a 'flattened' contract.
There is a plugin called `Flattener` which will stuff all the original code and the imported code into a single file.
### Deploy & Run
**Q:** I am using an Infura endpoint in my app, but when I try to deploy against that endpoint in remix IDE selecting "web3 provider" and putting my endpoint in, it's telling me that it can't connect
**A:** If the endpoint you are using is http, it won't work.
**Q:** Where is deploy button?
**A:** Its in the Deploy & Run module. If you haven't activated that module, you should do that by clicking Deploy & Run module in the Plugin Manager.
You could also activate everything you need to work with solidity on the landing page ( click the remix logo at the top left for the screen) and click the "Solidity" button in the environment section.
**Q:** How to pass a tuple to a public function in Remix?
**A:** Pass it as an array [].
**Q:** How to input a struct as input to a parameter of a function in the Deploy & Run module?
**A:** For inputting a struct, just like a tuple, pass it in as an array []. Also you need to put in the line:
`pragma experimental ABIEncoderV2;` at the top of the solidity file.
For example, here's a solidity file with a struct is an input parameter.
```
pragma solidity >=0.4.22 <0.6.0;
pragma experimental ABIEncoderV2;
contract daPeeps {
struct Peep {uint a; uint b;} // declaration of Peep type
Peep peep; //declaration of an object of Peep type
constructor () public
{
peep.a = 0; // definition/initialisation of object
peep.b = 0; //
}
function initPeepToPeep(Peep memory i) public payable {
peep.a = i.a;
peep.b = i.b;
}
function setPeep(uint a, uint b) public payable {
peep.a = a;
peep.b = b;
}
function getPeep() public view returns(Peep memory)
{
return peep;
}
}
```
The input of initPeepToPeeps takes a struct. If you input
`[1,2]` the transaction will go through.
### General
**Q:** Where do plugin developers go with their questions?
**A:** The Gitter Remix plugin developers room https://gitter.im/ethereum/remix-dev-plugin

@ -1,216 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
.PHONY: qthelp
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Remix.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Remix.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Remix"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Remix"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
.PHONY: latexpdf
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: latexpdfja
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
.PHONY: info
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

@ -1,95 +0,0 @@
Remix Assert Library
====================
* [Assert.ok(value[, message])](#assert-ok-value-message)
* [Assert.equal(actual, expected[, message])](#assert-equal-actual-expected-message)
* [Assert.notEqual(actual, expected[, message])](#assert-notequal-actual-expected-message)
* [Assert.greaterThan(value1, value2[, message])](#assert-greaterthan-value1-value2-message)
* [Assert.lesserThan(value1, value2[, message])](#assert-lesserthan-value1-value2-message)
## Assert
### Assert.ok(value[, message])
* `value`: \<bool\>
* `message`: \<string\>
Tests if value is truthy. `message` is returned in case of failure.
Examples:
```
Assert.ok(true);
// OK
Assert.ok(false, "it\'s false");
// error: it's false
```
### Assert.equal(actual, expected[, message])
* `actual`: \<uint | int | bool | address | bytes32 | string\>
* `expected`: \<uint | int | bool | address | bytes32 | string\>
* `message`: \<string\>
Tests if `actual` & `expected` values are same. `message` is returned in case of failure.
Examples:
```
Assert.equal(string("a"), "a");
// OK
Assert.equal(uint(100), 100);
// OK
foo.set(200)
Assert.equal(foo.get(), 200);
// OK
Assert.equal(foo.get(), 100, "value should be 200");
// error: value should be 200
```
### Assert.notEqual(actual, expected[, message])
* `actual`: \<uint | int | bool | address | bytes32 | string\>
* `expected`: \<uint | int | bool | address | bytes32 | string\>
* `message`: \<string\>
Tests if `actual` & `expected` values are not same. `message` is returned in case of failure.
Examples:
```
Assert.notEqual(string("a"), "b");
// OK
foo.set(200)
Assert.notEqual(foo.get(), 200, "value should not be 200");
// error: value should not be 200
```
### Assert.greaterThan(value1, value2[, message])
* `value1`: \<uint | int\>
* `value2`: \<uint | int\>
* `message`: \<string\>
Tests if `value1` is greater than `value2`. `message` is returned in case of failure.
Examples:
```
Assert.greaterThan(uint(2), uint(1));
// OK
Assert.greaterThan(uint(-2), uint(1));
// OK
Assert.greaterThan(int(2), int(1));
// OK
Assert.greaterThan(int(-2), int(-1), "-2 is not greater than -1");
// error: -2 is not greater than -1
```
### Assert.lesserThan(value1, value2[, message])
* `value1`: \<uint | int\>
* `value2`: \<uint | int\>
* `message`: \<string\>
Tests if `value1` is lesser than `value2`. `message` is returned in case of failure.
Examples:
```
Assert.lesserThan(int(-2), int(-1));
// OK
Assert.lesserThan(int(2), int(1), "2 is not lesser than 1");
// error: 2 is not greater than 1
```

@ -1,11 +0,0 @@
Code Contribution Guide
=======================
Remix is an open source tool and we encourage anyone to help us improve our tool.
You can do that by opening issues, giving feedback or by contributing a pull request
to our codebase.
The Remix application is built with JavaScript and React.
Check out the `package.json` files in the Remix submodules to learn more about the stack.
To learn more, please visit our [GitHub page](https://github.com/ethereum/remix-ide).

@ -1,14 +0,0 @@
Community Support
=======================
We know that blockchain ecosystem is very new and that lots of information is scattered around the web.
That is why we created a community support channel where we and other users try to answer your questions if
you get stuck using Remix. Please, join [the community](https://gitter.im/ethereum/remix) and ask for help.
For anyone who is interested in developing a custom plugin for Remix or who wants to contribute to the codebase,
we opened a [contributors' channel](https://gitter.im/ethereum/remix-dev) especially for developers working on Remix tools.
We would kindly ask you to respect the space and to use it for
getting help with your work and the developers' channel for discussions related to working on Remix codebase. If you have
ideas for collaborations or you want to promote your project, try to find some more appropriate channels to do so. Or you can contact
the main contributors directly on Gitter or Twitter.

@ -1,34 +0,0 @@
Compiler (Solidity)
===================
Clicking the Solidity icon in the icon panel brings you to the Solidty Compiler.
Compiling is triggered when you click the compile button ( **D. in image below**). If you want the file to be compiled each time the file is saved or when another file is selected - check the auto compile checkbox ( **E. in image below**).
Since the Solidity version `0.5.7`, it is possible to compile `Yul` files. Please read the ([solidity documentation about Yul](https://solidity.readthedocs.io/en/latest/yul.html)) which contain some code examples.
You can use the language dropdown ( **B. in image below**) to switch the language. **This dropdown list is only available for versions greater than or equal to `0.5.7`.**
The fork selection dropdown list ( **C. in image below**) allows to compile code against a specific ethereum hard fork.
The `compiler default` corresponds to the default hard fork used by a specific version. Please go to "Compilation Details" ( **G. in image below**) in the settings of `Metadata` section to see the harfork name used for the current compilation.
If the contract has a lot of dependencies it can take a while to compile - so you use autocompilation at your discretion.
![](images/a-sol-compiler.png)
After each compilation, a list is updated with all newly compiled
contracts. A compiled contract can be selected with the Contract pulldown menu ( **F. in the image**). Multiple contracts are compiled when one contract imports other contracts. Selecting a contract will show information about that one.
When the "Compilation Details" button is clicked ( **G. in image**), a modal opens displaying detailed information about the current selected contract.
For those writing your own custom solidity compiler, you can import that by clicking the **+** button (**X. in the image**) to open a modal where you can input the url of the compiler to be loaded.
From the Solidity Compiler module you can also publish your contract to Swarm (only non
abstract contracts can be published) & IPFS.
Published data notably contains the `abi` and the solidity source code.
After a contract is published, you can find its metadata information
using the bzz URL located in the details modal dialog `SWARM LOCATION`.
Compilation Errors and Warning are displayed below the contract section.
At each compilation, the static analysis tab builds a report. It is important to address reported issues even if the compiler doesn't complain. ([see more](static_analysis.html))

@ -1,305 +0,0 @@
# -*- coding: utf-8 -*-
#
# Remix documentation build configuration file, created by
# sphinx-quickstart on Mon Feb 20 12:16:16 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['recommonmark'] # required for sphinx v3.0.0
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
source_suffix = ['.rst', '.md']
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Remix, Ethereum-IDE'
copyright = u'2019, Remix'
author = u'Remix team'
github_doc_root = 'https://github.com/ethereum/remix/tree/master/docs/'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'1'
# The full version, including alpha/beta/rc tags.
release = u'1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
highlight_language = 'JavaScript'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
htmlhelp_basename = 'Remixdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Latex figure (float) alignment
#'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Remix.tex', u'Remix Documentation',
u'yann300', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'remix', u'Remix Documentation',
[author], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Remix', u'Remix Documentation',
author, 'Remix', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# Uncomment these two lines with sphinx version 1.0.0
# from recommonmark.parser import CommonMarkParser
# source_parsers = {'.md': CommonMarkParser}
# app setup hook
# def setup(app):
# app.add_config_value('recommonmark_config', {
# 'url_resolver': lambda url: github_doc_root + url,
# 'enable_auto_toc_tree': True,
# 'enable_eval_rst': True,
# 'enable_auto_doc_ref': True,
# }, True)
# app.add_transform(AutoStructify)

File diff suppressed because one or more lines are too long

@ -1,107 +0,0 @@
Creating and Deploying a Contract
================================
There are 3 type of environments Remix can be plugged to:
`Javascript VM`, `Injected provider`, or `Web3 provider`. (for details see [Running transactions](https://remix-ide.readthedocs.io/en/latest/run.html))
Both `Web3 provider` and `Injected provider` require the use of an
external tool.
The external tool for `Web3 provider` is an Ethereum node and for
`Injected provider` Metamask.
The `JavaScript VM` mode is convenient because each execution runs in
your browser and you don't need any other software or Ethereum node to run it.
So, it is the easiest test environment - **no setup required!**
But keep in mind that reloading the browser when you are in the Javascript VM will restart Remix in an empty state.
For performance purposes ( which is to say - for testing in an environment that is closest to the mainnet), it might also be better to use an external node.
Selecting the VM mode
---------------------
Make sure the VM mode is selected. All accounts displayed in `Accounts`
should have 100 ether.
Sample contract
---------------
```
pragma solidity ^0.5.1;
contract testContract {
uint value;
constructor (uint _p) public {
value = _p;
}
function setP(uint _n) payable public {
value = _n;
}
function setNP(uint _n) public {
value = _n;
}
function get () view public returns (uint) {
return value;
}
}
```
This contract is very basic. The goal is to quickly start to create and
to interact with a sample contract.
Deploying an instance
---------------------
The `Compile tab` displays information related to the current contract
(note that there can be more than one) ([see compile](compile.html)).
Moving on, in the `Run tab` select, `JavaScript VM` to specify that you
are going to deploy an instance of the contract in the `JavaScript VM`
state.
![](images/a-jvm.png)
The constructor of `Ballot.sol` needs a parameter (of type `uint8`).
Give any value and click on `Deploy`.
The transaction which deploys the instance of `Ballot` is created.
In a "normal" blockchain, it can take several seconds to execute. This
is the time for the transaction to be mined. However, because we are
using the `JavaScript VM`, our execution is immediate.
The terminal will inform you about the transaction. You can see details
there and start debugging.
The newly created instance is displayed in the `run tab`.
![](images/a-jvm-instance.png)
Interacting with an instance
----------------------------
This new instance contains 3 actions which corresponds to the 3
functions (`setP`, `setPN`, `get`). Clicking on `SetP` or `SetPN` will
create a new transaction.
Note that `SetP` is `payable` (red button) : it is possible to send
value (Ether) to the contract.
`SetPN` is not payable (orange button - depending on the theme) : it is not possible to send
value (Ether) to the contract.
Clicking on `get` will not execute a transaction (usually its a blue button - depending on the theme). It doesn't execute a transaction because a `get` does not modify the state (variable
`value`) of this instance.
As `get` is `view` you can see the return value just below the
action.
![](images/a-jvm-calling-instance.png)

@ -1,14 +0,0 @@
Debugger
========
This module allows you to debug the transaction. It can be used to
deploy transactions created from Remix and already mined transactions.
(debugging works only if the current environment provides the necessary
features).
To get to the debugger - you can click the debug button in the terminal when a successful or failed transaction appears there. You can also load the module from the plugin manager and then click the bug in the icon panel. Or you can get to the debugger by running the debug command in the console.
![](images/a-debugger.png)
To learn more about how to use this tool go to the [debugger tutorial](tutorial_debug.html).

@ -1,59 +0,0 @@
File Explorers
=============
To get to the File Explorers module - click the file explorers icon.
![](images/a-file-explorer1.png)
The basic files explorer lists all the files stored in your browser's **browser storage**.
You can see them in the **browser** folder.
**Important Note:** Clearing the browser storage will **permanently delete** all the
solidity files stored there. This is an inherent limitation of a browser-based IDE. However, if you want to store files outside of the browser and on your computer's filesystem, use [Remixd](remixd.html) or use the [desktop version of Remix-IDE](https://github.com/ethereum/remix-desktop/releases/). RemixD enables you to have access to a selected folder on your hard drive. Remix Desktop is a version of Remix-IDE in an Electron app.
You can rename, remove or
add new files to the file explorer.
![](images/a-file-explorer-buttons.png)
We will start by reviewing the icons in the image above.
The book icon - **A.** is the link to the module's documentation.
The icons to the right of the **browser** file explorer in the image above only appear for browser storage.
Create new File
---------------
The icon marked **B.** above. Creates a new file.
Publish to Gist
---------------
The icon marked **C.** above. Publishes all files from the browser folder to a gist. Only file in the root of **browser** will be published. Files in subfolders will not be publish to the Gist.
Gist API has changed in 2018 and **requires** users to be authenticated to be able to publish a gist.
Click [this link](https://github.com/settings/tokens) to GitHub tokens setup and select Generate new token. Then check the **Create gists** checkbox and generate a new token.
Take the token and paste it in Remix's **Settings** module in the **GitHub Access Token** section. And then click Save. Now you should be able to use the feature.
Create a folder
---------------
The icon marked **D.** above. Creates a new folder in **browser** file explorer.
Context Menu (Right Click)
-----------------------------
Right click on a file or a folder and the **context menu** will appear.
![](images/a-file-ex-rt-click.png)
You can rename or delete a selected file or a folder. You can also create a folder.
To create a file with the context menu, right click on a folder to get the **Create File** option. A file will be created inside that folder.
![](images/a-file-ex-rt-click-folder.png)
The functionality of the context menu also works with RemixD (which gives you have access to a folder on your hard drive).
**Note:** When working with RemixD, you need to open and close the **localhost** folder to refresh the view.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

@ -1,74 +0,0 @@
Importing Source Files in Solidity
==================================
There are multiple techniques for importing files into Remix.
For a tutorial about importing files click [here](https://github.com/ethereum/remix-workshops/tree/master/LoadingContent). You can also find this tutorial in the Remix Workshops plugin.
For a detailed explanation of the `import` keyword see the
[Solidity documentation](https://solidity.readthedocs.io/en/develop/layout-of-source-files.html?highlight=import#importing-other-source-files)
Here are a some of the main methods of importing a file:
Importing a file from the browser's local storage
-------------------------------------------------
Files in Remix can be imported with the `import` key word with the path to the file. Use ```./``` for relative paths to increase portability.
```
pragma solidity >=0.4.22 <0.6.0;
import "./ballot.sol";
```
Importing a file from your computer's filesystem
-------------------------------------------------
This method uses **remixd** - the remix daemon. Please go to the [remixd tutorial](remixd.html) for instructions about how to bridge the divide between the browser and your computers filesystem.
Importing from GitHub
---------------------
It is possible to import files directly from GitHub. You should specify the release tag (where available), otherwise you will get the latest code in the master branch. For OpenZeppelin Contracts you should only use code published in an official release, the example below imports from OpenZeppelin Contracts v2.5.0.
```
pragma solidity >=0.4.22 <0.6.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.0/contracts/math/SafeMath.sol";
```
Importing from Swarm
--------------------
Files can be imported using all URLs supported by swarm.
If you do not have a swarm node, then use swarm-gateways.net.
```
import 'bzz-raw://5766400e5d6d822f2029b827331b354c41e0b61f73440851dd0d06f603dd91e5';
```
Importing from IPFS
--------------------
Files can be imported from IPFS.
```
import 'ipfs://Qmdyq9ZmWcaryd1mgGZ4PttRNctLGUSAMpPqufsk6uRMKh';
```
Importing from the console
--------------------------
You can also use a remix command remix.loadurl('<the_url>')in the console. You should specify the release tag (where available), otherwise you will get the latest code in the master branch. For OpenZeppelin Contracts you should only use code published in an official release, the example below imports from OpenZeppelin Contracts v2.5.0.
```
remix.loadurl('https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.0/contracts/math/SafeMath.sol')
```
Notice that this will create a `github` folder in the file explorer. To load a file in the `github` folder, you would use a command like this:
```
import "github/OpenZeppelin/openzeppelin-contracts/contracts/math/SafeMath.sol";
```

@ -1,83 +0,0 @@
Welcome to Remix documentation!
===============================
Remix is a powerful, open source tool that helps you write Solidity contracts straight from the browser.
Written in JavaScript, Remix supports both usage in the browser and locally.
Remix also supports testing, debugging and deploying of smart contracts and much more.
Our Remix project with all its features is available
at `remix.ethereum.org <http://remix.ethereum.org>`__ and more information can be found in these
docs. Our IDE tool is available at `our GitHub repository
<https://github.com/ethereum/remix-ide>`__.
This set of documents covers instructions on how to use Remix and some tutorials to help you get started.
Useful links:
- `Solidity documentation <https://solidity.readthedocs.io>`__
- `Remix alpha <http://remix-alpha.ethereum.org>`__ - The version where we test new Remix release (not stable!).
- `Remix on Medium <https://medium.com/remix-ide>`__
- `Ethereum StackExchange for Remix <https://ethereum.stackexchange.com/questions/tagged/remix>`__
- `Community support channel <https://gitter.im/ethereum/remix>`__
- `Ðapp Developer resources (Ethereum wiki) <https://github.com/ethereum/wiki/wiki/Dapp-Developer-Resources>`__
.. toctree::
:maxdepth: 2
:caption: New Layout Intro
layout
.. toctree::
:maxdepth: 2
:caption: Tour of default modules
file_explorer
plugin_manager
settings
solidity_editor
terminal
.. toctree::
:maxdepth: 2
:caption: Tour of typical solidity modules
compile
run
udapp
debugger
static_analysis
.. toctree::
:maxdepth: 2
:caption: Solidity Unit Testing
unittesting
assert_library
unittesting_examples
.. toctree::
:maxdepth: 2
:caption: Using Remix
contract_metadata
create_deploy
tutorial_debug
import
remix_commands
remixd
FAQ
.. toctree::
:maxdepth: 2
:caption: Miscellaneous
locations
remix_tutorials_github
code_contribution_guide
community

@ -1,54 +0,0 @@
Remix-IDE Layout
==============
The new structure
--------------------
![](images/a-layout1c.png)
1. Icon Panel - click to change which plugin appears in the Side Panel
2. Side Panel - Most but not all plugins will have their GUI here.
3. Main Panel - In the old layout this was just for editing files. In the tabs can be plugins or files for the IDE to compile.
4. Terminal - where you will see the results of your interactions with the GUI's. Also you can run scripts here.
Icon Panel at Page Load
-----------------------
When you load remix - the icon panel show these icons by default.
![](images/a-icons-at-load.png)
Everything in remix is now a plugin... so the **[Plugin Manager](#plugin-manager)** is very important.
In the old layout, each basic task in remix was separated into the tabs. Now these tabs are plugins.
But to activate a half a dozen plugins - (or however many you are using) each time the page load is **tedious**. So learn about the **[Environments](#environments)**.
Homepage
--------
![](images/a-hometab.png)
The homepage is located in a tab in the Main Panel.
You can also get there by clicking the remix logo at the top of the icon panel.
### Environments
Clicking on one of the environment buttons loads up a collection of plugins. We currently have a **Solidity** Button and a **Vyper** button. In the future you will be able to save your own environment.
To see all the plugins go to the **plugin manager** - by selecting the plug in the icon panel.
![](images/a-plug.png)
The environment buttons are time & sanity savers - so you don't need to go to the plugin manager to get started everytime you load the page.
Plugin Manager
---------------
In order to make Remix flexible for integrating changes into its functionality and for integrating remix into other projects (your's for example), we've now made everything a plugin. This means that you only load the functionality you need. It also means that you need a place to turn off and on plugins - as your needs change. This all happens in the plug manager.
The Plugin Manager is also the place you go when you are creating your own plugin and you want to load your local plugin into Remix. In that case you'd click on the "Connect to a Local Plugin" link at the top of the Plugin Manager panel.
Themes
---------------
So you want to work on Remix with a dark theme or a gray theme or just a different theme that the one you are currently looking at? Go to the settings tab and at the bottom is a choice of lots of bootstrap based themes.
![](images/a-themes.png)

@ -1,14 +0,0 @@
Finding Remix
=============
So if you've found the documentation to Remix but don't know where to find Remix or if you want to run the remix-ide locally and want to find out where to download it - this page is here to help.
- An online version is available at [https://remix.ethereum.org](https://remix.ethereum.org). This version is stable and is updated at almost every release.
- An alpha online version is available at [https://remix-alpha.ethereum.org](https://remix-alpha.ethereum.org). This is not a stable version.
- npm `remix-ide` package `yarn global add remix-ide`. `remix-ide` create a new instance of `Remix IDE` available at [http://127.0.0.1:8080](http://127.0.0.1:8080) and make the current folder available to Remix IDE by automatically starting `remixd`.
see [Connection to `remixd`](https://remix-ide.readthedocs.io/en/latest/remixd.html) for more information about sharing local file with `Remix IDE`.
- GitHub release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `npm run build`.
- GitHub release: [https://github.com/ethereum/remix-ide/releases](https://github.com/ethereum/remix-ide/releases) . The source code is packaged at every release but still need to be built using `yarn run build`.

@ -1,263 +0,0 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
echo. coverage to run coverage check of the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 1>NUL 2>NUL
if errorlevel 9009 goto sphinx_python
goto sphinx_ok
:sphinx_python
set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
:sphinx_ok
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Remix.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Remix.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %~dp0
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "coverage" (
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
if errorlevel 1 exit /b 1
echo.
echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:end

@ -1,22 +0,0 @@
Plugin Manager
===================
## Everything is a PLUGIN in Remix
In order to integrate new tools made by us and by ...you into Remix, we've now made everything a plugin.
This architecture will also allow Remix or just parts of Remix to be integrated into other projects (your's for example).
This means that you only load the functionality you need.
It also means that you can turn off and on plugins - as your needs change.
This all happens in the plug manager.
The Plugin Manager is also the place you go when you are creating your own plugin and you want to load your local plugin into Remix.
To load your local plugin, you'd click on the "Connect to a Local Plugin" link at the top of the Plugin Manager panel.
![](images/a-plugin-man-local.png)
To learn more about how to create your own plugin, go to
[the README of remix-plugin repo](https://github.com/ethereum/remix-plugin).

@ -1,93 +0,0 @@
Remix Commands
==============
In the console, you can run the commands listed below. Once you start to type a command, there is *auto completion*. These commands are using the following libraries:
+ *ethers*: The [ethers.js](https://docs.ethers.io/ethers.js/html/getting-started.html) library is a compact and complete JavaScript library for Ethereum.
+ *remix*: Ethereum IDE and tools for the web.
+ *web3*: The [web3.js](https://web3js.readthedocs.io/en/1.0/) library is a collection of modules which contain specific functionality for the ethereum ecosystem.
+ *swarmgw*: This library can be used to upload/download files to Swarm via https://swarm-gateways.net/.
#### Here's the list of commands
**remix.debug(hash)**: Start debugging a transaction.
**remix.debugHelp()**: Display help message for debugging
**remix.execute(filepath)**: Run the script specified by file path. If filepath is empty, script currently displayed in the editor is executed.
**remix.exeCurrent()**: Run the script currently displayed in the editor.
**remix.getFile(path)**: Returns the content of the file located at the given path
**remix.help()**: Display this help message.
**remix.loadgist(id)**: Load a gist in the file explorer.
**remix.loadurl(url)**: Load the given url in the file explorer. The url can be of type github, swarm or ipfs.
**remix.setFile(path, content)**: set the content of the file located at the given path
**remix.setproviderurl(url)**: Change the current provider to Web3 provider and set the url endpoint.
**swarmgw.get(url, cb)**: Download files from Swarm via https**://swarm-gateways.net/
**swarmgw.put(content, cb)**: Upload files to Swarm via https**://swarm-gateways.net/
**ethers.Contract**: This API provides a graceful connection to a contract deployed on the blockchain, simplifying calling and querying its functions and handling all the binary protocol and conversion as necessarily.
**ethers.HDNode**: A Hierarchical Deterministic Wallet represents a large tree of private keys which can reliably be reproduced from an initial seed.
**ethers.Interface**: The Interface Object is a meta-class that accepts a Solidity (or compatible) Application Binary Interface (ABI) and populates functions to deal with encoding and decoding the parameters to pass in and results returned.
**ethers.providers**: A Provider abstracts a connection to the Ethereum blockchain, for issuing queries and sending state changing transactions.
**ethers.SigningKey**: The SigningKey interface provides an abstraction around the secp256k1 elliptic curve cryptography library.
**ethers.utils**: The utility functions exposed in both the ethers umbrella package and the ethers-utils.
**ethers.utils.AbiCoder**: Create a new ABI Coder object
**ethers.utils.RLP**: This encoding method is used internally for several aspects of Ethereum, such as encoding transactions and determining contract addresses.
**ethers.Wallet**: A wallet manages a private/public key pair which is used to cryptographically sign transactions and prove ownership on the Ethereum network.
**ethers.version**: Contains the version of the ethers container object.
**web3.bzz**: Bzz module for interacting with the swarm network.
**web3.eth**: Eth module for interacting with the Ethereum network.
**web3.eth.accounts**: The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.
**web3.eth.abi**: The web3.eth.abi functions let you de- and encode parameters to ABI (Application Binary Interface) for function calls to the EVM (Ethereum Virtual Machine).
**web3.eth.ens**: The web3.eth.ens functions let you interacting with ENS.
**web3.eth.Iban**: The web3.eth.Iban function lets convert Ethereum addresses from and to IBAN and BBAN.
**web3.eth.net**: Net module for interacting with network properties.
**web3.eth.personal**: Personal module for interacting with the Ethereum accounts.
**web3.eth.subscribe**: The web3.eth.subscribe function lets you subscribe to specific events in the blockchain.
**web3.givenProvider**: When using web3.js in an Ethereum compatible browser, it will set with the current native provider by that browser. Will return the given provider by the (browser) environment, otherwise null.
**web3.modules**: Contains the version of the web3 container object.
**web3.providers**: Contains the current available providers.
**web3.shh**: Shh module for interacting with the whisper protocol
**web3.utils**: This package provides utility functions for Ethereum dapps and other **web3.js packages.
**web3.version**: Contains the version of the web3 container object.
**web3.eth.clearSubscriptions();**: Resets subscriptions.
**web3.eth.Contract(jsonInterface[, address][, options])**: The **web3.eth.Contract object makes it easy to interact with smart contracts on the ethereum blockchain.
**web3.eth.accounts.create([entropy]);**: The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.

@ -1,37 +0,0 @@
Remix GitHub Tutorials
=======================
There are a series of tutorials in our github repo [remix-workshops](https://github.com/ethereum/remix-workshops).
We are in the process of upgrading these tutorials to use the new Remix layout.
In this repo there tutorials for all levels.
There are tutorials for specific remix functionalities like:
***Deploying***
Multiple ways of loading files in Remix
Deploying with libraries
Deploying a proxy contract
***Testing***
Testing Examples
Continuous integration
***Remix Plugin Development***
Developing a plugin for Remix and deploying it to swarm
***Other***
EtherAtom (walkthrough slides + screencast)
Debugging transactions with Remix IDE
Recording and replaying transactions
Using a Pipeline plugin for developing Solidity contracts with demo video
Running scripts in the Remix terminal (batch deployment) (proxy deployment)
***Additional external workshops***
Using Oraclize plugin in Remix

@ -1,57 +0,0 @@
Remixd: Access your Local Filesystem
=========================================
`remixd` is an npm module. Its purpose is to give the remix web
application access to a folder on your local computer.
The code of `remixd` is
[here](https://github.com/ethereum/remixd) .
`remixd` can be globally installed using the following command:
`yarn global add @remix-project/remixd`
Then from the terminal, the command `remixd -s <absolute-path-to-the-shared-folder> --remix-ide <your-remix-ide-URL-instance>` will start `remixd` and will share the given folder with remix-ide.
For example, to use remixd with Remix IDE ( and not the alpha version) use this command:
`remixd -s <absolute-path-to-the-shared-folder> --remix-ide https://remix.ethereum.org`
Make sure that if you use https://remix.ethereum.org (secure http) in the remixd command (like in the example above), that you are also pointing your browser to https://remix.ethereum.org and not to http://remix.ethereum.org (plain old insecure http). Or if you want to use http in the browser use http in the remixd command.
The folder is shared using a websocket connection between `Remix IDE`
and `remixd`.
Be sure the user executing `remixd` has read/write permission on the
folder.
There is an option to run remixd in read-only mode, use `--read-only` flag.
**Warning!**
`remixd` provides `full read and write access` to the given folder for `any
application` that can access the `TCP port 65520` on your local host.
From `Remix IDE`, in the Plugin Manager you need to activate the remixd plugin.
A modal dialog will ask confirmation
Accepting this dialog will start a session.
If you do not have `remixd` running in the background - another modal will open up and it will say:
```
Cannot connect to the remixd daemon.
Please make sure you have the remixd running in the background.
```
Assuming you don't get the 2nd modal, your connection to the remixd daemon is successful. The shared folder will be available in the file explorer.
**When you click the activation of remixd is successful - there will NOT be an icon that loads in the icon panel.**
Click the File Explorers icon and in the swap panel you should now see the folder for `localhost`.
Click on the `localhost connection` icon:
![](images/a-remixd-success.png)

@ -1,309 +0,0 @@
Deploy & Run
============
![](images/a-run-icon.png) The Deploy & Run module allows you to send transactions to the current environment.
To use this module, you need to have a contract compiled. So, if there is a contract name in the <b>CONTRACT</b> select box (the select box is under the VALUE input field), you can use this module. If nothing is there or you do not see the contract you want, you need to select a contract in the editor to make it active, go to a compiler module and compile it, and then come back to Deploy & Run.
![](images/a-runtab1a.png)
Environment
---------
- `JavaScript VM`: All the transactions will be executed in
a sandbox blockchain in the browser. This means nothing
will be persisted when you reload the page. The JsVM is its own blockchain and on each reload it will start a new blockchain, the old one will not be saved.
- `Injected Provider`: Remix will connect to an injected
web3 provider. `Metamask` is an example of a provider that inject web3.
- `Web3 Provider`: Remix will connect to a remote node. You will need to provide the URL to the selected provider: geth, parity or any Ethereum client.
More about Web3 Provider
-------------
If you are using Geth & https://remix.ethereum.org, please use the following Geth command to allow requests from Remix:
**geth --rpc --rpccorsdomain https://remix.ethereum.org**
Also see [Geth Docs about the rpc server](https://geth.ethereum.org/docs/rpc/server)
To run Remix using https://remix.ethereum.org & a local test node, use this Geth command:
**geth --rpc --rpccorsdomain="https://remix.ethereum.org" --rpcapi web3,eth,debug,personal,net --vmdebug --datadir <path/to/local/folder/for/test/chain> --dev console**
If you are using remix-alpha or a local version of remix - replace the url of the --rpccorsdomain with the url of Remix that you are using.
To run Remix Desktop & a local test node, use this Geth command:
**geth --rpc --rpccorsdomain="package://a7df6d3c223593f3550b35e90d7b0b1f.mod" --rpcapi web3,eth,debug,personal,net --vmdebug --datadir <path/to/local/folder/for/test/chain> --dev console**
Also see [Geth Docs on Dev mode](https://geth.ethereum.org/getting-started/dev-mode)
The Web3 Provider Endpoint for a local node is **http://localhost:8545**
---
**WARNING:** Don't get lazy. It is a bad idea to use the Geth flag <b>--rpccorsdomain</b> with a wildcard: `--rpccorsdomain *`
If you put the wildcard `*`, it means everyone can request the node. Whereas, if you put a URL, it restricts the urls to just that one - e.g. `--rpccorsdomain 'https://remix-alpha.ethereum.org'`
Only use `--rpccorsdomain *` when using a **test chain** AND using only **test accounts**. For real accounts or on the mainchain **specify the url**.
---
Account:
--------
- Account: the list of accounts associated with the current
environment (and their associated balances). On the JsVM, you have a choice of 5 accounts. If using Injected Web3 with MetaMask, you need to change the account in MetaMask.
Gas Limit:
---------
- This sets the maximum amount of gas that will be allowed for all the
transactions created in Remix.
Value:
-----
- This sets the amount of ETH, WEI, GWEI etc that is sent to a contract or a payable function. ( Note: payable functions have a red button). The value is always reset to 0 after each transaction execution). The Value field is **NOT** for gas.
![](images/a-Runtab-deploy-atAddress.png)
Initiate Instance
-----------------
- In the image above, the select box is set to Ballot. This select box will contain the list of compiled contracts.
- `Deploy` send a transaction that deploys the selected contract. When
the transaction is mined, the newly created instance will be added
(this might take several seconds). Note that if the `constructor`
has parameters, you need to specify them.
- `At Address` this is used at access a contract that has already been deployed. It assumes that the given address is an instance of the selected contract. **Note:** There's no check at this point, so be careful when using this feature, and be sure you trust the contract at that address.
Pending Instances
-----------------
Validating a transaction takes several seconds. During this time, the GUI
shows it in a pending mode. When the transaction is mined, the number of
pending transactions is updated and the transaction is added to the log
([see terminal](terminal.html)).
Using the ABI
------------
Using `Deploy` or `At Address` is a classic use case of Remix. However, it is
possible to interact with a contract by using its ABI. The ABI is
a JSON array which describe its interface.
To interact with a contract using the ABI, create a new file in Remix
with extension `*.abi` and copy the ABI content to it. Then, in the input
next to `At Address`, put the Address of the contract you want to
interact with. Click on `At Address`, a new "connection" with the
contract will popup below.
Using the Recorder
------------------
The Recorder is a tool used to save a bunch of transactions in a JSON file and
rerun them later either in the same environment or in another.
Saving to the JSON file ( by default its called scenario.json) allows one to easily check the transaction list, tweak input parameters, change linked library, etc...
There are many use cases for the recorder.
For instance:
- After having coded and tested contracts in a constrained
environment (like the JavaScript VM), you could then change the environment and redeploy it to a more realistic environment like a test net with an **injected web3** or to a Geth node. By using the generated **scenario.json** file, you will be using all the same settings that you used in the Javascript VM. And this mean that you won't need to click the interface 100 times or whatever to get the state that you achieved originally. So the recorder could be a tool to protect your sanity.
You can also change the settings in the scenario.json file to customize the playback.
- Deploying contract does often require more than creating one
transaction and so the recorder will automate this deployment.
- Working in a dev environment often requires to setup the
state in a first place.
![](images/a-runtab-recorder.png)
### scenario.json
To create this file in the recorder, you first of course need to have run some transactions. In the image above - it has a `0` next to **Transactions Recorded**. So this isn't the right moment to save transactions because - well because there aren't any. Each time you make a transaction, that number will increment. Then when you are ready, click the floppy disk icon and the scenario.json file will be created.
The JSON file below is an example of the scenario.json file.
In it, 3 transactions are executed:
The first corresponds to the deployment of the lib `testLib`.
The second corresponds to the deployment of the contract `test` with the
first parameter of the constructor set to 11. That contract depends
on a library. The linkage is done using the property `linkReferences`.
In that case we use the address of the previously created library :
`created{1512830014773}`. The number is the id (timestamp) of the
transaction that led to the creation of the library.
The third record corresponds to the call to the function `set` of the
contract `test` (the property to is set to: `created{1512830015080}`) .
Input parameters are `1` and
`0xca35b7d915458ef540ade6068dfe2f44e8fa733c`
All these transactions are created using the value of the accounts
`account{0}`.
```
{
"accounts": {
"account{0}": "0xca35b7d915458ef540ade6068dfe2f44e8fa733c"
},
"linkReferences": {
"testLib": "created{1512830014773}"
},
"transactions": [
{
"timestamp": 1512830014773,
"record": {
"value": "0",
"parameters": [],
"abi": "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a",
"contractName": "testLib",
"bytecode": "60606040523415600e57600080fd5b60968061001c6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636d4ce63c146044575b600080fd5b604a6060565b6040518082815260200191505060405180910390f35b6000610d809050905600a165627a7a7230582022d123b15248b8176151f8d45c2dc132063bcc9bb8d5cd652aea7efae362c8050029",
"linkReferences": {},
"type": "constructor",
"from": "account{0}"
}
},
{
"timestamp": 1512830015080,
"record": {
"value": "100",
"parameters": [
11
],
"abi": "0xc41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec",
"contractName": "test",
"bytecode": "60606040526040516020806102b183398101604052808051906020019091905050806000819055505061027a806100376000396000f300606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632f30c6f61461006757806338cc48311461009e57806362738998146100f357806387cc10e11461011c575b600080fd5b61009c600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610145565b005b34156100a957600080fd5b6100b1610191565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156100fe57600080fd5b6101066101bb565b6040518082815260200191505060405180910390f35b341561012757600080fd5b61012f6101c4565b6040518082815260200191505060405180910390f35b8160008190555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054905090565b600073__browser/ballot.sol:testLib____________636d4ce63c6000604051602001526040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b151561022e57600080fd5b6102c65a03f4151561023f57600080fd5b505050604051805190509050905600a165627a7a72305820e0b2510bb2890a0334bfe5613d96db3e72442e63b514cdeaee8fc2c6bbd19d3a0029",
"linkReferences": {
"browser/ballot.sol": {
"testLib": [
{
"length": 20,
"start": 511
}
]
}
},
"name": "",
"type": "constructor",
"from": "account{0}"
}
},
{
"timestamp": 1512830034180,
"record": {
"value": "1000000000000000000",
"parameters": [
1,
"0xca35b7d915458ef540ade6068dfe2f44e8fa733c"
],
"to": "created{1512830015080}",
"abi": "0xc41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec",
"name": "set",
"type": "function",
"from": "account{0}"
}
}
],
"abis": {
"0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a": [
{
"constant": true,
"inputs": [],
"name": "get",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
],
"0xc41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec": [
{
"constant": true,
"inputs": [],
"name": "getInt",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getFromLib",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getAddress",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_t",
"type": "uint256"
},
{
"name": "_add",
"type": "address"
}
],
"name": "set",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"name": "_r",
"type": "uint256"
}
],
"payable": true,
"stateMutability": "payable",
"type": "constructor"
}
]
}
}
```

@ -1,14 +0,0 @@
Settings
========
To get to **Settings** click the gear a the very bottom of the icon panel.
You can find a link to the homepage (if you closed it) as well as a link to our Gitter Channel and for you aesthetes out there, we now have a rather large list of themes.
![](images/a-themes.png)
Another important settings:
- Text wrap: controls if the text in the editor should be wrapped.
- Enable optimization: defines if the compiler should enable optimization during compilation. Enabling this option saves execution gas. It is useful to enable optimization for contracts ready to be deployed in production but could lead to some inconsistencies when debugging such a contract.

@ -1,18 +0,0 @@
Solidity Editor
===============
The Remix editor recompiles the code each time the current file is
changed or another file is selected. It also provides syntax
highlighting mapped to solidity keywords.
![](images/a-sol-editor.png)
Here's the list of some important features:
- It display opened files as tabs.
- Compilation Warning and Error are displayed in the gutter
- Remix saves the current file continuously (5s after the last
changes)
- +/- on the top left corner enable you to increase/decrease the font
size of the editor

@ -1,296 +0,0 @@
Solidity Static Analysis
========================
Static code analysis is a process to debug the code by examining it and without actually executing the code.
`Solidity Static Analysis` plugin performs static analysis on Solidity smart contracts once they are compiled. It checks for security vulnerabilities and bad development practices, among other issues. This plugin comes with `Solidity` environment of Remix IDE. It can also be activated individually from `Plugin Manager`.
How to use
------------
If you select this plugin, you will see a number of modules listed along with checkboxes, one `Auto run` checkbox and a `Run` button.
![](images/a-static-analysis.png)
By default, all modules are selected for analysis and a new analysis is performed at each compilation.
One can select/deselect the modules under which contract should be analyzed and can run the analysis again for last compiled contract by clicking on `Run`.
If you don't want to run analysis each time you compile a contract, just uncheck the checkbox near to `Auto run`.
Analysis Modules
-----------------
Currently, with Remix IDE v0.10.1, there are 21 analysis modules listed under 4 categories. Categories are: `Security`, `Gas & Economy`, `ERC` & `Miscellaneous`.
Here is the list of modules under each category along with the example code which **should be avoided or used very carefully while development**:
### Category: Security
- **Transaction origin: 'tx.origin' is used**
`tx.origin` is useful only in very exceptional cases. If you use it for authentication, you usually want to replace it by "msg.sender", because otherwise any contract you call can act on your behalf.
_Example:_
```
require(tx.origin == owner);
```
- **Check effects: Potential reentrancy bugs**
Potential Violation of Checks-Effects-Interaction pattern can lead to re-entrancy vulnerability.
_Example:_
```
// sending ether first
msg.sender.transfer(amount);
// updating state afterwards
balances[msg.sender] -= amount;
```
- **Inline assembly: Inline assembly used**
Use of inline assembly is advised only in rare cases.
_Example:_
```
assembly {
// retrieve the size of the code, this needs assembly
let size := extcodesize(_addr)
}
```
- **Block timestamp: Semantics maybe unclear**
`now` does not mean current time. `now` is an alias for `block.timestamp`. `block.timestamp` can be influenced by miners to a certain degree, be careful.
_Example:_
```
// using now for date comparison
if(startDate > now)
isStarted = true;
// using block.timestamp
uint c = block.timestamp;
```
- **Low level calls: Semantics maybe unclear**
Use of low level `call`, `callcode` or `delegatecall` should be avoided whenever possible. `send` does not throw an exception when not successful, make sure you deal with the failure case accordingly. Use `transfer` whenever failure of the ether transfer should rollback the whole transaction.
_Example:_
```
x.call('something');
x.send(1 wei);
```
- **Blockhash usage: Semantics maybe unclear**
`blockhash` is used to access the last 256 block hashes. A miner computes the block hash by "summing up" the information in the current block mined. By summing up the information in a clever way a miner can try to influence the outcome of a transaction in the current block.
_Example:_
```
bytes32 b = blockhash(100);
```
- **Selfdestruct: Beware of caller contracts**
`selfdestruct` can block calling contracts unexpectedly. Be especially careful if this contract is planned to be used by other contracts (i.e. library contracts, interactions). Selfdestruction of the callee contract can leave callers in an inoperable state.
_Example:_
```
selfdestruct(address(0x123abc..));
```
### Category: Gas & Economy
- **Gas costs: Too high gas requirement of functions**
If the gas requirement of a function is higher than the block gas limit, it cannot be executed. Please avoid loops in your functions or actions that modify large areas of storage
_Example:_
```
for (uint8 proposal = 0; proposal < proposals.length; proposal++) {
if (proposals[proposal].voteCount > winningVoteCount) {
winningVoteCount = proposals[proposal].voteCount;
winningProposal = proposal;
}
}
```
- **This on local calls: Invocation of local functions via 'this'**
Never use `this` to call functions in the same contract, it only consumes more gas than normal local calls.
_Example:_
```
contract test {
function callb() public {
address x;
this.b(x);
}
function b(address a) public returns (bool) {}
}
```
- **Delete on dynamic Array: Use require/assert appropriately**
The `delete` operation when applied to a dynamically sized array in Solidity generates code to delete each of the elements contained. If the array is large, this operation can surpass the block gas limit and raise an OOG exception. Also nested dynamically sized objects can produce the same results.
_Example:_
```
contract arr {
uint[] users;
function resetState() public{
delete users;
}
}
```
- **For loop over dynamic array: Iterations depend on dynamic array's size**
Loops that do not have a fixed number of iterations, for example, loops that depend on storage values, have to be used carefully: Due to the block gas limit, transactions can only consume a certain amount of gas. The number of iterations in a loop can grow beyond the block gas limit which can stall the complete contract at a certain point. Additionally, using unbounded loops can incur in a lot of avoidable gas costs. Carefully test how many items at maximum you can pass to such functions to make it successful.
_Example:_
```
contract forLoopArr {
uint[] array;
function shiftArrItem(uint index) public returns(uint[] memory) {
for (uint i = index; i < array.length; i++) {
array[i] = array[i+1];
}
return array;
}
}
```
- **Ether transfer in loop: Transferring Ether in a for/while/do-while loop**
Ether payout should not be done in a loop. Due to the block gas limit, transactions can only consume a certain amount of gas. The number of iterations in a loop can grow beyond the block gas limit which can cause the complete contract to be stalled at a certain point. If required, make sure that number of iterations are low and you trust each address involved.
_Example:_
```
contract etherTransferInLoop {
address payable owner;
function transferInForLoop(uint index) public {
for (uint i = index; i < 100; i++) {
owner.transfer(i);
}
}
function transferInWhileLoop(uint index) public {
uint i = index;
while (i < 100) {
owner.transfer(i);
i++;
}
}
}
```
### Category: ERC
- **ERC20: 'decimals' should be 'uint8'**
ERC20 Contracts `decimals` function should have `uint8` as return type.
_Example:_
```
contract EIP20 {
uint public decimals = 12;
}
```
### Category: Miscellaneous
- **Constant/View/Pure functions: Potentially constant/view/pure functions**
It warns for the methods which potentially should be constant/view/pure but are not.
_Example:_
```
function b(address a) public returns (bool) {
return true;
}
```
- **Similar variable names: Variable names are too similar**
It warns on the usage of similar variable names.
_Example:_
```
// Variables have very similar names voter and voters.
function giveRightToVote(address voter) public {
require(voters[voter].weight == 0);
voters[voter].weight = 1;
}
```
- **No return: Function with 'returns' not returning**
It warns for the methods which define a return type but never explicitly return a value.
_Example:_
```
function noreturn(string memory _dna) public returns (bool) {
dna = _dna;
}
```
- **Guard conditions: Use 'require' and 'assert' appropriately**
Use `assert(x)` if you never ever want x to be false, not in any circumstance (apart from a bug in your code). Use `require(x)` if x can be false, due to e.g. invalid input or a failing external component.
_Example:_
```
assert(a.balance == 0);
```
- **Result not used: The result of an operation not used**
A binary operation yields a value that is not used in the following. This is often caused by confusing assignment (=) and comparison (==).
_Example:_
```
c == 5;
or
a + b;
```
- **String Length: Bytes length != String length**
Bytes and string length are not the same since strings are assumed to be UTF-8 encoded (according to the ABI defintion) therefore one character is not nessesarily encoded in one byte of data.
_Example:_
```
function length(string memory a) public pure returns(uint) {
bytes memory x = bytes(a);
return x.length;
}
```
- **Delete from dynamic array: 'delete' on an array leaves a gap**
Using `delete` on an array leaves a gap. The length of the array remains the same. If you want to remove the empty position you need to shift items manually and update the length property.
_Example:_
```
contract arr {
uint[] array = [1,2,3];
function removeAtIndex() public returns (uint[] memory) {
delete array[1];
return array;
}
}
```
- **Data Truncated: Division on int/uint values truncates the result**
Division of integer values yields an integer value again. That means e.g. 10 / 100 = 0 instead of 0.1 since the result is an integer again. This does not hold for division of (only) literal values since those yield rational constants.
_Example:_
```
function contribute() payable public {
uint fee = msg.value * uint256(feePercentage / 100);
fee = msg.value * (p2 / 100);
}
```
Remix-analyzer
-----------------
`remix-analyzer` is the library which works underneath of remix-ide `Solidity Static Analysis` plugin.
`remix-analyzer` is an [NPM package](https://www.npmjs.com/package/remix-analyzer). It can be used as a library in a solution supporting node.js. Find more information about this type of usage in the [remix-analyzer repository](https://github.com/ethereum/remix/tree/master/remix-analyzer#how-to-use)

@ -1,9 +0,0 @@
Support chat
=======================
We know that blockchain ecosystem is very new and that lots of information is scattered around the web.
That is why we created a community support chat where we and other users try to answer your questions if
you get stuck using Remix. Please, join [the Remix channel](https://gitter.im/ethereum/remix) and ask the community for help.
For anyone who is interested in developing a custom plugin for Remix or who wants to contribute to the codebase,
we've opened [another channel](https://gitter.im/ethereum/remix-dev) specially for developers working on Remix tool.

@ -1,21 +0,0 @@
Terminal
========
![](images/a-terminal-and-more.png)
Features, available in the terminal:
- It integrates a JavaScript interpreter and the `web3` object. It
enables the execution of the JavaScript script which interacts with
the current context. (note that `web3` is only available if the
`web provider` or `injected provider` mode is selected).
- It displays important actions made while interacting with the Remix
IDE (i.e. sending a new transaction).
- It displays transactions that are mined in the current context. You
can choose to display all transactions or only transactions that
refers to the contracts Remix knows (e.g transaction created from
the Remix IDE).
- It allows searching for the data and clearing the logs from the
terminal.
- You can run scripts by inputting them at the bottom after the `>`.

@ -1,225 +0,0 @@
Debugging Transactions
======================
There are two ways to start debugging, each one corresponds to a different use case.
* from the transaction log in the Terminal - use this when you want to debug a transaction.
* from the Debugger - use this if you have a *transaction hash*.
### Initiate Debugging from the transaction log in the Terminal
Let's start with a basic contract ( or replace this one by your own ) :
- create a blank file in the file explorer (by clicking the + icon) and give it a name.
- copy the code below.
- compile the code.
- click the Run & Deploy icon in the icon panel.
```
pragma solidity >=0.5.1 <0.6.0;
contract Donation {
address owner;
event fundMoved(address _to, uint _amount);
modifier onlyowner { if (msg.sender == owner) _; }
address[] _giver;
uint[] _values;
constructor() public {
owner = msg.sender;
}
function donate() payable public {
addGiver(msg.value);
}
function moveFund(address payable _to, uint _amount) onlyowner public {
uint balance = address(this).balance;
uint amount = _amount;
if (_amount <= balance) {
if (_to.send(balance)) {
emit fundMoved(_to, _amount);
} else {
revert();
}
} else {
revert();
}
}
function addGiver(uint _amount) internal {
_giver.push(msg.sender);
_values.push(_amount);
}
}
```
For the purpose of this tutorial, we will run the `JavaScript VM`.
This simulates a custom blockchain. You could do the same using a proper backend node.
Let's deploy the contract:
Click the `Deploy` button
![](images/a-debug1-deploy.png)
You'll see the deployed instance (AKA the udapp).
![](images/a-debug2-udapp1a.png)
Then open it up (by clicking the caret).
![](images/a-debug3-udapp2.png)
We are going to call the `Donate` function and will send it ether.
To do this: in the value input box put in **2** and select Ether as the unit (and not wei like I did in the image below - well you could - it won't really change anything).
![](images/a-debug4-value-loc.png)
Then click the `Donate` button.
This will send Ether to the this function.
Because we are using the `JavaScript VM`, everything happens almost instantly. (If we had been using Injected Web 3, then we would have to need to approve the transaction, pay for gas and wait for the transaction to get mined.)
Remix displays information related to each transaction result in the terminal.
Check in the **terminal** where the transaction you just made is logged.
Click the debug button to start debugging it.
![](images/a-debug5-term-debug-but.png)
Before we get to the actual debugging tool, the next section show how to start debugging session directly from the Debugger.
### Initiate Debugging from the Debugger
Click the bug icon in the icon panel to get to the debugger in the side panel.
If you don't see the bug icon, go to the plugin manager and activate the debugger.
You can start a debug session by providing a `transaction hash`.
To find a transaction hash:
1. Go to a transaction in the terminal.
2. Click a line with a transaction - to exand the log.
3. The transaction hash is there - copy it.
![](images/a-debug6-term-txn-hash.png)
Then click in the debugger paste the hash and click on the `Start debugging` button.
![](images/a-debug7-debugger.png)
Using the debugger
------------------
![](images/a-debug8-top3.png)
The debugger allows one to see detailed informations about the
transaction's execution. It uses the editor to display the
location in the source code where the current execution is.
The navigation part contains a slider and buttons that can be used to
step through the transaction execution.
### More explaination of what these buttons do.
1. Step Into
2. Step Over Into
11 panels give detailed information about the execution:
### Instructions
The Instructions panel displays the bytecode of the current executing
contract- with the current step highlighted.
Important note: When this panel is hidden, the slider will have a
courser granularity and only stop at *expression boundaries*, even if they
are compiled into multiple EVM instructions. When the panel is
displayed, it will be possible to step over every instruction, even
those that refers to the same expression.
### Solidity Locals
The Solidity Locals panel displays local variables associated with the
current context.
### Solidity State
The Solidity State panel displays state variables of the current
executing contract.
### Low level panels
These panels display low level informations about the execution:
> - Stack
> - Storages Changes
> - Memory
> - Call Data
> - Call Stack
> - Return Value (only if the current step is a RETURN opcode)
> - Full Storages Changes (only at the end of the execution - display
> every storage change of every modified contract)
### Reverted Transaction
A transaction can be `reverted` (because of an *out of gas exception* or
Solidity `revert` statement or because of a low level exception).
It is important to be aware of the exception and to locate
where the exception is in the source code.
Remix will warn you when the execution throws an exception. The
`warning` button will jump to the last opcode before the exception
happened.
### Breakpoints
The two last buttons from the navigation area are used to jump either
back to the previous breakpoint or forward to the next breakpoint.
Breakpoints can be added and removed by clicking on the line number in the *Editor*.
When using debug session with breakpoints, the execution will jump to the first
encountered breakpoint.
**Important note:** If you add a breakpoint to a line that declares a
variable, it might be triggered twice: Once for initializing the
variable to zero and second time for assigning the actual value. As an
example, assume you are debugging the following contract:
```
pragma solidity >=0.5.1 <0.6.0;
contract ctr {
function hid () public {
uint p = 45;
uint m;
m = 89;
uint l = 34;
}
}
```
And let's says that breakpoints are set for the lines
`uint p = 45;`
`m = 89;`
`uint l = 34;`
then clicking on `Jump to next breakpoint` will stop at the following
lines in the given order:
> `uint p = 45;` (declaration of p)
>
> `uint l = 34;` (declaration of l)
>
> `uint p = 45;` (45 assigned to p)
>
> `m = 89;` (89 assigned to m)
>
> `uint l = 34;` (34 assigned to l)

@ -1,139 +0,0 @@
Run & Deploy (part 2)
=====================
## Deployed contracts
This section in the Run tab contains a list of deployed contracts to interact with through autogenerated UI of the deployed contract (also called udapp).
The deployed contract appears but is in its collapsed form.
![](images/a-debug2-udapp1a.png)
Click the sideways caret to open it up.
![](images/a-udapp1.png)
You will see the functions in the contract. The functions buttons can have different color buttons.
- Functions that are `constant` or `pure` functions in Solidity have a blue buttons. Clicking one of this type does not create a new transaction. So clicking will not cause state changes - it will only return a value stored in the contract - so it won't cost you anything in gas fees.
- Functions that change the state of the contract AND that do not accept Ether are called `non-payable` functions and have an orange button. Clicking on them will create a transaction and thus cost gas.
- Functions that have red buttons are `payable` functions in Solidity. Clicking one of these will create a new transaction and this transaction can accept a **value**. The **value** is put in in the Value field which is under the Gas Limit field.
![](images/a-jvm-calling-instance.png)
See more information about [Solidity
modifiers](http://solidity.readthedocs.io/en/develop/miscellaneous.html?highlight=pure#modifiers) in the Solidity docs.
.
If a function requires input parameters, well.. you gotta put them in.
## Inputting parameters
![](images/a-udapp-inputs.png)
### Inputting parameters in the collapsed view
(Inputting all the parameters in a single input box)
+ The input box tells you what type each parameter needs to be.
+ Numbers and addresses do not need to be wrapped in double quotes.
+ Strings need to be wrapped.
+ Parameters are separated by commas.
In the example above the "delegate" function has 3 parameters.
### Inputting parameters in the expanded view
Clicking the 'down' caret brings you to the *Multi-param Manager* - where you can input the parameters one at a time. **Much less confusing!**
![](images/a-udapp-multi-param-man.png)
In the expanded view, strings do not need to be wrapped.
Clicking the clipboard icon will encode the inputs and will copy them. Only a valid set of inputs can be encoded.
So if you made a mistake and put a uint8 where an address should have been, clicking the clipboard here will give you an error.
## Low level interactions
Low level interactions are used to send funds or calldata or funds & calldata to a contract through the **recieve()** or **fallback()** function. Typically, you should only need to implement the fallback function if you are following an upgrade or proxy pattern.
The low level interactions section is below the functions in each deployed contract.
![](images/a-udapp1.png)
Please note the following:
- If you are executing a plain Ether transfer to a contract, you need to have the receive() function in your contract. If your contract has been deployed and you want to send it funds, you would input the amount of Ether or Wei etc. (see **A** in graphic below), and then input **NOTHING** in the calldata field of **Low level interactions** (see **B** in graphic) and click the Transact button (see **C** in graphic below).
![](images/a-receive-fun.png)
- If you are sending calldata to your contract with Ether, then you need to use the fallback() function and have it with the state mutability of **payable**.
- If you are not sending ether to the contract but **are** sending call data then you need to use the fallback() function.
- If you break the rules when using the **Low level interactions** you will be slapped with a warning.
Please see the [solidity docs](https://solidity.readthedocs.io/en/latest/contracts.html#receive-ether-function) for more specifics about using the **fallback** and **receive** functions.
### Passing in a tuple or a struct to a function
To pass a tuple in, you need to put in an array [].
Similarly, to pass in a struct as a parameter of a function, it needs to be put in as an array []. Also note that the line
`pragma experimental ABIEncoderV2;`
needs to put in at the top of the solidity file.
### Example of passing nested struct to a function
Consider a nested struct defined like this:
```
struct gardenPlot {
uint slugCount;
uint wormCount;
Flower[] theFlowers;
}
struct Flower {
uint flowerNum;
string color;
}
```
If a function has the signature `fertilizer(Garden memory gardenPlot)` then the correct syntax is:
```
[1,2,[[3,"Petunia"]]]
```
To continue on this example, here's a sample contract:
```
pragma solidity >=0.4.22 <0.7.0;
pragma experimental ABIEncoderV2;
contract Sunshine {
struct Garden {
uint slugCount;
uint wormCount;
Flower[] theFlowers;
}
struct Flower {
uint flowerNum;
string color;
}
function picker(Garden memory gardenPlot) public {
uint a = gardenPlot.slugCount;
uint b = gardenPlot.wormCount;
Flower[] memory cFlowers = gardenPlot.theFlowers;
uint d = gardenPlot.theFlowers[0].flowerNum;
string memory e = gardenPlot.theFlowers[0].color;
}
}
```
After compiling, deploying the contract and opening up the deployed instance, we can then add the following input parameters to the function named **fertilizer** :
```
[1,2,[[3,"Black-eyed Susan"],[4,"Pansy"]]]
```
The function **fertilizer** accepts a single parameter of the type **Garden**. The type **Garden** is a **struct**. Structs are wrapped in **square brackets**. Inside **Garden** is an array that is an array of structs named **theFlowers**. It gets a set of brackets for the array and another set for the struct. Thus the double square brackets.

@ -1,100 +0,0 @@
Unit Testing Plugin
============
Click the
![double check](images/a-user-testing-icon.png)
icon to get to the `Solidity Unit Testing` plugin.
If you haven't used this plugin before and are not seeing `double check` icon, you have to activate it from Remix plugin manager.
Go to the plugin manager (by click the ![plug](images/a-plug.png) icon) and load up the unit testing plugin.
![](images/a-unit-testing-from-pm.png)
Now `double check` icon will appear on the left side icon bar. Clicking on icon will load the unit testing module in the side panel.
Alternatively, just select `Solidity` environment from remix IDE home page. This will activate `Solidity Unit Testing` plugin along with `Solidity Compiler`, `Deploy & Run Transactions` & `Solidity Static Analysis` plugins.
![](images/a-unit-testing-feature.png)
Generate
----------
Select a solidity file which you want to test and click on the button `Generate`. It will generate a new sample solidity test file **in the current folder** suffixed with `_test`. This file contains the minimum you need for running unit testing.
Write Tests
-----------
Write tests to check the functionality of your contract. Remix injects a built-in `assert` library which can be used for testing. Visit the library documentation [here](./assert_library).
Apart from this, Remix allows usage of some special functions to make testing more structural. They are:
* `beforeEach()` - Runs before each test
* `beforeAll()` - Runs before all tests
* `afterEach()` - Runs after each test
* `afterAll()` - Runs after all tests
To get started, see [this simple example](./unittesting_examples.html#simple-example).
Run
-----
Once you are done with writing tests, select the _test.sol files in the list and click on the button `Run` to execute the tests in the selected files. The execution will run in a separate environment and the result will be displayed below.
![](images/a-unit-testing-run-result.png)
Stop
-----
If you have selected multiple files to run the tests and want to stop the execution, click on `Stop` button. It will stop execution after running the tests for current file.
Customization
------------------
Remix facilitates users with various types of customizations to test a contract properly.
**1. Custom Compiler Context**
`Solidity Unit Testing` refers `Solidity Compiler` plugin for compiler configurations. One can provide customized inputs for `Compiler`, `EVM Version` & `Enable Optimization` and these will be the configuration settings used for contract compilation before running unit tests.
![](images/a-unit-testing-custom-compiler-config.png)
**2. Custom Transaction Context**
For a contract method interaction, prime parameters of transaction are `from` address, `value` & `gas`. Usually, we need to test a method's behaviour under different values of these parameters.
Remix provides the functionality of custom `msg.sender` & `msg.value` of transaction using method devdoc like:
```
/// #sender: account-0
/// #value: 10
function checkSenderIs0AndValueis10 () public payable {
Assert.equal(msg.sender, TestsAccounts.getAccount(0), "wrong sender in checkSenderIs0AndValueis10");
Assert.equal(msg.value, 10, "wrong value in checkSenderIs0AndValueis10");
}
```
Things to keep in mind while using custom transaction context:
1. Parameters must be defined in devdoc of related method
2. Each parameter key should be prefixed with a hash (**#**) and end with a colon following a space (**:&nbsp;**) like `#sender: ` & `#value: `
3. For now, customization is available for parameters `sender` & `value` only
4. Sender is `from` address of a transaction which is accessed using `msg.sender` inside a contract method. It should be defined in a fixed format as '**account-**<account_index>'
5. `<account_index>` varies from `0-2` before remix-ide release v0.10.0 and `0-9` afterwards
6. `remix_accounts.sol` must be imported in your test file to use custom `sender`
7. Value is `value` sent along with a transaction in `wei` which is accessed using `msg.value` inside a contract method. It should be a number.
Regarding `gas`, Remix estimates the required gas for each transaction internally. Still if a contract deployment fails with `Out-of-Gas` error, it tries to redeploy it by doubling the gas. Deployment failing with double gas will show error: ```contract deployment failed after trying twice: The contract code couldn't be stored, please check your gas limit```
Various test examples can be seen in [examples](./unittesting_examples) section.
Points to remember
------------------
* A test contract cannot have a method with parameters. Having one such method will show error: `Method 'methodname' can not have parameters inside a test contract`
* Number of test accounts are `3` before remix-ide release v0.10.0 and `10` afterwards
* A test file which imports `remix_accounts.sol` might not compile successfully with `Solidity Compiler` plugin but it will work fine with Solidity Unit Testing plugin.
Remix-tests
----------------------
`remix-tests` is the module which works underneath of remix-ide `Solidity Unit Testing` plugin.
`remix-tests` is an [NPM package](https://www.npmjs.com/package/remix-tests). It can also be used as a CLI/CI solution, supporting node.js. Find more information about this type of usage in the [remix-tests repository](https://github.com/ethereum/remix/tree/master/remix-tests#as-command-line-interface)
For CI implementation example, see [Su Squares contract](https://github.com/su-squares/ethereum-contract/tree/e542f37d4f8f6c7b07d90a6554424268384a4186) and [Travis build](https://travis-ci.org/su-squares/ethereum-contract/builds/446186067) that uses `remix-tests` for continuous integration testing.

@ -1,329 +0,0 @@
Testing by Example
============
Here are some examples which can give you better understanding to plan your tests.
**Note:** Examples in this section are intended to give you a push for development. We don't recommend to rely on them without verifying at your end.
### 1. Simple example
In this example, we test setting & getting variables.
Contract/Program to be tested: `Simple_storage.sol`
```
pragma solidity >=0.4.22 <0.7.0;
contract SimpleStorage {
uint public storedData;
constructor() public {
storedData = 100;
}
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint retVal) {
return storedData;
}
}
```
Test contract/program: `simple_storage_test.sol`
```
pragma solidity >=0.4.22 <0.7.0;
import "remix_tests.sol";
import "./Simple_storage.sol";
contract MyTest {
SimpleStorage foo;
// beforeEach works before running each test
function beforeEach() public {
foo = new SimpleStorage();
}
/// Test if initial value is set correctly
function initialValueShouldBe100() public returns (bool) {
return Assert.equal(foo.get(), 100, "initial value is not correct");
}
/// Test if value is set as expected
function valueIsSet200() public returns (bool) {
foo.set(200);
return Assert.equal(foo.get(), 200, "value is not 200");
}
}
```
### 2. Testing a method involving `msg.sender`
In Solidity, `msg.sender` plays a great role in access management of a smart contract methods interaction. Different `msg.sender` can help to test a contract involving multiple accounts with different roles. Here is an example for testing such case:
Contract/Program to be tested: `Sender.sol`
```
pragma solidity >=0.4.22 <0.7.0;
contract Sender {
address private owner;
constructor() public {
owner = msg.sender;
}
function updateOwner(address newOwner) public {
require(msg.sender == owner, "only current owner can update owner");
owner = newOwner;
}
function getOwner() public view returns (address) {
return owner;
}
}
```
Test contract/program: `Sender_test.sol`
```
pragma solidity >=0.4.22 <0.7.0;
import "remix_tests.sol"; // this import is automatically injected by Remix
import "remix_accounts.sol";
import "./Sender.sol";
// Inherit 'Sender' contract
contract SenderTest is Sender {
/// Define variables referring to different accounts
address acc0;
address acc1;
address acc2;
/// Initiate accounts variable
function beforeAll() public {
acc0 = TestsAccounts.getAccount(0);
acc1 = TestsAccounts.getAccount(1);
acc2 = TestsAccounts.getAccount(2);
}
/// Test if initial owner is set correctly
function testInitialOwner() public {
// account at zero index (account-0) is default account, so current owner should be acc0
Assert.equal(getOwner(), acc0, 'owner should be acc0');
}
/// Update owner first time
/// This method will be called by default account(account-0) as there is no custom sender defined
function updateOwnerOnce() public {
// check method caller is as expected
Assert.ok(msg.sender == acc0, 'caller should be default account i.e. acc0');
// update owner address to acc1
updateOwner(acc1);
// check if owner is set to expected account
Assert.equal(getOwner(), acc1, 'owner should be updated to acc1');
}
/// Update owner again by defining custom sender
/// #sender: account-1 (sender is account at index '1')
function updateOwnerOnceAgain() public {
// check if caller is custom and is as expected
Assert.ok(msg.sender == acc1, 'caller should be custom account i.e. acc1');
// update owner address to acc2. This will be successful because acc1 is current owner & caller both
updateOwner(acc2);
// check if owner is set to expected account i.e. account2
Assert.equal(getOwner(), acc2, 'owner should be updated to acc2');
}
}
```
### 3. Testing method execution
With Solidity, one can directly verify the changes made by a method in storage by retrieving those variables from a contract. But testing for a successful method execution takes some strategy. Well that is not entirely true, when a test is successful - it is usually obvious why it passed. However, when a test fails, it is essential to understand why it failed.
To help in such cases, Solidity introduced the `try-catch` statement in version `0.6.0`. Previously, we had to use low-level calls to track down what was going on.
Here is an example test file that use both **try-catch** blocks and **low level calls**:
Contract/Program to be tested: `AttendanceRegister.sol`
```
pragma solidity >=0.4.22 <0.7.0;
contract AttendanceRegister {
struct Student{
string name;
uint class;
}
event Added(string name, uint class, uint time);
mapping(uint => Student) public register; // roll number => student details
function add(uint rollNumber, string memory name, uint class) public returns (uint256){
require(class > 0 && class <= 12, "Invalid class");
require(register[rollNumber].class == 0, "Roll number not available");
Student memory s = Student(name, class);
register[rollNumber] = s;
emit Added(name, class, now);
return rollNumber;
}
function getStudentName(uint rollNumber) public view returns (string memory) {
return register[rollNumber].name;
}
}
```
Test contract/program: `AttendanceRegister_test.sol`
```
pragma solidity >=0.4.22 <0.7.0;
import "remix_tests.sol"; // this import is automatically injected by Remix.
import "./AttendanceRegister.sol";
contract AttendanceRegisterTest {
AttendanceRegister ar;
/// 'beforeAll' runs before all other tests
function beforeAll () public {
// Create an instance of contract to be tested
ar = new AttendanceRegister();
}
/// For solidity version greater or equal to 0.6.0,
/// See: https://solidity.readthedocs.io/en/v0.6.0/control-structures.html#try-catch
/// Test 'add' using try-catch
function testAddSuccessUsingTryCatch() public {
// This will pass
try ar.add(101, 'secondStudent', 11) returns (uint256 r) {
Assert.equal(r, 101, 'wrong rollNumber');
} catch Error(string memory /*reason*/) {
// This is executed in case
// revert was called inside getData
// and a reason string was provided.
Assert.ok(false, 'failed with reason');
} catch (bytes memory /*lowLevelData*/) {
// This is executed in case revert() was used
// or there was a failing assertion, division
// by zero, etc. inside getData.
Assert.ok(false, 'failed unexpected');
}
}
/// Test failure case of 'add' using try-catch
function testAddFailureUsingTryCatch1() public {
// This will revert on 'require(class > 0 && class <= 12, "Invalid class");' for class '13'
try ar.add(101, 'secondStudent', 13) returns (uint256 r) {
Assert.ok(false, 'method execution should fail');
} catch Error(string memory reason) {
// Compare failure reason, check if it is as expected
Assert.equal(reason, 'Invalid class', 'failed with unexpected reason');
} catch (bytes memory /*lowLevelData*/) {
Assert.ok(false, 'failed unexpected');
}
}
/// Test another failure case of 'add' using try-catch
function testAddFailureUsingTryCatch2() public {
// This will revert on 'require(register[rollNumber].class == 0, "Roll number not available");' for rollNumber '101'
try ar.add(101, 'secondStudent', 11) returns (uint256 r) {
Assert.ok(false, 'method execution should fail');
} catch Error(string memory reason) {
// Compare failure reason, check if it is as expected
Assert.equal(reason, 'Roll number not available', 'failed with unexpected reason');
} catch (bytes memory /*lowLevelData*/) {
Assert.ok(false, 'failed unexpected');
}
}
/// For solidity version less than 0.6.0, low level call can be used
/// See: https://solidity.readthedocs.io/en/v0.6.0/units-and-global-variables.html#members-of-address-types
/// Test success case of 'add' using low level call
function testAddSuccessUsingCall() public {
bytes memory methodSign = abi.encodeWithSignature('add(uint256,string,uint256)', 102, 'firstStudent', 10);
(bool success, bytes memory data) = address(ar).call(methodSign);
// 'success' stores the result in bool, this can be used to check whether method call was successful
Assert.equal(success, true, 'execution should be successful');
// 'data' stores the returned data which can be decoded to get the actual result
uint rollNumber = abi.decode(data, (uint256));
// check if result is as expected
Assert.equal(rollNumber, 102, 'wrong rollNumber');
}
/// Test failure case of 'add' using low level call
function testAddFailureUsingCall() public {
bytes memory methodSign = abi.encodeWithSignature('add(uint256,string,uint256)', 102, 'duplicate', 10);
(bool success, bytes memory data) = address(ar).call(methodSign);
// 'success' will be false if method execution is not successful
Assert.equal(success, false, 'execution should be successful');
}
}
```
### 4. Testing a method involving `msg.value`
In Solidity, ether can be passed along with a method call which is accessed inside contract as `msg.value`. Sometimes, multiple calculations in a method are performed based on `msg.value` which can be tested with various values using Remix's Custom transaction context. See the example:
Contract/Program to be tested: `Value.sol`
```
pragma solidity >=0.4.22 <0.7.0;
contract Value {
uint256 public tokenBalance;
constructor() public {
tokenBalance = 0;
}
function addValue() payable public {
tokenBalance = tokenBalance + (msg.value/10);
}
function getTokenBalance() view public returns (uint256) {
return tokenBalance;
}
}
```
Test contract/program: `Value_test.sol`
```
pragma solidity >=0.4.22 <0.7.0;
import "remix_tests.sol";
import "./Value.sol";
contract ValueTest{
Value v;
function beforeAll() public {
// create a new instance of Value contract
v = new Value();
}
/// Test initial balance
function testInitialBalance() public {
// initially token balance should be 0
Assert.equal(v.getTokenBalance(), 0, 'token balance should be 0 initially');
}
/// For Solidity version greater than 0.6.1
/// Test 'addValue' execution by passing custom ether amount
/// #value: 200
function addValueOnce() public payable {
// check if value is same as provided through devdoc
Assert.equal(msg.value, 200, 'value should be 200');
// execute 'addValue'
v.addValue{gas: 40000, value: 200}(); // introduced in Solidity version 0.6.2
// As per the calculation, check the total balance
Assert.equal(v.getTokenBalance(), 20, 'token balance should be 20');
}
/// For Solidity version less than 0.6.2
/// Test 'addValue' execution by passing custom ether amount again using low level call
/// #value: 100
function addValueAgain() public payable {
Assert.equal(msg.value, 100, 'value should be 100');
bytes memory methodSign = abi.encodeWithSignature('addValue()');
(bool success, bytes memory data) = address(v).call.gas(40000).value(100)(methodSign);
Assert.equal(success, true, 'execution should be successful');
Assert.equal(v.getTokenBalance(), 30, 'token balance should be 30');
}
}
```

@ -1,6 +1,7 @@
import React from 'react' // eslint-disable-line
import { RunTabUI } from '@remix-ui/run-tab'
import { ViewPlugin } from '@remixproject/engine-web'
import { addressToString } from '@remix-ui/helper'
import * as packageJson from '../../../../../package.json'
const EventManager = require('../../lib/events')
@ -18,7 +19,7 @@ const profile = {
version: packageJson.version,
permission: true,
events: ['newTransaction'],
methods: ['createVMAccount', 'sendTransaction', 'getAccounts', 'pendingTransactionsCount', 'getSettings', 'setEnvironmentMode', 'clearAllInstances', 'addInstance']
methods: ['createVMAccount', 'sendTransaction', 'getAccounts', 'pendingTransactionsCount', 'getSettings', 'setEnvironmentMode', 'clearAllInstances', 'addInstance', 'resolveContractAndAddInstance']
}
export class RunTab extends ViewPlugin {
@ -163,4 +164,11 @@ export class RunTab extends ViewPlugin {
readFile (fileName) {
return this.call('fileManager', 'readFile', fileName)
}
resolveContractAndAddInstance (contractObject, address) {
const data = this.compilersArtefacts.getCompilerAbstract(contractObject.contract.file)
this.compilersArtefacts.addResolvedContract(addressToString(address), data)
this.addInstance(address, contractObject.abi, contractObject.name)
}
}

@ -3,7 +3,6 @@ import React from 'react' // eslint-disable-line
import Web3 from 'web3'
import { Plugin } from '@remixproject/engine'
import { toBuffer, addHexPrefix } from 'ethereumjs-util'
import { waterfall } from 'async'
import { EventEmitter } from 'events'
import { format } from 'util'
import { ExecutionContext } from './execution-context'
@ -12,6 +11,8 @@ import InjectedProvider from './providers/injected.js'
import NodeProvider from './providers/node.js'
import { execution, EventManager, helpers } from '@remix-project/remix-lib'
import { etherScanLink } from './helper'
import { logBuilder, confirmProxyMsg } from "@remix-ui/helper"
import { cancelProxyMsg } from '@remix-ui/helper'
const { txFormat, txExecution, typeConversion, txListener: Txlistener, TxRunner, TxRunnerWeb3, txHelper } = execution
const { txResultHelper: resultToRemixTx } = helpers
const packageJson = require('../../../../package.json')
@ -113,7 +114,9 @@ export class Blockchain extends Plugin {
const { continueCb, promptCb, statusCb, finalCb } = callbacks
const constructor = selectedContract.getConstructorInterface()
txFormat.buildData(selectedContract.name, selectedContract.object, compilerContracts, true, constructor, args, (error, data) => {
if (error) return statusCb(`creation of ${selectedContract.name} errored: ${error.message ? error.message : error}`)
if (error) {
return statusCb(`creation of ${selectedContract.name} errored: ${error.message ? error.message : error}`)
}
statusCb(`creation of ${selectedContract.name} pending...`)
this.createContract(selectedContract, data, continueCb, promptCb, confirmationCb, finalCb)
@ -127,13 +130,73 @@ export class Blockchain extends Plugin {
const { continueCb, promptCb, statusCb, finalCb } = callbacks
const constructor = selectedContract.getConstructorInterface()
txFormat.encodeConstructorCallAndLinkLibraries(selectedContract.object, args, constructor, contractMetadata.linkReferences, selectedContract.bytecodeLinkReferences, (error, data) => {
if (error) return statusCb(`creation of ${selectedContract.name} errored: ${error.message ? error.message : error}`)
if (error) {
return statusCb(`creation of ${selectedContract.name} errored: ${error.message ? error.message : error}`)
}
statusCb(`creation of ${selectedContract.name} pending...`)
this.createContract(selectedContract, data, continueCb, promptCb, confirmationCb, finalCb)
})
}
async deployProxy (proxyData, implementationContractObject) {
const proxyModal = {
id: 'confirmProxyDeployment',
title: 'ERC1967',
message: `Confirm you want to deploy an ERC1967 proxy contract that is connected to your implementation.
For more info on ERC1967, see https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy`,
modalType: 'modal',
okLabel: 'OK',
cancelLabel: 'Cancel',
okFn: () => {
this.runProxyTx(proxyData, implementationContractObject)
},
cancelFn: () => {
this.call('notification', 'toast', cancelProxyMsg())
},
hideFn: () => null
}
this.call('notification', 'modal', proxyModal)
}
async runProxyTx (proxyData, implementationContractObject) {
const args = { useCall: false, data: proxyData }
const confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => {
// continue using original authorization given by user
continueTxExecution(null)
}
const continueCb = (error, continueTxExecution, cancelCb) => { continueTxExecution() }
const promptCb = (okCb, cancelCb) => { okCb() }
const finalCb = (error, txResult, address, returnValue) => {
if (error) {
const log = logBuilder(error)
return this.call('terminal', 'logHtml', log)
}
return this.call('udapp', 'resolveContractAndAddInstance', implementationContractObject, address)
}
this.runTx(args, confirmationCb, continueCb, promptCb, finalCb)
}
async getEncodedFunctionHex (args, funABI) {
return new Promise((resolve, reject) => {
txFormat.encodeFunctionCall(args, funABI, (error, data) => {
if (error) return reject(error)
resolve(data.dataHex)
})
})
}
async getEncodedParams (args, funABI) {
return new Promise((resolve, reject) => {
txFormat.encodeParams(args, funABI, (error, encodedParams) => {
if (error) return reject(error)
return resolve(encodedParams.dataHex)
})
})
}
createContract (selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) {
if (data) {
data.contractName = selectedContract.name
@ -433,55 +496,71 @@ export class Blockchain extends Plugin {
})
}
runTx (args, confirmationCb, continueCb, promptCb, cb) {
waterfall([
(next) => { // getGasLimit
async runTx (args, confirmationCb, continueCb, promptCb, cb) {
const getGasLimit = () => {
return new Promise((resolve, reject) => {
if (this.transactionContextAPI.getGasLimit) {
return this.transactionContextAPI.getGasLimit(next)
return this.transactionContextAPI.getGasLimit((err, value) => {
if (err) return reject(err)
return resolve(value)
})
}
next(null, 3000000)
},
(gasLimit, next) => { // queryValue
return resolve(3000000)
})
}
const queryValue = () => {
return new Promise((resolve, reject) => {
if (args.value) {
return next(null, args.value, gasLimit)
return resolve(args.value)
}
if (args.useCall || !this.transactionContextAPI.getValue) {
return next(null, 0, gasLimit)
return resolve(0)
}
this.transactionContextAPI.getValue(function (err, value) {
next(err, value, gasLimit)
this.transactionContextAPI.getValue((err, value) => {
if (err) return reject(err)
return resolve(value)
})
},
(value, gasLimit, next) => { // getAccount
})
}
const getAccount = () => {
return new Promise((resolve, reject) => {
if (args.from) {
return next(null, args.from, value, gasLimit)
return resolve(args.from)
}
if (this.transactionContextAPI.getAddress) {
return this.transactionContextAPI.getAddress(function (err, address) {
next(err, address, value, gasLimit)
if (err) return reject(err)
return resolve(address)
})
}
this.getAccounts(function (err, accounts) {
if (err) return reject(err)
const address = accounts[0]
if (err) return next(err)
if (!address) return next('No accounts available')
if (!address) return reject('No accounts available')
if (this.executionContext.isVM() && !this.providers.vm.RemixSimulatorProvider.Accounts.accounts[address]) {
return next('Invalid account selected')
return reject('Invalid account selected')
}
next(null, address, value, gasLimit)
return resolve(address)
})
},
(fromAddress, value, gasLimit, next) => { // runTransaction
})
}
const runTransaction = async () => {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
const fromAddress = await getAccount()
const value = await queryValue()
const gasLimit = await getGasLimit()
const tx = { to: args.to, data: args.data.dataHex, useCall: args.useCall, from: fromAddress, value: value, gasLimit: gasLimit, timestamp: args.data.timestamp }
const payLoad = { funAbi: args.data.funAbi, funArgs: args.data.funArgs, contractBytecode: args.data.contractBytecode, contractName: args.data.contractName, contractABI: args.data.contractABI, linkReferences: args.data.linkReferences }
if (!tx.timestamp) tx.timestamp = Date.now()
if (!tx.timestamp) tx.timestamp = Date.now()
const timestamp = tx.timestamp
this.event.trigger('initiatingTransaction', [timestamp, tx, payLoad])
this.txRunner.rawRun(tx, confirmationCb, continueCb, promptCb,
async (error, result) => {
if (error) return next(error)
if (error) return reject(error)
const isVM = this.executionContext.isVM()
if (isVM && tx.useCall) {
@ -500,16 +579,15 @@ export class Blockchain extends Plugin {
try { error = 'error: ' + JSON.stringify(error) } catch (e) { console.log(e) }
}
}
next(error, result, tx)
return resolve({ result, tx })
}
)
}
],
async (error, txResult, tx) => {
if (error) {
return cb(error)
}
})
}
try {
const transaction = await runTransaction()
const txResult = transaction.result
const tx = transaction.tx
/*
value of txResult is inconsistent:
- transact to contract:
@ -517,12 +595,12 @@ export class Blockchain extends Plugin {
- call to contract:
{"result":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionHash":"0x5236a76152054a8aad0c7135bcc151f03bccb773be88fbf4823184e47fc76247"}
*/
const isVM = this.executionContext.isVM()
let execResult
let returnValue = null
if (isVM) {
const hhlogs = await this.web3().eth.getHHLogsForTx(txResult.transactionHash)
if (hhlogs && hhlogs.length) {
let finalLogs = '<b>console.log:</b>\n'
for (const log of hhlogs) {
@ -552,17 +630,19 @@ export class Blockchain extends Plugin {
}
}
}
if (!isVM && tx && tx.useCall) {
returnValue = toBuffer(addHexPrefix(txResult.result))
}
let address = null
if (txResult && txResult.receipt) {
address = txResult.receipt.contractAddress
}
cb(error, txResult, address, returnValue)
})
cb(null, txResult, address, returnValue)
} catch (error) {
cb(error)
}
}
}

File diff suppressed because one or more lines are too long

@ -1,26 +1,77 @@
import { Plugin } from '@remixproject/engine';
import { ContractData } from '../types/contract';
import { ContractABI, ContractAST, DeployOption } from '../types/contract';
import { UUPS, UUPSABI, UUPSBytecode, UUPSfunAbi } from './constants/uups';
const proxyProfile = {
name: 'openzeppelin-proxy',
displayName: 'openzeppelin-proxy',
description: 'openzeppelin-proxy',
methods: ['isConcerned', 'execute']
methods: ['isConcerned', 'execute', 'getDeployOptions']
};
export class OpenZeppelinProxy extends Plugin {
blockchain: any
kind: 'UUPS' | 'Transparent'
constructor(blockchain) {
super(proxyProfile)
this.blockchain = blockchain
}
async isConcerned(contractData: ContractData): Promise<boolean> {
async isConcerned(ast: ContractAST = {} as ContractAST): Promise<boolean> {
// check in the AST if it's an upgradable contract
if (ast.nodes && ast.nodes.find(node => node.absolutePath && node.absolutePath.includes(UUPS))) {
this.kind = 'UUPS'
return true
}
//
// else if transparent contract run check true/false
//
return false
}
async execute(contractData: ContractData, contractMetadata: any, compiledContracts: any) {
async getDeployOptions (contracts: ContractABI): Promise<{ [name: string]: DeployOption }> {
const inputs = {}
if (this.kind === 'UUPS') {
Object.keys(contracts).map(name => {
const abi = contracts[name].abi
const initializeInput = abi.find(node => node.name === 'initialize')
if (initializeInput) {
inputs[name] = {
inputs: initializeInput,
initializeInputs: this.blockchain.getInputs(initializeInput)
}
}
})
}
return inputs
}
async execute(implAddress: string, args: string | string [] = '', initializeABI, implementationContractObject): Promise<void> {
// deploy the proxy, or use an existing one
if (!initializeABI) throw new Error('Cannot deploy proxy: Missing initialize ABI')
args = args === '' ? [] : args
const _data = await this.blockchain.getEncodedFunctionHex(args || [], initializeABI)
if (this.kind === 'UUPS') this.deployUUPSProxy(implAddress, _data, implementationContractObject)
}
async deployUUPSProxy (implAddress: string, _data: string, implementationContractObject): Promise<void> {
const args = [implAddress, _data]
const constructorData = await this.blockchain.getEncodedParams(args, UUPSfunAbi)
const proxyName = 'ERC1967Proxy'
const data = {
contractABI: UUPSABI,
contractByteCode: UUPSBytecode,
contractName: proxyName,
funAbi: UUPSfunAbi,
funArgs: args,
linkReferences: {},
dataHex: UUPSBytecode + constructorData.replace('0x', '')
}
// re-use implementation contract's ABI for UI display in udapp and change name to proxy name.
implementationContractObject.name = proxyName
this.blockchain.deployProxy(data, implementationContractObject)
}
}

@ -3,8 +3,8 @@ export interface FuncABI {
type: string,
inputs: { name: string, type: string }[],
stateMutability: string,
payable: boolean,
constant: any
payable?: boolean,
constant?: any
}
export interface ContractData {
@ -20,4 +20,135 @@ export interface ContractData {
getConstructorInputs: () => any,
isOverSizeLimit: () => boolean,
metadata: any
}
}
export interface ContractAST {
id: number,
absolutePath: string,
exportedSymbols: {
[key: string]: number[]
},
license: string,
nodeType: string,
src: string,
nodes: {
id: number,
literals: string[],
nodeType: string,
src: string,
absolutePath?: string,
file?: string,
nameLocation?: string,
scope?: number,
srcUnit?: number,
unitAlias?: string,
symbolAliases?: any[],
abstract?: boolean,
baseContracts?: any[],
contractDependencies?: any[],
contractKind?: string,
fullyImplemented?: boolean,
linearizedBaseContracts?: number[],
name?: string,
usedErrors?: any[]
}[]
}
export interface ContractABI {
[key: string]: {
abi: ({
inputs: never[];
stateMutability: string;
type: string;
anonymous?: undefined;
name?: undefined;
outputs?: undefined;
} | {
anonymous: boolean;
inputs: {
indexed: boolean;
internalType: string;
name: string;
type: string;
}[];
name: string;
type: string;
stateMutability?: undefined;
outputs?: undefined;
} | {
inputs: {
internalType: string;
name: string;
type: string;
}[];
name: string;
outputs: {
internalType: string;
name: string;
type: string;
}[];
stateMutability: string;
type: string;
anonymous?: undefined;
})[];
devdoc: {
kind: string;
methods: {
[key: string]: {
[key: string]: string
}
};
version: number;
};
evm: any
metadata: string;
storageLayout: {
storage: {
astId: number;
contract: string;
label: string;
offset: number;
slot: string;
type: string;
}[];
types: {
[key: string]: {
base: string;
encoding: string;
label: string;
numberOfBytes: string;
members?: {
astId: number;
contract: string;
label: string;
offset: number;
slot: string;
type: string;
}[];
};
};
};
userdoc: {
kind: string;
methods: any;
version: number;
};
};
}
export type DeployOption = {
initializeInputs: string,
inputs: {
inputs: {
internalType?: string,
name: string,
type: string
}[],
name: "initialize",
outputs?: any[],
stateMutability: string,
type: string,
payable?: boolean,
constant?: any
}
}

@ -38,26 +38,40 @@ export function encodeData (funABI, values, contractbyteCode) {
export function encodeParams (params, funAbi, callback) {
let data: Buffer | string = ''
let dataHex = ''
let funArgs
if (params.indexOf('raw:0x') === 0) {
let funArgs = []
if (Array.isArray(params)) {
funArgs = params
if (funArgs.length > 0) {
try {
data = encodeParamsHelper(funAbi, funArgs)
dataHex = data.toString()
} catch (e) {
return callback('Error encoding arguments: ' + e)
}
}
if (data.slice(0, 9) === 'undefined') {
dataHex = data.slice(9)
}
if (data.slice(0, 2) === '0x') {
dataHex = data.slice(2)
}
} else if (params.indexOf('raw:0x') === 0) {
// in that case we consider that the input is already encoded and *does not* contain the method signature
dataHex = params.replace('raw:0x', '')
data = Buffer.from(dataHex, 'hex')
} else {
try {
params = params.replace(/(^|,\s+|,)(\d+)(\s+,|,|$)/g, '$1"$2"$3') // replace non quoted number by quoted number
params = params.replace(/(^|,\s+|,)(0[xX][0-9a-fA-F]+)(\s+,|,|$)/g, '$1"$2"$3') // replace non quoted hex string by quoted hex string
funArgs = JSON.parse('[' + params + ']')
funArgs = parseFunctionParams(params)
} catch (e) {
return callback('Error encoding arguments: ' + e)
}
if (funArgs.length > 0) {
try {
try {
if (funArgs.length > 0) {
data = encodeParamsHelper(funAbi, funArgs)
dataHex = data.toString()
} catch (e) {
return callback('Error encoding arguments: ' + e)
}
} catch (e) {
return callback('Error encoding arguments: ' + e)
}
if (data.slice(0, 9) === 'undefined') {
dataHex = data.slice(9)
@ -396,7 +410,7 @@ export function decodeResponse (response, fnabi) {
}
export function parseFunctionParams (params) {
let args = []
const args = []
// Check if parameter string starts with array or string
let startIndex = isArrayOrStringStart(params, 0) ? -1 : 0
for (let i = 0; i < params.length; i++) {
@ -431,29 +445,27 @@ export function parseFunctionParams (params) {
if (bracketCount !== 0 && j === params.length - 1) {
throw new Error('invalid tuple params')
}
if (bracketCount === 0) break
}
// If bracketCount = 0, it means complete array/nested array parsed, push it to the arguments list
args.push(JSON.parse(params.substring(i, j)))
args.push(parseFunctionParams(params.substring(i + 1, j)))
i = j - 1
} else if (params.charAt(i) === ',') {
// if startIndex >= 0, it means a parameter was being parsed, it can be first or other parameter
} else if (params.charAt(i) === ',' || i === params.length - 1) { // , or end of string
// if startIndex >= 0, it means a parameter was being parsed, it can be first or other parameter
if (startIndex >= 0) {
args.push(params.substring(startIndex, i))
let param = params.substring(startIndex, i === params.length - 1 ? undefined : i)
const trimmed = param.trim()
if (param.startsWith('0x')) param = `${param}`
if (/[0-9]/g.test(trimmed)) param = `${trimmed}`
if (typeof param === 'string') {
if (trimmed === 'true') param = true
if (trimmed === 'false') param = false
}
args.push(param)
}
// Register start index of a parameter to parse
startIndex = isArrayOrStringStart(params, i + 1) ? -1 : i + 1
} else if (startIndex >= 0 && i === params.length - 1) {
// If start index is registered and string is completed (To handle last parameter)
args.push(params.substring(startIndex, params.length))
}
}
args = args.map(e => {
if (!Array.isArray(e)) {
return e.trim()
} else {
return e
}
})
return args
}

@ -35,7 +35,7 @@ tape('ContractParameters - (TxFormat.buildData) - format input parameters', func
function testWithInput (st, params, expected) {
txFormat.buildData('uintContractTest', context.contract, context.output.contracts, true, context.contract.abi[0], params, (error, data) => {
if (error) { return st.fails(error) }
if (error) { return st.fail(error) }
console.log(data)
if (!data.dataHex.endsWith(expected)) {
st.fail(`result of buildData ${data.dataHex} should end with ${expected} . `)
@ -62,7 +62,7 @@ tape('ContractStringParameters - (TxFormat.buildData) - format string input para
function testWithStringInput (st, params, expected) {
txFormat.buildData('stringContractTest', context.contract, context.output.contracts, true, context.contract.abi[0], params, (error, data) => {
if (error) { return st.fails(error) }
if (error) { return st.fail(error) }
console.log(data)
if (!data.dataHex.endsWith(expected)) {
st.fail(`result of buildData ${data.dataHex} should end with ${expected} . `)
@ -88,7 +88,7 @@ tape('ContractArrayParameters - (TxFormat.buildData) - format array input parame
function testWithArrayInput (st, params, expected) {
txFormat.buildData('arrayContractTest', context.contract, context.output.contracts, true, context.contract.abi[0], params, (error, data) => {
if (error) { return st.fails(error) }
if (error) { return st.fail(error) }
console.log(data)
if (!data.dataHex.endsWith(expected)) {
st.fail(`result of buildData ${data.dataHex} should end with ${expected} . `)
@ -113,7 +113,7 @@ tape('ContractNestedArrayParameters - (TxFormat.buildData) - format nested array
function testWithNestedArrayInput (st, params, expected) {
txFormat.buildData('nestedArrayContractTest', context.contract, context.output.contracts, true, context.contract.abi[4], params, (error, data) => {
if (error) {
return st.fails(error)
return st.fail(error)
}
console.log(data)
if (!data.dataHex.endsWith(expected)) {
@ -185,7 +185,7 @@ function testLinkLibrary (st, fakeDeployedContracts, callbackDeployLibraries) {
const deployMsg = ['creation of library test.sol:lib1 pending...',
'creation of library test.sol:lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2_lib2 pending...']
txFormat.buildData('testContractLinkLibrary', context.contract, context.output.contracts, true, context.contract.abi[0], '', (error, data) => {
if (error) { return st.fails(error) }
if (error) { return st.fail(error) }
console.log(data)
const linkedbyteCode = data.dataHex
let libReference = context.contract.evm.bytecode.linkReferences['test.sol']['lib1']

@ -84,3 +84,13 @@ export const recursivePasteToastMsg = () => (
File(s) to paste is an ancestor of the destination folder
</div>
)
export const logBuilder = (msg: string) => {
return <pre>{msg}</pre>
}
export const cancelProxyMsg = () => (
<div>
<b>Proxy deployment cancelled.</b>
</div>
)

@ -0,0 +1,135 @@
import { shortenAddress, web3Dialog } from "@remix-ui/helper"
import { RunTab } from "../types/run-tab"
import { clearInstances, setAccount, setExecEnv } from "./actions"
import { displayNotification, displayPopUp, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, setExternalEndpoint, setMatchPassphrase, setPassphrase } from "./payload"
export const updateAccountBalances = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
const accounts = plugin.REACT_API.accounts.loadedAccounts
Object.keys(accounts).map((value) => {
plugin.blockchain.getBalanceInEther(value, (err, balance) => {
if (err) return
const updated = shortenAddress(value, balance)
accounts[value] = updated
})
})
dispatch(fetchAccountsListSuccess(accounts))
}
export const fillAccountsList = async (plugin: RunTab, dispatch: React.Dispatch<any>) => {
try {
dispatch(fetchAccountsListRequest())
const promise = plugin.blockchain.getAccounts()
promise.then(async (accounts: string[]) => {
const loadedAccounts = {}
if (!accounts) accounts = []
// allSettled is undefined..
// so the current promise (all) will finish when:
// - all the promises resolve
// - at least one reject
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
await (Promise as any).all(accounts.map((account) => {
return new Promise((resolve, reject) => {
plugin.blockchain.getBalanceInEther(account, (err, balance) => {
if (err) return reject(err)
const updated = shortenAddress(account, balance)
loadedAccounts[account] = updated
resolve(account)
})
})
}))
const provider = plugin.blockchain.getProvider()
if (provider === 'injected') {
const selectedAddress = plugin.blockchain.getInjectedWeb3Address()
if (!(Object.keys(loadedAccounts).includes(selectedAddress))) setAccount(dispatch, null)
}
dispatch(fetchAccountsListSuccess(loadedAccounts))
}).catch((e) => {
dispatch(fetchAccountsListFailed(e.message))
})
} catch (e) {
dispatch(displayPopUp(`Cannot get account list: ${e}`))
}
}
export const setFinalContext = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
// set the final context. Cause it is possible that this is not the one we've originaly selected
const value = _getProviderDropdownValue(plugin)
setExecEnv(dispatch, value)
clearInstances(dispatch)
}
const _getProviderDropdownValue = (plugin: RunTab): string => {
const provider = plugin.blockchain.getProvider()
const fork = plugin.blockchain.getCurrentFork()
return provider === 'vm' ? provider + '-' + fork : provider
}
export const setExecutionContext = (plugin: RunTab, dispatch: React.Dispatch<any>, executionContext: { context: string, fork: string }) => {
const displayContent = web3Dialog(plugin.REACT_API.externalEndpoint, (endpoint: string) => {
dispatch(setExternalEndpoint(endpoint))
})
plugin.blockchain.changeExecutionContext(executionContext, () => {
plugin.call('notification', 'modal', {
id: 'envNotification',
title: 'External node request',
message: displayContent,
okLabel: 'OK',
cancelLabel: 'Cancel',
okFn: () => {
plugin.blockchain.setProviderFromEndpoint(plugin.REACT_API.externalEndpoint, executionContext, (alertMsg) => {
if (alertMsg) plugin.call('notification', 'toast', alertMsg)
setFinalContext(plugin, dispatch)
})
},
cancelFn: () => {
setFinalContext(plugin, dispatch)
}
})
}, (alertMsg) => {
plugin.call('notification', 'toast', alertMsg)
}, () => { setFinalContext(plugin, dispatch) })
}
export const createNewBlockchainAccount = async (plugin: RunTab, dispatch: React.Dispatch<any>, cbMessage: JSX.Element) => {
plugin.blockchain.newAccount(
'',
(cb) => {
dispatch(displayNotification('Enter Passphrase', cbMessage, 'OK', 'Cancel', async () => {
if (plugin.REACT_API.passphrase === plugin.REACT_API.matchPassphrase) {
cb(plugin.REACT_API.passphrase)
} else {
dispatch(displayNotification('Error', 'Passphase does not match', 'OK', null))
}
setPassphrase('')
setMatchPassphrase('')
}, () => {}))
},
async (error, address) => {
if (error) {
return dispatch(displayPopUp('Cannot create an account: ' + error))
}
dispatch(displayPopUp(`account ${address} created`))
await fillAccountsList(plugin, dispatch)
}
)
}
export const signMessageWithAddress = (plugin: RunTab, dispatch: React.Dispatch<any>, account: string, message: string, modalContent: (hash: string, data: string) => JSX.Element, passphrase?: string) => {
plugin.blockchain.signMessage(message, account, passphrase, (err, msgHash, signedData) => {
if (err) {
return displayPopUp(err)
}
dispatch(displayNotification('Signed Message', modalContent(msgHash, signedData), 'OK', null, () => {}, null))
})
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save