How To Create an Ethereum Automated Smart Contract Auditor for the Web.

These days the cost of auditing an advanced smart contract can range between $50,000–100,000 and sometimes more, plus it often takes months to complete a comprehensive audit. So why not extract most of this process to an automated software auditor? If there is one thing we know as devs, when it comes it verifying complex and highly detailed things such as code, computers have the potential to do a much more efficient job. I am not saying we do not need human security auditors, I just think human auditing should be a final step after a comprehensive automated audit.

To test this idea, I decided to create a free automated web-based smart contract auditor and open source it very similar to the web-based solidity remix compiler. Please keep in mind that this auditor is still primitive and needs a lot of work and hopefully contributions from the blockchain community can help grow it to a mature platform. But I think it has the basic foundations to build on.

Lets jump in. I built the front end of the auditor in React, but this tutorial will focus mostly on the back-end to keep it short and readable. I will start by generally explaining how I created the auditor and then go through an example of how I included auditing logic to the code. Currently the auditor can scan code written in solidity, with plans to expand into Move and Vyper smart contract languages in the future. I will assume you know the basics of react, terminal, node.js, and JavaScript.

Front End : For the front I used React( create-react-app) . Back End: Node.js /java script. Server: I deployed my code to Netflify(serverless). You can also take a look at my web app here and source code here for more details.

1)Basic set up.

Navigate to your preferred directory in command line and create a new react project.

terminal: create-react-app auditorTutorial

Delete all the files in the src folder in your newly created project.

Create an index.js file and a components folder and in it, an app.js file. You can set up your src folder however you prefer, but you can also view mine here.

Install a few modules and libraries. BrowserSolc: a solidity wrapper that can compile smart contracts in the browser. Web3: This will be used to retrieve additional information from the ethereum blockchain, such as estimated gas costs, I used infura as a my provider to connect to an ethereum node.

terminal: npm i BrowserSolc, web3, semantic-ui-react

As I mentioned above, this article will focus mostly on the back-end, so you can create your any front end layout however you wish but if you are using React, it is advisable to use a controlled text component that can store the smart contract text the user inputs. First we need to read the smart contract code pasted in the browser. I used a controlled text area semantic react component as the input of the auditor and its content are stored in state.

example:

state = {value: “ ”, contract: “”};

//update the state of the contract based on the user input
handleChangesToContract=(event)=>{
this.setState({
contract:event.target.value
});
}

render(){<TextArea value= {this.state.contractCode} onChange={this.handleChangesToContract} />}

2)Extract Contract Code and Save in array Format.

//example of when to run the audit, assuming you have a submit button that calls a function

onSubmit(){ let data = this.state.contract;}

Next I used the javascript method ‘.split(“\n”)’ to split the smart contract code into an array based on each new line.

onSubmit(){ let data = this.state.contract;

let dataArray = source.split(“\n”)} ;

3)Compile Code

The backend of the auditor is structured in 2 different parts. First, a solidity compilers runs the smart contract code and provides feed back on any errors and if it compiles successfully , the second is a set of logic that checks for security vulnerabilities.

Make sure BrowserSolc and web3 are defined in your app.js file(or wherever you are compiling the smart contract file) . BrowserSolc can be included as a script in your ‘public.index.html by including :

<script src=”./browser-solc.min.js” type=”text/javascript”></script>

Web3 can be defined your app component:

import Web3 from ‘web3’;

Next we compile our smart contract code which is current saved in state. Mine is stored with the name ‘data’. You will also need an infura account. To set up an account, click here.

//Load a chosen compiler version
window.BrowserSolc.loadVersion(this.state.currentCompiler, async function (compiler){

let optimize = 1;
let result = compiler.compile(data, optimize);

const provider = new Web3.providers.HttpProvider(
‘https://rinkeby.infura.io/v3/(your infura number here)'
)
const web3 = new Web3(provider);

let bytecode = result.contracts[“:SampleContract”].bytecode;

}

With web3 and bytecode from a successful compile, calls can be made to the ethereum blockchain to retrieve additional data such as estimated gas costs.

4) Run Audit on Smart Contract

Create a separate file outside your app component and name it auditor.js . This is the file that will contain all audit logic. We will send our smart contract array to this file, audit it and then send it back to our component. You can define your audit.js file similar to this:

export default(dataArray)=>{

//define a single warning and an array of all discovered warnings

let warn;

let warnings=[];

return warnings;

}

Based on my research, the best sources to find auditing logic are from earlier hacks such as the DAO and Parity hack, and from patterns based on ‘Ethereum Smart Contract Best Practices’ such as the consensys published guidelines for securing smart contracts. For this tutorial we will use the consensys guideline as our source of audit logic.

Let us break down the code to check for a Reentrancy attack, which is relatively common.

Excerpt form the consensys website on reentrancy attacks -

“One of the major dangers of calling external contracts is that they can take over the control flow, and make changes to your data that the calling function wasn’t expecting. This class of bug can take many forms, and both of the major bugs that led to the DAO’s collapse were bugs of this sort.”

“Reentrancy on a Single Function: The first version of this bug to be noticed involved functions that could be called repeatedly, before the first invocation of the function was finished. This may cause the different invocations of the function to interact in destructive ways.”

Basically it is possible to make very quick multiple calls on a contract function before the entire logic of the function in complete. For example, a malicious user can make multiple withdrawals on an account beyond the actual account balance if the account balance(state) is not updated before each withdraw call.

One way to prevent this is is to use send() instead of call.value()(). This will limit any external code from being executed.

To translate this to logic we can simply search our smart contract code array for the set of strings “call.value()()".

//define the string you wish to search for

let dangerousCalls1 = ‘.call.value()’;

//iterate through the smart contract line by line and store all found warnings in //an array

for (let index=0; index<dataArray.length; index++) {
if (dataArray[index].includes(dangerousCalls1)) {
warn = {key:(index), value:”Be aware that using ‘.call.value()’, it is susceptible to re-entry attacks, if possible use send() or transfer(). Also do not forget to set your new account balance before the transfer “};
warnings.push(warn);
}

}

We can then return the results to our component and display all warnings to the user.

This is a very simple example of searching for vulnerabilities within code but basically any pattern can be broken down into building blocks and added into the auditor.js logic. Other factors should also be taken into consideration, such as the string being searched for on a particular line might not all be on the same line, so in the example above, “.call.” and “.value()” might be called on separate lines, so a more detailed check can split the search for each string separately and check the next ‘active’ line if it contains a particular string.

As you might observe, to create a reliable free open public auditor would require quite a comprehensive database of logic which can be accomplished by community contributions to the audit logic.

If you have any ideas on how to contribute to this project or questions, feel free to contact me via website or open an issue on GitHub.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Christopher Igbojekwe

Written by

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +792K followers.

Christopher Igbojekwe

Written by

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +792K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store