2021-08-12 09:58:13 +00:00
|
|
|
//
|
|
|
|
// Copyright 2021 Vulcanize, Inc.
|
|
|
|
//
|
|
|
|
|
2021-06-16 10:44:35 +00:00
|
|
|
{
|
|
|
|
minVanityAddressLength: 35,
|
|
|
|
|
|
|
|
excludedAddresses: [
|
|
|
|
"0x0000000000000000000000000000000000000000",
|
|
|
|
"0xffffffffffffffffffffffffffffffffffffffff"
|
|
|
|
],
|
|
|
|
|
|
|
|
// Known vanity addresses. Empty by default, but can replace this object when making dynamic requests.
|
|
|
|
// Burner addresses go here too.
|
|
|
|
knownVanityAddresses: {
|
|
|
|
// "0x000026b86Ac8B3c08ADDEeacd7ee19e807D94742": true
|
|
|
|
},
|
|
|
|
|
|
|
|
data: {},
|
|
|
|
|
|
|
|
isAddress: function(log, db, value) {
|
|
|
|
// More than 40 chars or too small in length, so not an address.
|
|
|
|
if (value.length > 40 || value.length < this.minVanityAddressLength) {
|
|
|
|
return { isAddress: false };
|
|
|
|
}
|
|
|
|
|
|
|
|
var address = toAddress(value);
|
|
|
|
var addressAsHex = toHex(address);
|
|
|
|
|
|
|
|
// Check list of known exclusions.
|
|
|
|
if (this.excludedAddresses.indexOf(addressAsHex) != -1) {
|
|
|
|
return { isAddress: false };
|
|
|
|
}
|
|
|
|
|
|
|
|
// Address exists in db, so definitely an address.
|
|
|
|
if (db.exists(address)) {
|
|
|
|
return { isAddress: true, address: addressAsHex, confidence: 1 };
|
|
|
|
}
|
|
|
|
|
|
|
|
// May still be a valid address (e.g. for ERC20 transfer).
|
|
|
|
// It won't exist in DB e.g. if no ETH was sent to it directly.
|
|
|
|
// Apply heuristics.
|
|
|
|
|
|
|
|
// Length heuristic - addresses are usually 40 bytes.
|
|
|
|
if (value.length == 40 && log.op.isPush()) {
|
|
|
|
return { isAddress: true, address: addressAsHex, confidence: 0.75 };
|
|
|
|
}
|
|
|
|
|
|
|
|
// Vanity addresses might start with leading zeros, so length will be < 40.
|
|
|
|
// But we use a min length of addresses, otherwise there are too many false positives.
|
|
|
|
// Also use a known vanity address list to override the normal logic.
|
|
|
|
if (this.knownVanityAddresses[addressAsHex] || (log.op.isPush() && value.length > this.minVanityAddressLength)) {
|
|
|
|
return { isAddress: true, address: addressAsHex, confidence: 0.60 };
|
|
|
|
}
|
|
|
|
|
|
|
|
return { isAddress: false };
|
|
|
|
},
|
|
|
|
|
|
|
|
// step is invoked for every opcode that the VM executes.
|
|
|
|
step: function(log, db) {
|
2021-06-25 11:05:47 +00:00
|
|
|
if (log.stack.length()) {
|
|
|
|
var topOfStack = log.stack.peek(0).toString(16);
|
|
|
|
var result = this.isAddress(log, db, topOfStack);
|
2021-06-16 10:44:35 +00:00
|
|
|
|
2021-06-25 11:05:47 +00:00
|
|
|
if (result.isAddress) {
|
|
|
|
this.data[result.address] = result.confidence;
|
|
|
|
}
|
2021-06-16 10:44:35 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
// fault is invoked when the actual execution of an opcode fails.
|
|
|
|
fault: function(log, db) { },
|
|
|
|
|
|
|
|
// result is invoked when all the opcodes have been iterated over and returns
|
|
|
|
// the final result of the tracing.
|
|
|
|
result: function(ctx, db) {
|
|
|
|
return this.data;
|
|
|
|
}
|
|
|
|
}
|