Guía de Migración de Ethereum a Aptos
Para aprender más sobre las diferencias y similitudes mira Aptos Learn
Aptos está diseñado para permitirte prototipar rápidamente y escalar aplicaciones seguras a nivel de producción. Combina una capa de blockchain rápida, estable y de bajo costo con la seguridad en tiempo de compilación de Move, que detecta exploits antes del deploy. Ofrece tooling completo para un desarrollo rápido y un ecosistema sólido de exchanges y bridges para una integración fluida.
Resumen de Alto Nivel
Sección titulada «Resumen de Alto Nivel»Resumen General
Sección titulada «Resumen General»| Feature | Ethereum | Aptos |
|---|---|---|
| Account Addresses | 160-bit | 256-bit |
| Mentalidad del Storage | Storage basado en el contrato | Mentalidad centrada en la cuenta (account-centric) para código y data |
| Caller ID | msg.sender | Referencia &signer |
| Smart Contracts | Solidity, EVM | Move, MoveVM |
| Beneficios | Madurez, amplia adopción | Escalabilidad, baja latencia, fees predecibles |
| Transaction Fees | Variables, pueden ser altos | Más bajos y predecibles |
| Sponsored Transactions | Requiere servicios de terceros o soporte de wallets EIP-7702 (2025+) | Soportado nativamente mediante el campo fee payer. Geomi Gas Stations provee infraestructura de producción |
| Estructura de Cuenta | Balance en un solo campo, usa nonce | Módulos y resources, usa sequence number |
| Data Storage | Patricia Merkle Trees | Storage global con resources y módulos |
| Upgradeability | Patrones proxy | Actualizaciones directas de módulos |
| Safety & Security | Vulnerable a ataques como reentrancy | Mitiga vulnerabilidades comunes |
| Dispatch Type | Dynamic dispatch | Static dispatch |
| Frontend SDK | Librería Ethers.js | Aptos Typescript SDK |
| NFT Standards | ERC-721, ERC-1155 | Digital Asset |
| FT Standard | ERC-20, factory pattern | Ver Fungible Asset, copia y pega en tu módulo: use aptos_framework::fungible_asset... |
| Código de Ejemplo | ERC-20 (nuevo contrato por deploy) | Fungible Asset (módulo único reutilizable) |
La documentación del Coin legacy aún cubre el estándar original; la mayoría de los nuevos deployments deberían preferir el módulo Fungible Asset referenciado arriba.
Comparativa Detallada de Estándares de Tokens
Sección titulada «Comparativa Detallada de Estándares de Tokens»Comparando Estándares de Token en Detalle
Sección titulada «Comparando Estándares de Token en Detalle»| Solidity | Move (Aptos) | |
|---|---|---|
| Estructura del Token | Cada token es su propio contrato. | Cada token es una instanciación tipada de FungibleAsset que reutiliza el mismo módulo publicado. |
| Token Standard | Debe cumplir estándares como ERC-20; las implementaciones pueden variar por deploy. | Interfaz e implementación uniformes impuestas por el módulo compartido; los nuevos tokens simplemente registran un nuevo tipo en lugar de redeployar código. |
| Almacenamiento del Balance | Balances almacenados en el contrato usando una estructura de mapping. | Balance Orientado a Resources: los balances viven en un objeto extensible propiedad de la cuenta del usuario. |
| Mecanismo de Transferencia | Los tokens pueden transferirse sin el permiso explícito del receptor. | Las transferencias pueden omitir el permiso del receptor, pero solo cuando el FA habilita explícitamente la auto-creación de primary-store (visible en el código de creación del token). |
| Solidity | Move (Aptos) | |
| ---------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Estructura del Token | Cada token es su propio contrato. | Cada token es un Coin tipado o FungibleAsset usando un contrato único y reutilizable. |
| Estándar del Token | Debe cumplir con estándares como ERC20; las implementaciones pueden variar. | Interfaz e implementación uniforme para todos los tokens. |
| Almacenamiento del Balance | Balances guardados en el contrato usando una estructura de mapping. | Balance Orientado a Recursos: Balances guardados como un recurso en la cuenta del usuario. Los recursos no pueden ser creados arbitrariamente, asegurando la integridad del valor del token. |
| Mecanismo de Transferencia | Los tokens se pueden transferir sin permiso explícito del receptor. | Excepto en casos específicos (como AptosCoin), los Tokens generalmente requieren la autoridad del signer del receptor para la transferencia. |
Comparativa Detallada: EVM vs. Move VM
Sección titulada «Comparativa Detallada: EVM vs. Move VM»Comparando la EVM y la Move VM en Detalle
Sección titulada «Comparando la EVM y la Move VM en Detalle»- EVM: Conocida por su flexibilidad y dynamic dispatch, que permite una amplia gama de comportamientos en los smart contracts. Sin embargo, esta flexibilidad puede generar complejidades en la ejecución paralela y las operaciones de red.
- Move VM: Se enfoca en la seguridad y eficiencia con un enfoque más integrado entre la VM y el lenguaje de programación. Su modelo de almacenamiento de data permite una mejor paralelización, y su método de static dispatch mejora la seguridad y la predictibilidad.
- EVM: Conocida por su flexibilidad y dispatch dinámico, lo que permite una amplia gama de comportamientos en los smart contracts. Esta flexibilidad, sin embargo, puede llevar a complejidades en la ejecución paralela y operaciones de red.
- Move VM: Se enfoca en la seguridad y eficiencia con un enfoque más integrado entre la VM y el lenguaje de programación. Su modelo de data storage permite una mejor paralelización, y su método de dispatch estático mejora la seguridad y la predictibilidad.
| EVM (Ethereum Virtual Machine) | Move VM (Move Virtual Machine) | |
|---|---|---|
| Data Storage | La data se almacena en el espacio de storage del smart contract. | La data se almacena entre smart contracts, cuentas de usuario y objects. |
| Paralelización | La ejecución paralela es limitada debido al espacio de storage compartido. | Mayor ejecución paralela habilitada por un diseño de storage dividido y flexible. |
| Integración VM y Lenguaje | Capas separadas para la EVM y los lenguajes de smart contract (ej. Solidity). | Integración fluida entre la capa de la VM y el lenguaje Move, con funciones nativas escritas en Rust ejecutables en Move. |
| Operaciones Críticas de Red | La implementación de operaciones de red puede ser compleja y menos directa. | Operaciones críticas como la gestión del validator set están implementadas nativamente en Move, permitiendo su ejecución directa. |
| Function Calling | El dynamic dispatch permite llamadas arbitrarias a smart contracts. | El static dispatch se alinea con el enfoque en seguridad y comportamiento predecible. |
| Type Safety | Los tipos de contrato proveen un nivel de type safety. | Los structs de módulos y los genéricos en Move ofrecen un type safety robusto. |
| Transaction Safety | Usa nonces para el orden y seguridad de las transacciones. | Usa sequence numbers para el orden y seguridad de las transacciones. |
| Authenticated Storage | Sí, con el storage del smart contract. | Sí, aprovechando el modelo de resources de Move. |
| Accesibilidad de Objects | Los objects no son accesibles globalmente; están ligados al scope del smart contract. | Accesibilidad global garantizada de los objects. |
Tips de Migración para Desarrolladores de Ethereum
Sección titulada «Tips de Migración para Desarrolladores de Ethereum»Ethereum almacena toda la data en el storage del contrato usando mappings. Aptos usa un modelo centrado en la cuenta (account-centric) donde cada cuenta almacena sus propios resources. En lugar de que un contrato mantenga un mapping(address => T), cada usuario almacena su propio resource T en su dirección.
module my_hackathon_account::prototype { use std::string; use std::signer;
// Unlike Solidity's mapping(address => string), each account stores their own resource struct MessageHolder has key, store, drop { message: string::String, }
entry fun set_message(account: &signer, message: string::String) acquires MessageHolder { let addr = signer::address_of(account); // Check if resource exists at this account (like checking mapping[addr]) if (exists<MessageHolder>(addr)) { move_from<MessageHolder>(addr); // Remove old resource }; // Store resource at the user's address (in their account, not in contract storage!) move_to(account, MessageHolder { message }); }
#[view] public fun get_message(addr: address): string::String acquires MessageHolder { assert!(exists<MessageHolder>(addr), 0); // Read message stored at the user's address borrow_global<MessageHolder>(addr).message }}Por defecto, los módulos se deployean en la dirección de tu cuenta. Para apps en producción, considera hacer deploy en Objects, lo que crea una dirección única por cada deploy y permite la propiedad transferible del código. Revisa Using Objects para detalles de implementación.
Aprende más: global storage operators, structs and resources
En Ethereum, msg.sender es establecido por la EVM, pero muchos bugs provienen de usar tx.origin para autenticación (auth) o de confiar en direcciones proveídas por el usuario. El &signer de Aptos va más allá: es una capability infalsificable creada únicamente por la VM para los signers reales de la transacción. Por lo tanto, cualquier función que requiera &signer no puede ser llamada con una identidad falsificada (spoofed). En las dapps, las wallets, junto con el Aptos TypeScript SDK y el wallet adapter, conectan esta identidad del signer desde el frontend hasta el on-chain.
module my_hackathon_account::prototype { use std::string; use std::signer;
struct MessageHolder has key, store, drop { message: string::String, }
// Only the account owner can provide their &signer (unforgeable authentication) entry fun set_message(account: &signer, message: string::String) acquires MessageHolder { // Extract address from authenticated signer (no spoofing possible!) let addr = signer::address_of(account); if (exists<MessageHolder>(addr)) { move_from<MessageHolder>(addr); }; // account is guaranteed to be authentic move_to(account, MessageHolder { message }); }
#[view] public fun get_message(addr: address): string::String acquires MessageHolder { assert!(exists<MessageHolder>(addr), 0); // Read message stored at the user's address borrow_global<MessageHolder>(addr).message }}Crea y fondea una cuenta usando el Aptos CLI:
aptos initAprende más: tipo signer, functions
Move tiene cuatro abilities: copy, drop, store, y key, que controlan cómo se pueden usar los valores. En este ejemplo, MessageHolder omite deliberadamente copy para que los mensajes almacenados como resources no puedan ser duplicados; generalmente querrás evitar copy en cualquier tipo que represente estado on-chain o assets. key + store le permiten vivir en el storage global en una dirección, y drop te permite destruir el resource antiguo de forma segura al sobrescribirlo.
module my_hackathon_account::prototype { use std::string; use std::signer;
// Resources: structs with 'key' ability that live in global storage // key = can be stored at account addresses (makes it a "resource") // store = can be stored inside other structs // drop = can be destroyed/discarded implicitly struct MessageHolder has key, store, drop { message: string::String, }
entry fun set_message(account: &signer, message: string::String) acquires MessageHolder { let addr = signer::address_of(account); // The 'drop' ability allows implicit destruction if (exists<MessageHolder>(addr)) { move_from<MessageHolder>(addr); // Old resource is destroyed (requires 'drop') }; move_to(account, MessageHolder { message }); }
#[view] public fun get_message(addr: address): string::String acquires MessageHolder { assert!(exists<MessageHolder>(addr), 0); // Read message stored at the user's address borrow_global<MessageHolder>(addr).message }}Aprende más: abilities, structs and resources
Los packages de Aptos soportan dos políticas de actualización (upgrade policies): compatible (por defecto; solo permite cambios retrocompatibles) e immutable (no permite actualizaciones). Por defecto, los packages publicados con el Aptos CLI usando aptos move publish usan la política compatible, que te permite pushear nuevas versiones siempre y cuando no rompas los layouts de los structs o las firmas de las funciones públicas.
Para prevenir todas las actualizaciones futuras, establece la política immutable:
aptos move publish --upgrade-policy immutableO configúralo en tu Move.toml:
[package]name = "MyPackage"version = "1.0.0"upgrade_policy = "immutable"Revisa Package Upgrades para ver las reglas exactas de compatibilidad.
En Ethereum tú “deployeas un contrato a una nueva dirección”. En Aptos tú publicas un package de módulos Move a una dirección de cuenta (o de un object) usando el Aptos CLI.
Publica tu package:
aptos move publishLlama a una función entry después del deploy:
aptos move run --function-id 'your_address::module_name::function_name'Tanto la publicación basada en cuentas como el deploy basado en objects (vía aptos move deploy-object) respetan la política de actualización (upgrade policy) del package. Revisa Your First Move Module para una guía completa y Objects para patrones centrados en objects.
| EVM (Ethereum Virtual Machine) | Move VM (Move Virtual Machine) | |
|---|---|---|
| Data Storage | La data se almacena en el espacio de storage del smart contract. | La data se almacena a través de smart contracts, cuentas de usuario y objetos. |
| Paralelización | La ejecución paralela es limitada debido al espacio de storage compartido. | Mayor ejecución paralela habilitada gracias al diseño flexible de split storage. |
| Integración de VM y Lenguaje | Capas separadas para la EVM y lenguajes de smart contracts (ej. Solidity). | Integración fluida entre la capa de VM y el lenguaje Move, con funciones nativas escritas en Rust ejecutables en Move. |
| Operaciones Críticas de Red | La implementación de operaciones de red puede ser compleja y menos directa. | Operaciones críticas como la gestión del validator set implementadas nativamente en Move, permitiendo ejecución directa. |
| Llamadas a Funciones | El dispatch dinámico permite llamadas arbitrarias a smart contracts. | El dispatch estático se alinea con un enfoque en seguridad y comportamiento predecible. |
| Type Safety | Los tipos de contrato proveen cierto nivel de type safety. | Los structs de módulos y genéricos en Move ofrecen un type safety robusto. |
| Transaction Safety | Usa nonces para el ordenamiento y seguridad de transacciones. | Usa sequence numbers para el ordenamiento y seguridad de transacciones. |
| Storage Autenticado | Sí, con storage de smart contract. | Sí, aprovechando el modelo de recursos de Move. |
| Accesibilidad de Objetos | Los objetos no son accesibles globalmente; están atados al scope del smart contract. | Accesibilidad global garantizada de objetos. |