EOSIO Ethereum Virtual Machine (EVM)
Action | CPU Cost |
---|---|
ERC20 Transfer | 504µs (TX) |
ERC20 Deploy | 764µs (TX) |
EVM Transfer | 325µs (TX) |
EVM New Address | 553µs (TX) |
The code in this repository has not been audited by a professional audit firm. Please use at your own discretion and risk. The author takes no responsibility for any material or inmaterial losses from any form of operation or deployment of the software within this repository.
eosio.evm supports all 9 precompiles
All constants are found at constants.hpp
NOTE: [TESTING, CHARGE_SENDER_FOR_GAS] must be enabled, and [OPTRACE, PRINT_LOGS] must be disabled for ethereum/tests testing to pass successfuly.
NOTE: If ec_add, ec_mul and ec_pairing precompiles are required, set BN_CURVE to true (will increase WASM size by 210KB, or ~2MB onchain).
Deployment steps are laid out step-by-step in both the JS and cleos guides:
JS Guide: eos-evm-js guide
Cleos Guide: cleos guide
Basic Guide: Simply deploy the WASM and ABI at eosio.evm/eosio.evm/eosio.evm.wasm and eosio.evm/eosio.evm/eosio.evm.abi
It is important that any node that you deploy the contract to is running EOSVM OC through the --eos-vm-oc-enable
option
sudo apt install make
sudo snap install cmake --classic
sudo apt install build-essential
wget https://github.com/eosio/eos/releases/download/v2.0.4/eosio_2.0.4-1-ubuntu-18.04_amd64.deb
sudo apt install ./eosio_2.0.4-1-ubuntu-18.04_amd64.deb
wget https://github.com/eosio/eosio.cdt/releases/download/v1.7.0/eosio.cdt_1.7.0-1-ubuntu-18.04_amd64.deb
sudo apt install ./eosio.cdt_1.7.0-1-ubuntu-18.04_amd64.deb
For other platforms than Ubuntu 18.04, check eos and eosio.cdt
Note: You must build eos from source if you wish to manually build the unit tests in eosio.evm
git clone https://github.com/jafri/eosio.evm
cd eosio.evm
cmake .
make -j4
If you wish to build tests, use cmake . -DBUILD_TESTS=true
If not set automatically, you may need to manually set BOOST_ROOT to the directory of your boost installation.
tests/eosio.evm_tests.cpp has five types of tests, which can each be turned on or off individually:
const bool base_enabled = false; // Base testing of linking EOS account
const bool erc20_enabled = false; // Test ERC20 contract deployments
const bool erc721_enabled = false; // Test ERC721 contract deployments
const bool transaction_tests_enabled = false; // Test ethereum/tests TransactionTests
const bool state_tests_enabled = true; // Test ethereum/tests GeneralStateTests
In constants.hpp, TESTING must be enabled to seed initial state of accounts and CHARGE_SENDER_FOR_GAS must be enabled if using unmodified ethereum/tests since tests will only match post-state balances if gas is charged.
If using modified tests to account for no gas being charged, simply ensure CHARGE_SENDER_FOR_GAS is set to false (default), and replace the default path jsontests/BlockchainTests/GeneralStateTests
in eosio.evm_tests.cpp with the path to the modified tests.
Running tests:
cd tests
make -j4
./unit_test # Non-verbose
./unit_test -- --verbose # Expanded logging
ACTION raw ( const eosio::name& ram_payer,
const std::vector<int8_t>& tx,
const std::optional<eosio::checksum160>& sender);
ram_payer
Name of account paying for RAM coststx
will take a raw Ethereum transaction RLP hex encoded without the ‘0x’ prefixsender
is an optional parameter used when the tx
is not signedACTION create ( const eosio::name& account,
const std::string& data);
account
is the EOSIO account creating the new Ethereum accountdata
is an arbitrary string used as a salt to create the new Ethereum accountACTION withdraw ( const eosio::name& to,
const eosio::asset& quantity);
account
is the EOSIO account associated with an Ethereum account with a balancequantity
is an EOSIO asset like “4.0000 SYS” for the amount to withdraw[[eosio::on_notify("eosio.token::transfer")]]
void transfer( const eosio::name& from,
const eosio::name& to,
const eosio::asset& quantity,
const std::string& memo );
ACTION call( const eosio::name& ram_payer,
const std::vector<int8_t>& tx,
const std::optional<eosio::checksum160>& sender );
struct Account {
uint64_t index;
eosio::checksum160 address;
eosio::name account;
uint64_t nonce;
std::vector<uint8_t> code;
bigint::checksum256 balance;
}
index
- auto-incremented counter for accounts, also used as scope index for AccountStatesaddress
- Ethereum 160 bit addressaccount
- EOSIO account associated with Ethereum accountnonce
- Current nonce of the accountcode
- Contract code for Ethereum account if presentbalance
- 256 bit balance stored as a bigint (shows as big endian when printed). The precision is 10^18 as specified in Ethereum whitepaper. Therefore, 1 EOS is represented as 1000000000000000000, which is de0b6b3a7640000 in big-endian hex.struct AccountState {
uint64_t index;
eosio::checksum256 key;
bigint::checksum256 value;
}
index
- auto-incremented counter for account states, only used as primary keykey
- big-endian encoded key for storagevalue
- big-endian encoded value for storageNote that this repository is still in a highly iterative state, if you find any bugs, please open an issue or a pull request.