Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Fraunhofer-AISEC/cpg-contract-check…
Browse files Browse the repository at this point in the history
…er into main
  • Loading branch information
konradweiss committed Dec 4, 2023
2 parents 461c361 + 36eca61 commit b95af47
Show file tree
Hide file tree
Showing 88,142 changed files with 989,930 additions and 90,539 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
137 changes: 137 additions & 0 deletions data-collection/snippets/parser/analyze_compiler_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import re
import time
import pprint
import pymongo
import datetime

from web3 import Web3
from tqdm import tqdm
from packaging import version

MONGO_HOST = "sectrs-vascodagama"
MONGO_PORT = 27017

def extract_version(source_code):
versions = re.compile("pragma solidity (.+?);").findall(source_code)
if len(versions) == 0:
return None
v = " ".join(versions)
v = v.replace('"', '')
v = v.replace("\t", "")
v = v.replace(" .", ".")
v = v.replace(". ", ".")
v = v.replace("||", " ")
v = v.replace("-", " ")
v = v.replace("x", "0")
v = v.replace("*", "0")
v = v.replace("^", "")
v = v.replace("~", "")
v = v.replace("=", " ")
v = v.replace(">", " ")
v = v.replace("<", " ")
v = v.replace("=", " ")
v = " ".join(v.split())
v = v.strip()
if len(v.split(" ")) != 1:
min = None
for w in v.split(" "):
if min == None or version.parse(w) < version.parse(min):
min = w
v = min
v = v.replace(".99", ".9")
v = v.replace(".00", ".0")
if len(v.split(".")) == 4:
v = v.replace(".0", "")
if v.endswith(".01"):
v = v.replace(".01", ".1")
if v.endswith(".02"):
v = v.replace(".02", ".2")
if v.endswith(".03"):
v = v.replace(".03", ".3")
if v.endswith(".04"):
v = v.replace(".04", ".4")
if v.endswith(".05"):
v = v.replace(".05", ".5")
if v.endswith(".06"):
v = v.replace(".06", ".6")
if v.endswith(".07"):
v = v.replace(".07", ".7")
if v.endswith(".08"):
v = v.replace(".08", ".8")
if v.endswith(".09"):
v = v.replace(".09", ".9")
if v.startswith("8.") and v.endswith(".0"):
v = "0."+v.replace(".0", "")
if len(v.split(".")) == 2:
v = v+".0"
return v

def main():
solidity_contracts = list()
for root, subdirs, files in os.walk("../../source-code/smart-contract-sanctuary-ethereum"):
for file_name in files:
if file_name.endswith(".sol"):
file_path = os.path.join(root, file_name)
solidity_contracts.append(file_path)

pragmas = dict()
for contract in tqdm(solidity_contracts):
with open(contract, "r") as f:
source_code = f.read()
v = extract_version(source_code)
if v == None:
continue
if not v in pragmas:
pragmas[v] = 0
pragmas[v] += 1

pragmas = dict(sorted(pragmas.items(), key=lambda item: item[1], reverse=True))
for v in pragmas:
print(v, "\t", pragmas[v], pragmas[v] / len(solidity_contracts) * 100)

print()
major_versions = dict()
for v in pragmas:
try:
major_version = v.split(".")[0]+"."+v.split(".")[1]
if not major_version in major_versions:
major_versions[major_version] = 0
major_versions[major_version] += pragmas[v]
except:
pass

major_versions = dict(sorted(major_versions.items(), key=lambda item: item[1], reverse=True))
for v in major_versions:
print(v, "\t", major_versions[v], major_versions[v] / len(solidity_contracts) * 100)

print()
unix_timestamp_start_date = int(time.mktime(datetime.datetime(2023, 5, 1, 0, 0).timetuple()))
unix_timestamp_end_date = int(time.mktime(datetime.datetime(2023, 6, 30, 0, 0).timetuple()))
mongo_connection = pymongo.MongoClient("mongodb://"+MONGO_HOST+":"+str(MONGO_PORT), maxPoolSize=None)
collection = mongo_connection["smart_contract_snippets"]["smart_contract_sanctuary_timestamps"]
cursor = collection.find({"timestamp":{"$gte":unix_timestamp_start_date,"$lte":unix_timestamp_end_date}})
deployments = set()
for document in cursor:
deployments.add(document["contractAddress"])
deployment_versions = dict()
for contract in solidity_contracts:
address = Web3.toChecksumAddress("0x"+contract.split("/")[-1].split("_")[0])
if address.lower() in deployments:
with open(contract, "r") as f:
source_code = f.read()
v = extract_version(source_code)
if v != None:
major_version = v.split(".")[0]+"."+v.split(".")[1]
if not major_version in deployment_versions:
deployment_versions[major_version] = 0
deployment_versions[major_version] += 1
deployment_versions = dict(sorted(deployment_versions.items(), key=lambda item: item[1], reverse=True))
for v in deployment_versions:
print(v, "\t", deployment_versions[v], deployment_versions[v] / len(deployments) * 100)

if __name__ == '__main__':
main()
Loading

0 comments on commit b95af47

Please sign in to comment.