Foundry가 홀수 길이의 지갑 vanity 주소 패턴을 정확히 처리하도록 고쳤다

사용자가 ‘A’처럼 한 글자의 16진수 패턴으로 시작하거나 끝나는 지갑 주소를 찾을 때, 대소문자 때문에 놓치거나 지나치게 긴 입력을 잘못 받아들이지 않게 했다.

이더리움 주소는 20바이트, 즉 16진수 40자리로 표현된다. vanity address는 주소의 앞이나 뒤가 사람이 원하는 문자 패턴과 일치하도록 개인키를 반복 생성해 찾은 주소다. 예를 들어 주소가 ‘0xabc…’로 시작하게 만들 수 있다.

16진수 두 글자는 한 바이트다. 따라서 ‘AB’처럼 짝수 길이의 문자열은 바로 바이트로 변환할 수 있지만, ‘A’나 ‘ABC’처럼 홀수 길이는 일반 hex decoder가 그대로 해석하지 못한다. 그렇다고 이것을 일반 정규식으로만 넘기면, 주소 문자열은 소문자로 출력되는데 입력 ‘A’는 대문자이므로 일치하지 않는 문제가 생긴다.

이번 변경은 무엇인가

Foundry는 2026-08-01 21:50 UTC 커밋에서 cast wallet vanity의 패턴 파서를 수정했다. 입력이 전부 16진수 문자인지 먼저 검사하고, 40자를 넘으면 바이트 디코딩 성공 여부와 관계없이 거부한다. 홀수 길이라 바이트 디코딩을 할 수 없는 16진수 패턴은 소문자로 바꾼 뒤 정규식으로 처리한다.

출처: https://github.com/foundry-rs/foundry/commit/d6d349715f25c43a1a64b2e39589b98b284e2aac

코드/구조에서는 어떤 차이인가

실제 Rust diff의 흐름을 단순화한 의사코드다.

isHex = everyCharacterIsHexDigit(pattern)
if isHex && pattern.length > 40:
	error("Hex pattern must be less than 20 bytes")

if decodeEvenLengthHex(pattern) succeeds:
	return ByteMatcher(decodedBytes)

if isHex:
	pattern = pattern.toLowerCase()

return RegexMatcher(anchorStartOrEnd(pattern))

기존에는 ‘A’를 바이트로 디코딩하지 못하면 대문자 정규식으로 사용했다. 변경 후에는 주소 출력과 같은 소문자로 정규화한다. ‘1’을 41번 쓴 홀수 길이 입력도 20바이트 주소보다 길다는 이유로 명확히 거부한다.

왜 이것이 중요한가

이 문제는 자산을 직접 잃게 하는 계약 취약점은 아니다. 그러나 지갑 생성 도구의 입력 의미가 사용자 기대와 달라지면, 많은 연산을 수행하고도 원하는 주소를 찾지 못하거나 불가능한 조건을 계속 시도할 수 있다. 암호키 관련 CLI는 작은 입력 모호성도 명시적으로 처리해야 한다.

쉬운 비유

전화번호 검색에서 ‘A’를 대문자로 입력했다는 이유만으로 소문자 ‘a’가 포함된 동일한 번호 표현을 놓치지 않게 만든 것과 비슷하다. 동시에 전화번호 자릿수보다 긴 검색 조건은 처음부터 거부한다.

블록체인 발전 흐름에서의 의미

블록체인 개발자 경험은 스마트컨트랙트 언어뿐 아니라 키 생성, 주소 처리, 서명 도구의 정확성에도 달려 있다. 주소가 고정 길이의 바이너리 값이라는 성질과 사람이 입력하는 문자열 표현 사이의 경계를 엄격히 다루는 사례다.

1차 출처: https://github.com/foundry-rs/foundry/commit/d6d349715f25c43a1a64b2e39589b98b284e2aac

Reth가 일부만 돌아온 블록 헤더 응답을 오류로 버리지 않고 이어받도록 바꿨다