The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.
-- Donald Knuth (Computer Programming as an Art; 1974; page 671)
When optimizing C++ code I made heavy use of profiling tools. This gave me insights on which lines of code the running time is spend. More often than not, this was not in the place where I expected it to be.
Solidity is only different in the metric. We are not interested in time, but in gas cost.
What it does
Given a contract address, it will show the Solidity source code with the gas cost for each line in the left margin. The gas cost is the total gas cost for past transaction on the Ethereum main net.
How we built it
It is built using NodeJS, Solc-js, Express, React, etc. It is forked of the 0x monorepo as a starter-kit, but honestly it does not use much of it and can easily be turned into an independent project.
It works as follows:
- The user submits a contract address.
- The contract source code and compilation options is fetched from Etherscan.
- The correct historic version of Solidity is instantiated and the contract is recompiled with sourcemaps.
- The bytecode, sourcemap and sourcecode are parsed to create a mapping from program counter to line of code.
- Execution traces for historical transactions on the contract are fetched using
- Traces are converted to mappings from program counter to gas consumption and aggregated.
- Program counters are mapped to line numbers and aggregated.
- The contract source code is presented with syntax highlighting.
- The gas cost is presented in customizable formats in the margin.
Challenges we ran into
- Internet connectivity.
- Access to healthy drinks and food.
- Access to sanitary facilities.
Accomplishments that we're proud of
What we learned
What's next for Profiler
Code coverage tool: If the profiler is run on unit tests, it effectively becomes a code-coverage tool. If there is gas consumed on a line of code, then it is covered by the tests.
- Support cross-contract calls.
- Statistics on conditional branches.
- Profiler guided optimization in Solidity.