Wdrożenie smart kontraktu na mainnecie (czyli głównej sieci blockchain, takiej jak Ethereum) wiąże się z zasadniczą cechą tej technologii – niezmiennością. To jedna z kluczowych zalet blockchainu, która daje użytkownikom pewność, że wdrożony kod nie zostanie zmieniony bez ich wiedzy. Jednakże w rzeczywistości programiści blockchain znaleźli kilka kreatywnych sposobów na wprowadzenie możliwości aktualizacji kontraktów. W tym artykule przyjrzymy się dostępnym rozwiązaniom, ich zaletom, wadom oraz przeanalizujemy konkretne przykłady ich zastosowań.
Dlaczego kontrakty na blockchainie są zazwyczaj niezmienne?
Gdy kontrakt zostaje wdrożony na blockchain, jego kod staje się trwale zapisany w sieci i działa według ustalonych w nim zasad. Dzięki temu użytkownicy mają pewność, że raz wdrożony kontrakt działa zgodnie z zaprogramowanymi regułami i nikt nie może ich zmienić bez ich zgody.
Przykład:
Załóżmy, że powstał kontrakt służący do przechowywania głosów oddanych w referendum online. Użytkownicy mogą zaufać, że zasady głosowania są ustalone raz na zawsze, a wyniki nie będą zmienione, ponieważ nikt nie może zmodyfikować kodu kontraktu po jego wdrożeniu. To daje pewność uczestnikom, że ich głosy nie zostaną zmanipulowane.
Techniki umożliwiające aktualizację kontraktów
Pomimo niezmienności blockchainu, istnieje kilka sposobów na obejście tej cechy i zapewnienie pewnej elastyczności, szczególnie w projektach, które wymagają dostosowywania się do zmieniających się potrzeb użytkowników.
1. Proxy Pattern (wzorzec proxy)
Proxy Pattern to jedna z najczęściej stosowanych technik, która umożliwia aktualizację smart kontraktów. Metoda ta polega na podzieleniu kontraktu na dwie odrębne części:
- Kontrakt logiki (Logic Contract) – przechowujący kod i funkcjonalność.
- Kontrakt proxy (Proxy Contract) – przechowujący dane i delegujący wywołania do kontraktu logiki.
Proxy Contract działa jako pośrednik i deleguje wszystkie zapytania do Logic Contract. Kiedy zachodzi potrzeba aktualizacji, programiści wdrażają nowy kontrakt logiki i wskazują na niego adres proxy. Dzięki temu logika działania może zostać zmieniona bez konieczności zmiany danych i adresu proxy, który pozostaje bez zmian dla użytkowników.
Przykład zastosowania Proxy Pattern
Wyobraźmy sobie, że wdrażamy aplikację DeFi (Decentralized Finance), która pozwala użytkownikom pożyczać i inwestować środki w różnych kryptowalutach. Początkowa wersja kontraktu może mieć podstawowe funkcje, takie jak wpłaty i wypłaty. Z czasem, gdy projekt się rozwija, twórcy chcą dodać nowe opcje, np. automatyczne alokowanie kapitału czy lepsze mechanizmy zabezpieczeń. Zamiast wdrażać nowy kontrakt i przenosić wszystkie środki, twórcy mogą po prostu wdrożyć nową wersję kontraktu logiki, a Proxy Contract będzie dalej działać z nową logiką, bez wpływu na użytkowników.
2. Zarządzanie danymi poza kontraktem
Kolejnym sposobem jest przechowywanie tylko najważniejszych danych w głównym kontrakcie, a cała logika jest wykonywana w innych, wymiennych kontraktach. W ten sposób można aktualizować te kontrakty bez wpływu na główny kontrakt, który zarządza tylko danymi.
Przykład zastosowania zewnętrznego zarządzania danymi
Załóżmy, że tworzysz zdecentralizowaną giełdę kryptowalut, która przechowuje salda użytkowników w głównym kontrakcie, natomiast logika handlu i wymiany kryptowalut jest rozdzielona na mniejsze moduły. Kiedy chcesz zaktualizować mechanizm wymiany, możesz zmienić tylko ten moduł, nie wpływając na dane użytkowników ani inne funkcje platformy.
3. Kontrakty oparte na modułach
Niektóre kontrakty są tworzone w sposób modułowy, co oznacza, że każda funkcjonalność jest wydzielona jako osobny moduł. Umożliwia to aktualizację poszczególnych modułów bez ingerencji w cały kontrakt. Tego rodzaju rozwiązania są bardziej zaawansowane i wymagają odpowiedniego projektowania, by zachować integralność systemu.
Przykład kontraktów modułowych
Przykładem jest platforma do zarządzania zasobami cyfrowymi, która ma oddzielne moduły do emisji tokenów, transferu środków i raportowania. Jeśli jeden z modułów, np. odpowiedzialny za raporty, wymaga aktualizacji, można go wymienić bez konieczności przerabiania pozostałych części systemu.
Uprawnienia i zabezpieczenia w kontraktach aktualizowalnych
Możliwość aktualizacji kontraktu niesie za sobą ryzyko, że dostęp do funkcji aktualizacji zostanie wykorzystany w nieodpowiedni sposób. Dlatego twórcy kontraktów stosują różne zabezpieczenia, by zminimalizować to ryzyko:
- Admin Key – tylko wybrane adresy, np. administrator lub wielopodpisowy portfel (multisig), mogą przeprowadzać aktualizacje.
- Mechanizmy zatwierdzania – w przypadku organizacji zdecentralizowanych (DAO), zmiany muszą zostać zatwierdzone przez społeczność lub przez większość członków DAO.
Te rozwiązania pomagają zapewnić użytkownikom, że aktualizacje są przeprowadzane z należytą ostrożnością i za zgodą wszystkich zainteresowanych stron.
Wyzwania związane z możliwością aktualizacji
Choć aktualizowalne kontrakty oferują dużą elastyczność, ich stosowanie wiąże się z pewnymi trudnościami i ryzykiem:
- Koszt gazu – stosowanie proxy wiąże się z dodatkowymi operacjami, co może podnieść koszty transakcji.
- Problem zaufania – użytkownicy mogą mieć obawy związane z kontraktami, które można aktualizować, szczególnie jeśli uprawnienia do aktualizacji są zbyt szerokie i mogą prowadzić do zmian w funkcjach, które pierwotnie zaakceptowali.
- Ryzyko błędów – skomplikowane kontrakty wymagają dokładnego audytu. Przeoczenia w kodzie mogą prowadzić do poważnych błędów, które mogą być wykorzystywane przez osoby trzecie.
Podsumowanie
Możliwość aktualizacji kontraktów na blockchainie otwiera nowe możliwości, szczególnie w złożonych projektach. Wdrożenie takich funkcji wymaga jednak zaawansowanego podejścia projektowego i zabezpieczeń, które gwarantują, że kontrakt pozostanie zaufany dla użytkowników. Techniki takie jak Proxy Pattern, zewnętrzne zarządzanie danymi i kontrakty modułowe pozwalają na stopniowe doskonalenie aplikacji bez konieczności ponownego wdrażania całości kontraktu.
Ciekawostki
DAO Hack: W 2016 roku w Ethereum doszło do słynnego DAO Hack. Luka w kodzie kontraktu spowodowała stratę dużej liczby Etherów, co doprowadziło do rozłamu w społeczności i powstania dwóch sieci: Ethereum i Ethereum Classic.
Ubiquity Proxy Standard: W społeczności Ethereum istnieje EIP (Ethereum Improvement Proposal) – standard UUPS (Universal Upgradeable Proxy Standard), który usprawnia mechanizm proxy i jest szeroko stosowany w nowoczesnych kontraktach Ethereum.
Vitalik Buterin: Sam Vitalik Buterin, współzałożyciel Ethereum, wyrażał pewne obawy wobec częstego stosowania wzorca proxy ze względu na komplikacje z bezpieczeństwem. Jego zdaniem nadmierna elastyczność może prowadzić do potencjalnych luk.
Tworząc smart kontrakt, warto zastanowić się nad przyszłością projektu. Wdrożenie mechanizmów aktualizacyjnych może pozwolić na dostosowanie się do zmieniających się potrzeb, ale wymaga solidnych zabezpieczeń i projektowania. Dobre przygotowanie i przemyślane decyzje mogą przełożyć się na sukces projektu oraz większe zaufanie użytkowników.