
0. 리뷰
1. 개요
이전 블로그에서는 invoke 함수와 invoke_signed 함수를 통해 크로스 프로그램 호출을 구현하는 방법을 소개했습니다. 이번 포스트에서는 또 다른 기본 주제인 프로그램 업그레이드에 대해 소개하겠습니다.
2. 업그레이드 가능한 프로그램 배포
기본적으로 배포된 모든 프로그램은 Solana에서 BPFLoaderUpgradeable 로더를 사용하여 배포되며, 이는 업그레이드가 가능함을 의미합니다. 이 외에도 Solana는 배포된 프로그램을 불변으로 만들기 위한 --final 옵션을 제공합니다. 이 경우 BPFLoader2 로더를 사용하여 프로그램을 배포하며, 배포 후에는 프로그램을 업그레이드할 수 없습니다.
BPFLoaderUpgradeable 로더 프로그램은 프로그램 계정, 프로그램 데이터 계정, 버퍼 계정의 세 가지 유형의 계정을 관리합니다. 배포 과정에서 먼저 버퍼 계정이 생성됩니다. 그 후 Solana CLI는 대상 프로그램의 바이트코드를 로드하여 버퍼 계정에 기록합니다. 최종적으로 버퍼 계정에 저장된 바이트코드는 프로그램 데이터 계정에 복사됩니다.
따라서 버퍼 계정은 배포 과정에서 바이트코드를 임시로 저장하기 위해 업그레이드 가능한 BPF 로더가 사용하며, 프로그램 데이터 계정은 프로그램의 실제 데이터를 저장하고, 프로그램 계정은 해당 프로그램 데이터 계정을 가리키는 프록시 역할을 합니다.
아래에서는 프로그램을 업그레이드하는 몇 가지 샘플을 살펴보겠습니다. 이 포스트에서 사용된 모든 코드는 여기에서 확인할 수 있습니다.
2.1 코드 리뷰 (Rectangle_Area)

이 샘플 컨트랙트에서는 13번째 줄부터 17번째 줄까지 width, height, area의 세 가지 속성을 포함하는 Rectangle이라는 구조체를 정의합니다. 또한 Rectangle에 대한 area() 함수를 정의합니다. area() 함수는 width와 height를 사용하여 사각형의 넓이를 계산합니다.

process_instruction() 함수에서는 먼저 unpack_u32() 함수를 사용하여 명령 데이터에서 사각형의 width와 height를 추출합니다 (45번째 줄 - 46번째 줄). 51번째 줄에서는 사각형의 데이터를 저장하는 데 사용되는 계정을 추출합니다. 59번째 줄에서는 try_from_slice_unchecked() 함수가 Rectangle 구조체 타입으로 계정의 데이터를 역직렬화합니다. 다음으로 구조체의 해당 필드에 데이터를 할당하고 넓이 값을 계산합니다 (61번째 줄 - 63번째 줄). 마지막 단계는 데이터를 직렬화하고 데이터 계정에 다시 기록하는 것입니다.
배포된 프로그램은 아래 링크에서 확인할 수 있습니다.
https://explorer.solana.com/address/84mMqHRTQT6b2vfsD7XRxVKA3XMd7xoEXFdF6pLNw8y?cluster=testnet
2.2 트랜잭션 전송

클라이언트 측에서는 먼저 데이터를 저장할 계정을 생성하기 위한 트랜잭션을 전송합니다. 충분한 공간을 확보하기 위해 공간 크기를 1,024바이트로 설정합니다.

그런 다음 사각형의 넓이를 계산하고 데이터 계정에 저장하기 위한 또 다른 트랜잭션을 전송합니다.
트랜잭션은 아래 링크에서 확인할 수 있습니다.
https://explorer.solana.com/tx/4PybjXGRpuPKpak7FAz4BKMbcQCWmway69zAxtTnpFRuTTg7onyxW7agSe6ETx44iAGexbgnBUa8WdzdTTQSawJ3?cluster=testnet
3. 업그레이드
이제 프로그램에 사각형의 둘레를 계산하는 새로운 함수를 추가하고자 합니다.

업데이트된 프로젝트를 컴파일한 후, 다음 명령어를 사용하여 온체인에 배포된 프로그램을 업그레이드합니다.
solana program deploy /path/to/program.so --program-id <PROGRAM_ID>
컨트랙트는 직접 업그레이드할 수 있으며, 관련 트랜잭션은 아래에서 확인할 수 있습니다.
https://explorer.solana.com/tx/4Dm9v4zMiijKjQBhatx1D9xbV9PvMLdaonUWLaC2VwzkFvzdgorzbX5vsy4VQ7VxSUmqadftjiDzbyUmXgQchYmk?cluster=testnet
업그레이드가 성공적으로 완료되었는지 확인하기 위해 프로그램에 트랜잭션을 추가로 전송합니다. 결과는 함수가 정상적으로 작동함을 보여줍니다.
관련 트랜잭션은 아래에서 확인할 수 있습니다.
https://explorer.solana.com/tx/21c2G7kPVktAtdUFkH3QwGVi7orajRmy5PJo1UxX1mmAMU68eUkNuLzWYJRBaTzwGi5DxeocYjHfpWiU4hcSFtpQ?cluster=testnet
4. 재업그레이드

이번에는 계산된 둘레를 데이터 계정에 저장하고자 합니다. 이를 위해 Rectangle 구조체에 perimeter 속성을 하나 더 추가합니다 (18번째 줄).

데이터 계정의 구조체가 이전과 다르기 때문에, 먼저 데이터 계정에서 데이터를 읽어야 합니다. 기존 구조체(즉, OldRectangle)를 사용하여 저장된 데이터를 역직렬화합니다. 그 후 관련 속성을 새 구조체(즉, CurrentRectangle)에 할당하고 새 속성(즉, perimeter)을 초기화합니다.

마지막으로 둘레 값을 계산하여 account_data에 직렬화하기 전에 update_account에 다시 할당합니다.
업그레이드를 위한 트랜잭션은 아래에서 확인할 수 있습니다.
https://explorer.solana.com/tx/5J3oKxZXtCi755gD7pMnVh48AFvmeVzRLPgJiyNn8JFeCKx1xpAfJtsi34zjyYKJmnMk8LtC3bcwfFSP7H2gtj5o?cluster=testnet
업그레이드 후 solana account <DataAccount> 명령어를 사용하여 계정에 저장된 데이터를 확인할 수 있습니다. 속성들이 처음 32바이트에 저장되어 있는 것을 확인할 수 있습니다. 전체 업그레이드 과정이 완료되었습니다.

5. 결론
이 글에서는 Solana에서 프로그램을 업그레이드하는 방법을 소개했습니다. 다양한 예시를 통해 세부 과정을 설명했습니다. 계속 지켜봐 주세요. Solana에 관한 더 많은 글이 게시될 예정입니다.
이 시리즈의 다른 글 읽기:
- Solana 생태계 보안 (1) — Hello Solana
- Solana 생태계 보안 (2) — 프로그램 간 호출
- Solana 생태계 보안 (4) — 계정 유효성 검사
- Solana 생태계 보안 (5) — 멀티 서명
- Solana 생태계 보안 (6) — 멀티 서명2
- Solana 생태계 보안 (7) — 타입 혼동
BlockSec 소개
BlockSec은 전 세계적으로 著名한 보안 전문가 그룹이 2021년에 설립한 선도적인 블록체인 보안 회사입니다. 이 회사는 대중적 채택을 촉진하기 위해 새롭게 부상하는 Web3 세계의 보안성과 사용성을 향상시키는 데 전념하고 있습니다. 이를 위해 BlockSec은 스마트 컨트랙트 및 EVM 체인 보안 감사 서비스, 위협을 사전에 차단하고 보안 개발을 위한 Phalcon 플랫폼, 자금 추적 및 조사를 위한 MetaSleuth 플랫폼, 그리고 Web3 빌더들이 크립토 세계를 효율적으로 탐색할 수 있는 MetaSuites 확장 프로그램을 제공합니다.
현재까지 MetaMask, Uniswap Foundation, Compound, Forta, PancakeSwap 등 300개 이상의 저명한 클라이언트에 서비스를 제공했으며, Matrix Partners, Vitalbridge Capital, Fenbushi Capital 등 저명한 투자자들로부터 두 차례의 자금 조달 라운드를 통해 수천만 달러를 유치했습니다.
공식 웹사이트: https://blocksec.com/
공식 트위터 계정: https://twitter.com/BlockSecTeam



