19/06/2026
En el ecosistema de Ethereum, la dirección de un contrato inteligente es su identificador único e inmutable. Comprender cómo se calcula esta dirección no es solo una curiosidad técnica; es una habilidad fundamental que desbloquea patrones de diseño avanzados y optimizaciones de gas. Un contrato puede ser desplegado en la red de tres maneras principales: a través de una transacción iniciada por una Cuenta de Propiedad Externa (EOA) donde el campo `to` es nulo, mediante la ejecución del opcode CREATE desde otro contrato, o utilizando el más moderno y flexible opcode CREATE2. En este artículo, desglosaremos en detalle cada uno de estos métodos y te enseñaremos a predecir con exactitud la dirección que tendrá tu contrato antes de que siquiera toque la blockchain.

El Método Tradicional: Direcciones con CREATE y EOA
Cuando un contrato se despliega utilizando el método más común, ya sea desde una EOA o mediante el opcode CREATE, su dirección se calcula de una manera sorprendentemente simple pero robusta. La dirección es el resultado de una fórmula que depende exclusivamente de dos factores: la dirección de la cuenta que realiza el despliegue (el deployer) y el nonce de esa cuenta.
La fórmula es la siguiente:
address = keccak256(RLP([deployer_address, nonce]))[-20 bytes]
Como se puede observar, la dirección del contrato son los últimos 20 bytes del hash Keccak-256 de la codificación RLP de la dirección del desplegador y su nonce. Es crucial entender que ni el bytecode del contrato, ni sus argumentos del constructor, ni ningún otro factor externo influyen en este cálculo. Esto tiene implicaciones importantes: dos contratos diferentes desplegados por la misma cuenta con el mismo nonce resultarían en la misma dirección, aunque en la práctica esto es imposible ya que el nonce es secuencial e incremental.
¿Qué es la Codificación RLP?
RLP (Recursive Length Prefix) es un formato de serialización de datos utilizado en Ethereum para codificar objetos de estructura arbitraria. A un alto nivel, RLP concatena los elementos que se están codificando. Cada elemento (excepto los bytes individuales en el rango `[0x00, 0x7f]`) va precedido por uno o más bytes que indican si el elemento es una cadena o una lista, y la longitud de su contenido. Para el cálculo de la dirección, RLP simplemente estructura la dirección del desplegador y el nonce en una lista codificada.
El Papel Fundamental del Nonce
El `nonce` es un contador asociado a cada cuenta en Ethereum, pero su comportamiento difiere entre las EOAs y las cuentas de contrato.
- Nonce en Cuentas EOA: Para una cuenta externa, el nonce comienza en
0y se incrementa en 1 con cada transacción que envía, ya sea una transferencia de ETH, una llamada a un contrato o el despliegue de un nuevo contrato. Incluso si una transacción falla (revierte), el nonce se incrementa. - Nonce en Cuentas de Contrato: Los contratos no pueden iniciar transacciones por sí mismos. Su nonce, según EIP-161, se inicializa en
1en el momento de su creación. Este nonce solo se incrementa cuando el contrato despliega otro contrato utilizandoCREATEoCREATE2. Las llamadas internas o la emisión de eventos no afectan al nonce del contrato.
Esta diferencia es vital para predecir direcciones correctamente. Si un contrato `A` recién desplegado (con nonce 1) despliega un contrato `B`, usará el nonce 1 para el cálculo. Inmediatamente después, el nonce del contrato `A` se incrementará a 2, listo para un posible despliegue de un contrato `C`.
La Revolución Determinista: CREATE2
Introducido en el EIP-1014, el opcode CREATE2 cambió las reglas del juego al permitir la creación de contratos en direcciones predecibles y deterministas que no dependen del nonce. En su lugar, la dirección depende de la dirección del desplegador, un valor arbitrario proporcionado por el usuario llamado salt, y el hash del código de creación (init code) del contrato.
La fórmula de CREATE2 es:
address = keccak256(0xff + deployer_address + salt + keccak256(init_code))[-20 bytes]
Analicemos sus componentes:
0xff: Un byte constante que se antepone para evitar colisiones con las direcciones generadas porCREATE. Garantiza que los dos métodos operen en dominios separados.deployer_address: La dirección del contrato que ejecuta el opcodeCREATE2.salt: Un valor de 32 bytes elegido por el desarrollador. Permite desplegar el mismo código varias veces desde el mismo desplegador, pero en direcciones diferentes, simplemente cambiando el salt.keccak256(init_code): El hash del bytecode de creación del contrato. Es importante destacar que esto incluye tanto el código de inicialización como los argumentos del constructor debidamente codificados.
La gran ventaja de CREATE2 es que la dirección del contrato puede ser conocida antes de su despliegue, independientemente del estado de la red o del nonce del desplegador. Esto permite interacciones con contratos que aún no existen, un concepto conocido como instanciación contrafactual.
Manejando Argumentos del Constructor con CREATE2
Un punto que a menudo genera confusión es cómo los argumentos del constructor afectan la dirección. Dado que la dirección de CREATE2 depende del hash del `init_code`, y el `init_code` completo es la concatenación del bytecode de creación más los argumentos del constructor codificados en formato ABI, cualquier cambio en los argumentos resultará en una dirección de contrato completamente diferente.
En Solidity, para construir el `init_code` manualmente, se usaría un patrón como:
bytes memory full_init_code = abi.encodePacked(type(MyContract).creationCode, abi.encode(arg1, arg2));
Afortunadamente, las versiones más recientes de Solidity han simplificado enormemente el despliegue con CREATE2. Ahora se puede usar una sintaxis nativa:
MyContract instance = new MyContract{salt: mySalt}(arg1, arg2);
El compilador se encarga de todo el trabajo de codificación y construcción del bytecode por debajo, haciendo el proceso mucho más limpio y menos propenso a errores.
Tabla Comparativa: CREATE vs. CREATE2
| Característica | CREATE | CREATE2 |
|---|---|---|
| Dependencia Principal | Dirección del Desplegador y Nonce | Dirección del Desplegador, Salt y Bytecode de Creación |
| Naturaleza de la Dirección | Secuencial (dependiente del estado) | Determinista (independiente del estado) |
| ¿Afectan los Argumentos del Constructor? | No | Sí, porque modifican el `init_code` |
| Re-despliegue en la Misma Dirección | Prácticamente imposible (requeriría resetear el nonce) | Posible si el contrato original fue destruido (SELFDESTRUCT) |
| Caso de Uso Principal | Despliegues estándar | Canales de estado, fábricas de contratos, instanciación contrafactual |
Caso de Uso Avanzado: Despliegue de Contratos Interdependientes
Imaginemos un escenario complejo: necesitamos desplegar dos contratos, `ContratoA` y `ContratoB`, donde `ContratoA` necesita la dirección de `ContratoB` en su constructor, y viceversa. Además, estas direcciones deben ser inmutables. ¿Cómo resolvemos este problema del huevo y la gallina?
La predicción de direcciones es la solución elegante. Usando el método CREATE, podemos lograr esto sin necesidad de una fábrica de contratos separada, lo que ahorra gas.
- Obtener la dirección del desplegador (EOA) y su nonce actual. Supongamos que la dirección es `0xDeployer` y el nonce actual es `N`.
- Pre-calcular las direcciones. Sabemos que el primer contrato que despleguemos usará el nonce `N`, y el segundo usará el nonce `N+1`. Por lo tanto, podemos calcular ambas direcciones de antemano:
- `addressA = keccak256(RLP([0xDeployer, N]))`
- `addressB = keccak256(RLP([0xDeployer, N+1]))`
- Desplegar los contratos. Ahora, realizamos el despliegue en una única transacción o script, pasando las direcciones pre-calculadas como argumentos del constructor:
- Desplegar `ContratoA`, pasándole `addressB` en su constructor. Esta transacción consume el nonce `N`.
- Desplegar `ContratoB`, pasándole `addressA` en su constructor. Esta transacción consume el nonce `N+1`.
Al final del proceso, ambos contratos estarán en la blockchain en las direcciones exactas que predijimos, con referencias inmutables el uno al otro desde el momento de su creación. Este patrón demuestra el poder práctico de entender a fondo los mecanismos de cálculo de direcciones de Ethereum.
Preguntas Frecuentes (FAQ)
- ¿Cuál es la principal diferencia entre CREATE y CREATE2 para un desarrollador?
- La principal diferencia es el control. Con CREATE, la dirección está fuera de tu control directo, ya que depende del nonce (estado de la cuenta). Con CREATE2, tienes control total sobre la dirección a través del `salt` y el `init_code`, permitiéndote predecirla y garantizarla sin importar cuándo o cómo se despliegue el contrato.
- ¿Por qué mi dirección predicha con CREATE es incorrecta?
- El error más común es usar un nonce incorrecto. Asegúrate de obtener el nonce más reciente de la cuenta desplegadora justo antes de la transacción de despliegue. Recuerda que cualquier transacción enviada desde la cuenta (incluso una fallida) incrementará el nonce.
- ¿Los argumentos del constructor afectan siempre la dirección del contrato?
- No siempre. Con CREATE, los argumentos del constructor no tienen ningún efecto en la dirección final. Sin embargo, con CREATE2, son cruciales, ya que forman parte del `init_code` cuyo hash se utiliza en el cálculo. Un cambio mínimo en un argumento generará una dirección completamente diferente.
Conclusión
El cálculo de direcciones de contratos en Ethereum es un pilar del desarrollo en la EVM. Mientras que el método CREATE, basado en el nonce, ha sido el estándar durante años, la introducción de CREATE2 ha abierto un nuevo mundo de posibilidades con sus direcciones deterministas y predecibles. Dominar ambos mecanismos, entender el papel del nonce, el RLP, el salt y el bytecode de creación, no solo te convertirá en un mejor desarrollador de Solidity, sino que también te permitirá diseñar y construir sistemas descentralizados más eficientes, robustos y elegantes.
Si quieres conocer otros artículos parecidos a Calcular Direcciones de Contratos en Ethereum puedes visitar la categoría Blockchain.
