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 --versionDownload 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 --helpconvertConverting a sol script to move binary codecallRun a Move functionresourcesCommand 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,--outputWhere to save the converted Move binary file--moduleThe name of the move module. If not specified, the name will be taken from the abi path-p,--profileProfile name or address. The address must start with "0x". [default: default]-a,--argsParameters for initialization--native-inputInput params of native type--native-outputOutput value of native type--u128_ioUse u128 instead of u256-d,--deployDeploying the module in aptos node--max-gasMaximum 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 anabifile with the same name in the same folder. These abi and bin will be translated into move binarycodeabi- It is expected that there is anbinfile 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.solSaved in the "./APlusB"
Move module address: Address from the "default" profile
Move module name: APlusB
e2m convert examples/APlusB.abiSaved in "./APlusB.mv"
Move module address: Address from the "default" profile
Move module name: APlusB
e2m convert examples/APlusB.binSaved in "./APlusB.mv"
Move module address: Address from the "default" profile
Move module name: APlusB
e2m convert examples/BinNotFound.abiError: 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 ./TestSaved 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 ./ABSaved 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 ApBSaved in "./ApB"
Move module address: Address from the "default" profile
Move module name: ApB
e2m convert examples/two_functions.sol --module TFSaved 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 0x3Saved in "./ConstFn"
Move module address: 0x3
Move module name: ConstFn
e2m convert examples/two_functions.sol --profile demoSaved 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 20000e2m convert examples/a_plus_b.sol \
-o ./aplusbA "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-outpute2m convert examples/a_plus_b.sol \
--native-input \
--native-output \
--u128-ioSee help:
e2m call --help-
-f,--function-idFunction name as<ADDRESS>::<MODULE_ID>::<FUNCTION_NAME>\ -
-a,--argsArguments 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-argsParameters for initialization. Required if a sol file is specified in the path -
--native-typeUse native "move" types for input and output values -
--howDefault: 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 -
--pathPath to converted project or sol file -
-p,--profileProfile name or address. The address must start with "0x". [default: default] -
--max-gasMaximum amount of gas units to be used to send this transaction
See help:
e2m resources --help-
--queryType of items to list: [balance, resources, modules, resource, events] [default: resources] -
--decode-typesTypes for decoding. Used for decoding EVENTS -
-r,--resource-pathQuery<ADDRESS>::<MODULE_ID>::<FUNCTION_NAME>(::<FIELD_NAME>)?Example: Resource:
default::ModuleName::StuctureName
List of Events:default::ModuleName::StuctureName::field_name -
--abiPath to abi for decoding events -
--limitMax number of events to retrieve [default: 10] -
--startStarting sequence number of events [default: 0] -
--urlURL to a fullnode on the network -
--connection-timeout-sConnection timeout in seconds, used for the REST endpoint of the fullnode [default: 30] -
--accountAddress of the account you want to list resources/modules for -
--profileProfile 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 \
-dPublishing 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-yesCalling the module constructor to assign the current account as the owner
aptos move run \
--function-id default::ScUsersNative::constructor \
--max-gas 5000 \
--assume-yesOr
e2m call \
--function-id default::ScUsersNative::constructor \
--max-gas 5000 \
--nativeaptos move run \
--function-id default::ScUsersNative::create_user \
--max-gas 25000 \
--assume-yes \
--profile demoOr
e2m call \
--function-id default::ScUsersNative::create_user \
--max-gas 25000 \
--native \
--profile demoaccount "default": id = 1
aptos move run \
--function-id default::ScUsersNative::is_id \
--args u128:1 \
--max-gas 10000 \
--assume-yesor
e2m call \
--function-id default::ScUsersNative::is_id \
--args u128:1 \
--max-gas 10000 \
--nativeaccount "demo": id = 2
aptos move run \
--function-id default::ScUsersNative::is_id \
--args u128:2 \
--max-gas 10000 \
--profile demo \
--assume-yesOr
e2m call \
--function-id default::ScUsersNative::is_id \
--args u128:2 \
--max-gas 10000 \
--profile demo \
--nativeaptos move run \
--function-id default::ScUsersNative::is_owner \
--max-gas 10000 \
--assume-yesor
e2m call \
--function-id default::ScUsersNative::is_owner \
--max-gas 10000
--nativeAn error will occur when checking from another account
aptos move run \
--function-id default::ScUsersNative::is_owner \
--max-gas 10000 \
--profile demo \
--assume-yesaccount "default": 10000000000000000000000000000
aptos move run \
--function-id default::ScUsersNative::check_balance \
--args u128:10000000000000000000000000000 \
--max-gas 10000 \
--assume-yesOr
e2m call \
--function-id default::ScUsersNative::check_balance \
--args u128:10000000000000000000000000000 \
--max-gas 10000 \
--nativeaccount "demo": 0
aptos move run \
--function-id default::ScUsersNative::is_empty_balance \
--max-gas 10000 \
--profile demo \
--assume-yesor
e2m call \
--function-id default::ScUsersNative::is_empty_balance \
--max-gas 10000 \
--profile demo \
--nativeSending 200 coins from "default" to "demo"
aptos move run \
--function-id default::ScUsersNative::transfer \
--args address:demo u128:200 \
--max-gas 25000 \
--assume-yesOr
e2m call \
--function-id default::ScUsersNative::transfer \
--args address:demo u128:200 \
--max-gas 25000 \
--nativeAccount default
aptos move run \
--function-id default::ScUsersNative::check_balance \
--args u128:9999999999999999999999999800 \
--max-gas 10000 \
--assume-yesOr
e2m call \
--function-id default::ScUsersNative::check_balance \
--args u128:9999999999999999999999999800 \
--max-gas 10000 \
--nativeAccount demo
aptos move run \
--function-id default::ScUsersNative::check_balance \
--args u128:200 \
--max-gas 10000 \
--profile demo \
--assume-yesOr
e2m call \
--function-id default::ScUsersNative::check_balance \
--args u128:200 \
--max-gas 10000 \
--native \
--profile demoThis 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 \
-dPublishing 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-yesCalling the module constructor to assign the current account as the owner
e2m call \
--function-id default::ScUsersEth::constructor \
--max-gas 5000e2m call \
--function-id default::ScUsersEth::create_user \
--max-gas 25000 \
--profile demoaccount "default": id = 1
e2m call \
--function-id default::ScUsersEth::is_id \
--args u128:1 \
--max-gas 10000account "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 10000An error will occur when checking from another account
e2m call \
--function-id default::ScUsersEth::is_owner \
--max-gas 10000 \
--profile demoaccount "default": 10000000000000000000000000000
e2m call \
--function-id default::ScUsersEth::check_balance \
--args u128:10000000000000000000000000000 \
--max-gas 10000account "demo": 0
e2m call \
--function-id default::ScUsersEth::is_empty_balance \
--max-gas 10000 \
--profile demoSending 200 coins from "default" to "demo"
e2m call \
--function-id default::ScUsersEth::transfer \
--args address:demo u128:200 \
--max-gas 25000Account default
e2m call \
--function-id default::ScUsersEth::check_balance \
--args u128:9999999999999999999999999800 \
--max-gas 10000Account 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 localUint(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.solUint(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.solUint(27)
e2m resources --query resource \
--resource-path default::UsersEth::Persiste2m resources --query events \
--resource-path default::UsersEth::Persist::eventse2m resources --query events \
--resource-path default::UsersEth::Persist::events \
--abi ./examples/i_users_ethtypes/UsersEth.abie2m resources --query events \
--resource-path default::UsersEth::Persist::events \
--decode-types data:address,address,u256 topics:bytes