Skip to content

Instantly share code, notes, and snippets.

@dmdque
Created February 18, 2019 05:24
Show Gist options
  • Save dmdque/fe425295be4794bf15bf62bd7e6d8f3e to your computer and use it in GitHub Desktop.
Save dmdque/fe425295be4794bf15bf62bd7e6d8f3e to your computer and use it in GitHub Desktop.
const explorer = require('sol-explore');
const SolidityParser = require('solparse');
const _ = require('underscore');
const soltar = require('soltar');
const Web3 = require('web3');
const web3 = new Web3();
function generateFunctionSignatures(file) {
const ast = SolidityParser.parseFile(`${file}`, false);
// Preprocess with table for structs
let structSignatureTable = {};
explorer.traverse(ast, (node, parent) => {
if (node.type === 'StructDeclaration') {
let structName = node.name;
let structSignature = '(';
let structTypes = _.map(node.body, _.property(['literal', 'literal']));
structSignature += structTypes.join(',');
structSignature += ')';
structSignatureTable[structName] = structSignature;
}
});
let functionSignatureList = [];
explorer.traverse(ast, (node, parent) => {
if (node.type === 'FunctionDeclaration') {
let functionSignature = '';
functionSignature += node.name + '(';
let params = [];
_.each(node.params, (param) => {
// Handle struct types
let type = _.property(['literal', 'literal'])(param);
// Hack for struct defined in other contract
if (_.property(['literal', 'members'])(param).length > 0) {
type = _.property(['literal', 'members'])(param)[0];
}
if (_.contains(Object.keys(structSignatureTable), type)) {
type = structSignatureTable[type];
}
// Handle multi-dimensional arrays
for (let i = 0; i < param.literal.array_parts.length; i++) {
type += '[]';
}
params.push(type);
});
functionSignature += params.join(',');
functionSignature += ')';
functionSignatureList.push(functionSignature);
}
});
return functionSignatureList;
}
function computeFunctionSelector(functionSignature) {
let functionSelector = web3.utils.keccak256(functionSignature).substring(0, 10); // 10 because '0x' is included
return functionSelector;
}
// Main
let functionSignatureList = generateFunctionSignatures('./contracts/Forwarder.sol')
_.each(functionSignatureList, (functionSignature, index) => {
let functionSelector = computeFunctionSelector(functionSignature);
console.log(`${functionSelector}: ${functionSignature}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment