Skip to content

Commit a09acb9

Browse files
authored
feat: add verification functionality (#71)
* feat: add source code verification * fix: ci * fix: sticky * fix: bugs
1 parent 37e4d3c commit a09acb9

File tree

22 files changed

+736
-115
lines changed

22 files changed

+736
-115
lines changed

.github/workflows/cloud-run.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545
RPC_URL=${{secrets.RPC_TEST_URL}},
4646
REDIS_URL=${{secrets.REDIS_TEST_URL}},
4747
USER_SERVICE_URL=https://user.test.etdstatsapi.net
48+
SOLIDITY_SERVICE_URL=https://functions.etdstatsapi.net/api/solidity/compile
4849
region: asia-southeast1
4950
flags: --allow-unauthenticated
5051

.github/workflows/release.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
file: ./docker/services/service.dockerfile
3131
platforms: linux/amd64
3232
push: true
33-
tags: ghcr.io/${{ github.repository }}/${{ matrix.app }}:${{ github.event.release.tag_name }},gcr.io/${{ secrets.GCP_PROJECT_ID }}/${{ matrix.app }}:${{ github.event.release.tag_name }}
33+
tags: ghcr.io/${{ github.repository }}/${{ matrix.app }}:${{ github.event.release.tag_name }}
3434
build-args: |
3535
APP_NAME=${{ matrix.app }}
3636
cache-from: type=gha

apps/etdstats/lib/components/display/contract/ByteCodeDisplay.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
import { Card, CardContent, Stack, Typography } from "@mui/material";
2+
import useCbor from "../../../hooks/useCbor";
23

34
interface Props {
45
bytecode: string;
56
}
67

78
export default function ByteCodeDisplay({ bytecode }: Props) {
9+
const decodedData = useCbor(bytecode);
10+
811
return (
9-
<Stack>
12+
<Stack spacing={2}>
13+
<Typography fontWeight={"bold"}>Metadata</Typography>
14+
<Card variant="outlined" sx={{ boxShadow: "none" }}>
15+
<CardContent>
16+
<pre>{JSON.stringify(decodedData, null, 4)}</pre>
17+
</CardContent>
18+
</Card>
19+
<Typography fontWeight={"bold"}>ByteCode</Typography>
1020
<Card variant="outlined" sx={{ boxShadow: "none" }}>
1121
<CardContent>
1222
<Typography sx={{ wordWrap: "break-word" }}>{bytecode}</Typography>

apps/etdstats/lib/hooks/useCbor.tsx

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from "react";
2+
import cbor from "cbor";
3+
4+
function getMetadataBytes(bytecode: string) {
5+
// get last 4 bytes of bytecode
6+
const metadataLength = bytecode.slice(-4);
7+
// convert to decimal
8+
const metadataLengthDecimal = parseInt(metadataLength, 16);
9+
// get metadata bytes
10+
const metadataBytes = bytecode.slice(-metadataLengthDecimal * 2 - 4, -4);
11+
return metadataBytes;
12+
}
13+
14+
function parseMetadata(metadataBytes: string) {
15+
const metadata = cbor.decode(Buffer.from(metadataBytes, "hex"));
16+
return metadata;
17+
}
18+
19+
function covertBufferObjectToHexObject(object: any) {
20+
const hexObject: any = {};
21+
for (const key in object) {
22+
if (object.hasOwnProperty(key)) {
23+
const element = object[key];
24+
if (Buffer.isBuffer(element)) {
25+
hexObject[key] = element.toString("hex");
26+
} else {
27+
hexObject[key] = element;
28+
}
29+
}
30+
}
31+
return hexObject;
32+
}
33+
34+
export default function useCbor(bytecode: string) {
35+
const [decodedData, setDecodedData] = React.useState<any | undefined>();
36+
37+
React.useEffect(() => {
38+
if (bytecode) {
39+
const metadataBytes = getMetadataBytes(bytecode);
40+
const metadata = parseMetadata(metadataBytes);
41+
const hexObject = covertBufferObjectToHexObject(metadata);
42+
setDecodedData(hexObject);
43+
}
44+
}, [bytecode]);
45+
46+
return decodedData;
47+
}

apps/etdstats/lib/hooks/useContract.tsx

+40-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,25 @@ import { useCallback } from "react";
44
import { useQuery } from "react-query";
55
import useAuthentication from "./useAuthentication";
66

7+
const solcURL = "https://solc-bin.ethereum.org/bin/";
8+
9+
interface VersionList {
10+
builds: {
11+
path: string;
12+
version: string;
13+
longVersion: string;
14+
build: string;
15+
}[];
16+
}
17+
718
export function useContract({ page }: { page: number }) {
819
const { accessToken } = useAuthentication();
920

21+
const solidityVersions = useQuery(["solidity", "versions"], async () => {
22+
const { data } = await axios.get<VersionList>(solcURL + "list.json");
23+
return data;
24+
});
25+
1026
const result = useQuery(["contracts", page], async () => {
1127
const analyticsService = new ContractService({
1228
client: axios,
@@ -55,20 +71,42 @@ export function useContract({ page }: { page: number }) {
5571

5672
const getContract = useCallback(
5773
async (address: string) => {
58-
const analyticsService = new ContractService({
74+
const contractService = new ContractService({
5975
client: axios,
6076
baseUrl: process.env.NEXT_PUBLIC_CONTRACT_API_ENDPOINT!,
6177
});
62-
const response = await analyticsService.getContract(address);
78+
const response = await contractService.getContract(address);
6379
return response;
6480
},
6581
[accessToken]
6682
);
6783

84+
const compile = useCallback(
85+
async (
86+
source: string,
87+
compiler: string | undefined,
88+
contractName: string
89+
) => {
90+
const contractService = new ContractService({
91+
client: axios,
92+
baseUrl: process.env.NEXT_PUBLIC_CONTRACT_API_ENDPOINT!,
93+
});
94+
const response = await contractService.compile(
95+
source,
96+
compiler,
97+
contractName
98+
);
99+
return response;
100+
},
101+
[]
102+
);
103+
68104
return {
69105
contracts: result,
106+
solidityVersions,
70107
search,
71108
update,
72109
getContract,
110+
compile,
73111
};
74112
}

apps/etdstats/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@mui/x-data-grid": "5.17.10",
2222
"@types/react-highlight-words": "0.16.4",
2323
"axios": "1.1.3",
24+
"cbor": "^8.1.0",
2425
"dayjs": "^1.11.6",
2526
"dexie": "3.2.2",
2627
"dexie-react-hooks": "1.1.1",
@@ -42,6 +43,7 @@
4243
"react-highlight-words": "0.18.0",
4344
"react-json-tree": "^0.17.0",
4445
"react-query": "3.39.2",
46+
"react-syntax-highlighter": "^15.5.0",
4547
"recharts": "2.1.16",
4648
"ui": "workspace:*"
4749
},

0 commit comments

Comments
 (0)