Skip to content

Commit

Permalink
add evmole.xyz redirect
Browse files Browse the repository at this point in the history
  • Loading branch information
cdump committed Nov 13, 2024
1 parent a3ee9b1 commit 58b241e
Showing 1 changed file with 3 additions and 220 deletions.
223 changes: 3 additions & 220 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,227 +3,10 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EVMole Demo</title>
<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js"></script>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/[email protected]/dist/index.css" />
<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/index.full.min.js"></script>
<style>
body {
font-family: Monospace;
}
p, h1 {
margin: 5px 0 5px 0;
}
#app {
max-width: 1400px;
margin: 0 auto;
}
.signature {
display: flex;
padding-right: 1.5em;
}
.lookup{
display: flex;
flex-direction: column;
}
.local_lookup {
display: flex;
align-items: center;
color: #000a7a;
}
.mutability {
padding-left: 0.5em;
font-size: 0.9em;
color: #888899;
}
.remote_lookup {
display: flex;
color: #957676;
}
.results {
padding-top: 30px;
}
.function {
font-family: Monospace;
font-size: 1.3em;
display: flex;
align-items: center;
}
.label {
font-size: 0.5em;
display: flex;
align-items: center;
padding-right: 1em;
}
.local_lookup .label {
padding-left: 2em;
}
</style>
<title>EVMole</title>
<meta http-equiv="refresh" content="0; url=https://evmole.xyz/">
</head>
<body>
<div id="app">
<h1>EVMole demo</h1>

<p>
Function selectors, arguments & mutability: <a href="https://github.com/cdump/evmole" target="_blank">cdump/evmole</a> (v0.5.1)
</p>

<p>
Function signature database: <a href="https://openchain.xyz/signatures" target="_blank">openchain.xyz</a> | RPC: <a href="https://1rpc.io" target="_blank">1rpc.io</a>
</p>

<br>
<b>Contract Address:</b><br>
<el-form :model="addressForm" @validate="address_changed">
<el-form-item prop="address"
:rules="[
{ pattern: /^(0x)?[a-fA-F0-9]{40}$/, message: 'Address must be hex string', trigger: 'change' },
]"
>
<el-input v-model="addressForm.address" placeholder="Address, ex: 0xdac17f958d2ee523a2206206994597c13d831ec7" style="width: 600px">
<template #prepend>
<el-select v-model="addressForm.rpc" placeholder="Chain" style="width: 140px">
<el-option label="Ethereum" value="eth"></el-option>
<el-option label="BNB" value="bnb"></el-option>
<el-option label="Polygon" value="matic"></el-option>
<el-option label="Optimism" value="op"></el-option>
<el-option label="Arbitrum" value="arb"></el-option>
</el-select>
</template>
</el-input>
</el-form-item>
</el-form>

<b>Contract Deployed Bytecode:</b>
<el-skeleton v-if="bytecode_loading" :rows="4"></el-skeleton>
<el-input v-else
v-model="code"
:rows="8"
type="textarea"
placeholder="Please input hex bytecode"
></el-input>

<div class="results">
<template v-for="item in selectors">
<div class="function">
<div class="signature">{{item}}</div>
<div class="lookup">
<div class="local_lookup"><div class="label">evmole:</div>{{'&nbsp;'.repeat((remote_lookup[item] || '(').indexOf('('))}}({{local_lookup[item]?.arguments || ''}})<div class="mutability">{{local_lookup[item]?.mutability || ''}}</div></div>

<el-skeleton v-if="lookup_loading" class="name">
<template #template>
<el-skeleton-item variant="p" style="width: 300px" />
</template>
</el-skeleton>
<div v-else class="remote_lookup"><div class="label">openchain:</div>{{remote_lookup[item] || '?'}}</div>
</div>
</div>
<div style='height: 0; margin: 5px; width: 100%; border-top: 1px dashed #dadada;'></div>
</template>
</div>
</div>
<script type="module">
import {functionSelectors, functionArguments, functionStateMutability} from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/evmole.mjs';

const {ref, reactive, watch, nextTick, createApp} = Vue
const {ElNotification} = ElementPlus
createApp({
setup() {
const addressForm = reactive({
rpc: 'eth',
address: '',
});

const h = location.hash;
if (h != '') {
const hs = h.slice(1).split('/');
if ((hs.length == 1 || hs.length == 2)) {
nextTick(() => {
if (hs[0].length == 42 || hs[0].length == 40) {
addressForm.address = hs[0];
}
if (hs.length == 2) {
addressForm.rpc = hs[1];
}
});
}
}

const code = ref('0x6060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029');
const selectors = ref([]);
const local_lookup = ref({});
const remote_lookup = ref({});
const lookup_loading = ref(false);
const bytecode_loading = ref(false);

async function load_lookup(selectors) {
// await new Promise(r => setTimeout(() => r(), 1000));
// return {"ok":true,"result":{"event":{},"function":{"0xb69ef8a8":[{"name":"balance()","filtered":false}],"0xd0e30db0":[{"name":"deposit()","filtered":false}]}}};
const resp = await fetch(`https://api.openchain.xyz/signature-database/v1/lookup?filter=true&function=` + selectors.join(','));
return await resp.json();
}

async function load_code(rpc, address) {
// await new Promise(r => setTimeout(() => r(), 1000));
// return '0x6080'
const req = {'method':'eth_getCode','params': [address.startsWith('0x') ? address : `0x${address}`,'latest'],'id':1,'jsonrpc':'2.0'}
try {
const resp = await fetch(`https://1rpc.io/${rpc}`, {method: 'POST', headers: {'Content-Type': 'application/json',}, body: JSON.stringify(req)});
if (resp.status != 200) {
throw new Error(`HTTP ${resp.status}`);
}
const j = await resp.json();
return j.result;
} catch(e) {
console.log(e)
ElNotification({
type: 'error',
title: 'Code fetch error',
message: e,
})
return '0x'
}
}

async function address_changed(prop, isValid, message) {
if (!isValid) {
return;
}

const address = addressForm.address;
if (address === '') {
return;
}

location.hash = `${address}/${addressForm.rpc}`;

bytecode_loading.value = true;
code.value = '';
selectors.value = [];
code.value = await load_code(addressForm.rpc, address);
bytecode_loading.value = false;
};

watch(code, async (val) => {
if (val == '') {
return;
}
const codeHex = code.value.trim();
const s = functionSelectors(codeHex).map((v) => `0x${v}`).sort();
selectors.value = s;

local_lookup.value = Object.fromEntries(s.map((s) => [s, {arguments: functionArguments(codeHex, s), mutability: functionStateMutability(codeHex, s)}]));

if (s.length > 0) {
lookup_loading.value = true;
const r = await load_lookup(s);
lookup_loading.value = false;
remote_lookup.value = Object.fromEntries(Object.entries(r.result.function).map(([k, v]) => [k, v ? v[0].name : '']));
}
}, { immediate: true });
return {addressForm, address_changed, code, selectors, local_lookup, remote_lookup, lookup_loading, bytecode_loading}
}
}).use(ElementPlus).mount('#app')
</script>
Now at <a href="https://evmole.xyz">evmole.xyz</a>
</body>
</html>

0 comments on commit 58b241e

Please sign in to comment.