EVM to Move static bytecode translator.
We are working on updating the project.
Development roadmap:
- Update dependencies
- We plan to abandon parsing the Ether bytecode and switch to Yul
- Implement all control flow instructions
- Call other contracts with a known address at compile time
- Move call
Converts solidity file to binary move code. You can convert from abi + bin files or a sol file
! IMPORTANT
To convert from a sol file, solc must be installed on the computer and accessible from the terminal using the short command solc.\
How to install solc, see the documentation
The solc version must be at least 0.8.15
solc --version
! IMPORTANT
If this command is not available for execution from the terminal, e2m will not work.
How to install aptos, see the documentation
The aptos version must be at least 1.0.0
aptos --version
Download link for the latest version of e2m
Unpack the archive and place the executable file in a place convenient for you. For convenience, create an alias e2m
in the system for this file.
! IMPORTANT In all examples, e2m will be called via an alias
! IMPORTANT
Creating an account "default" and "demo" Before running the examples, you will need to create a private key. It will be used both for the module address and for publishing on the node.
Default profile:
aptos initDemo profile:
aptos init --profile demoSee more: aptos init
Replenishment of the balance in "devnet"
Default profile:
aptos account fund-with-faucet --amount 10000000Demo profile:
aptos account fund-with-faucet --account demo --amount 10000000 --profile demoSee more: aptos account
e2m --help
convert
Converting a sol script to move binary codecall
Run a Move functionresources
Command to list resources, modules, or other items owned by an address
e2m convert --help
<PATH>
Path to the file. Specify the path to sol file or abi | bin-o
,--output
Where to save the converted Move binary file--module
The name of the move module. If not specified, the name will be taken from the abi path-p
,--profile
Profile name or address. The address must start with "0x". [default: default]-a
,--args
Parameters for initialization--native-input
Input params of native type--native-output
Output value of native type--u128_io
Use u128 instead of u256-d
,--deploy
Deploying the module in aptos node--max-gas
Maximum amount of gas units to be used to send this transaction
You can find the files from the examples in the ./examples folder
Required parameters are the paths to sol file (<PATH>
).
The file can be extensions:
sol
- The file will be compiled using the solc utility. The resulting abi and bin will be translated into ** move binarycode**bin
- It is expected that there is anabi
file with the same name in the same folder. These abi and bin will be translated into move binarycodeabi
- It is expected that there is anbin
file with the same name in the same folder. These abi and bin will be translated into move binarycode
The name from the passed solidity library will be used as the filename and the name of the move module.
After executing the command, you will see the path to the created directory (Example: "./NameSolModule/").
The directory will contain the interface for interacting with the module, the abi and the move binarycode
file.
By default, the directory is saved to the current directory.
e2m convert examples/a_plus_b.sol
Saved in the "./APlusB"
Move module address: Address from the "default" profile
Move module name: APlusB
e2m convert examples/APlusB.abi
Saved in "./APlusB.mv"
Move module address: Address from the "default" profile
Move module name: APlusB
e2m convert examples/APlusB.bin
Saved in "./APlusB.mv"
Move module address: Address from the "default" profile
Move module name: APlusB
e2m convert examples/BinNotFound.abi
Error: Couldn't find bin. Path:"examples/BinNotFound.bin"
! IMPORTANT
A successful broadcast always requires a bin and an abi solidity library
The -o
, --output
parameter is responsible for specifying the location of the directory where the result will be
saved.
e2m convert examples/const_fn.sol -o ./Test
Saved in "./Test"
The move binary file will be created in the directory named ./Test/ConstFn.mv
Move module address: Address from the "default" profile
Move module name: ConstFn
e2m convert examples/APlusB.bin -o ./AB
Saved in "./AB"
Move module address: Address from the "default" profile
Move module name: APlusB
The --module
argument is responsible for explicitly specifying the move module name.
e2m convert examples/APlusB.abi --module ApB
Saved in "./ApB"
Move module address: Address from the "default" profile
Move module name: ApB
e2m convert examples/two_functions.sol --module TF
Saved in "./TF"
Move module address: Address from the "default" profile
Move module name: TF
The argument -p
, --profile
is responsible for explicitly specifying the address of the transfer module or the name
of the profile from which the address will be taken.
If the parameter value starts with "0x", then it will be taken as an address, everything else will be considered
the profile name.
Profile data will be taken from .aptos/config.yaml
e2m convert examples/const_fn.sol -p 0x3
Saved in "./ConstFn"
Move module address: 0x3
Move module name: ConstFn
e2m convert examples/two_functions.sol --profile demo
Saved in "./TwoFunctions"
Move module address: Address from the "demo" profile
Move module name: TwoFunctions
e2m convert examples/const_fn.sol -o ./MyMove --module DemoName --profile 0x3
Saved in "./MyMove"
Move module address: 0x3
Move module name: DemoName
In order for the module to be published on the aptos node after conversion, use the -d
, --deploy
flag.
After successful publication, you will receive complete information in json format about the completed process.
! IMPORTANT
When you try to re-publish the module, you will see the message "DUPLICATE_MODULE_NAME"
e2m convert examples/two_functions.sol -d --max-gas 20000
e2m convert examples/APlusB.abi -o ./module --profile demo --deploy --max-gas 20000
e2m convert examples/a_plus_b.sol \
-o ./aplusb
A "move" project will be created in the current directory. This interface is necessary for accessing the published module.
By default, the module uses "Ethereum" types for data input and output.
--native-input
, --native-output
- by setting these flags, the functions in the module will use the "move" types as
input and output parameters.
--u128-io
- Use u128 instead of u256
e2m convert examples/a_plus_b.sol \
--native-input \
--native-output
e2m convert examples/a_plus_b.sol \
--native-input \
--native-output \
--u128-io
See help:
e2m call --help
-
-f
,--function-id
Function name as<ADDRESS>::<MODULE_ID>::<FUNCTION_NAME>
\ -
-a
,--args
Arguments combined with their type separated by spaces. Supported types
[u8, u64, u128, bool, hex, string, address, raw]
Example:
address:0x1 bool:true u8:0 Example:
0x02::message::set_message
default::message::set_message -
--init-args
Parameters for initialization. Required if a sol file is specified in the path -
--native-type
Use native "move" types for input and output values -
--how
Default: nodenode
- Call a remote contract on a nodelocal
- Call a remote contract locally and display the return valuelocal-source
- Call a local contract with remote resources and display the return valuevm
- Call a local contract and display the return value -
--path
Path to converted project or sol file -
-p
,--profile
Profile name or address. The address must start with "0x". [default: default] -
--max-gas
Maximum amount of gas units to be used to send this transaction
See help:
e2m resources --help
-
--query
Type of items to list: [balance, resources, modules, resource, events] [default: resources] -
--decode-types
Types for decoding. Used for decoding EVENTS -
-r
,--resource-path
Query<ADDRESS>::<MODULE_ID>::<FUNCTION_NAME>(::<FIELD_NAME>)?
Example: Resource:
default::ModuleName::StuctureName
List of Events:default::ModuleName::StuctureName::field_name
-
--abi
Path to abi for decoding events -
--limit
Max number of events to retrieve [default: 10] -
--start
Starting sequence number of events [default: 0] -
--url
URL to a fullnode on the network -
--connection-timeout-s
Connection timeout in seconds, used for the REST endpoint of the fullnode [default: 30] -
--account
Address of the account you want to list resources/modules for -
--profile
Profile to use from the CLI config This will be used to override associated settings such as the REST URL, the Faucet URL, and the private key arguments.Defaults to "default"
Defaults to https://fullnode.devnet.aptoslabs.com/v1
This command we will make
- Converting a ./examples/users.sol file to "mv"
- Generate an interface to use in source. The
./examples/i_users_native/
folder will appear in the current directory - Module will support "move" types
- We will publish the generated module from the "default" profile
e2m convert ./examples/users.sol \
-o ./examples/i_users_native \
--module UsersNative \
-a self \
--native-input \
--native-output \
--max-gas 25000 \
-d
Publishing a ./examples/sc_users_native for interacting with the module
Important don't forget to replace the address
aptos move publish \
--package-dir ./examples/sc_users_native \
--max-gas 10000 \
--assume-yes
Calling the module constructor to assign the current account as the owner
aptos move run \
--function-id default::ScUsersNative::constructor \
--max-gas 5000 \
--assume-yes
Or
e2m call \
--function-id default::ScUsersNative::constructor \
--max-gas 5000 \
--native
aptos move run \
--function-id default::ScUsersNative::create_user \
--max-gas 25000 \
--assume-yes \
--profile demo
Or
e2m call \
--function-id default::ScUsersNative::create_user \
--max-gas 25000 \
--native \
--profile demo
account "default": id = 1
aptos move run \
--function-id default::ScUsersNative::is_id \
--args u128:1 \
--max-gas 10000 \
--assume-yes
or
e2m call \
--function-id default::ScUsersNative::is_id \
--args u128:1 \
--max-gas 10000 \
--native
account "demo": id = 2
aptos move run \
--function-id default::ScUsersNative::is_id \
--args u128:2 \
--max-gas 10000 \
--profile demo \
--assume-yes
Or
e2m call \
--function-id default::ScUsersNative::is_id \
--args u128:2 \
--max-gas 10000 \
--profile demo \
--native
aptos move run \
--function-id default::ScUsersNative::is_owner \
--max-gas 10000 \
--assume-yes
or
e2m call \
--function-id default::ScUsersNative::is_owner \
--max-gas 10000
--native
An error will occur when checking from another account
aptos move run \
--function-id default::ScUsersNative::is_owner \
--max-gas 10000 \
--profile demo \
--assume-yes
account "default": 10000000000000000000000000000
aptos move run \
--function-id default::ScUsersNative::check_balance \
--args u128:10000000000000000000000000000 \
--max-gas 10000 \
--assume-yes
Or
e2m call \
--function-id default::ScUsersNative::check_balance \
--args u128:10000000000000000000000000000 \
--max-gas 10000 \
--native
account "demo": 0
aptos move run \
--function-id default::ScUsersNative::is_empty_balance \
--max-gas 10000 \
--profile demo \
--assume-yes
or
e2m call \
--function-id default::ScUsersNative::is_empty_balance \
--max-gas 10000 \
--profile demo \
--native
Sending 200 coins from "default" to "demo"
aptos move run \
--function-id default::ScUsersNative::transfer \
--args address:demo u128:200 \
--max-gas 25000 \
--assume-yes
Or
e2m call \
--function-id default::ScUsersNative::transfer \
--args address:demo u128:200 \
--max-gas 25000 \
--native
Account default
aptos move run \
--function-id default::ScUsersNative::check_balance \
--args u128:9999999999999999999999999800 \
--max-gas 10000 \
--assume-yes
Or
e2m call \
--function-id default::ScUsersNative::check_balance \
--args u128:9999999999999999999999999800 \
--max-gas 10000 \
--native
Account demo
aptos move run \
--function-id default::ScUsersNative::check_balance \
--args u128:200 \
--max-gas 10000 \
--profile demo \
--assume-yes
Or
e2m call \
--function-id default::ScUsersNative::check_balance \
--args u128:200 \
--max-gas 10000 \
--native \
--profile demo
This command we will make
- Converting a ./examples/users.sol file to "mv"
- Generate an interface to use in source. The
./i_users_ethtypes/
folder will appear in the current directory - We will publish the generated module from the "default" profile
e2m convert ./examples/users.sol \
--module UsersEth \
-o ./examples/i_users_ethtypes \
-a self \
--max-gas 30000 \
-d
Publishing a ./examples/sc_users_ethtypes for interacting with the module
Important don't forget to replace the address
aptos move publish \
--package-dir ./examples/sc_users_ethtypes \
--max-gas 20000 \
--assume-yes
Calling the module constructor to assign the current account as the owner
e2m call \
--function-id default::ScUsersEth::constructor \
--max-gas 5000
e2m call \
--function-id default::ScUsersEth::create_user \
--max-gas 25000 \
--profile demo
account "default": id = 1
e2m call \
--function-id default::ScUsersEth::is_id \
--args u128:1 \
--max-gas 10000
account "demo": id = 2
e2m call \
--function-id default::ScUsersEth::is_id \
--args u128:2 \
--max-gas 10000 \
--profile demo
e2m call \
--function-id default::ScUsersEth::is_owner \
--max-gas 10000
An error will occur when checking from another account
e2m call \
--function-id default::ScUsersEth::is_owner \
--max-gas 10000 \
--profile demo
account "default": 10000000000000000000000000000
e2m call \
--function-id default::ScUsersEth::check_balance \
--args u128:10000000000000000000000000000 \
--max-gas 10000
account "demo": 0
e2m call \
--function-id default::ScUsersEth::is_empty_balance \
--max-gas 10000 \
--profile demo
Sending 200 coins from "default" to "demo"
e2m call \
--function-id default::ScUsersEth::transfer \
--args address:demo u128:200 \
--max-gas 25000
Account default
e2m call \
--function-id default::ScUsersEth::check_balance \
--args u128:9999999999999999999999999800 \
--max-gas 10000
Account demo
e2m call \
--function-id default::ScUsersEth::check_balance \
--args u128:200 \
--max-gas 10000 \
--profile demo
! IMPORTANT
When starting contacts locally, you cannot access other resources. For this reason, the data may be incorrect or will not work:msg.sender.balance
,block.number
,block.timestamp
, etc.
--how local
- Call a remote contract locally and display the return value
e2m call \
--function-id default::UsersEth::get_id \
--path ./examples/i_users_ethtypes \
--how local
Uint(1)
--how local-source
- Call a local contract with remote resources and display the return value
e2m call \
--function-id default::ConstFn::const_fn_10 \
--how local-source \
--path ./examples/const_fn.sol
Uint(10)
--how vm
Call a local contract and display the return value
e2m call \
--function-id default::APlusB::plus \
--how vm \
--path ./examples/a_plus_b.sol
Uint(27)
e2m resources --query resource \
--resource-path default::UsersEth::Persist
e2m resources --query events \
--resource-path default::UsersEth::Persist::events
e2m resources --query events \
--resource-path default::UsersEth::Persist::events \
--abi ./examples/i_users_ethtypes/UsersEth.abi
e2m resources --query events \
--resource-path default::UsersEth::Persist::events \
--decode-types data:address,address,u256 topics:bytes