# Fuzzy Identity
This contract can only be used by me (smarx). I don’t trust myself to remember my private key, so I’ve made it so whatever address I’m using in the future will work.
I always use a wallet contract that returns “smarx” if you ask its name.
Everything I write has bad code in it, so my address always includes the hex
string bad
. To complete this challenge, steal my identity!
// ref. https://capturetheether.com/challenges/accounts/fuzzy-identity/
pragma solidity ^0.8.11;
interface IName {
function name() external view returns (bytes32);
}
contract FuzzyIdentity {
bool public isComplete;
function authenticate() public {
require(isSmarx(msg.sender));
require(isBadCode(msg.sender));
isComplete = true;
}
function isSmarx(address addr) internal view returns (bool) {
return IName(addr).name() == bytes32("smarx");
}
function isBadCode(address _addr) internal pure returns (bool) {
bytes20 addr = bytes20(_addr);
bytes20 id = hex"0000000000000000000000000000000000000bad";
bytes20 mask = hex"0000000000000000000000000000000000000fff";
for (uint256 i = 0; i < 34; i++) {
if (addr & mask == id) {
return true;
}
mask <<= 4;
id <<= 4;
}
return false;
}
}
TIP
The address of a new contract is assigned in a deterministic manner: a hash of the creator and the nonce. The nonce of a EOA is the number of transactions made so far and the nonce of a contract is the number of new contracts created so far.
def new_contract_address(address, nonce):
"""Calculate the address of a new contract"""
addr = web3.keccak(hexstr=rlp.encode([int(address, 16), rlp.encode(nonce)]).hex())[12:]
return web3.toChecksumAddress(addr)