﻿---
title: "Tabrakan penyimpanan proxy: bagaimana upgrade merusak state kontrak"
description: "Proxy mempertahankan state saat kode implementasi berubah. Pelajari bagaimana layout yang tidak kompatibel menimpa saldo, owner, dan kendali upgrade, serta cara memvalidasi upgrade."
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tabrakan penyimpanan proxy: bagaimana upgrade merusak state kontrak

> Hanya untuk tujuan edukasi; bukan merupakan nasihat investasi. Investasi dapat mengakibatkan kerugian.

<a id="answer"></a>

## Jawaban langsung

Tabrakan penyimpanan proxy terjadi saat kode implementasi membaca atau menulis slot penyimpanan proxy dengan makna yang berbeda dari layout pembentuk state yang sudah ada. Upgrade kemudian dapat membuat saldo terbaca sebagai alamat, menghapus owner, merusak slot dasar mapping, atau menimpa data kendali upgrade.

Dengan `delegatecall`, bytecode implementasi berjalan dalam konteks proxy: penyimpanan, saldo, dan `address(this)` adalah milik proxy. Nama variabel tidak disimpan on-chain, sehingga EVM hanya mengikuti slot dan offset byte yang dihitung kode baru.

Karena itu, upgrade harus mempertahankan layout yang sudah di-deploy, bukan sekadar berhasil dikompilasi atau menyediakan fungsi yang sama. Sebelum mengotorisasi upgrade, bandingkan layout keluaran compiler dengan versi tepat yang telah di-deploy.

<a id="mechanism"></a>

## Cara kerjanya

Solidity biasanya menempatkan variabel state mulai slot `0` sesuai urutan deklarasi setelah linearisasi C3 pada pewarisan. Nilai di bawah 32 byte dapat berbagi slot; struct dan array memiliki aturan tambahan, sedangkan mapping dan array dinamis menurunkan lokasi datanya dari slot dasar. Pergeseran slot dasar turut mengubah lokasi data turunannya.

Ada empat batas tabrakan berbeda yang perlu diaudit:

- **Proxy versus implementasi:** field milik proxy seperti implementasi atau administrator tidak boleh menempati slot state aplikasi. ERC-1967 menetapkan slot standar yang dihindari alokasi compiler untuk data implementasi, beacon, dan administrator.
- **Implementasi lama versus baru:** variabel aplikasi yang ada harus mempertahankan slot, offset, dan tipe yang kompatibel. Menambahkan variabel di akhir dapat aman, tetapi menyisipkan, mengurutkan ulang, menghapus, atau mengganti tipe dapat menafsirkan ulang word lama.
- **Pewarisan:** menambahkan state ke kontrak dasar atau mengubah urutan pewarisan dapat menggeser penyimpanan turunan meskipun source turunannya tidak berubah.
- **Penyimpanan cadangan atau namespace:** storage gap yang digunakan dengan benar dapat mencadangkan ruang untuk kontrak dasar, sedangkan namespace bergaya ERC-7201 dapat mengisolasi layout. Keduanya tidak mengizinkan perubahan sembarang di dalam layout yang sudah ada.

<a id="example"></a>

## Contoh

Misalkan versi 1 memiliki layout berikut:

```solidity
uint256 totalAssets; // slot 0
address owner;       // slot 1
```

Versi 2 keliru menyisipkan variabel di awal:

```solidity
bool paused;         // slot 0, offset 0
uint256 totalAssets; // slot 1
address owner;       // slot 2
```

Setelah upgrade, `paused` membaca byte rendah dari `totalAssets` lama, `totalAssets` baru membaca word `owner` lama sebagai bilangan bulat, dan `owner` membaca isi yang sudah ada di slot `2`, biasanya nol. Word asli tetap tersimpan, tetapi kode baru memberinya makna berbeda. Transaksi dapat berhasil sambil menjalankan otorisasi atau akuntansi terhadap tafsiran state yang rusak.

<a id="risks"></a>

## Risiko dan pemeriksaan upgrade

- Hasilkan layout penyimpanan kedua implementasi dan bandingkan slot, offset, tipe, serta pewarisan dengan kontrak referensi yang benar-benar di-deploy.
- Untuk layout linear konvensional, tambahkan variabel baru hanya di akhir. Jangan mengurutkan ulang field, mengganti tipe, menghapus lalu memakainya kembali, atau mengubah kontrak dasar tanpa membuktikan kompatibilitas.
- Saat memakai storage gap, kurangi sebesar jumlah tepat slot cadangan yang digunakan. Untuk namespace, pertahankan identifier yang unik dan validasi perubahan di setiap namespace yang sudah ada.
- Jangan menganggap ERC-1967 sebagai perlindungan lengkap. Standar ini memisahkan metadata proxy dari slot aplikasi hasil alokasi compiler, tetapi tidak membuat dua layout implementasi menjadi kompatibel.
- Uji upgrade dan setiap reinitializer pada fork atau snapshot state. Periksa owner, role, saldo, allowance, entri mapping, status pause, slot implementasi, serta kendali rollback atau darurat sebelum dan sesudah eksekusi.

Jika upgrade diduga telah menyebabkan tabrakan, hentikan upgrade lanjutan dan panggilan pengubah state jika tata kelola memungkinkan. Simpan nomor blok dan bytecode sebelum upgrade, bandingkan penyimpanan mentah pada slot terdampak, lalu minta engineer kontrak yang kompeten merancang migrasi dan menjalani tinjauan independen. Mengulangi upgrade tanpa peta penyimpanan yang terbukti dapat merusak lebih banyak state yang semula dapat dipulihkan.

<a id="misconceptions"></a>

## Kesalahpahaman umum

- **“Nama variabel tidak berubah, jadi layout aman.”** Nama tidak menentukan lokasi penyimpanan. Tipe, urutan, packing, pewarisan, dan aturan namespace yang menentukannya.
- **“Menghapus variabel membebaskan slot untuk dipakai lagi.”** Penyimpanan proxy tetap ada. Pemakaian ulang memberi makna baru pada word lama kecuali migrasi yang ditinjau menghapus atau mengubahnya.
- **“Satu transaksi uji yang berhasil membuktikan kompatibilitas.”** Pengujian mungkin hanya menyentuh sedikit slot. Validasi layout dan uji perbedaan state harus mencakup field istimewa, nilai packed, mapping, array, dan penyimpanan warisan.

<a id="related"></a>

## Topik terkait

- [Risiko penyimpanan delegatecall](/id/crypto/delegatecall-storage-risk/)
- [Pengambilalihan initializer](/id/crypto/initializer-takeover/)
- [Kontrak proxy](/id/crypto/proxy-contract/)
- [Pemantauan upgrade proxy](/id/crypto/proxy-upgrade-monitoring/)
- [Kontrak yang dapat di-upgrade](/id/crypto/upgradeable-contract/)

<a id="sources"></a>

## Sumber

- [Pengantar smart contract](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html) - Solidity Documentation (diakses: 2026-08-21)
- [Layout variabel state dalam penyimpanan](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html) - Solidity Documentation (diakses: 2026-08-21)
- [ERC-1967: slot penyimpanan proxy](https://eips.ethereum.org/EIPS/eip-1967) - Ethereum Improvement Proposals (diakses: 2026-08-21)
- [Menulis kontrak yang dapat di-upgrade](https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable) - OpenZeppelin Documentation (diakses: 2026-08-21)

Source: https://wiki.fcontext.com/id/crypto/proxy-storage-collision/index.mdx
