W Solanie smart kontrakt nazywany jest programem. Program to bezstanowe konto, które zawiera kod wykonywalny. Kod ten jest zorganizowany w funkcje zwane instrukcjami. Użytkownicy wchodzą w interakcję z programem, wysyłając transakcję zawierającą jedną lub więcej instrukcji. Jedna transakcja może zawierać instrukcje z wielu programów.
Podczas wdrażania programu Solana używa LLVM do kompilacji kodu do formatu wykonywalnego i linkowalnego (ELF). Plik ELF zawiera binarkę programu w formacie Solana Bytecode Format (sBPF) i jest zapisywany on-chain w koncie wykonywalnym.
sBPF to niestandardowa wersja bajtkodu eBPF stworzona przez Solanę.
Tworzenie programów
Większość programów powstaje w języku Rust, a najpopularniejsze są dwa podejścia do developmentu:
- Anchor: Anchor to framework zaprojektowany do szybkiego i prostego tworzenia na Solanie. Wykorzystuje makra Rust, by ograniczyć ilość kodu szablonowego—co czyni go świetnym wyborem dla początkujących.
- Czysty Rust: Pisanie programów w Rust bez użycia frameworków. To podejście daje większą elastyczność, ale jest bardziej złożone.
Aktualizacja programów
Aby
zmodyfikować
istniejący program, należy wyznaczyć konto jako
autorytet do aktualizacji.
(Zwykle jest to to samo konto, które pierwotnie
wdrożyło program.) Jeśli autorytet do aktualizacji
zostanie odebrany i ustawiony na None, program nie może być już aktualizowany.
Weryfikacja programów
Solana obsługuje weryfikowalne buildy, które pozwalają użytkownikom sprawdzić, czy kod programu na blockchainie odpowiada jego publicznemu kodowi źródłowemu. Framework Anchor oferuje wbudowane wsparcie dla tworzenia weryfikowalnych buildów.
Aby sprawdzić, czy istniejący program jest zweryfikowany, wyszukaj jego identyfikator programu (program ID) w Solana Explorer. Alternatywnie możesz użyć narzędzia Ellipsis Labs Solana Verifiable Build CLI, aby samodzielnie zweryfikować programy on-chain.
Wbudowane programy
The System Program
System Program to jedyne konto, które może tworzyć nowe konta. Domyślnie wszystkie nowe konta są własnością System Program, choć wiele z nich otrzymuje nowego właściciela podczas tworzenia. System Program wykonuje następujące kluczowe funkcje:
| Funkcja | Opis |
|---|---|
| Tworzenie nowego konta | Tylko System Program może tworzyć nowe konta. |
| Alokacja miejsca | Ustawia pojemność bajtową pola danych każdego konta. |
| Przypisanie właściciela programu | Po utworzeniu konta przez System Program, może on przypisać innego właściciela programu do tego konta. W ten sposób niestandardowe programy przejmują własność nowych kont utworzonych przez System Program. |
| Transfer SOL | Przesyła lamporty (SOL) z kont System Program do innych kont. |
Adres system program to 11111111111111111111111111111111.
Programy loaderów
Każdy program jest własnością innego programu — swojego loadera. Loadery służą do wdrażania, ponownego wdrażania, aktualizacji lub zamykania programów. Umożliwiają także finalizację programu i przekazanie uprawnień do programu.
Obecnie istnieje pięć programów loaderów, przedstawionych w poniższej tabeli.
| Loader | Program ID | Uwagi | Link do instrukcji |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | Jest właścicielem 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 kod programu jest przechowywany w osobnym koncie programdata | 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 aktualizacji.
Gdy nowy program jest wdrażany, domyślnie używana jest najnowsza wersja loadera.
Programy prekompilowane
Oprócz programów loadera, Solana udostępnia następujące prekompilowane 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 którykolwiek 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 serializowana jest poniższa struktura, po jednej dla każdego podpisu
do weryfikacji.
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 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 poniższa struktura, która jest serializowana i dodawana do instruction data.
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}
Pozwala to użytkownikowi określić dowolne instruction data w transakcji dla podpisu i danych wiadomości. Określając specjalny sysvar instrukcji, można także otrzymać dane bezpośrednio z transakcji.
Koszt transakcji to liczba podpisów do weryfikacji pomnożona przez mnożnik kosztu weryfikacji podpisu.
Program secp256r1 służy 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 podpis jest niepoprawny. | Instrukcje |
Program secp256r1 przetwarza instrukcję. Pierwszy u8 to liczba podpisów do
sprawdzenia, po której następuje pojedynczy bajt wypełnienia. Następnie dla
każdego podpisu tworzona jest poniższa struktura, serializowana i dodawana do
instruction data.
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 zapobiec przypadkowej podatności na modyfikację 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}
Programy podstawowe
Programy z poniższej listy zapewniają podstawową funkcjonalność sieci.
| Program | ID programu | Opis | Instrukcje |
|---|---|---|---|
| System | 11111111111111111111111111111111 | Tworzenie nowych kont, alokacja danych konta, przypisywanie kont do programów właścicieli, transfer lamportów z kont należących do System Program oraz opłacanie opłat transakcyjnych | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | Tworzenie i zarządzanie kontami śledzącymi stan głosowania validatorów oraz nagrody | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | Tworzenie i zarządzanie kontami reprezentującymi stake oraz nagrody za delegacje do validatorów | StakeInstruction |
| Config | Config1111111111111111111111111111111111111 | Dodawanie danych konfiguracyjnych do łańcucha, a następnie listy 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". Jego instruction data to zestaw kluczy kontrolujących dostęp do konta i przechowywanych danych | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | Ustalanie limitów jednostek obliczeniowych i cen dla transakcji, umożliwiając użytkownikom kontrolę nad zasobami obliczeniowymi i opłatami za priorytet | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | Zarządzanie tabelami wyszukiwania adresów, które pozwalają transakcjom odwoływać się do większej liczby kont, niż normalnie zmieściłoby się na liście kont transakcji | ProgramInstruction |
| ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | Zapewnia weryfikację dowodu zerowej wiedzy dla danych zaszyfrowanych ElGamal | — |
Is this page helpful?