Programy
Na Solanie inteligentny kontrakt nazywany jest programem. Program to bezstanowe konto, które zawiera kod wykonywalny. Kod ten jest zorganizowany w funkcje nazywane instrukcjami. Użytkownicy interagują z programem, wysyłając transakcję zawierającą jedną lub więcej instrukcji. Transakcja może zawierać instrukcje z wielu programów.
Gdy program jest wdrażany, Solana używa LLVM do skompilowania go w format wykonywalny i linkowalny (ELF). Plik ELF zawiera binarny kod programu w formacie Solana Bytecode Format (sBPF) i jest zapisywany w łańcuchu bloków w koncie wykonywalnym.
sBPF to niestandardowa wersja kodu bajtowego eBPF używana przez Solanę.
Tworzenie programów
Większość programów jest pisana w języku Rust, z dwoma popularnymi podejściami do tworzenia oprogramowania:
- Anchor: Anchor to framework zaprojektowany do szybkiego i łatwego tworzenia na Solanie. Wykorzystuje makra w Rust, aby zredukować ilość kodu szablonowego—co czyni go świetnym wyborem dla początkujących.
- Natívny Rust: Pisanie programów w Rust bez użycia frameworków. To podejście oferuje większą elastyczność, ale wiąże się z większą złożonością.
Aktualizacja programów
Aby
zmodyfikować
istniejący program, konto musi być wyznaczone jako
autorytet aktualizacji.
(Zazwyczaj jest to to samo konto, które pierwotnie
wdrożyło program.) Jeśli autorytet aktualizacji
zostanie odwołany i ustawiony na None, program nie może być już aktualizowany.
Weryfikacja programów
Solana obsługuje weryfikowalne kompilacje, które pozwalają użytkownikom sprawdzić, czy kod programu w łańcuchu bloków odpowiada jego publicznemu kodowi źródłowemu. Framework Anchor zapewnia wbudowane wsparcie dla tworzenia weryfikowalnych kompilacji.
Aby sprawdzić, czy istniejący program jest zweryfikowany, wyszukaj jego ID programu w Solana Explorer. Alternatywnie możesz użyć narzędzia Ellipsis Labs Solana Verifiable Build CLI, aby niezależnie zweryfikować programy w łańcuchu bloków.
Wbudowane programy
System Program
System Program to jedyny program, który może tworzyć nowe konta. Domyślnie wszystkie nowe konta są własnością System Program, chociaż wiele z nich otrzymuje nowego właściciela w momencie tworzenia. System Program wykonuje następujące kluczowe funkcje:
| Funkcja | Opis |
|---|---|
| Tworzenie nowych kont | Tylko System Program może tworzyć nowe konta. |
| Alokacja przestrzeni | Ustawia pojemność w bajtach dla pola danych każdego konta. |
| Przypisanie własności programu | Po utworzeniu konta przez System Program, może on przypisać wyznaczonego właściciela programu do innego konta programu. W ten sposób niestandardowe programy przejmują własność nowych kont utworzonych przez System Program. |
| Transfer SOL | Przenosi lamporty (SOL) z kont System Program na inne konta. |
Adres System Program to 11111111111111111111111111111111.
Programy ładujące
Każdy program jest własnością innego programu – swojego loadera. Loadery są używane do wdrażania, ponownego wdrażania, aktualizacji lub zamykania programów. Służą również do finalizacji programu i przekazania uprawnień programu.
Obecnie istnieje pięć programów ładujących, jak pokazano w poniższej tabeli.
| Loader | ID programu | Uwagi | Link do instrukcji |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | Właściciel pozostałych czterech loaderów | — |
| v1 | BPFLoader1111111111111111111111111111111111 | Instrukcje zarządzania są wyłączone, ale programy nadal działają | — |
| v2 | BPFLoader2111111111111111111111111111111111 | Instrukcje zarządzania są wyłączone, ale programy nadal działają | Instrukcje |
| v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Programy mogą być aktualizowane po wdrożeniu. Wykonywalny program jest przechowywany w oddzielnym koncie danych programu | Instrukcje |
| v4 | LoaderV411111111111111111111111111111111111 | W fazie rozwoju (niewydany) | Instrukcje |
Programy wdrożone za pomocą loader-v3 lub loader-v4 mogą być modyfikowalne po wdrożeniu, w zależności od uprawnień do ich aktualizacji.
Gdy nowy program jest wdrażany, domyślnie używana jest najnowsza wersja loadera.
Wstępnie skompilowane programy
Oprócz programów loader, Solana udostępnia następujące wstępnie skompilowane programy.
Weryfikacja podpisu ed25519
Program ed25519 służy do weryfikacji jednego lub więcej podpisów ed25519.
| Program | ID programu | Opis | Instrukcje |
|---|---|---|---|
| Program Ed25519 | Ed25519SigVerify111111111111111111111111111 | Weryfikuje podpisy ed25519. Jeśli jakikolwiek podpis nie przejdzie, zwracany jest błąd. | Instrukcje |
Program ed25519 przetwarza instrukcję. Pierwszy u8 instrukcji zawiera liczbę
podpisów do sprawdzenia, po której następuje pojedynczy bajt wypełnienia.
Następnie dla każdego podpisu, który ma zostać sprawdzony, serializowana jest
następująca struktura.
struct Ed25519SignatureOffsets {signature_offset: u16, // offset to ed25519 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to public key of 32 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionsinstruction_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}
Weryfikacja odzyskiwania klucza publicznego secp256k1
Program secp256k1 służy do weryfikacji operacji odzyskiwania klucza publicznego secp256k1.
| Program | ID programu | Opis | Instrukcje |
|---|---|---|---|
| Program Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Weryfikuje operacje odzyskiwania klucza publicznego secp256k1 (ecrecover). | Instrukcje |
Program secp256k1 przetwarza instrukcję. Pierwszy bajt instrukcji zawiera liczbę kluczy publicznych do sprawdzenia. Następnie dla każdego klucza publicznego tworzona jest struktura, która jest serializowana i dodawana do danych instrukcji.
struct Secp256k1SignatureOffsets {secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytessecp_signature_instruction_index: u8, // instruction index to find signaturesecp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytessecp_pubkey_instruction_index: u8, // instruction index to find pubkeysecp_message_data_offset: u16, // offset to start of message datasecp_message_data_size: u16, // size of message datasecp_message_instruction_index: u8, // instruction index to find message data}
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionssignature = 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}
To pozwala użytkownikowi określić dowolne dane instrukcji w transakcji dla podpisu i danych wiadomości. Określając specjalny sysvar instrukcji, można również otrzymać dane bezpośrednio z samej transakcji.
Koszt transakcji będzie obliczany jako liczba podpisów do weryfikacji pomnożona przez mnożnik kosztu weryfikacji podpisu.
Program secp256r1 jest używany do weryfikacji do 8 podpisów secp256r1.
| Program | ID programu | Opis | Instrukcje |
|---|---|---|---|
| Program secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Weryfikuje do 8 podpisów secp256r1. Przyjmuje podpis, klucz publiczny i wiadomość. Zwraca błąd, jeśli którykolwiek zawiedzie. | Instrukcje |
Program secp256r1 przetwarza instrukcję. Pierwszy u8 instrukcji to liczba
podpisów do sprawdzenia, po której następuje pojedynczy bajt wypełnienia.
Następnie dla każdego podpisu tworzona jest struktura, która jest serializowana
i dodawana do danych instrukcji.
struct Secp256r1SignatureOffsets {signature_offset: u16, // offset to compact secp256r1 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to compressed public key of 33 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
Niskie wartości S są wymuszane dla wszystkich podpisów, aby uniknąć przypadkowej podatności na modyfikowalność podpisu.
process_instruction() {if data.len() < SIGNATURE_OFFSETS_START {return Error}num_signatures = data[0] as usizeif num_signatures == 0 || num_signatures > 8 {return Error}expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_STARTif 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}
Podstawowe programy
Programy wymienione poniżej zapewniają podstawową funkcjonalność sieci.
| Program | ID programu | Opis | Instrukcje |
|---|---|---|---|
| System | 11111111111111111111111111111111 | Tworzenie nowych kont, przydzielanie danych konta, przypisywanie kont do programów właścicieli, transfer lamportów z kont należących do programu System oraz opłacanie opłat transakcyjnych | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | Tworzenie i zarządzanie kontami śledzącymi stan głosowania walidatorów i nagrody | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | Tworzenie i zarządzanie kontami reprezentującymi stawki i nagrody za delegacje do walidatorów | StakeInstruction |
| Config | Config1111111111111111111111111111111111111 | Dodawanie danych konfiguracyjnych do łańcucha, a następnie lista kluczy publicznych, które mogą je modyfikować. W przeciwieństwie do innych programów, program Config nie definiuje żadnych indywidualnych instrukcji. Ma tylko jedną domyślną instrukcję: „store”. Dane instrukcji to zestaw kluczy, które kontrolują dostęp do konta i przechowywanych w nim danych | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | Ustalanie limitów jednostek obliczeniowych i cen dla transakcji, umożliwiając użytkownikom kontrolowanie zasobów obliczeniowych i opłat za priorytetyzację | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | Zarządzanie tabelami wyszukiwania adresów, które pozwalają transakcjom odwoływać się do większej liczby kont, niż zmieściłoby się na liście kont transakcji | ProgramInstruction |
| ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | Zapewnia weryfikację dowodów zerowej wiedzy dla danych zaszyfrowanych za pomocą ElGamal | — |
Is this page helpful?