솔라나 문서프로그램 개발하기

프로그램 검증하기

이 가이드는 솔라나에서 자신의 프로그램에 대한 검증된 빌드를 구현하고자 하는 개발자를 위한 참고 자료입니다. 검증된 빌드가 무엇인지, 어떻게 사용하는지, 특별한 고려사항 및 온체인 프로그램의 신뢰성을 보장하기 위한 모범 사례를 다룰 것입니다.

검증된 빌드란 무엇인가요?

검증된 빌드는 솔라나 네트워크에 배포하는 실행 가능한 프로그램이 저장소의 소스 코드와 일치하는지 확인합니다. 이를 통해 개발자와 사용자는 온체인에서 실행되는 프로그램이 공개 코드베이스와 정확히 일치한다는 확신을 가질 수 있어 투명성과 보안을 촉진합니다.

검증 과정은 온체인 프로그램의 해시와 소스 코드에서 로컬로 빌드된 프로그램의 해시를 비교하는 것을 포함합니다. 이는 두 버전 간에 불일치가 없음을 보장합니다.

검증된 빌드가 검증되지 않은 빌드보다 더 안전하다고 간주되어서는 안 되지만, 이 빌드는 개발자가 소스 코드가 온체인에 배포된 것과 일치하는지 스스로 확인할 수 있게 합니다. 소스 코드를 사용하여 개발자는 트랜잭션을 보낼 때 코드가 실행하는 내용을 검증할 수 있습니다.

검증된 빌드 파이프라인은 Ellipsis LabsOtterSec에 의해 고안되고 유지되고 있습니다. 자세한 내용은 원본 검증된 빌드 저장소의 가이드를 따르고, 지원되면 Anza 도구 모음에 직접 빌드 프로세스를 검증하세요.

어떻게 작동하나요?

검증 프로세스는 온체인 프로그램의 해시와 소스 코드에서 로컬로 빌드된 프로그램의 해시를 비교하여 수행됩니다. Solana Verify CLI와 Docker를 사용하여 제어된 환경에서 프로그램을 빌드합니다. 이를 통해 빌드 프로세스가 다양한 시스템에서 결정적이고 일관되게 유지됩니다. 실행 파일을 얻은 후에는 Solana 네트워크에 배포할 수 있습니다. 빌드 프로세스 중에 verify 프로그램PDA가 생성됩니다. 이 PDA에는 프로그램을 검증하는 데 필요한 모든 데이터가 포함되어 있습니다. PDA에는 프로그램 주소, git URL, 커밋 해시 및 프로그램을 빌드하는 데 사용된 인수가 포함됩니다.

PDA의 데이터를 사용하여 누구나 로컬에서 verify 프로그램 명령을 실행하고 프로그램이 제공된 소스 코드에서 빌드되었는지 확인할 수 있습니다. 그런 다음 모든 사람이 완전히 신뢰 없이 직접 검증하거나 OtterSec에서 유지 관리하는 자체 verify API를 실행하여 사용자가 검증을 쉽게 확인할 수 있는 접근점을 제공할 수 있습니다. 이미 Solana ExplorerSolanaFM 등 여러 곳에서 이러한 API 호출이 사용되는 것을 볼 수 있습니다.

왜 검증된 빌드를 사용해야 하나요?

검증된 빌드를 사용하면 다음과 같은 이점이 있습니다:

  • 보안: 온체인에서 실행 중인 프로그램이 소스 코드와 일치하는지 보장하여 악의적인 변경을 방지합니다.

  • 투명성: 다른 사용자와 개발자가 온체인 프로그램을 공개 코드베이스와 비교하여 신뢰할 수 있는지 검증할 수 있습니다.

  • 신뢰: 검증된 빌드는 프로그램의 온체인 동작이 공개 코드와 일치함을 보여주므로 사용자 신뢰도를 높입니다. 검증 가능한 프로그램을 구축할 때 승인되지 않거나 악의적인 코드 실행과 관련된 위험을 최소화합니다. 또한 모범 사례를 준수하고 보안 연구원이 쉽게 연락할 수 있는 방법을 제공합니다. 또한 지갑 및 기타 도구는 프로그램이 검증되는 한 해당 프로그램의 트랜잭션을 더 쉽게 허용할 수 있습니다.

  • 발견 가능성: 프로그램의 검증된 빌드를 제공하면 모든 사람이 소스 코드, 문서, 프로그램 SDK 또는 IDL을 찾을 수 있으며, 문제가 있을 경우 GitHub을 통해 쉽게 연락할 수 있습니다.

검증된 빌드는 어떻게 만드나요?

검증된 빌드를 만들려면 다음 단계를 따라야 합니다:

요약:

  • 코드를 공개 저장소에 커밋하기
  • Docker에서 검증된 빌드 만들기
  • 검증된 빌드 배포하기
  • 배포된 프로그램을 공개 API와 대조하여 검증하기

Docker 컨테이너에서 빌드되지 않은 프로그램을 검증하려고 하면 대부분 실패할 것입니다. 이는 Solana 프로그램 빌드가 서로 다른 시스템에서 결정적이지 않기 때문입니다.

Docker와 Cargo 설치하기

필요한 도구를 설치하고 Docker와 Cargo가 설치되어 있는지 확인하세요. Docker는 일관성을 보장하기 위한 제어된 빌드 환경을 제공하며, Cargo는 Rust 패키지 관리에 사용됩니다.

  • Docker: Docker 웹사이트에서 플랫폼에 맞는 Docker 설치 단계를 따르세요. 설치 후, 이 가이드를 계속 따라 Docker 서비스가 실행 중인지 확인하세요.
  • Cargo: 아직 Cargo가 설치되어 있지 않다면, 다음 명령어를 실행하여 설치할 수 있습니다:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Solana Verify CLI 설치하기

Solana Verify CLI는 빌드를 검증하는 데 사용되는 주요 도구입니다. Solana Verify CLI는 현재 Ellipsis Labs에서 유지 관리하고 있으며 Cargo를 사용하여 설치할 수 있습니다.

다음 명령어를 실행하여 설치할 수 있습니다:

cargo install solana-verify

특정 버전의 CLI가 필요한 경우, 다음과 같이 버전을 지정할 수 있습니다:

cargo install solana-verify --version $VERSION

원하는 경우, 특정 커밋에서 직접 버전을 설치할 수 있습니다:

cargo install solana-verify --git https://github.com/Ellipsis-Labs/solana-verifiable-build --rev 13a1db2

프로젝트 준비

저장소에 대해 검증하려면 저장소의 루트 디렉토리에 Cargo.lock 파일이 있어야 합니다. 저장소에 프로그램이 하나만 있고 루트에 cargo.lock 파일이 있는 경우 다음 단계로 바로 이동하여 프로그램을 빌드할 수 있습니다.

프로그램이 하위 폴더에 있고 rust 워크스페이스가 있는 경우 저장소의 루트 디렉토리에 워크스페이스 Cargo.toml 파일을 생성해야 합니다.

Cargo.toml 예제를 프리셋으로 사용할 수 있습니다:

Cargo.toml
[workspace]
members = ["program/programs/*"]
resolver = "2"
[profile.release]
overflow-checks = true
lto = "fat"
codegen-units = 1
[profile.release.build-override]
opt-level = 3
incremental = false
codegen-units = 1

프로그램이 workspace/members 배열에 있고 프로그램의 Cargo.toml에 올바른 lib 이름이 구성되어 있는지 확인하세요.

중요한 것은 lib name이지 패키지 이름이 아닙니다!

다음과 같이 구성됩니다:

waffle/Cargo.toml
[package]
name = "waffle"
version = "0.1.0"
edition = "2021"
[lib]
name = "waffle"
crate-type = ["cdylib", "lib"]
[dependencies]
solana-program = "2.1.0"

저장소에서 하위 폴더에 프로그램이 있는 워크스페이스의 예제를 볼 수 있습니다. 또한 프로그램이 하위 폴더에 있는 경우 나중에 이 폴더를 verify-from-repo 명령에 --mount-path로 추가해야 한다는 점에 유의하세요.

저장소에서 Anchor 예제를 찾을 수 있습니다. 이 저장소에서는 네이티브 러스트 예제를 찾을 수 있습니다.

Cargo.toml 파일이 준비되면 cargo generate-lockfile를 실행하여 락 파일을 생성하고 프로그램 빌드를 계속할 수 있습니다.

검증 가능한 프로그램 빌드하기

Solana 프로그램을 검증 가능하게 빌드하려면 워크스페이스의 Cargo.toml 파일이 있는 디렉토리로 이동하여 다음을 실행하세요:

solana-verify build

이렇게 하면 환경이 도커 컨테이너로 복사되어 결정적인 방식으로 빌드됩니다.

실제로 검증된 빌드를 배포하고 anchor build 또는 cargo build-sbf로 실수로 덮어쓰지 않도록 주의하세요. 이러한 명령은 동일한 해시를 생성하지 않을 가능성이 높아 검증이 실패할 수 있습니다.

여러 프로그램이 있는 프로젝트의 경우, 라이브러리 이름(패키지 이름이 아님)을 사용하여 특정 프로그램을 빌드할 수 있습니다:

solana-verify build --library-name $PROGRAM_LIB_NAME

이 과정은 결정적 빌드를 보장하며, 특히 특정 시스템(예: M1 맥북)에서는 도커 컨테이너 내에서 실행되기 때문에 시간이 걸릴 수 있습니다. 더 빠른 빌드를 위해서는 x86 아키텍처를 실행하는 리눅스 머신을 사용하는 것이 좋습니다.

빌드가 완료되면 다음 명령어를 사용하여 실행 파일의 해시를 검색할 수 있습니다:

solana-verify get-executable-hash target/deploy/$PROGRAM_LIB_NAME.so

검증 가능한 프로그램 배포하기

프로그램을 빌드하고 해시를 검색한 후에는 Solana 네트워크에 배포할 수 있습니다. 안전한 배포를 위해 Squads Protocol과 같은 다중 서명 또는 거버넌스 솔루션을 사용하는 것이 좋지만, 다음과 같이 직접 배포할 수도 있습니다:

solana program deploy -u $NETWORK_URL target/deploy/$PROGRAM_LIB_NAME.so --program-id $PROGRAM_ID --with-compute-unit-price 50000 --max-sign-attempts 100 --use-rpc

현재 적합한 낮은 우선순위 수수료는 Quicknode와 같은 RPC 제공업체에서 요청할 수 있습니다.

배포된 프로그램이 빌드된 실행 파일과 일치하는지 확인하려면 다음을 실행하세요:

solana-verify get-program-hash -u $NETWORK_URL $PROGRAM_ID

다른 Solana 클러스터(예: devnet, testnet, mainnet)에 다른 버전이 배포되어 있을 수 있습니다. 프로그램을 검증하려는 Solana 클러스터에 맞는 올바른 네트워크 URL을 사용하세요. 원격 검증은 메인넷에서만 작동합니다.

저장소에 대한 검증

공개 저장소에 대해 프로그램을 검증하려면 다음을 사용하세요:

solana-verify verify-from-repo -u $NETWORK_URL --program-id $PROGRAM_ID https://github.com/$REPO_PATH --commit-hash $COMMIT_HASH --library-name $PROGRAM_LIB_NAME --mount-path $MOUNT_PATH

프로그램 디렉토리에서 검증된 빌드를 실행하는 동안 verify-from-repo를 실행할 때 --mount-path 플래그를 추가해야 합니다. 이는 프로그램의 라이브러리 이름이 포함된 Cargo.toml가 있는 폴더의 경로입니다.

이 명령은 온체인 프로그램 해시와 지정된 커밋 해시의 소스에서 빌드된 실행 파일 해시를 비교합니다.

명령 마지막에 검증 데이터를 온체인에 업로드할지 물어볼 것입니다. 업로드하면 Solana 익스플로러에 즉시 프로그램의 검증 데이터가 표시됩니다. 원격 빌드로 검증될 때까지는 미검증 상태로 표시됩니다. 다음 단계에서 공개 API를 통해 프로그램을 검증하는 방법을 알아보세요.

특정 릴리스로 검증을 고정하려면 명령에 --commit-hash 플래그를 추가할 수 있습니다.

공개 API를 통한 검증

마지막으로 검증 API를 실행하는 누구에게나 직접 프로그램을 검증할 수도 있습니다:

solana-verify verify-from-repo --remote -um --program-id PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY https://github.com/Ellipsis-Labs/phoenix-v1

무료 RPC의 속도 제한에 걸릴 수 있으므로 유료 RPC URL을 사용하는 것이 좋습니다. 따라서 -um 대신 더 안정적인 검증을 위해 --url yourRpcUrl를 사용해야 합니다.

--remote 플래그는 OtterSec API에 빌드 요청을 보내 프로그램의 원격 빌드를 트리거합니다. 빌드가 완료되면 시스템은 프로그램의 온체인 해시가 저장소에서 생성된 빌드 아티팩트의 해시와 일치하는지 확인합니다.

기본값은 OtterSec API입니다.

검증 데이터를 온체인에 업로드할지 물어볼 때 '예'를 선택하세요. 이는 API가 검증 데이터를 업로드했는지 확인하는 데 사용됩니다.

다음을 사용하여 수동으로 원격 작업을 트리거할 수도 있습니다:

solana-verify remote submit-job --program-id <program-id> --uploader <address>

업로더는 PDA에 쓰기 권한이 있는 주소입니다. 대부분의 경우 프로그램 권한이어야 합니다. 만약 프로그램이 멀티시그에 의해 제어되는 경우, 이 가이드 아래의 멀티시그 검증 부분을 계속 진행하세요.

이것은 OtterSec API에 작업을 제출하고 다음 명령으로 작업 상태를 확인할 수 있습니다:

solana-verify remote get-job-status --job-id <job-id>

검증이 성공적으로 완료되면(시간이 다소 걸릴 수 있음), 프로그램이 검증된 것을 다음에서 확인할 수 있습니다: 단일 프로그램용 OtterSec API, Solana 익스플로러, SolanaFM, SolScan, 그리고 결국 0xDeep이 유지 관리하는 커뮤니티 운영 웹사이트인 SolanaVerify.orgOtterSec 검증 프로그램 API, 마지막으로 검증된 프로그램 Dune 대시보드에서도 확인할 수 있으며, 이는 더 건강한 Solana 생태계에 기여합니다.

Squads와 같은 멀티시그에 의해 제어되는 프로그램을 검증하는 방법

원격 검증이 작동하려면 프로그램 권한에 의해 서명된 PDA에 검증 데이터를 작성해야 합니다. 프로그램이 멀티시그에 의해 제어되는 경우, 이 PDA 작성 트랜잭션을 내보내고 Squads Protocol 또는 다른 멀티시그 솔루션을 통해 제출할 수 있습니다.

1. 검증 가능한 프로그램 빌드하기

먼저 프로그램을 빌드합니다:

solana-verify build

Cargo.lock 파일에 지정된 솔라나 버전을 사용하여 도커 컨테이너를 통해 검증 가능한 빌드를 생성합니다.

2. 프로그램 배포하기

solana config set --url "PayedMainnetRPCAddress" // the public endpoint will be rate limited too much
solana program deploy target/deploy/verify_squads.so

이 멀티시그 가이드의 나머지 부분에서는 예시 프로그램 ID로 6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD를 사용합니다.

3. 저장소에 커밋하고 검증하기

완료되면 프로젝트를 깃허브에 커밋합니다. 다음은 예시입니다: https://github.com/solana-developers/verify-squads

선택 사항: 먼저 로컬에서 검증할 수 있는지 확인하세요(이 명령은 예시 프로그램 ID 6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD를 사용합니다):

solana-verify verify-from-repo https://github.com/solana-developers/verify-squads --program-id 6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD

매개변수가 올바른지 확인하기 위함입니다.

4. 프로그램 권한을 멀티시그으로 이전하기

아직 프로그램 권한을 멀티시그으로 이전하지 않았다면 멀티시그 권한을 복사하세요. 다음 단계에서 필요합니다.

5. PDA 트랜잭션 내보내기

프로그램 권한을 로컬에 보유하고 있는 경우 solana-verify verify-from-repo 명령을 사용할 때 빌드 데이터를 온체인에 업로드하라는 메시지가 표시됩니다.

멀티시그을 사용할 때는 이 작업을 수행할 수 없으므로 PDA 트랜잭션을 수동으로 내보낸 다음 Squads를 통해 트랜잭션을 실행해야 합니다.

solana-verify export-pda-tx https://github.com/solana-developers/verify-squads --program-id 6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD --uploader <your program authority> --encoding base58 --compute-unit-price 0

이 명령은 base58 트랜잭션을 반환합니다. 트랜잭션 검사기에서 사용할 base64 인코딩된 트랜잭션이 필요한 경우 --encoding base64를 사용할 수 있습니다.

P6vBfcPaaXb8fZoT3NBAYEcdtEj7tubA1k2gBxmFKZ3UWF5YyrmDMFTvLKALCJoUuRsPAjMckudYruCu3eeWQtuDrFbEMLxLFutnKXac974fnkMivcwUdY66VLjbxQT6ATmcy7F4hBtz1G4P1h6iBJLhb8WtrtgY3i4qq45MUEb7RjuMEfUFXKrNgPdGxkz5xvMHq3dxKRcpmEK5k2DkeW6SUQYBVe19Ga3B9GyhTX8k3CMt9JCEah13WyRnQd8GjoK6sTEvGJym6xDNvmd8yiJYSNcaYwEJsjHEUf4Yh6kAC7ki2KRvVAr3NVe1gjqK9McrwSQjtUatvydTG8Zovcr7PPUEMf3yPMgKXjZLB2QpkH63yTTYdNAnWFuv9E6b6nYRqye5XcNi436yKw5U14fXh65yK34bgYLi9328UT1huJELsJU9BRGnGUmb6GWp6c2WL5BhnzgNTSnt9TXFfEgUMzhvKzpVBxLP44hwqqBdyUhHFysCF37531PnmiESq8x1xou23xJ6FcQbc199754MkqQd7tX9CUznGzAEqHGkzn3VBoJnojsKtgYmiTYbdRsT1CU18MbYEE7WvGAvXyxxbpNzbAcc94HrnM6cqRGmwhEBroPfFghTdmzg9D

6. Squads를 통해 트랜잭션 제출하기

Squads 트랜잭션 빌더로 이동하여 base58로 인코딩된 트랜잭션을 가져옵니다. 시뮬레이션에서 트랜잭션이 osec 검증 프로그램과 컴퓨터 예산 프로그램에만 호출하고 다른 것은 없는지 확인하세요!

7. 원격 검증 작업 제출하기

Squads에 트랜잭션이 성공적으로 제출되면 원격 작업을 제출할 수 있습니다:

solana-verify remote submit-job --program-id 6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD
--uploader <your program authority>

이것으로 완료되었습니다! 공개 저장소에 대해 프로그램을 검증하고 OtterSec API에 원격 작업을 제출했습니다. 이제 솔라나 익스플로러와 다른 곳에서 반영된 것을 확인할 수 있을 것입니다.

8. 프로그램 업데이트하기 (선택사항)

프로그램을 업데이트할 때는 새로운 PDA 트랜잭션을 내보내고 Squads를 통해 다시 제출해야 합니다.

프로그램 업데이트 방법:

solana-verify build
solana program write-buffer target/deploy/verify_squads.so --with-compute-unit-price 50000 --max-sign-attempts 50

그런 다음 해당 버퍼 권한을 멀티시그로 이전하거나 멀티시그의 권한으로 직접 버퍼를 생성합니다.

solana program set-buffer-authority Fu3k79g53ZozAj47uq1tXrFy4QbQYh7y745DDsxjtyLR --new-buffer-authority 3JG6ULvZVCrkKtSSskKNJGe8RNZGFe8Ruev9KUhxzK5K

9. 새 PDA 트랜잭션 내보내기 및 제출하기

변경 사항을 깃허브에 커밋하는 것을 잊지 마세요. PDA 업그레이드 트랜잭션을 다시 내보냅니다:

solana-verify export-pda-tx https://github.com/solana-developers/verify-squads --program-id 6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD --uploader 3JG6ULvZVCrkKtSSskKNJGe8RNZGFe8Ruev9KUhxzK5K

Squads를 통해 트랜잭션을 다시 제출하세요.

예시 트랜잭션은 여기에서 확인할 수 있습니다.

그런 다음 원격 빌드를 다시 제출하세요:

solana-verify remote submit-job --program-id 6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD --uploader 3JG6ULvZVCrkKtSSskKNJGe8RNZGFe8Ruev9KUhxzK5K

다음과 같은 결과가 나와야 합니다:

Verification request sent with request id: b63339d2-163e-49ac-b55d-3454c1c2b5b3
Verification in progress... ⏳ [00:18:02] ✅ Process completed. (Done in 18
minutes) Program 6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD has been verified.
The provided GitHub build matches the on-chain hash. On Chain Hash:
96f8c3d9400258f7759408d1f6f8435b4a24d9b52f5a0340d97907e567cb8773 Executable
Hash: 96f8c3d9400258f7759408d1f6f8435b4a24d9b52f5a0340d97907e567cb8773 Repo URL:
https://github.com/Woody4618/verify-squads/tree/0fb0a2e30c15c51732c0ad5e837975a6f7bbc7ed
Check the verification status at:
https://verify.osec.io/status/6XBGfP17P3KQAKoJb2s5M5fR4aFTXzPeuC1af2GYkvhD Job
url: https://verify.osec.io/job/b63339d2-163e-49ac-b55d-3454c1c2b5b3

축하합니다! 멀티시그 업그레이드 후 프로그램을 검증했습니다!

도커 이미지에서 검증하기

다음 명령을 실행하여 도커 이미지로 프로그램을 검증할 수도 있습니다:

solana-verify verify-from-image -e
examples/hello_world/target/deploy/hello_world.so -i
ellipsislabs/hello_world_verifiable_build:latest -p
2ZrriTQSVekoj414Ynysd48jyn4AX6ZF4TTJRqHfbJfn

이 명령은 ellipsislabs/hello_world_verifiable_build:latest에 저장된 이미지를 로드하고, 컨테이너 내 실행 파일 경로의 해시가 명령에 제공된 온체인 프로그램의 해시와 동일한지 확인합니다. 빌드가 이미 이미지에 업로드되었기 때문에 시간이 오래 걸릴 수 있는 실행 파일의 전체 재빌드가 필요하지 않습니다.

ellipsislabs/hello_world_verifiable_build:latest 이미지를 생성하는 Dockerfile은 ellipsis labs 저장소의 /examples/hello_world에서 찾을 수 있습니다.

아래는 예상되는 출력 결과입니다:

Verifying image: "ellipsislabs/hello_world_verifiable_build:latest", on network
"https://api.mainnet.solana.com" against program ID
2ZrriTQSVekoj414Ynysd48jyn4AX6ZF4TTJRqHfbJfn Executable path in container:
"examples/hello_world/target/deploy/hello_world.so"
Executable hash:
08d91368d349c2b56c712422f6d274a1e8f1946ff2ecd1dc3efc3ebace52a760 Program hash:
08d91368d349c2b56c712422f6d274a1e8f1946ff2ecd1dc3efc3ebace52a760 Executable
matches on-chain program data ✅

검증된 빌드 예시

다음은 이 저장소의 소스 코드를 사용하여 ID가 FWEYpBAf9WsemQiNbAewhyESfR38GBBHLrCaU3MpEKWv인 예제 프로그램을 검증하는 예시입니다:

solana-verify verify-from-repo https://github.com/solana-developers/verified-program --url YOUR-RPC-URL --program-id FWEYpBAf9WsemQiNbAewhyESfR38GBBHLrCaU3MpEKWv --mount-path waffle --library-name waffle --commit-hash 5b82b86f02afbde330dff3e1847bed2d42069f4e

기본적으로 verify-from-repo 명령은 main 브랜치의 마지막 커밋을 사용합니다. 저장소 작업을 계속하려는 경우 commit-hash 매개변수를 사용하여 특정 커밋을 지정할 수도 있습니다: --commit-hash 5b82b86f02afbde330dff3e1847bed2d42069f4e

마지막으로 OtterSec API를 통해 직접 프로그램을 검증할 수도 있습니다:

solana-verify verify-from-repo https://github.com/solana-developers/verified-program --url YOUR-RPC-URL --remote --program-id FWEYpBAf9WsemQiNbAewhyESfR38GBBHLrCaU3MpEKWv --mount-path waffle --library-name waffle --commit-hash 5b82b86f02afbde330dff3e1847bed2d42069f4e

--remote 명령은 OtterSec API에 빌드 요청을 보내고, 이는 프로그램의 원격 빌드를 트리거합니다. 빌드가 완료되면 시스템은 프로그램의 온체인 해시가 저장소에서 생성된 빌드 결과물의 해시와 일치하는지 확인합니다.

이미 검증된 인기 프로그램들

Phoenix

solana-verify verify-from-repo -um --program-id PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY https://github.com/Ellipsis-Labs/phoenix-v1

최종 출력:

Executable Program Hash from repo: 6877a5b732b3494b828a324ec846d526d962223959534dbaf4209e0da3b2d6a9
On-chain Program Hash: 6877a5b732b3494b828a324ec846d526d962223959534dbaf4209e0da3b2d6a9
Program hash matches ✅

Squads V3

solana-verify verify-from-repo https://github.com/Squads-Protocol/squads-mpl --commit-hash c95b7673d616c377a349ca424261872dfcf8b19d --program-id SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu -um --library-name squads_mpl --bpf

Squads 저장소에 여러 프로그램이 포함되어 있기 때문에 library-name를 지정해야 했습니다. squads_mpl가 이전에 Anchor로 검증되었기 때문에 --bpf 플래그를 사용합니다.

최종 출력:

Executable Program Hash from repo: 72da599d9ee14b2a03a23ccfa6f06d53eea4a00825ad2191929cbd78fb69205c
On-chain Program Hash: 72da599d9ee14b2a03a23ccfa6f06d53eea4a00825ad2191929cbd78fb69205c
Program hash matches ✅

Drift V2

solana-verify verify-from-repo -um --program-id dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH https://github.com/drift-labs/protocol-v2 --commit-hash 110d3ff4f8ba07c178d69f9bfc7b30194fac56d6 --library-name drift

최종 출력:

Executable Program Hash from repo: e31d58edeabc3c30bf6f2aa60bfaa5e492b41ec203e9006404b463e5adee5828
On-chain Program Hash: e31d58edeabc3c30bf6f2aa60bfaa5e492b41ec203e9006404b463e5adee5828
Program hash matches ✅

Marginfi V2

solana-verify verify-from-repo -um --program-id MFv2hWf31Z9kbCa1snEPYctwafyhdvnV7FZnsebVacA https://github.com/mrgnlabs/marginfi-v2 --commit-hash d33e649e415c354cc2a1e3c49131725552d69ba0 --library-name marginfi -- --features mainnet-beta

최종 출력:

Executable Program Hash from repo: 890d68f48f96991016222b1fcbc2cc81b8ef2dcbf280c44fe378c523c108fad5
On-chain Program Hash: 890d68f48f96991016222b1fcbc2cc81b8ef2dcbf280c44fe378c523c108fad5
Program hash matches ✅

자주 묻는 질문

검증이 실패합니다. 어떻게 해야 하나요?

다음과 같은 일반적인 문제를 확인하세요:

  • 잘못된 서명자: solana program show YourProgramId를 실행하여 서명자가 프로그램의 업그레이드 권한자인지 확인하세요
  • 온체인 PDA 없음: solana-verify verify-from-repo -um를 실행하고 메시지가 표시되면 YES를 선택하세요. PDA를 업로드하지 않으면 API가 검증 메타데이터를 가져올 수 없습니다.
  • PDA 데이터 불일치: 프로그램을 재배포한 경우 PDA를 업데이트하세요. PDA 데이터는 배포된 프로그램과 일치해야 합니다.
  • 잘못된 커밋 해시: 배포한 정확한 커밋 해시를 사용하여 PDA를 생성하세요
  • 빌드 환경 차이: PDA를 생성할 때 solana-verify와 함께 Docker를 사용하세요

로컬 빌드 해시가 온체인 해시와 일치하지 않습니다. 왜 그런가요?

일반적으로 다음을 의미합니다:

  • 다른 Rust/Solana 툴체인 버전을 사용하고 있습니다
  • 빌드 사이에 종속성이 업데이트되었습니다
  • Docker 컨테이너에서 빌드하지 않았습니다
  • 잘못된 커밋을 체크아웃했습니다

배포한 정확한 커밋을 사용하여 Docker에서 solana-verify build로 빌드하여 이 문제를 해결하세요.

검증에 얼마나 걸리나요?

프로그램 크기에 따라 다음과 같은 시간이 예상됩니다:

  • 간단한 프로그램: 1-5분
  • 복잡한 프로그램: 5-15분
  • 매우 큰 프로그램: 최대 30분

작업 상태 엔드포인트를 사용하여 진행 상황을 추적하세요.

제 프로그램은 불변입니다(업그레이드 권한 없음). 어떻게 검증할 수 있나요?

프로그램에 업그레이드 권한이 없거나 PDA를 생성하기 전에 불변으로 만들어진 경우, 이러한 상황을 위한 화이트리스트 주소가 있습니다. contact@osec.io로 문의하시면 프로그램 검증을 도와드리겠습니다.

PDA란 무엇이며 왜 중요한가요?

PDA(프로그램 파생 계정)는 무신뢰 검증을 가능하게 합니다:

  • 온체인 저장소: 검증 메타데이터(레포지토리 URL, 커밋 해시, 빌드 매개변수)를 Otter Verify 프로그램(verifycLy8mB96wd9wqq3WDXQwM4oU6r42Th37Db9fC)이 소유한 PDA에 온체인으로 저장합니다
  • 암호화 연결: PDA는 프로그램 주소에서 파생되어 검증 데이터에 대한 불변의 연결을 생성합니다
  • 탈중앙화된 신뢰: 누구나 PDA를 읽고 프로그램을 독립적으로 검증할 수 있습니다

API를 사용하기 전에 PDA를 생성해야 하는 이유는 무엇인가요?

API는 온체인 PDA에서만 작동합니다. 그 이유는:

  • 무신뢰성: API는 임의의 데이터를 거부하며, 업그레이드 권한이 온체인에 저장한 데이터만 사용합니다
  • 간소화: 서명자 + program_id만 제공하면 되며, API는 PDA에서 나머지 모든 정보를 가져옵니다
  • 변조 방지: PDA는 누구나 독립적으로 검증할 수 있는 불변의 기록을 생성합니다
  • 소유권 증명: 서명자는 업그레이드 권한이어야 하며, 이는 프로그램을 제어한다는 것을 암호학적으로 증명합니다

프로그램을 얼마나 자주 검증해야 하나요?

다음의 경우 프로그램을 검증하세요:

  • 배포 또는 업그레이드 후마다
  • 소스 레포지토리를 업데이트할 때
  • 그 외의 경우 재검증을 걱정할 필요가 없습니다 - API는 모든 프로그램을 24시간마다 자동으로 재검증합니다

프로그램을 업그레이드하면 어떻게 되나요?

업그레이드 후 다음 단계를 따르세요:

  1. API가 업그레이드를 감지하고 프로그램의 검증을 해제합니다.
  2. 새로운 검증 메타데이터로 PDA를 업데이트합니다:
solana-verify verify-from-repo -um \
--program-id YourProgramId... \
https://github.com/your-org/your-program
  1. 업그레이드 권한을 사용하여 새로운 검증 요청을 제출합니다
  2. API는 업데이트된 PDA에 대해 새 버전을 검증합니다

중요: 업그레이드된 프로그램의 새 커밋 해시로 항상 업그레이드 권한을 사용하여 PDA를 업데이트하세요.

검증 결과를 신뢰할 수 있나요?

네 - 이 시스템은 신뢰가 필요 없으며 독립적으로 검증 가능하도록 설계되었습니다:

신뢰할 수 있는 이유:

  • 온체인 PDA: 검증 메타데이터가 온체인에 존재하며, 어떤 중앙 기관도 통제하지 않습니다
  • 업그레이드 권한 증명: 프로그램의 업그레이드 권한 소유자만이 PDA를 생성/업데이트할 수 있습니다
  • 독립적인 검증: 누구나 PDA를 읽고 solana-verify를 로컬에서 실행하여 검증할 수 있습니다
  • 지속적인 재검증: API가 24시간마다 모든 프로그램을 자동으로 재검증합니다

다음 제약 사항을 이해하세요:

  • 검증은 소스 코드가 배포된 것과 일치함을 확인할 뿐, 코드가 안전하다는 것을 보장하지는 않습니다
  • 프로그램과 상호작용하기 전에 항상 코드를 검토하세요
  • 검증됨 ≠ 감사됨, 또는 안전함
  • PDA의 저장소와 커밋을 확인하여 신뢰할 수 있는 출처인지 확인하세요

프로그램을 직접 검증하려면 어떻게 하나요?

온체인 PDA를 읽고 로컬에서 검증을 실행하여 어떤 프로그램이든 직접 검증할 수 있습니다:

1단계: 온체인 PDA 읽기

# Install solana-verify if you haven't
cargo install solana-verify
# Get the PDA data
solana-verify list-program-pdas --program-id YourProgramId...

2단계: 로컬에서 검증하기

# Verify using the repository and commit & other arguments from the PDA
solana-verify verify-from-repo \
--program-id YourProgramId... \
https://github.com/your-org/your-program
--commit-hash <commit-hash>
... (other arguments from the PDA)
# Confirm the hash output matches the on-chain program hash

이것이 증명하는 것:

  1. PDA 메타데이터가 진본임 (온체인에 저장됨)
  2. PDA의 저장소에 있는 소스 코드가 배포된 프로그램과 일치함
  3. API를 신뢰할 필요가 없음 - 온체인에서 모든 것을 직접 검증할 수 있음

다른 사람이 내 허락 없이 내 프로그램을 검증할 수 있나요?

네, 그래서 서명자가 업그레이드 권한 소유자여야 한다는 요구 사항이 있습니다. 서명자가 업그레이드 권한 소유자일 때만 검증이 유효한 것으로 간주합니다.

검증 가능한 빌드를 만들려면 무엇이 필요한가요?

다음 도구를 설치하세요:

  • Docker (결정론적 빌드용)
  • Cargo (Rust 패키지 매니저)
  • Solana Verify CLI: cargo install solana-verify
  • 소스 코드가 있는 공개 Git 저장소

비공개 저장소를 검증할 수 있나요?

아니요 - 검증에는 공개 소스 코드가 필요합니다:

  • PDA는 누구나 접근할 수 있는 공개 저장소 URL을 저장합니다
  • 무신뢰 검증은 공개 코드 접근에 의존합니다
  • 사용자는 프로그램의 동작을 이해하기 위해 소스 코드를 읽어야 합니다
  • 전체 목적은 사용자가 소스와 배포가 일치하는지 독립적으로 검증할 수 있도록 하는 것입니다

비공개 저장소는 검증 시스템의 핵심 신뢰 모델을 무너뜨립니다.

Squads Multisig로 제어되는 프로그램을 어떻게 검증하나요?

멀티시그로 제어되는 프로그램의 경우 다음 단계를 따르세요:

# 1. Build and deploy normally
solana-verify build
solana program deploy <your-program.so> --program-id YourProgramId...
# 2. Verify locally first - confirm the hash matches
solana-verify verify-from-repo -um \
--program-id YourProgramId... \
https://github.com/your-org/your-program
# 3. Export the PDA creation transaction
solana-verify export-pda-tx \
--program-id YourProgramId... \
https://github.com/your-org/your-program
# 4. Execute the PDA transaction through your Squads Multisig interface
# 5. After multisig execution, trigger remote verification
solana-verify remote submit-job \
--program-id YourProgramId... \
--uploader YourMultisigAddress...

중요: PDA 트랜잭션을 내보내기 전에 항상 로컬에서 검증(2단계)하여 빌드 해시가 일치하는지 확인하세요.

결론

솔라나의 검증된 빌드를 사용하면 네트워크에서 프로그램의 무결성과 신뢰성을 보장하고 개발자가 Solana Explorer에서 직접 SDK를 찾을 수 있습니다. Solana Verify CLI 및 Docker와 같은 도구를 활용하면 소스 코드와 일치하는 검증 가능하고 안전한 빌드를 유지할 수 있습니다. 항상 일관된 환경을 사용하기 위한 필요한 예방 조치를 취하고, 안전한 업그레이드 및 배포를 위한 거버넌스 솔루션을 고려하세요.

보안 + 면책조항

검증된 빌드는 솔라나 프로그램의 무결성을 보장하는 강력한 도구이지만 기본 설정에서는 완전히 무신뢰적이지 않습니다. Docker 이미지는 Solana Foundation에서 빌드하고 호스팅합니다.

다운로드한 Docker 이미지에서 프로젝트를 빌드하고 있으며, 잠재적으로 민감한 정보를 포함한 전체 설정이 빌드를 위해 해당 Docker 이미지로 복사된다는 점을 유의하세요.

완전히 무신뢰적인 설정을 원한다면 Docker 이미지를 직접 빌드하고 자체 인프라에서 호스팅할 수 있습니다. 이렇게 하면 Docker 이미지가 변조되지 않았음을 확신할 수 있습니다. 검증된 빌드 저장소에서 자체 Docker 이미지를 생성하는 스크립트를 찾을 수 있으며, 포크하여 GitHub Actions를 직접 실행하거나 올바른지 검증할 수 있습니다.

또한 원격 검증을 위해서는 OtterSec API와 Solana Explorer를 어느 정도 신뢰해야 합니다.

API 또는 Solana Explorer가 손상된 경우 잘못된 정보를 표시할 수 있습니다.

완전히 신뢰가 필요 없는 설정을 원한다면 Verify API를 직접 실행하거나, verify-from-repo 명령을 사용하여 프로그램 검증을 로컬에서 직접 실행할 수 있습니다. 이때 프로그램의 배포 권한과 검증 프로그램에서 파생된 PDA에 저장된 온체인 검증 데이터를 사용합니다.

검증 프로그램은 OtterSec 팀이 배포했으며 아직 동결되지 않았으므로 언제든지 업그레이드될 수 있습니다.

Solana Foundation, OtterSec 및 Ellipsis Labs 팀은 검증된 빌드 파이프라인 사용으로 인해 발생할 수 있는 손실이나 손해에 대해 책임지지 않습니다.

Solana 프로그램을 위한 Security.txt

검증된 빌드 외에도 프로그램에 security.txt 파일을 추가할 수 있습니다. 향후 구현되면 security.txt는 검증 PDA에 저장된 검증 데이터에 쉽게 접근할 수 있도록 검증자 공개 키를 보유하게 됩니다. 프로그램을 빌드하고 검증하는 데 필요한 모든 정보를 포함하는 PDA는 프로그램 주소와 검증자 pubkey에서 파생됩니다. 기본적으로 이는 프로그램을 빌드하고 배포한 동일한 pubkey입니다. 하지만 security.txt에서 지정할 수 있는 다른 pubkey일 수도 있습니다.

security.txt 기능을 통해 개발자는 Solana 스마트 계약 내에 연락처 및 보안 정보를 직접 임베드할 수 있습니다. securitytxt.org에서 영감을 받은 이 접근 방식은 보안 연구원이 계약 주소만 알고 있어도 프로젝트 관리자에게 연락할 수 있는 표준화된 방법을 제공합니다.

security.txt를 사용하는 이유는?

많은 프로젝트, 특히 소규모 또는 비공개 프로젝트의 경우, 컨트랙트 주소만으로 개발자를 식별하는 것은 어렵고 시간이 많이 소요될 수 있습니다. 프로그램 내에 security.txt 파일을 포함하면 보안 연구원들이 올바른 담당자에게 쉽게 연락할 수 있어 잠재적 취약점을 방지하고 버그 리포트를 신속하게 받을 수 있습니다.

security.txt 구현 방법

Solana 프로그램에 security.txt를 추가하려면 다음 단계를 수행하세요:

Cargo.tomlsolana-security-txt 의존성을 추가합니다:

Cargo.toml
[dependencies]
solana-security-txt = "1.1.1"

컨트랙트에서 security_txt! 매크로를 사용하여 보안 정보를 정의합니다. 연락처 정보, 프로젝트 URL, 보안 정책까지 포함할 수 있습니다. 다음은 예시입니다:

#[cfg(not(feature = "no-entrypoint"))]
use {default_env::default_env, solana_security_txt::security_txt};
#[cfg(not(feature = "no-entrypoint"))]
security_txt! {
name: "MyProject",
project_url: "https://myproject.com",
contacts: "email:security@myproject.com,discord:security#1234",
policy: "https://myproject.com/security-policy",
// Optional Fields
preferred_languages: "en,de",
source_code: "https://github.com/solana-developers/solana-game-preset",
source_revision: "5vJwnLeyjV8uNJSp1zn7VLW8GwiQbcsQbGaVSwRmkE4r",
source_release: "",
encryption: "",
auditors: "Verifier pubkey: 5vJwnLeyjV8uNJSp1zn7VLW8GwiQbcsQbGaVSwRmkE4r",
acknowledgements: "Thank you to our bug bounty hunters!"
}

security.txt 정보가 프로그램에 포함되면 Solana Explorer와 같은 도구를 통해 쉽게 조회할 수 있어, 잠재적 문제를 보고하려는 누구에게나 연락처 및 보안 세부 정보를 제공할 수 있습니다.

모범 사례

  • 링크 사용: 변경 가능성이 높은 정보(예: 연락처 정보)의 경우, 컨트랙트에 직접 하드코딩하기보다 웹 페이지로 연결하는 것이 좋습니다. 이를 통해 빈번한 프로그램 업그레이드를 피할 수 있습니다.

  • 검증: 배포 전에 query-security-txt 도구를 사용하여 형식과 내용을 검증하세요. 이 도구는 온체인 프로그램과 로컬 바이너리 모두를 검증할 수 있습니다:

query-security-txt target/bpfel-unknown-unknown/release/my_contract.so

보안 연락처 정보를 컨트랙트에 직접 포함함으로써 연구원들이 쉽게 연락할 수 있도록 하여 Solana 생태계 내에서 보다 나은 보안과 소통을 촉진할 수 있습니다.

다음은 Solana Explorer에서 security.txt가 어떻게 표시되는지 보여주는 예시입니다.

security.txt 프로젝트는 Neodyme Labs에서 관리합니다.

verify.osec.io에서 검증 상태를 확인하고 검증된 프로그램을 둘러볼 수 있습니다.

Is this page helpful?

목차

검증된 빌드란 무엇인가요?어떻게 작동하나요?왜 검증된 빌드를 사용해야 하나요?검증된 빌드는 어떻게 만드나요?Docker와 Cargo 설치하기Solana Verify CLI 설치하기프로젝트 준비검증 가능한 프로그램 빌드하기검증 가능한 프로그램 배포하기저장소에 대한 검증공개 API를 통한 검증Squads와 같은 멀티시그에 의해 제어되는 프로그램을 검증하는 방법1. 검증 가능한 프로그램 빌드하기2. 프로그램 배포하기3. 저장소에 커밋하고 검증하기4. 프로그램 권한을 멀티시그으로 이전하기5. PDA 트랜잭션 내보내기6. Squads를 통해 트랜잭션 제출하기7. 원격 검증 작업 제출하기8. 프로그램 업데이트하기 (선택사항)9. 새 PDA 트랜잭션 내보내기 및 제출하기도커 이미지에서 검증하기검증된 빌드 예시이미 검증된 인기 프로그램들PhoenixSquads V3Drift V2Marginfi V2자주 묻는 질문검증이 실패합니다. 어떻게 해야 하나요?로컬 빌드 해시가 온체인 해시와 일치하지 않습니다. 왜 그런가요?검증에 얼마나 걸리나요?제 프로그램은 불변입니다(업그레이드 권한 없음). 어떻게 검증할 수 있나요?PDA란 무엇이며 왜 중요한가요?API를 사용하기 전에 PDA를 생성해야 하는 이유는 무엇인가요?프로그램을 얼마나 자주 검증해야 하나요?프로그램을 업그레이드하면 어떻게 되나요?검증 결과를 신뢰할 수 있나요?프로그램을 직접 검증하려면 어떻게 하나요?다른 사람이 내 허락 없이 내 프로그램을 검증할 수 있나요?검증 가능한 빌드를 만들려면 무엇이 필요한가요?비공개 저장소를 검증할 수 있나요?Squads Multisig로 제어되는 프로그램을 어떻게 검증하나요?결론보안 + 면책조항Solana 프로그램을 위한 Security.txtsecurity.txt를 사용하는 이유는?security.txt 구현 방법모범 사례
페이지 편집

관리자

© 2026 솔라나 재단.
모든 권리 보유.
연결하기