Skip to content

Commit

Permalink
add call evm from a demo move contract
Browse files Browse the repository at this point in the history
  • Loading branch information
lei-1993 committed Jan 19, 2024
1 parent 2785a60 commit 7cc2488
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 8 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ coverage/
coverage.json
yarn-error.log
typechain-types
.aptos

# Certora Formal Verification related files
.certora_internal
.certora_recent_jobs.json
.zip-output-url.txt
.zip-output-url.txt
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The application uses several environment variables, which should be set in a `.e
- `EVM_PRECOMPILE_CONTRACT`: The address of the EVM precompile contract.
- `MOVE_FRAMEWORK`: The address of the Move framework.

## Steps for `evm-to-move.js`
## Steps for `mevm-to-aptosvm.js`

1. Create a Gnosis Safe contract using the EVM wallet.
2. Create a multisig account using the Move wallet, and set the Gnosis Safe contract created in step 1 as one of the owners.
Expand All @@ -59,10 +59,10 @@ The application uses several environment variables, which should be set in a `.e
6. Execute the transaction created in step 4 using the EVM wallet.
7. Check whether the multisig account has voted successfully.

## Steps for `move-to-evm.js`
## Steps for `aptosvm-to-mevm.js`

1. Create a NumberRegistry.sol contract using the EVM wallet.
2. Call the setNumber function of the NumberRegistry contract using the Move wallet.
2. Call the setNumber function of the NumberRegistry contract using the Move wallet or using the Move Contract(you must compile the and publish the move package as the demo contract in move-contract).
3. Check whether the number is set successfully.

## Note
Expand Down
42 changes: 38 additions & 4 deletions aptosvm-to-mevm.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ const client = new AptosClient(process.env.MOVEMENT_RPC_ENDPOINT);
let pk = process.env.MOVE_PRIVATE_KEY;
let owner = new AptosAccount(new HexString(pk).toUint8Array())

const fs = require("fs");
const path = require("path");

const web3Provider = process.env.EVM_RPC_ENDPOINT
const provider = getDefaultProvider(web3Provider)
const wallet = new ethers.Wallet(process.env.ETHEREUM_PRIVATE_KEY, provider);
const account = wallet.connect(provider);
const data = require("./NumberRegistry.json")
const moveModule = "./move-contract";

async function deployNumberRegistry() {
const factory = new ContractFactory(data.abi, data.bytecode, account);
Expand All @@ -22,6 +26,15 @@ async function deployNumberRegistry() {
return contract
}

async function deployMovePackage() {
const moduleData = fs.readFileSync(path.join(moveModule, "build", "CallEVMDemo", "bytecode_modules", "demo.mv"));
const packageMetadata = fs.readFileSync(path.join(moveModule, "build", "CallEVMDemo", "package-metadata.bcs"));
let txnHash = await client.publishPackage(owner, new HexString(packageMetadata.toString("hex")).toUint8Array(), [
new TxnBuilderTypes.Module(new HexString(moduleData.toString("hex")).toUint8Array()),
]);
await client.waitForTransaction(txnHash, { checkSuccess: true });
}

// Function to submit a transaction
async function submitTx(rawTxn) {
const bcsTxn = await client.signTransaction(owner, rawTxn);
Expand All @@ -42,8 +55,24 @@ async function getNonce(addr) {
}
}

async function setNumberByMoveContract(contract) {
let interface = new ethers.utils.Interface(data.abi);

// 1. Encodes the EVM function
let calldata = interface.encodeFunctionData("setNumber", [200]);

// 2. Generates the AptosVM transaction that interacts with the EVM contract
let txn = await client.generateTransaction(owner.address(), {
function: `${owner.address()}::demo::call_evm`,
type_arguments: [],
arguments: [new HexString(contract.address).toUint8Array(), new HexString(calldata).toUint8Array(), BCS.bcsSerializeU256(0)],
});

console.log(`setting number tx ${await submitTx(txn)}`);
}

// Function to set the number
async function setNumber(contract) {
async function setNumberByWallet(contract) {
let interface = new ethers.utils.Interface(data.abi);

// 1. Encodes the EVM function
Expand All @@ -63,13 +92,18 @@ async function setNumber(contract) {
}

async function run() {
await getNonce(owner.address())
let contract = await deployNumberRegistry();
let number = await contract.number();
console.log(`number before setting ${number}`)
await setNumber(contract)
await setNumberByWallet(contract)
number = await contract.number();
console.log(`number after setting by wallet ${number}`)

await deployMovePackage(); // only need to deploy once
await setNumberByMoveContract(contract);
number = await contract.number();
console.log(`number after setting ${number}`)
console.log(`number after setting by contract ${number}`)

}

run().then()
Expand Down
27 changes: 27 additions & 0 deletions move-contract/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "CallEVMDemo"
version = "1.0.0"


[addresses]
call_evm_demo = "_"

#[dependencies.AptosFramework]
#git = 'https://github.com/aptos-labs/aptos-core'
#rev = 'devnet'
#subdir = 'aptos-move/framework/aptos-framework'
#
#[dependencies.AptosStdlib]
#git = 'https://github.com/aptos-labs/aptos-core'
#rev = 'devnet'
#subdir = 'aptos-move/framework/aptos-stdlib'

[dependencies.AptosFramework]
git = 'https://github.com/shaokun11/move-me2'
rev = 'acc184f9af236ac318b8235ea61fc6669a8a3b79'
subdir = 'aptos-move/framework/aptos-framework'
#
#[dependencies.AptosStdlib]
#git = 'https://github.com/shaokun11/move-me2'
#rev = 'acf53c7de6982aee4747b1ff47908326da52487c'
#subdir = 'aptos-move/framework/aptos-stdlib'
19 changes: 19 additions & 0 deletions move-contract/sources/demo.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module call_evm_demo::demo {
use aptos_framework::evm::{MoveContractCap, register_move_contract, call_evm_from_move, get_nonce, get_evm_address};

struct ModuleCap has key {
cap: MoveContractCap
}

fun init_module(signer: &signer) {
move_to(signer, ModuleCap {
cap: register_move_contract(signer)
});
}

public entry fun call_evm(to: vector<u8>, calldata: vector<u8>, value_bytes: vector<u8>) acquires ModuleCap {
let cap = borrow_global_mut<ModuleCap>(@call_evm_demo);
let nonce = get_nonce(get_evm_address(@call_evm_demo));
call_evm_from_move(&cap.cap, nonce, to, calldata, value_bytes, 1);
}
}

0 comments on commit 7cc2488

Please sign in to comment.