├── .DS_Store
├── .babelrc
├── .gitignore
├── .idea
├── misc.xml
├── modules.xml
├── truffle-intellij-debug.iml
├── vcs.xml
└── workspace.xml
├── README.md
├── Screenshots
├── .DS_Store
├── DebugResult.png
├── DebuggerConsole.png
├── EditConfig.png
├── EditRunConfig.png
├── RunExternalTool.png
└── TestResult.png
├── contracts
├── Migrations.sol
└── TruffleIntellijDebug.sol
├── migrations
├── 1_initial_migration.js
└── 2_test_migrations.js
├── package-lock.json
├── package.json
├── scripts
├── setup.sh
└── test.sh
├── test
└── TestIntellijDebug.js
└── truffle-config.js
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/80Trill/truffle-intellij-debug/78e99f07d402224ef1600e4a4e805ea1d0646f7e/.DS_Store
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"]
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | node_modules
3 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/truffle-intellij-debug.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | true
109 | DEFINITION_ORDER
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 | 1524519932504
259 |
260 |
261 | 1524519932504
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 | file://$PROJECT_DIR$/test/TestIntellijDebug.js
326 | 23
327 |
328 |
329 |
330 | file://$PROJECT_DIR$/test/TestIntellijDebug.js
331 | 17
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Using Intellij Debugger for Truffle Testsuites
2 |
3 | Currently when it comes to debugging smart contracts in Solidity, developers must use a plethora of tools to test and debug their code. Unfortunately this is less than desirable, as it can cause unneccesary friction and inefficiency in your workflow. By utilizing some of the configurations inside of Intellij, we have found a way to debug Truffle Javascript test suites inside of the IDE.
4 |
5 | This will allow you to utilize the built in debugger.
6 |
7 | As you can see inside of this example project, this will prove to be invaluable when it comes to testing smart contracts.
8 |
9 |
10 |
11 |
12 | ## Getting Started
13 |
14 | The following instructions will allow you to run a small test suite for demonstration purposes. There is certainly room for improving on the setup, but for now this will open the door to improving the development process for Solidity Smart Contracts.
15 |
16 |
17 |
18 | ### Prerequisites
19 |
20 | This requires an up-to-date installation of the Intellij IDE, the Intellij-Solidity plugin, and NPM.
21 |
22 | ```
23 | https://www.jetbrains.com/idea/
24 | https://plugins.jetbrains.com/plugin/9475-intellij-solidity
25 | ```
26 |
27 |
28 |
29 | ### The Files
30 |
31 | Navigate to the project root and install the dependencies via NPM.
32 |
33 | ```
34 | npm install
35 | ```
36 |
37 | Here is the directory which contains the scripts used to run the debugger. As well as a modified "truffle-config.js"
38 |
39 | ```
40 | "truffle-intellij-debug/scripts/setup.sh"
41 | "truffle-intellij-debug/scripts/test.sh"
42 |
43 | "truffle-intellij-debug/truffle-config.js"
44 | ```
45 |
46 |
47 | ### Applying the Settings
48 |
49 | Inside of edit configurations, you will need to create a new run/debug configuration.
50 |
51 | 
52 | 
53 | ```
54 | Ensure that Command -> run, and Scripts -> test
55 | ```
56 |
57 | 
58 |
59 | ```
60 | Ensure that external tool "start testrpc" has Program -> Setup.sh, and Working Directory -> truffle-intellij-debug
61 | (The relative paths where they are saved on your computer)
62 | ```
63 |
64 | ## Running the Debugger
65 |
66 | Now you should be able to **run** the project scripts and the following should be displayed in the console.
67 |
68 | 
69 | 
70 |
71 |
72 |
73 |
74 |
75 | Inside of the "test/TestIntellijDebug.js" file, you can see the following breakpoints and examine how it works.
76 |
77 | 
78 |
79 |
80 |
81 |
82 |
83 | ### Limitations
84 |
85 | For the foreseeable future, the debugger only allows you to monitor variables inside of the Javascript test files. It cannot display the variables being stored in the .Sol files.
86 |
87 | ### Acknowledgements
88 |
89 | Part of this example uses pieces of OpenZeppelin code.
90 |
91 | ## Authors
92 |
93 | Riley@80trill.com
94 |
95 |
96 | https://80trill.com/
97 |
--------------------------------------------------------------------------------
/Screenshots/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/80Trill/truffle-intellij-debug/78e99f07d402224ef1600e4a4e805ea1d0646f7e/Screenshots/.DS_Store
--------------------------------------------------------------------------------
/Screenshots/DebugResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/80Trill/truffle-intellij-debug/78e99f07d402224ef1600e4a4e805ea1d0646f7e/Screenshots/DebugResult.png
--------------------------------------------------------------------------------
/Screenshots/DebuggerConsole.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/80Trill/truffle-intellij-debug/78e99f07d402224ef1600e4a4e805ea1d0646f7e/Screenshots/DebuggerConsole.png
--------------------------------------------------------------------------------
/Screenshots/EditConfig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/80Trill/truffle-intellij-debug/78e99f07d402224ef1600e4a4e805ea1d0646f7e/Screenshots/EditConfig.png
--------------------------------------------------------------------------------
/Screenshots/EditRunConfig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/80Trill/truffle-intellij-debug/78e99f07d402224ef1600e4a4e805ea1d0646f7e/Screenshots/EditRunConfig.png
--------------------------------------------------------------------------------
/Screenshots/RunExternalTool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/80Trill/truffle-intellij-debug/78e99f07d402224ef1600e4a4e805ea1d0646f7e/Screenshots/RunExternalTool.png
--------------------------------------------------------------------------------
/Screenshots/TestResult.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/80Trill/truffle-intellij-debug/78e99f07d402224ef1600e4a4e805ea1d0646f7e/Screenshots/TestResult.png
--------------------------------------------------------------------------------
/contracts/Migrations.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.4.17;
2 |
3 | contract Migrations {
4 | address public owner;
5 | uint public last_completed_migration;
6 |
7 | modifier restricted() {
8 | if (msg.sender == owner) _;
9 | }
10 |
11 | constructor() public {
12 | owner = msg.sender;
13 | }
14 |
15 | function setCompleted(uint completed) public restricted {
16 | last_completed_migration = completed;
17 | }
18 |
19 | function upgrade(address new_address) public restricted {
20 | Migrations upgraded = Migrations(new_address);
21 | upgraded.setCompleted(last_completed_migration);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/contracts/TruffleIntellijDebug.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.4.19;
2 |
3 |
4 | contract TruffleIntellijDebug {
5 |
6 | uint256[] public ListOfValues;
7 |
8 | address public owner;
9 |
10 | constructor() public {
11 | owner = msg.sender;
12 | }
13 |
14 | function addValue(uint256 valueToAdd) public {
15 | ListOfValues.push(valueToAdd);
16 | }
17 |
18 | function getListOfValues()public constant returns (uint256[]) {
19 | return ListOfValues;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/migrations/1_initial_migration.js:
--------------------------------------------------------------------------------
1 | var Migrations = artifacts.require("./Migrations.sol");
2 |
3 | module.exports = function(deployer) {
4 | deployer.deploy(Migrations);
5 | };
6 |
--------------------------------------------------------------------------------
/migrations/2_test_migrations.js:
--------------------------------------------------------------------------------
1 | var instance = artifacts.require("../contracts/TruffleIntellijDebug.sol");
2 | module.exports = function(deployer) {
3 | deployer.deploy(instance);
4 | };
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "truffle-intellij-debug",
3 | "version": "1.0.0",
4 | "description": "A test contract",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "node $NODE_DEBUG_OPTION ./node_modules/.bin/truffle test",
8 | "deploy": "truffle migrate --reset --network $NETWORK"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {},
13 | "devDependencies": {
14 | "babel-polyfill": "^6.23.0",
15 | "babel-preset-env": "^1.1.8",
16 | "babel-preset-es2015": "^6.18.0",
17 | "babel-preset-stage-2": "^6.18.0",
18 | "babel-preset-stage-3": "^6.17.0",
19 | "babel-register": "^6.23.0",
20 | "chai": "^4.0.2",
21 | "chai-as-promised": "^7.0.0",
22 | "chai-bignumber": "^2.0.0",
23 | "ethereumjs-testrpc": "^6.0.1",
24 | "ethereumjs-util": "^5.1.2",
25 | "truffle": "^4.0.0",
26 | "truffle-hdwallet-provider": "0.0.3",
27 | "zeppelin-solidity": "1.8.0",
28 | "dotenv": "^4.0.0",
29 | "ethjs-abi": "^0.2.1"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/scripts/setup.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Exit script as soon as a command fails.
4 | set -o errexit
5 |
6 | # Executes cleanup function at script exit.
7 | #rm -f ../build/contracts/*
8 |
9 |
10 | if [ -n "$testrpc_pid" ] && ps -p $testrpc_pid > /dev/null; then
11 | kill -9 $testrpc_pid
12 | fi
13 |
14 | testrpc_running() {
15 | nc -z localhost "$testrpc_port"
16 | }
17 |
18 | start_testrpc() {
19 | # We define 10 accounts with balance 1M ether, needed for high-value tests.
20 | local accounts=(
21 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200,1000000000000"
22 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201,1000000000000"
23 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501202,1000000000000"
24 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501203,1000000000000"
25 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501204,1000000000000"
26 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501205,1000000000000000000000000"
27 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501206,1000000000000000000000000"
28 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501207,1000000000000000000000000"
29 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501208,1000000000000000000000000"
30 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501209,1000000000000000000000000"
31 | )
32 | testrpc_pid=$!
33 | }
34 |
35 | if testrpc_running; then
36 | echo "Using existing testrpc instance"
37 | else
38 | echo "Starting our own testrpc instance"
39 | start_testrpc
40 | fi
41 |
42 |
--------------------------------------------------------------------------------
/scripts/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Exit script as soon as a command fails.
4 | set -o errexit
5 |
6 | # Executes cleanup function at script exit.
7 | trap cleanup EXIT
8 | #rm -f build/contracts/*
9 |
10 | cleanup() {
11 | # Kill the testrpc instance that we started (if we started one and if it's still running).
12 | if [ -n "$testrpc_pid" ] && ps -p $testrpc_pid > /dev/null; then
13 | kill -9 $testrpc_pid
14 | fi
15 | }
16 |
17 | testrpc_running() {
18 | nc -z localhost "$testrpc_port"
19 | }
20 |
21 | start_testrpc() {
22 | # We define 10 accounts with balance 1M ether, needed for high-value tests.
23 | local accounts=(
24 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200,1000000000000"
25 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201,1000000000000"
26 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501202,1000000000000"
27 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501203,1000000000000"
28 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501204,1000000000000"
29 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501205,1000000000000000000000000"
30 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501206,1000000000000000000000000"
31 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501207,1000000000000000000000000"
32 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501208,1000000000000000000000000"
33 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501209,1000000000000000000000000"
34 | )
35 | testrpc_pid=$!
36 | }
37 |
38 | if testrpc_running; then
39 | echo "Using existing testrpc instance"
40 | else
41 | echo "Starting our own testrpc instance"
42 | start_testrpc
43 | fi
44 |
45 |
--------------------------------------------------------------------------------
/test/TestIntellijDebug.js:
--------------------------------------------------------------------------------
1 | var debug = artifacts.require("./TruffleIntellijDebug.sol");
2 |
3 | contract('TestIntellijDebug', function(accounts) {
4 |
5 | it("This is a test", async function() {
6 | let instance = await debug.new();
7 |
8 | let owner = accounts[0];
9 |
10 | let a = 1;
11 | let b = 2;
12 | let c = 3;
13 |
14 | await instance.addValue(a);
15 | await instance.addValue(b);
16 | await instance.addValue(c);
17 |
18 | let listOfValues = await instance.getListOfValues.call();
19 | let ownerActual = await instance.owner();
20 |
21 | assert.equal(owner, ownerActual, "The owners address was not stored properly");
22 | assert.equal(listOfValues[0], a, 'The value in listOfValues is not stored properly');
23 | assert.equal(listOfValues[1], b, 'The value in listOfValues is not stored properly');
24 | assert.equal(listOfValues[2], c, 'The value in listOfValues is not stored properly');
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/truffle-config.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | require("babel-register")({
3 | // Ignore can also be specified as a function.
4 | ignore: function(filename) {
5 | if (filename.indexOf("node_modules/zeppelin-solidity") !== -1 || filename.indexOf("truffle-intellij-debug/contracts") !== -1 || filename.indexOf("truffle-intellij-debug/test") !== -1 ) {
6 | return false;
7 | } else {
8 | return true;
9 | }
10 | },
11 |
12 | });require('babel-polyfill');
13 |
14 | const HDWalletProvider = require('truffle-hdwallet-provider');
15 |
16 | const providerWithMnemonic = (mnemonic, rpcEndpoint) =>
17 | new HDWalletProvider(mnemonic, rpcEndpoint);
18 |
19 | const infuraProvider = network => providerWithMnemonic(
20 | process.env.MNEMONIC || '',
21 | `https://${network}.infura.io/${process.env.INFURA_API_KEY}`
22 | );
23 |
24 | const ropstenProvider = process.env.SOLIDITY_COVERAGE
25 | ? undefined
26 | : infuraProvider('ropsten');
27 |
28 | module.exports = {
29 | networks: {
30 | development: {
31 | host: 'localhost',
32 | port: 8545,
33 | network_id: '*', // eslint-disable-line camelcase
34 | gasPrice:0x01
35 | },
36 | ropsten: {
37 | provider: ropstenProvider,
38 | network_id: 3, // eslint-disable-line camelcase
39 | gas: 4612388
40 | },
41 | coverage: {
42 | host: 'localhost',
43 | network_id: '*', // eslint-disable-line camelcase
44 | port: 8555,
45 | },
46 | testrpc: {
47 | host: 'localhost',
48 | port: 8545,
49 | network_id: '*', // eslint-disable-line camelcase
50 | gasPrice:0x01
51 | },
52 | ganache: {
53 | host: 'localhost',
54 | port: 7545,
55 | network_id: '*', // eslint-disable-line camelcase
56 | gasPrice:0x01
57 | },
58 | },
59 | };
60 |
--------------------------------------------------------------------------------