스마트 컨트랙트 검증
스마트 컨트랙트는 "무신뢰"를 바탕으로 설계되었습니다. 즉, 사용자가 컨트랙트와 상호작용하기 전에 제3자(예: 개발자 및 기업)를 신뢰할 필요가 없어야 합니다. 무신뢰성을 위한 필수 조건으로, 사용자와 다른 개발자는 스마트 컨트랙트의 소스 코드를 검증할 수 있어야 합니다. 소스 코드 검증은 게시된 컨트랙트 코드가 이더리움 블록체인의 컨트랙트 주소에서 실행되는 코드와 동일하다는 것을 사용자와 개발자에게 보장합니다.
"소스 코드 검증"과 "정형 검증"을 구분하는 것이 중요합니다. 아래에서 자세히 설명할 소스 코드 검증은 고급 언어(예: Solidity)로 작성된 스마트 컨트랙트의 주어진 소스 코드가 컨트랙트 주소에서 실행될 동일한 바이트코드로 컴파일링되는지 확인하는 것을 의미합니다. 반면, 정형 검증은 스마트 컨트랙트의 정확성을 검증하는 것, 즉 컨트랙트가 예상대로 작동하는지 확인하는 것을 설명합니다. 문맥에 따라 다르지만, 컨트랙트 검증은 일반적으로 소스 코드 검증을 의미합니다.
소스 코드 검증이란 무엇인가요?
이더리움 가상 머신(EVM)에 스마트 컨트랙트를 배포하기 전에, 개발자는 컨트랙트의 소스 코드(즉, Solidity나 다른 고급 프로그래밍 언어로 작성된 명령어)를 바이트코드로 컴파일링합니다. EVM은 고급 명령어를 해석할 수 없으므로, EVM에서 컨트랙트 로직을 실행하려면 소스 코드를 바이트코드(즉, 저수준 기계어 명령어)로 컴파일링해야 합니다.
소스 코드 검증은 스마트 컨트랙트의 소스 코드와 컨트랙트 생성 시 사용된 컴파일된 바이트코드를 비교하여 차이점을 찾아내는 과정입니다. 광고된 컨트랙트 코드가 블록체인에서 실제로 실행되는 코드와 다를 수 있기 때문에 스마트 컨트랙트를 검증하는 것은 중요합니다.
스마트 컨트랙트 검증을 통해 기계어를 읽을 필요 없이 컨트랙트가 작성된 고급 언어를 통해 컨트랙트가 수행하는 작업을 조사할 수 있습니다. 함수, 값, 그리고 일반적으로 변수 이름과 주석은 컴파일링되어 배포된 원본 소스 코드와 동일하게 유지됩니다. 이로 인해 코드를 읽기가 훨씬 쉬워집니다. 또한 소스 검증은 코드 문서화를 제공하여 최종 사용자가 스마트 컨트랙트가 어떤 작업을 수행하도록 설계되었는지 알 수 있게 해줍니다.
전체 검증이란 무엇인가요?
소스 코드에는 주석이나 변수 이름과 같이 컴파일된 바이트코드에 영향을 주지 않는 부분이 있습니다. 이는 변수 이름과 주석이 다른 두 소스 코드가 모두 동일한 컨트랙트를 검증할 수 있음을 의미합니다. 이를 악용하여 악의적인 행위자가 소스 코드 내에 기만적인 주석을 추가하거나 오해의 소지가 있는 변수 이름을 지정하여 원본 소스 코드와 다른 소스 코드로 컨트랙트를 검증받을 수 있습니다.
소스 코드의 정확성에 대한 암호학적 보장 및 컴파일링 정보의 지문 역할을 하도록 바이트코드에 추가 데이터를 덧붙임으로써 이를 방지할 수 있습니다. 필요한 정보는 Solidity의 컨트랙트 메타데이터 (opens in a new tab)에서 찾을 수 있으며, 이 파일의 해시가 컨트랙트의 바이트코드에 추가됩니다. 메타데이터 플레이그라운드 (opens in a new tab)에서 실제 작동 방식을 확인할 수 있습니다.
메타데이터 파일에는 소스 파일과 그 해시를 포함하여 컨트랙트의 컴파일링에 대한 정보가 포함되어 있습니다. 즉, 컴파일링 설정이나 소스 파일 중 하나의 단 1바이트라도 변경되면 메타데이터 파일이 변경됩니다. 결과적으로 바이트코드에 추가된 메타데이터 파일의 해시도 변경됩니다. 이는 컨트랙트의 바이트코드와 추가된 메타데이터 해시가 주어진 소스 코드 및 컴파일링 설정과 일치한다면, 단 1바이트도 다르지 않은 원본 컴파일링에 사용된 것과 정확히 동일한 소스 코드임을 확신할 수 있다는 것을 의미합니다.
메타데이터 해시를 활용하는 이러한 유형의 검증을 "전체 검증 (opens in a new tab)"(또는 "완벽한 검증")이라고 합니다. 메타데이터 해시가 일치하지 않거나 검증에서 고려되지 않는 경우 "부분 일치"가 되며, 이는 현재 컨트랙트를 검증하는 더 일반적인 방법입니다. 전체 검증 없이는 검증된 소스 코드에 반영되지 않는 악성 코드를 삽입 (opens in a new tab)하는 것이 가능합니다. 대부분의 개발자는 전체 검증을 알지 못하고 컴파일링의 메타데이터 파일을 보관하지 않기 때문에, 지금까지는 부분 검증이 컨트랙트를 검증하는 사실상의 표준 방법이었습니다.
소스 코드 검증이 중요한 이유는 무엇인가요?
무신뢰성
무신뢰성은 스마트 컨트랙트와 탈중앙화 애플리케이션 (dapp)의 가장 큰 전제라고 할 수 있습니다. 스마트 컨트랙트는 "불변"이며 변경할 수 없습니다. 컨트랙트는 배포 시점에 코드에 정의된 비즈니스 로직만 실행합니다. 이는 개발자와 기업이 이더리움에 배포한 후에는 컨트랙트의 코드를 조작할 수 없음을 의미합니다.
스마트 컨트랙트가 무신뢰성을 가지려면, 독립적인 검증을 위해 컨트랙트 코드를 사용할 수 있어야 합니다. 모든 스마트 컨트랙트의 컴파일된 바이트코드는 블록체인에 공개되어 있지만, 저수준 언어는 개발자와 사용자 모두가 이해하기 어렵습니다.
프로젝트는 컨트랙트의 소스 코드를 게시하여 신뢰 가정을 줄입니다. 하지만 이는 또 다른 문제로 이어집니다. 게시된 소스 코드가 컨트랙트 바이트코드와 일치하는지 검증하기 어렵다는 것입니다. 이 시나리오에서는 사용자가 블록체인에 배포하기 전에 개발자가 컨트랙트의 비즈니스 로직을 변경하지 않을 것(즉, 바이트코드를 변경하여)이라고 신뢰해야 하므로 무신뢰성의 가치가 상실됩니다.
소스 코드 검증 도구는 스마트 컨트랙트의 소스 코드 파일이 어셈블리 코드와 일치한다는 보장을 제공합니다. 그 결과 사용자가 제3자를 맹목적으로 신뢰하지 않고 컨트랙트에 자금을 예치하기 전에 코드를 검증하는 무신뢰 생태계가 조성됩니다.
사용자 안전
스마트 컨트랙트에는 일반적으로 많은 자금이 걸려 있습니다. 이로 인해 더 높은 보안 보장과 사용 전 스마트 컨트랙트 로직의 검증이 요구됩니다. 문제는 부도덕한 개발자가 스마트 컨트랙트에 악성 코드를 삽입하여 사용자를 속일 수 있다는 것입니다. 검증이 없다면 악의적인 스마트 컨트랙트는 백도어 (opens in a new tab), 논란의 여지가 있는 접근 제어 메커니즘, 악용 가능한 취약점 및 사용자 안전을 위협하는 기타 요소들을 감지되지 않은 채로 포함할 수 있습니다.
스마트 컨트랙트의 소스 코드 파일을 게시하면 감사자와 같은 이해관계자가 잠재적인 공격 벡터에 대해 컨트랙트를 평가하기가 더 쉬워집니다. 여러 당사자가 독립적으로 스마트 컨트랙트를 검증함으로써 사용자는 보안에 대해 더 강력한 보장을 받게 됩니다.
이더리움 스마트 컨트랙트의 소스 코드를 검증하는 방법
이더리움에 스마트 컨트랙트를 배포하려면 데이터 페이로드(컴파일된 바이트코드)가 포함된 트랜잭션을 특수 주소로 전송해야 합니다. 데이터 페이로드는 소스 코드를 컴파일링하여 생성되며, 여기에 트랜잭션의 데이터 페이로드에 추가된 컨트랙트 인스턴스의 생성자 인수 (opens in a new tab)가 더해집니다. 컴파일링은 결정론적입니다. 즉, 동일한 소스 파일과 컴파일링 설정(예: 컴파일러 버전, 최적화 도구)을 사용하면 항상 동일한 출력(즉, 컨트랙트 바이트코드)을 생성합니다.
스마트 컨트랙트 검증에는 기본적으로 다음 단계가 포함됩니다.
-
소스 파일과 컴파일링 설정을 컴파일러에 입력합니다.
-
컴파일러가 컨트랙트의 바이트코드를 출력합니다.
-
주어진 주소에 배포된 컨트랙트의 바이트코드를 가져옵니다.
-
배포된 바이트코드와 다시 컴파일된 바이트코드를 비교합니다. 코드가 일치하면 주어진 소스 코드 및 컴파일링 설정으로 컨트랙트가 검증됩니다.
-
추가로, 바이트코드 끝에 있는 메타데이터 해시가 일치하면 전체 일치가 됩니다.
이것은 검증에 대한 단순화된 설명이며, 불변 변수 (opens in a new tab)를 갖는 것과 같이 이 방식이 작동하지 않는 많은 예외가 있다는 점에 유의하세요.
소스 코드 검증 도구
컨트랙트를 검증하는 전통적인 과정은 복잡할 수 있습니다. 이것이 바로 이더리움에 배포된 스마트 컨트랙트의 소스 코드를 검증하기 위한 도구가 있는 이유입니다. 이러한 도구는 소스 코드 검증의 많은 부분을 자동화하고 사용자의 편의를 위해 검증된 컨트랙트를 선별합니다.
Etherscan
주로 이더리움 블록 탐색기로 알려져 있지만, Etherscan은 스마트 컨트랙트 개발자와 사용자를 위한 소스 코드 검증 서비스 (opens in a new tab)도 제공합니다.
Etherscan을 사용하면 원본 데이터 페이로드(소스 코드, 라이브러리 주소, 컴파일러 설정, 컨트랙트 주소 등)에서 컨트랙트 바이트코드를 다시 컴파일링할 수 있습니다. 다시 컴파일된 바이트코드가 온체인 컨트랙트의 바이트코드(및 생성자 매개변수)와 연관되어 있다면 컨트랙트가 검증됩니다 (opens in a new tab).
검증이 완료되면 컨트랙트의 소스 코드는 "Verified(검증됨)" 라벨을 받고 다른 사람들이 감사할 수 있도록 Etherscan에 게시됩니다. 또한 검증된 소스 코드가 있는 스마트 컨트랙트 저장소인 검증된 컨트랙트(Verified Contracts) (opens in a new tab) 섹션에 추가됩니다.
Etherscan은 컨트랙 검증에 가장 많이 사용되는 도구입니다. 하지만 Etherscan의 컨트랙트 검증에는 한 가지 단점이 있습니다. 온체인 바이트코드와 다시 컴파일된 바이트코드의 메타데이터 해시를 비교하지 못한다는 것입니다. 따라서 Etherscan에서의 일치는 부분 일치입니다.
Etherscan에서 컨트랙트 검증에 대해 자세히 알아보기 (opens in a new tab).
Blockscout
Blockscout (opens in a new tab)은 스마트 컨트랙트 개발자와 사용자를 위한 컨트랙트 검증 서비스 (opens in a new tab)도 제공하는 오픈 소스 블록 탐색기입니다. 오픈 소스 대안으로서 Blockscout은 검증 수행 방식에 대한 투명성을 제공하고 검증 프로세스를 개선하기 위한 커뮤니티의 기여를 가능하게 합니다.
다른 검증 서비스와 마찬가지로 Blockscout을 사용하면 바이트코드를 다시 컴파일링하고 배포된 컨트랙트와 비교하여 컨트랙트의 소스 코드를 검증할 수 있습니다. 검증이 완료되면 컨트랙트는 검증 상태를 받게 되며 소스 코드는 감사 및 상호작용을 위해 공개적으로 사용할 수 있게 됩니다. 검증된 컨트랙트는 쉽게 탐색하고 디스커버리할 수 있도록 Blockscout의 검증된 컨트랙트 저장소 (opens in a new tab)에도 나열됩니다.
Sourcify
Sourcify (opens in a new tab)는 오픈 소스이며 탈중앙화된 또 다른 컨트랙트 검증 도구입니다. 이것은 블록 탐색기가 아니며 다양한 EVM 기반 네트워크 (opens in a new tab)에서만 컨트랙트를 검증합니다. 다른 도구들이 그 위에 구축될 수 있는 공공 인프라 역할을 하며, 메타데이터 파일에 있는 ABI 및 NatSpec (opens in a new tab) 주석을 사용하여 보다 인간 친화적인 컨트랙트 상호작용을 가능하게 하는 것을 목표로 합니다.
Etherscan과 달리 Sourcify는 메타데이터 해시와의 전체 일치를 지원합니다. 검증된 컨트랙트는 HTTP 및 탈중앙화된 콘텐츠 주소 지정 (opens in a new tab) 스토리지인 IPFS (opens in a new tab)의 공개 저장소 (opens in a new tab)에서 제공됩니다. 추가된 메타데이터 해시가 IPFS 해시이므로 이를 통해 IPFS를 통해 컨트랙트의 메타데이터 파일을 가져올 수 있습니다.
또한 이러한 파일의 IPFS 해시도 메타데이터에 있으므로 IPFS를 통해 소스 코드 파일을 검색할 수도 있습니다. API나 UI (opens in a new tab)를 통해 메타데이터 파일과 소스 파일을 제공하거나 플러그인을 사용하여 컨트랙트를 검증할 수 있습니다. Sourcify 모니터링 도구는 또한 새로운 블록의 컨트랙트 생성을 수신하고 메타데이터와 소스 파일이 IPFS에 게시된 경우 컨트랙트를 검증하려고 시도합니다.
Sourcify에서 컨트랙트 검증에 대해 자세히 알아보기 (opens in a new tab).
Tenderly
Tenderly 플랫폼 (opens in a new tab)을 통해 Web3 개발자는 스마트 컨트랙트를 구축, 테스트, 모니터링 및 운영할 수 있습니다. 디버깅 도구를 관찰 가능성 및 인프라 구성 요소와 결합하여 Tenderly는 개발자가 스마트 컨트랙트 개발을 가속화하도록 돕습니다. Tenderly 기능을 완전히 활성화하려면 개발자는 여러 가지 방법을 사용하여 소스 코드 검증을 수행 (opens in a new tab)해야 합니다.
컨트랙트를 비공개 또는 공개적으로 검증할 수 있습니다. 비공개로 검증된 경우 스마트 컨트랙트는 본인(및 프로젝트의 다른 멤버)에게만 표시됩니다. 컨트랙트를 공개적으로 검증하면 Tenderly 플랫폼을 사용하는 모든 사람에게 표시됩니다.
대시보드 (opens in a new tab), Tenderly Hardhat 플러그인 (opens in a new tab) 또는 CLI (opens in a new tab)를 사용하여 컨트랙트를 검증할 수 있습니다.
대시보드를 통해 컨트랙트를 검증할 때는 소스 파일이나 Solidity 컴파일러에서 생성된 메타데이터 파일, 주소/네트워크 및 컴파일러 설정을 가져와야 합니다.
Tenderly Hardhat 플러그인을 사용하면 적은 노력으로 검증 프로세스를 더 세밀하게 제어할 수 있으며, 자동(노코드) 검증과 수동(코드 기반) 검증 중에서 선택할 수 있습니다.
