Misma sal, otra dirección: revisa el inicializador
Los bytes del inicializador de un proxy pueden formar parte de los datos usados para crearlo. Cambiar un argumento puede cambiar su dirección CREATE2, aunque la sal siga siendo la misma.
Alcance: cálculo educativo con datos inventados. No desplegamos contratos, reproducimos transacciones ajenas ni verificamos una migración.
Un dato distinto, dos direcciones
En este ejemplo se mantienen la fábrica, la sal, la dirección de implementación y el propietario inicial. Solo cambia la segunda dirección del inicializador.
| Dato / resultado | Ejemplo A | Ejemplo B |
|---|---|---|
| Segunda dirección del inicializador | 0x5050505050505050505050505050505050505050 | 0x5151515151515151515151515151515151515151 |
| Hash del código de inicialización completo | 0x82c940f3425d5b6d300b9d83fce6e4c179e5bbb6e5ba86621abdeb37c6a2cdbe | 0x34566302fe22f91ca08557b9368dbc4feac958f6cae978794a30cc30386e77de |
| Dirección calculada | 0xc4d56ea9fd41fb2741b8697848436dd26eaa66b6 | 0x02f2329a1c562d24384b03dc96ee2f53e1380c28 |
El bytecode es un ejemplo sintético, no el de un proxy de OpenZeppelin. Demuestra la dependencia de los datos; no es una receta de despliegue.
Control: con los mismos datos y otra etiqueta descriptiva de cadena, la dirección no cambia. Esa etiqueta no entra en CREATE2; esto no demuestra compatibilidad de despliegue entre cadenas.
Datos sintéticos completos para reproducir el cálculo
{
"hash_function": "Keccak-256, not SHA3-256",
"formula": "last_20_bytes(keccak256(0xff || factory_20_bytes || salt_32_bytes || keccak256(init_code)))",
"stub_bytecode": "0x6001600c60003960016000f300",
"constructor_abi": "(address,address,bytes)",
"initializer_signature": "initialize(address,address,address,address)",
"examples": [
{
"label": "A",
"factory": "0x1010101010101010101010101010101010101010",
"salt": "0x000000000000000000000000000000000000000000000000000000000000002a",
"implementation": "0x2020202020202020202020202020202020202020",
"initial_owner": "0x3030303030303030303030303030303030303030",
"initializer_arguments": [
"0x4040404040404040404040404040404040404040",
"0x5050505050505050505050505050505050505050",
"0x6060606060606060606060606060606060606060",
"0x7070707070707070707070707070707070707070"
],
"init_code": "0x6001600c60003960016000f3000000000000000000000000002020202020202020202020202020202020202020000000000000000000000000303030303030303030303030303030303030303000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000084f8c8765e000000000000000000000000404040404040404040404040404040404040404000000000000000000000000050505050505050505050505050505050505050500000000000000000000000006060606060606060606060606060606060606060000000000000000000000000707070707070707070707070707070707070707000000000000000000000000000000000000000000000000000000000",
"predicted_address": "0xc4d56ea9fd41fb2741b8697848436dd26eaa66b6"
},
{
"label": "B",
"factory": "0x1010101010101010101010101010101010101010",
"salt": "0x000000000000000000000000000000000000000000000000000000000000002a",
"implementation": "0x2020202020202020202020202020202020202020",
"initial_owner": "0x3030303030303030303030303030303030303030",
"initializer_arguments": [
"0x4040404040404040404040404040404040404040",
"0x5151515151515151515151515151515151515151",
"0x6060606060606060606060606060606060606060",
"0x7070707070707070707070707070707070707070"
],
"init_code": "0x6001600c60003960016000f3000000000000000000000000002020202020202020202020202020202020202020000000000000000000000000303030303030303030303030303030303030303000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000084f8c8765e000000000000000000000000404040404040404040404040404040404040404000000000000000000000000051515151515151515151515151515151515151510000000000000000000000006060606060606060606060606060606060606060000000000000000000000000707070707070707070707070707070707070707000000000000000000000000000000000000000000000000000000000",
"predicted_address": "0x02f2329a1c562d24384b03dc96ee2f53e1380c28"
}
]
}Por qué puede ocurrir con un proxy
El código examinado de Hardhat Upgrades 3.9.1 construye los datos del inicializador a partir de los argumentos y los pasa al constructor del proxy. El proxy transparente v5.4.0 recibe esos bytes explícitamente. CREATE2 usa el código de inicialización completo, no solo el código final que quedará desplegado.
Qué comparar en un caso real
Compara la fábrica real, la sal de 32 bytes y el hash completo del código de inicialización. Si cambia el hash, revisa los argumentos del constructor y los datos del inicializador antes de atribuirlo a un fallo del proveedor.
Comprobaciones del cálculo
Coincidieron seis ejemplos publicados en EIP-1014. En la comparación sintética cambiaron 20 bytes de un bloque de argumentos de 288 bytes. Esto verifica estos cálculos, no una biblioteca criptográfica de producción ni un despliegue real.