{"id":15676790,"url":"https://github.com/tintinweb/solidity-doppelganger","last_synced_at":"2025-07-20T12:05:43.962Z","repository":{"id":57365924,"uuid":"313656483","full_name":"tintinweb/solidity-doppelganger","owner":"tintinweb","description":null,"archived":false,"fork":false,"pushed_at":"2023-10-13T10:34:55.000Z","size":1422,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-16T03:13:43.284Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tintinweb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-17T15:09:38.000Z","updated_at":"2022-12-05T09:12:45.000Z","dependencies_parsed_at":"2024-06-19T01:33:09.261Z","dependency_job_id":"47f818bd-b494-4561-aa94-72d57addd380","html_url":"https://github.com/tintinweb/solidity-doppelganger","commit_stats":{"total_commits":21,"total_committers":1,"mean_commits":21.0,"dds":0.0,"last_synced_commit":"5f2f456063b1364a412b26417dd4cc4b384af21b"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/tintinweb/solidity-doppelganger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tintinweb%2Fsolidity-doppelganger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tintinweb%2Fsolidity-doppelganger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tintinweb%2Fsolidity-doppelganger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tintinweb%2Fsolidity-doppelganger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tintinweb","download_url":"https://codeload.github.com/tintinweb/solidity-doppelganger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tintinweb%2Fsolidity-doppelganger/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266120249,"owners_count":23879285,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T16:05:34.003Z","updated_at":"2025-07-20T12:05:43.949Z","avatar_url":"https://github.com/tintinweb.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[\u003cimg width=\"200\" alt=\"get in touch with Consensys Diligence\" src=\"https://user-images.githubusercontent.com/2865694/56826101-91dcf380-685b-11e9-937c-af49c2510aa0.png\"\u003e](https://diligence.consensys.net)\u003cbr/\u003e\n\u003csup\u003e\n[[  🌐  ](https://diligence.consensys.net)  [  📩  ](https://github.com/ConsenSys/vscode-solidity-doppelganger/blob/master/mailto:diligence@consensys.net)  [  🔥  ](https://consensys.github.io/diligence/)]\n\u003c/sup\u003e\u003cbr/\u003e\u003cbr/\u003e\n\n\n# Solidity Doppelgaenger\n\n[🌐](https://www.npmjs.com/package/solidity-doppelganger) `npm install solidity-doppelganger` \n\nA tool to check if a contract is similar to a set of known/common contracts stored in a DB. E.g. quickly check if a contract `SafeMath` was copied from a reputable source without having to manually check it.\n\nAllows for `strict/exact` and `fuzzy` AST based Doppelgänger detection.\n\n## Example\n\n### Setup\n\n```javascript\n// Import\nconst { SolidityDoppelganger, HASH_MODES } = require('./SolidityDoppelganger');\n```\n\n### Input is Solidity SourceCode\n\n```js\n// Import: \nconst fs = require(\"fs\");\n\nfs.readFile(fpath, (err, data) =\u003e {\n    if (err) {\n        console.error(`ERROR processing file '${fpath}': ${err}`);\n        return;\n    }\n    let selectedModes = Array(...new Set(options.modes.split(',').filter(m =\u003e HASH_MODES.includes(m))));\n    let dupeFinder = new SolidityDoppelganger({ modes: selectedModes });\n\n    /**\n     *  Optionally hash inputs and print them\n     * */\n    dupeFinder.hashSourceCode(data.toString('utf-8'))\n        .then(results =\u003e\n            results.forEach(r =\u003e\n                r.then(x =\u003e {\n                    // Result Object\n                    let result = {\n                        name: x.name,\n                        hash: x.hash,\n                        options: x.options,\n                        path: `${fpath}`\n                    };\n                    console.log(JSON.stringify(result));\n                })\n            )\n        );\n\n    /**\n     * Compare sourceCode with database\n     * */\n    dupeFinder.compareSourceCode(data.toString('utf-8'), fpath)\n        .then(results =\u003e {\n            Object.keys(results.results).forEach(contractName =\u003e {\n                // results per contract and path\n                let resultobj = results.results[contractName];\n                console.log(`**** MATCH ****: ${resultobj.target.path} :: ${resultobj.target.name}`);\n                for (let m of resultobj.matches) {\n                    console.log(`    :: ${m.name} :: ${m.path}  (mode=${m.options.mode})`);\n                }\n            });\n        });\n\n });\n```\n\n### Input is Contract AST\n\n```javascript\n/*\n    print codehashes\n*/\nif (options.print) {\n    dupeFinder.hashSourceCode(data.toString('utf-8'))\n        .then(results =\u003e {\n            results.forEach(x =\u003e {\n                let result = {\n                    name: x.name,\n                    hash: x.hash,\n                    options: x.options,\n                    path: `${options.basePath}${fpath}`\n                };\n                console.log(JSON.stringify(result));\n            });\n        });\n}\n/*\n    find similar contracts\n*/\nif (options.compare) {\n    dupeFinder.compareSourceCode(data.toString('utf-8'), fpath)\n        .then(results =\u003e {\n            Object.keys(results.results).forEach(contractName =\u003e {\n                let resultobj = results.results[contractName];\n                console.log(`**** MATCH ****: ${resultobj.target.path} :: ${resultobj.target.name}`);\n                for (let m of resultobj.matches) {\n                    console.log(`    :: ${m.name} :: ${m.path}  (mode=${m.options.mode})`);\n                }\n            });\n        });\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftintinweb%2Fsolidity-doppelganger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftintinweb%2Fsolidity-doppelganger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftintinweb%2Fsolidity-doppelganger/lists"}