프로그램

솔라나에서 스마트 컨트랙트는 프로그램이라고 불립니다. 프로그램은 실행 가능한 코드를 포함하는 상태가 없는 계정입니다. 이 코드는 명령어라고 불리는 함수로 구성되어 있습니다. 사용자는 하나 이상의 명령어가 포함된 트랜잭션을 보내 프로그램과 상호작용합니다. 트랜잭션은 여러 프로그램의 명령어를 포함할 수 있습니다.

프로그램이 배포되면, 솔라나는 LLVM을 사용하여 실행 가능하고 연결 가능한 형식 (ELF)으로 컴파일합니다. ELF 파일은 솔라나 바이트코드 형식(sBPF)으로 된 프로그램의 바이너리를 포함하며 실행 가능한 계정에 온체인으로 저장됩니다.

sBPF는 솔라나의 맞춤형 eBPF 바이트코드 버전입니다.

프로그램 작성하기

대부분의 프로그램은 Rust로 작성되며, 두 가지 일반적인 개발 접근 방식이 있습니다:

  • Anchor: Anchor는 빠르고 쉬운 솔라나 개발을 위해 설계된 프레임워크입니다. Rust 매크로를 사용하여 상용구 코드를 줄여 초보자에게 적합합니다.
  • 네이티브 Rust: 프레임워크를 활용하지 않고 Rust로 프로그램을 작성합니다. 이 접근 방식은 더 많은 유연성을 제공하지만 복잡성이 증가합니다.

프로그램 업데이트하기

기존 프로그램을 수정하려면, 계정이 업그레이드 권한으로 지정되어야 합니다. (일반적으로 원래 프로그램을 배포한 동일한 계정입니다.) 업그레이드 권한이 취소되고 null로 설정되면, 프로그램은 더 이상 업데이트될 수 없습니다.

프로그램 검증하기

솔라나는 사용자가 프로그램의 온체인 코드가 공개 소스 코드와 일치하는지 확인할 수 있는 검증 가능한 빌드를 지원합니다. Anchor 프레임워크는 검증 가능한 빌드를 생성하기 위한 내장 지원을 제공합니다.

기존 프로그램이 검증되었는지 확인하려면, 솔라나 익스플로러에서 프로그램 ID를 검색하세요. 또는 Ellipsis Labs의 솔라나 검증 가능한 빌드 CLI를 사용하여 온체인 프로그램을 독립적으로 검증할 수 있습니다.

내장 프로그램

System Program

System Program은 새 계정을 생성할 수 있는 유일한 계정입니다. 기본적으로, 모든 새 계정은 System Program이 소유하지만, 많은 계정들은 생성 시 새로운 소유자에게 할당됩니다. System Program은 다음과 같은 주요 기능을 수행합니다:

기능설명
새 계정 생성System Program만이 새 계정을 생성할 수 있습니다.
공간 할당각 계정의 데이터 필드에 대한 바이트 용량을 설정합니다.
프로그램 소유권 할당System Program이 계정을 생성한 후, 지정된 프로그램 소유자를 다른 program account로 재할당할 수 있습니다. 이것이 커스텀 프로그램이 System Program에 의해 생성된 새 계정의 소유권을 가져가는 방식입니다.
SOL 전송시스템 계정에서 다른 계정으로 lamports(SOL)를 전송합니다.

System Program의 주소는 11111111111111111111111111111111입니다.

로더 프로그램

모든 프로그램은 다른 프로그램—로더—에 의해 소유됩니다. 로더는 프로그램을 배포, 재배포, 업그레이드 또는 종료하는 데 사용됩니다. 또한 프로그램을 완료하고 프로그램 권한을 이전하는 데도 사용됩니다.

로더 프로그램은 때때로 'BPF 로더'라고도 불립니다.

현재 아래 표와 같이 다섯 개의 로더 프로그램이 있습니다.

로더프로그램 ID참고명령어 링크
nativeNativeLoader1111111111111111111111111111111다른 네 개의 로더를 소유함
v1BPFLoader1111111111111111111111111111111111관리 명령어는 비활성화되었지만, 프로그램은 여전히 실행됨
v2BPFLoader2111111111111111111111111111111111관리 명령어는 비활성화되었지만, 프로그램은 여전히 실행됨명령어
v3BPFLoaderUpgradeab1e11111111111111111111111프로그램은 배포 후 업데이트 가능. 프로그램 실행 파일은 별도의 프로그램 데이터 계정에 저장됨명령어
v4LoaderV411111111111111111111111111111111111개발 중(미출시)명령어

loader-v3 또는 loader-v4로 배포된 프로그램은 업그레이드 권한에 따라 배포 후에도 수정이 가능할 수 있습니다.

새 프로그램이 배포될 때는 기본적으로 최신 로더 버전이 사용됩니다.

사전 컴파일된 프로그램

로더 프로그램 외에도 Solana는 다음과 같은 사전 컴파일된 프로그램을 제공합니다.

ed25519 서명 검증

ed25519 프로그램은 하나 이상의 ed25519 서명을 검증하는 데 사용됩니다.

프로그램프로그램 ID설명명령어
Ed25519 프로그램Ed25519SigVerify111111111111111111111111111ed25519 서명을 검증합니다. 서명이 하나라도 실패하면 오류가 반환됩니다.명령어

ed25519 프로그램은 명령어를 처리합니다. 명령어의 첫 번째 u8에는 검사할 서명 수가 포함되어 있고, 그 뒤에 단일 바이트 패딩이 있습니다. 그 후, 검사할 각 서명에 대해 다음 구조체가 직렬화됩니다.

Ed25519SignatureOffsets
struct Ed25519SignatureOffsets {
signature_offset: u16, // offset to ed25519 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to public key of 32 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}
Signature verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
instruction_index = ed25519_signature_instruction_index != u16::MAX ? ed25519_signature_instruction_index : current_instruction;
signature = instructions[instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]
instruction_index = ed25519_pubkey_instruction_index != u16::MAX ? ed25519_pubkey_instruction_index : current_instruction;
pubkey = instructions[instruction_index].data[ed25519_pubkey_offset..ed25519_pubkey_offset + 32]
instruction_index = ed25519_message_instruction_index != u16::MAX ? ed25519_message_instruction_index : current_instruction;
message = instructions[instruction_index].data[ed25519_message_data_offset..ed25519_message_data_offset + ed25519_message_data_size]
if pubkey.verify(signature, message) != Success {
return Error
}
}
return Success
}

secp256k1 복구 검증

secp256k1 프로그램은 secp256k1 공개 키 복구 작업을 검증하는 데 사용됩니다.

프로그램프로그램 ID설명명령어
Secp256k1 프로그램KeccakSecp256k11111111111111111111111111111secp256k1 공개 키 복구 작업(ecrecover)을 검증합니다.명령어

secp256k1 프로그램은 명령어를 처리합니다. 명령어의 첫 번째 바이트에는 검사할 공개 키 수가 포함되어 있습니다. 그 후, 각 공개 키에 대해 다음 구조체가 한 번씩 생성된 다음 직렬화되어 명령어 데이터에 추가됩니다.

Secp256k1SignatureOffsets
struct Secp256k1SignatureOffsets {
secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytes
secp_signature_instruction_index: u8, // instruction index to find signature
secp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytes
secp_pubkey_instruction_index: u8, // instruction index to find pubkey
secp_message_data_offset: u16, // offset to start of message data
secp_message_data_size: u16, // size of message data
secp_message_instruction_index: u8, // instruction index to find message data
}
Recovery verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
signature = instructions[secp_signature_instruction_index].data[secp_signature_offset..secp_signature_offset + 64]
recovery_id = instructions[secp_signature_instruction_index].data[secp_signature_offset + 64]
ref_eth_pubkey = instructions[secp_pubkey_instruction_index].data[secp_pubkey_offset..secp_pubkey_offset + 20]
message_hash = keccak256(instructions[secp_message_instruction_index].data[secp_message_data_offset..secp_message_data_offset + secp_message_data_size])
pubkey = ecrecover(signature, recovery_id, message_hash)
eth_pubkey = keccak256(pubkey[1..])[12..]
if eth_pubkey != ref_eth_pubkey {
return Error
}
}
return Success
}

이를 통해 사용자는 서명 및 메시지 데이터에 대한 트랜잭션에서 어떤 명령어 데이터도 지정할 수 있습니다. 특별한 명령어 sysvar를 지정하면 트랜잭션 자체에서도 데이터를 받을 수 있습니다.

트랜잭션 비용은 검증할 서명 수에 서명 비용 검증 승수를 곱한 값으로 계산됩니다.

secp256r1 프로그램은 최대 8개의 secp256r1 서명을 검증하는 데 사용됩니다.

프로그램프로그램 ID설명명령어
Secp256r1 프로그램Secp256r1SigVerify1111111111111111111111111최대 8개의 secp256r1 서명을 검증합니다. 서명, 공개 키 및 메시지를 입력받습니다. 실패 시 오류를 반환합니다.명령어

secp256r1 프로그램은 명령어를 처리합니다. 명령어의 첫 번째 u8에는 확인할 서명 수가 포함되어 있으며, 그 뒤에 단일 바이트 패딩이 있습니다. 그 후, 다음 구조체가 각 서명마다 생성된 다음 직렬화되어 명령어 데이터에 추가됩니다.

Secp256r1SignatureOffsets
struct Secp256r1SignatureOffsets {
signature_offset: u16, // offset to compact secp256r1 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to compressed public key of 33 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}

모든 서명에 대해 낮은 S 값이 적용되어 우발적인 서명 가변성을 방지합니다.

Signature verification psuedocode
process_instruction() {
if data.len() < SIGNATURE_OFFSETS_START {
return Error
}
num_signatures = data[0] as usize
if num_signatures == 0 || num_signatures > 8 {
return Error
}
expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START
if data.len() < expected_data_size {
return Error
}
for i in 0..num_signatures {
offsets = parse_signature_offsets(data, i)
signature = get_data_slice(data, instruction_datas, offsets.signature_instruction_index, offsets.signature_offset, SIGNATURE_SERIALIZED_SIZE)
if s > half_curve_order {
return Error
}
pubkey = get_data_slice(data, instruction_datas, offsets.public_key_instruction_index, offsets.public_key_offset, COMPRESSED_PUBKEY_SERIALIZED_SIZE)
message = get_data_slice(data, instruction_datas, offsets.message_instruction_index, offsets.message_data_offset, offsets.message_data_size)
if !verify_signature(signature, pubkey, message) {
return Error
}
}
return Success
}

코어 프로그램

아래 목록의 프로그램들은 네트워크의 핵심 기능을 제공합니다.

프로그램프로그램 ID설명명령어
시스템11111111111111111111111111111111새 계정 생성, 계정 데이터 할당, 계정을 소유 프로그램에 할당, 시스템 프로그램 소유 계정에서 lamport 전송, 트랜잭션 수수료 지불SystemInstruction
투표Vote111111111111111111111111111111111111111validator 투표 상태 및 보상을 추적하는 계정 생성 및 관리VoteInstruction
스테이크Stake11111111111111111111111111111111111111validator에 위임된 스테이크 및 보상을 나타내는 계정 생성 및 관리StakeInstruction
설정Config1111111111111111111111111111111111111체인에 구성 데이터를 추가하고, 이를 수정할 수 있는 공개 키 목록을 추가합니다. 다른 프로그램과 달리 Config 프로그램은 개별 명령어를 정의하지 않습니다. 단 하나의 암시적 명령어 "store"만 있습니다. 명령어 데이터는 계정 및 그 안에 저장된 데이터에 대한 접근을 제어하는 키 세트입니다ConfigInstruction
컴퓨트 예산ComputeBudget111111111111111111111111111111트랜잭션의 컴퓨트 유닛 한도와 가격을 설정하여 사용자가 컴퓨팅 리소스와 우선순위 수수료를 제어할 수 있게 합니다ComputeBudgetInstruction
주소 조회 테이블AddressLookupTab1e1111111111111111111111111주소 조회 테이블을 관리하여 트랜잭션이 계정 목록에 맞는 것보다 더 많은 계정을 참조할 수 있게 합니다ProgramInstruction
ZK ElGamal 증명ZkE1Gama1Proof11111111111111111111111111111ElGamal 암호화 데이터에 대한 영지식 증명 검증을 제공합니다

Is this page helpful?

목차

페이지 편집

관리자

© 2025 솔라나 재단.
모든 권리 보유.