Transakcje
Ostatnia edycja: @wosek_(opens in a new tab), 16 lipca 2024
Transakcje to podpisane kryptograficznie instrukcje od kont. Konto inicjuje transakcję, aby zaktualizować stan sieci Ethereum. Najprostszą transakcją jest przeniesienie ETH z jednego konta na drugie.
Warunki wstępne
Aby lepiej zrozumieć tę stronę, zalecamy najpierw przeczytanie rozdziału o kontach oraz naszym wprowadzeniu do Ethereum.
Czym jest transakcja?
Transakcja Ethereum odnosi się do działania zainicjowanego przez konto zewnętrzne, czyli takie, które jest zarządzane przez człowieka, a nie przez kontrakt. Na przykład, jeśli Bob wysyła Alice 1 ETH, na koncie Boba musi się pojawić obciążenie, a na koncie Alice uznanie. Ta zmiana stanu ma miejsce w ramach transakcji.
Diagram zaadaptowany z Ilustrowanego Ethereum EVM(opens in a new tab)
Transakcje, które zmieniają stan EVM, muszą być rozesłane do całej sieci. Każdy węzeł może rozesłać prośbę o wykonanie transakcji na EVM; po tym wydarzeniu walidator wykona transakcję i roześle powstałą zmianę stanu do reszty sieci.
Transakcje wymagają opłaty i muszą być uwzględnione w ważnym bloku. Aby uprościć ten przegląd, omówimy opłaty za gaz i walidację w innym miejscu.
Przesłana transakcja zawiera następujące informacje:
from
— adres nadawcy, który będzie podpisywać transakcję. Będzie to konto zewnętrzne, ponieważ konta kontraktowe nie mogą wysyłać transakcjito
— adres odbiorcy (jeśli jest to konto zewnętrzne, to transakcja przekaże wartość. Natomiast jeśli jest to konto kontraktowe to, transakcja wykona kod kontraktu)signature
— identyfikator nadawcy. Jest on generowany, kiedy klucz prywatny nadawcy podpisuje transakcję i potwierdza, że nadawca autoryzował tę transakcjęnonce
— sekwencyjnie zwiększający się licznik, który wskazuje na numer transakcji kontavalue
— kwota ETH do przesłania od nadawcy do odbiorcy (wyrażona w WEI, gdzie 1 ETH jest równy 1e+18wei)input data
— opcjonalne pole do umieszczania dowolnych danychgasLimit
— maksymalna ilość jednostek gazu, które mogą zostać zużyte w trakcie transakcji. EVM określa, ile jednostek gazu wymaga każdy krok obliczeniowymaxPriorityFeePerGas
— maksymalna cena zużytego gazu, która zostanie uwzględniona jako napiwek dla walidatoramaxFeePerGas
— maksymalna opłata za jednostkę gazu, jaką użytkownik jest w stanie zapłacić za transakcję (w tymbaseFeePerGas
imaxPriorityFeePerGas
)
Gaz jest odniesieniem do obliczeń wymaganych do przetworzenia transakcji przez walidatora. Użytkownicy muszą zapłacić opłatę za to obliczenie. gasLimit
i maxPriorityFeePerGas
określają maksymalną opłatę transakcyjną płaconą walidatorowi. Więcej na temat gazu.
Obiekt transakcji będzie wyglądał mniej więcej w ten sposób:
1{2 from: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8",3 to: "0xac03bb73b6a9e108530aff4df5077c2b3d481e5a",4 gasLimit: "21000",5 maxFeePerGas: "300",6 maxPriorityFeePerGas: "10",7 nonce: "0",8 value: "10000000000"9}Pokaż wszystkoKopiuj
Obiekt transakcji musi być podpisany jednak przy użyciu klucza prywatnego nadawcy. Dowodzi to, że transakcja mogła pochodzić jedynie od nadawcy i nie została wysłana w sposób nieuczciwy.
Klient Ethereum, jak Geth, będzie obsługiwać ten proces podpisywania.
Przykład wywołania JSON-RPC:
1{2 "id": 2,3 "jsonrpc": "2.0",4 "method": "account_signTransaction",5 "params": [6 {7 "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db",8 "gas": "0x55555",9 "maxFeePerGas": "0x1234",10 "maxPriorityFeePerGas": "0x1234",11 "input": "0xabcd",12 "nonce": "0x0",13 "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",14 "value": "0x1234"15 }16 ]17}Pokaż wszystkoKopiuj
Przykładowa odpowiedź:
1{2 "jsonrpc": "2.0",3 "id": 2,4 "result": {5 "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",6 "tx": {7 "nonce": "0x0",8 "maxFeePerGas": "0x1234",9 "maxPriorityFeePerGas": "0x1234",10 "gas": "0x55555",11 "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",12 "value": "0x1234",13 "input": "0xabcd",14 "v": "0x26",15 "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e",16 "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",17 "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"18 }19 }20}Pokaż wszystkoKopiuj
raw
jest podpisaną transakcją w zakodowanym formacie prefiksu o rekursywnej długości (RLP)tx
jest podpisaną transakcją w formacie JSON
Dzięki hashowi podpisu można udowodnić kryptograficznie, że transakcja pochodzi od nadawcy i została przesłana do sieci.
Pole danych
Zdecydowana większość transakcji uzyskuje dostęp do kontraktu z konta zewnętrznego. Większość kontraktów jest napisana w Solidity i interpretuje swoje pole danych zgodnie z .
Pierwsze cztery bajty określają, które funkcje mają zostać wywołane, korzystając z hasha nazwy funkcji i jej argumentów. Możesz czasami zidentyfikować funkcję z selektora korzystając z tej bazy danych(opens in a new tab).
Reszta danych wywoławczych to argumenty, zakodowane zgodnie ze specyfikacją ABI(opens in a new tab).
Spójrzmy dla przykładu na tę transakcję(opens in a new tab). Kliknij Click to show more, aby zobaczyć dane wywoławcze.
Selektorem funkcji jest 0xa9059cbb
. Istnieje kilka znanych funkcji z tym podpisem(opens in a new tab). W tym przypadku kod źródłowy kontraktu(opens in a new tab) został opublikowany na Etherscan, więc wiemy, że funkcją jest transfer(address,uint256)
.
Reszta danych to:
10000000000000000000000004f6742badb049791cd9a37ea913f2bac38d012792000000000000000000000000000000000000000000000000000000003b0559f4
Zgodnie ze specyfikacją ABI wartości całkowite (takie jak adresy, które są 20-bajtowymi wartościami całkowitymi) wyświetlają się w ABI jako 32-bajtowe słowa, uzupełnione zerami z przodu. Wiemy więc, że adres to
wygląda tak 4f6742badb049791cd9a37ea913f2bac38d01279
(opens in a new tab). Wartość value
wynosi 0x3b0559f4 = 990206452.
Rodzaje transakcji
W Ethereum istnieje kilka różnych rodzajów transakcji:
- Zwykłe transakcje: transakcja z jednego konta na drugie.
- Transakcje wdrożenia kontraktu: transakcja bez adresu „to”, w którym pole danych jest wykorzystywane dla kodu kontraktu.
- Wykonanie kontraktu: transakcja, która wchodzi w interakcję z wdrożonym inteligentnym kontraktem. W tym przypadku adres „to” jest adresem inteligentnego kontraktu.
Na temat gazu
Jak już wspomniano, wykonanie transakcji kosztuje gaz. Proste transakcje transferu wymagają 21 000 jednostek gazu.
A więc, aby Bob mógł wysłać Alice 1 ETH przy baseFeePerGas
wynoszącym 190 gwei i maxPriorityFeePerGas
wynoszącym 10 gwei, Bob będzie musiał zapłacić następującą opłatę:
1(190 + 10) * 21 000 = 4 200 000 gwei2--lub--30,0042 ETH
Konto Boba zostanie obciążone kwotą 1,0042 ETH (1 ETH dla Alice + 0,0042 ETH w opłatach za gaz)
Konto Alicji zostanie zasilone kwotą 1,0 ETH
Podstawowa opłata wynosząca 0,00399 ETH zostanie spalona
Walidator zatrzyma napiwek wynoszący 0,000210 ETH
Schemat zaadaptowany z Ilustracja Ethereum EVM(opens in a new tab)
Gaz niewykorzystany w transakcji jest zwracany na konto użytkownika.
Interakcje z inteligentnymi kontraktami
Gaz jest wymagany dla każdej transakcji wiążącej się z inteligentnym kontraktem.
Inteligentne kontrakty mogą również zawierać funkcje takie jak view
(opens in a new tab) czy pure
(opens in a new tab), które nie zmieniają stanu kontraktu. W związku z tym wywoływanie tych funkcji z konta zewnętrznego nie będzie wymagało żadnego gazu. Podstawowym wywołaniem RPC dla takiego scenariusza jest eth_call
W przeciwieństwie do dostępu przy użyciu eth_call
, funkcje view
czy pure
są również często wywoływane wewnętrznie (tj. z samego kontraktu lub od innego kontraktu) co już wymaga gazu.
Cykl życiowy transakcji
Po przesłaniu transakcji dzieją się następujące wydarzenia:
- Hash transakcji zostaje kryptograficznie wygenerowany:
0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017
- Transakcja zostaje następnie rozgłoszona do sieci i dodawana do puli transakcji składającej się z wszystkich innych oczekujących transakcji w sieci.
- Walidator musi wybrać Twoją transakcję i uwzględnić ją w bloku, aby ją zweryfikować transakcję i uznać ją za „udaną”.
- W miarę upływu czasu blok zawierający Twoją transakcję zostanie zaktualizowany do kategorii „uzasadniony”, a następnie „sfinalizowany”. Aktualizacje te znacznie zwiększają pewność, że Twoja transakcja zakończyła się sukcesem i nie będzie można jej zmienić. Po „sfinalizowaniu” bloku mógłby on zostać zmieniony tylko przez atak na poziomie sieci, który kosztowałby miliardy dolarów.
Demo wizualne
Zobacz, jak Austin opowiada o transakcjach, gazie i kopaniu.
Typed Transaction Envelope
Ethereum pierwotnie miało jeden format transakcji. Każda transakcja zawierała nonce, cenę gazu, limit gazu, adres docelowy, wartość, dane, v, r oraz s. Pola te są zakodowane w RLP, aby wyglądały mniej więcej tak:
RLP([nonce, gasPrice, gasLimit, to, value, data, v, r, s])
Ethereum wyewoluowało i wspiera wiele rodzajów transakcji, zezwalając na wdrażanie nowych funkcji takich jak listy dostępu i EIP-1559(opens in a new tab), bez wpływania na starsze formaty transakcji.
EIP-2718(opens in a new tab) jest tym, co umożliwia takie zachowanie. Transakcję są interpretowane jako:
TransactionType || TransactionPayload
Gdzie pola są definiowane jako:
TransactionType
— liczba z zakresu od 0 do 0x7f, zapewniająca w sumie 128 możliwych rodzajów transakcji.TransactionPayload
— dowolna tablica bajtów zdefiniowana przez rodzaj transakcji.
Na podstawie wartości TransactionType
, transakcje mogą być definiowane jako:
Transakcje typu 0 (starsze): oryginalny format transakcji używany od samego początku Ethereum. Nie zawierają funkcji z EIP-1559(opens in a new tab), takich jak dynamiczne obliczenia opłat za gaz czy list dostępu do inteligentnych kontraktów. Starsze transakcje nie mają określonego prefiksu wskazującego na ich typ w ich serializowanej formie, począwszy od bajtu
0xf8
przy użyciu kodowania prefiksu o rekursywnej długości (RLP). Wartość TransactionType dla tych transakcji wynosi0x0
.Transakcje typu 1: wprowadzone w EIP-2930(opens in a new tab) jako część uaktualnienia Berlin sieci Ethereum transakcje te zawierają parametr
accessList
. Ta lista określa adresy i klucze przechowywania, do których transakcja oczekuje dostępu, potencjalnie pomagając zmniejszyć koszty gazu złożonych transakcji wykorzystujących inteligentne kontrakty. Zmiany rynku opłat EIP-1559 nie są uwzględnione w transakcjach typu 1. Transakcje typu 1 zawierają również parametryParity
, który może wynosić zarówno0x0
jak i0x1
, wskazując na parzystość wartości y podpisu secp256k1. Są identyfikowane przez początkowy bajt0x01
, a ich wartość TransactionType wynosi0x1
.Transakcje typu 2, powszechnie określane jako transakcje EIP-1559, to transakcje wprowadzone w EIP-1559(opens in a new tab), w ramach uaktualnienia London sieci Ethereum. Stały się one standardowym rodzajem transakcji w sieci Ethereum. Transakcje te wprowadziły nowy mechanizm rynku opłat, który poprawia przewidywalność, rozdzielając opłaty transakcyjne na opłatę podstawową oraz opłatę priorytetową. Zaczynają się bajtem
0x02
i zawierają takie pola jakmaxPriorityFeePerGas
imaxFeePerGas
. Transakcje typu 2 są teraz domyślnymi, ze względu na ich elastyczność i wydajność, są szczególnie preferowanie podczas okresów dużego przeciążenia sieci ze względu na zdolność pomagania użytkownikom w zarządzaniu opłatami transakcyjnymi w bardziej przewidywalny sposób. Wartość TransactionType dla tych transakcji wynosi0x2
.
Dodatkowo przeczytaj
Znasz jakieś zasoby społeczności, które Ci pomogły? Wyedytuj tę stronę i dodaj je!