AptosVM<>MEVM

En esta guía aprenderá cómo enviar transacciones entre AptosVM y MEVM.

Descripción general

¡Bienvenido al tutorial para usar la cadena de bloques de Movement Labs y el lenguaje Move! En este tutorial, cubriremos dos partes:

Parte 1 : Firma de transacciones de múltiples partes con cuentas de firma múltiple, ¡incluida una billetera segura multifirma MEVM!

Parte 2 : Llamar a un contrato inteligente EVM desde una billetera AptosVM

Requisitos

  • Nodo.js

  • npm

Configuración

Clona nuestro repositorio de demostración para acceder a los archivos necesarios:

Copiar

git clone https://github.com/movemntdev/movement_interop_demo

Accede al directorio de la aplicación:

Copiar

cd movement_interop_demo

Instale todas las dependencias:

Copiar

npm install

Abre tu IDE favorito. Recomendamos usar VSCode:

Copiar

code .

Encontrará un .envarchivo en el directorio de la aplicación. La mayoría de las variables ya están completadas, pero preste atención a MOVE_PRIVATE_KEYy ETHEREUM_PRIVATE_KEY. Asegúrese de utilizar claves privadas para las billeteras que hayan sido financiadas. Puedes utilizar nuestro Faucet para financiarlos.

Nota: Se necesitan las siguientes variables para la demostración:

  • MOVE_MULTISIG_OTHER_OWNER_ADDR

  • MOVE_FRAMEWORK

  • EVM_PRECOMPILE_CONTRACT

Después de configurar sus claves privadas, echemos un vistazo a nuestra configuración. En la parte superior, importamos nuestras dependencias:

  • ethers: Monedero y utilidades de Ethereum

  • @safe-global/protocol-kit: Kit de herramientas para interactuar con el protocolo Safe

  • aptos: Biblioteca para interactuar con el protocolo Aptos

  • dotenv: Módulo para cargar variables de entorno desde un .envarchivo aprocess.env

Copiar

const { ethers, getDefaultProvider } = require('ethers');
const { EthersAdapter, SafeFactory } = require('@safe-global/protocol-kit');
const Safe = require('@safe-global/protocol-kit').default;
const { AptosAccount, BCS, AptosClient, HexString, TxnBuilderTypes } = require("aptos");
const dotenv = require("dotenv");
dotenv.config();

Parte 1: MEVM a AptosVM

Dirigirse a mevm-to-aptosvm.js. Encontrarás varias funciones. Siéntete libre de explorarlos y comprender lo que hacen.

  • deploySafe(): Implementa un nuevo contrato MEVM Safe

  • setupMoveMultisigAccount(safeAddress): configura una nueva cuenta Move multifirma

  • vote(safeAddress, multiAccount): Votos sobre una propuesta Move de un contrato Safe

  • checkSafeContractVoted(safeAddress, multiAccount): Comprueba si se ha votado un contrato seguro

  • submitTx(rawTxn): envía una transacción

  • zeroPad(multiAccount): Se rellena con ceros si la dirección de varias cuentas tiene un tamaño diferente al tipo de dirección Mover.

Ahora, todo lo que tienes que hacer es ejecutar:

Copiar

node mevm-to-aptosvm.js

Básicamente, lo siguiente es lo que realizará el script:

  1. Crea un contrato inteligente de Gnosis Safe utilizando la billetera EVM.

  2. Crea una cuenta multifirma utilizando la billetera Move y establece el contrato Gnosis Safe creado en el paso 1 como uno de los propietarios.

  3. Crea una transacción multifirma (el contenido puede ser arbitrario, pero para esta demostración agregaremos un propietario a la cuenta multifirma) y vota usando la billetera Move.

  4. Crea una transacción utilizando la billetera EVM para votar por la transacción creada en el paso anterior en la cuenta multifirma Move.

  5. Propone y confirma la transacción creada por la billetera EVM al servicio Safe implementado.

  6. Ejecuta la transacción la transacción confirmada.

  7. Comprueba si la cuenta multifirma de EVM ha votado correctamente.

Como puede ver, estamos interactuando entre AptosVM y MEVM cuando finalmente firmamos una transacción Move desde EVM multisig. Para ello debemos prestar atención a la vote()función:

Copiar

async function vote(safeAddress, multiAccount) {
    (...)
    // 1.Encodes the predefine vote calldata
    // function vote(bytes32 multisigAccount, uint sequenceNumber, bool approve)
    let calldata = safeInterface.encodeFunctionData("vote", [multiAccount, 1, true]);

    // 2.Encodes the callMove function present in the Precompile contract
    let txdata = precompileInterface.encodeFunctionData("callMove", [process.env.MOVE_FRAMEWORK, calldata])
    let safeTransactionData = {to: process.env.EVM_PRECOMPILE_CONTRACT, data: txdata, value: 0}

    // 3.creates a safe transaction
    const safeTransaction = await safeSDK.createTransaction({ safeTransactionData })
    
    // 4. signs the safe tx
    const safeTxHash = await safeSDK.getTransactionHash(safeTransaction)
    const senderSignature = await safeSDK.signTransactionHash(safeTxHash)
    
    // 5. sends the safe tx to the api kit
    await safeService.proposeTransaction({safeAddress,safeTransactionData: safeTransaction.data, Hash,senderAddress: await wallet.getAddress(),senderSignature: senderSignature.data,})
    await safeService.confirmTransaction(safeTxHash, senderSignature.data)
    
    // 6. execute the safe tx
    const executeTxResponse = await safeSDK.executeTransaction(safeTransaction)
    (...)
}

Para interactuar entre AptosVM y MEVM, preste atención a la vote()función, donde codificamos una transacción Move y la pasamos a la callMove()función precompilada, que sirve como punto de entrada para llamar a funciones Move desde MEVM.

Parte 2: AptosVM a MEVM

Ahora, dirígete a aptosvm-to-mevm.js. Encontrarás un guión más estricto:

  • deployNumberRegistry(): Implementa un nuevo NumberRegistrycontrato inteligente de Solidity

  • submitTx(rawTxn): Envía una transacción AptosVM

  • getNonce(addr): obtiene el nonce EVM de una cuenta AptosVM.

  • setNumber(contract): Llama a la función setNumber presente en el NumberRegistrycontrato inteligente

Ahora puedes ejecutar el script:

Copiar

aptosvm-to-mevm.js

Esto es lo que realizará el guión:

  1. Crea un NumberRegistry.solcontrato inteligente utilizando la billetera EVM.

  2. Llama a la setNumber()función del contrato NumberRegistry utilizando la billetera Move.

  3. Comprueba si el número se configuró correctamente.

Aquí debemos prestar especial atención a la setNumber()función:

Copiar

async function setNumber(contract) {
	// 1. Encodes the EVM function
	let calldata = interface.encodeFunctionData("setNumber", [100]);
	
	// 2. Gets the AptosVM Account EVM nonce
	let nonce = await getNonce(owner.address())
	
	// 3. Generates the AptosVM transaction that interacts with the EVM contract
	let txn = await client.generateTransaction(owner.address(), {
		function: `0x1::evm::send_move_tx_to_evm`,
		type_arguments: [],
		arguments: [nonce, new HexString(contract.address).toUint8Array(), BCS.bcsSerializeU256(0), new HexString(calldata).toUint8Array(), 1],
	});
}

Aquí estamos codificando una función EVM y pasándola a la 0x1::evm::send_move_tx_to_evmfunción presente en nuestro evmmarco.

En la setNumber()función, codificamos una función EVM y la pasamos a la 0x1::evm::send_move_tx_to_evmfunción en nuestro marco EVM.

Conclusión

¡Esto concluye nuestro tutorial! Hemos cubierto la firma de transacciones de múltiples partes con cuentas de múltiples firmas desde un EVM multisig y la llamada a contratos inteligentes de EVM desde una billetera AptosVM.

No dudes en comunicarte con nosotros en Discord si tienes algún problema, pregunta o comentario. ¡Nos encantaría saber de usted!

Last updated