marco evm
Módulo0x1::evm
0x1::evm- Recurso - Account
- estructura - Log0Event
- estructura - Log1Event
- estructura - Log2Event
- estructura - Log3Event
- estructura - Log4Event
- Recurso - ContractEvent
- Constantes 
- Función - send_tx
- Función - estimate_tx_gas
- Función - deposit
- Función - get_move_address
- Función - query
- Función - get_storage_at
- Función - execute
- Función - run
- Función - exist_contract
- Función - add_balance
- Función - transfer_from_move_addr
- Función - transfer_to_evm_addr
- Función - transfer_to_move_addr
- Función - create_event_if_not_exist
- Función - create_account_if_not_exist
- Función - verify_nonce
- Función - verify_signature
Copiar
use 0x1::account;
use 0x1::aptos_account;
use 0x1::aptos_coin;
use 0x1::aptos_hash;
use 0x1::block;
use 0x1::coin;
use 0x1::create_signer;
use 0x1::debug;
use 0x1::event;
use 0x1::evm_util;
use 0x1::from_bcs;
use 0x1::option;
use 0x1::rlp_decode;
use 0x1::rlp_encode;
use 0x1::secp256k1;
use 0x1::signer;
use 0x1::string;
use 0x1::table;
use 0x1::timestamp;
use 0x1::vector;RecursoAccount
AccountCopiar
struct Account has keyCampos
balance: u256nonce: u64is_contract: boolcode: vector<u8>storage: table::Table<u256, vector<u8>>
estructuraLog0Event
Log0EventCopiar
struct Log0Event has drop, storeestructuraLog1Event
Log1EventCopiar
struct Log1Event has drop, storeestructuraLog2Event
Log2EventCopiar
struct Log2Event has drop, storeestructuraLog3Event
Log3EventCopiar
struct Log3Event has drop, storeestructuraLog4Event
Log4EventCopiar
struct Log4Event has drop, storeCampos
contract: vector<u8>data: vector<u8>topic0: vector<u8>topic1: vector<u8>topic2: vector<u8>topic3: vector<u8>
RecursoContractEvent
ContractEventCopiar
struct ContractEvent has keyCampos
log0Event: event::EventHandle<evm::Log0Event>log1Event: event::EventHandle<evm::Log1Event>log2Event: event::EventHandle<evm::Log2Event>log3Event: event::EventHandle<evm::Log3Event>log4Event: event::EventHandle<evm::Log4Event>
Constantes
Copiar
const U256_MAX: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;Copiar
const ACCOUNT_NOT_EXIST: u64 = 10008;Copiar
const ADDR_LENGTH: u64 = 10001;Copiar
const CHAIN_ID: u64 = 336;Copiar
const CHAIN_ID_BYTES: vector<u8> = [1, 80];Copiar
const CONTRACT_DEPLOYED: u64 = 10006;Copiar
const CONTRACT_READ_ONLY: u64 = 10005;Copiar
const CONVERT_BASE: u256 = 10000000000;Copiar
const INSUFFIENT_BALANCE: u64 = 10003;Copiar
const NONCE: u64 = 10004;Copiar
const ONE_ADDR: vector<u8> = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];Copiar
const SIGNATURE: u64 = 10002;Copiar
const TX_NOT_SUPPORT: u64 = 10007;Copiar
const TX_TYPE_LEGACY: u64 = 1;Copiar
const ZERO_ADDR: vector<u8> = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];Funciónsend_tx
send_txCopiar
public entry fun send_tx(sender: &signer, evm_from: vector<u8>, tx: vector<u8>, gas_bytes: vector<u8>, tx_type: u64)Implementación
Copiar
public entry fun send_tx(
    sender: &signer,
    evm_from: vector<u8>,
    tx: vector<u8>,
    gas_bytes: vector<u8>,
    tx_type: u64,
) acquires Account, ContractEvent {
    let gas = to_u256(gas_bytes);
    if(tx_type == TX_TYPE_LEGACY) {
        let decoded = decode_bytes_list(&tx);
        debug::print(&decoded);
        let nonce = to_u256(*vector::borrow(&decoded, 0));
        let gas_price = to_u256(*vector::borrow(&decoded, 1));
        let gas_limit = to_u256(*vector::borrow(&decoded, 2));
        let evm_to = *vector::borrow(&decoded, 3);
        let value = to_u256(*vector::borrow(&decoded, 4));
        let data = *vector::borrow(&decoded, 5);
        let v = (to_u256(*vector::borrow(&decoded, 6)) as u64);
        let r = *vector::borrow(&decoded, 7);
        let s = *vector::borrow(&decoded, 8);
        let message = encode_bytes_list(vector[
            u256_to_trimed_data(nonce),
            u256_to_trimed_data(gas_price),
            u256_to_trimed_data(gas_limit),
            evm_to,
            u256_to_trimed_data(value),
            data,
            CHAIN_ID_BYTES,
            x"",
            x""
            ]);
        let message_hash = keccak256(message);
        verify_signature(evm_from, message_hash, to_32bit(r), to_32bit(s), v);
        execute(to_32bit(evm_from), to_32bit(evm_to), (nonce as u64), data, value);
        transfer_to_move_addr(to_32bit(evm_from), address_of(sender), gas * CONVERT_BASE);
    } else {
        assert!(false, TX_NOT_SUPPORT);
    }
}Funciónestimate_tx_gas
estimate_tx_gasCopiar
public entry fun estimate_tx_gas(evm_from: vector<u8>, evm_to: vector<u8>, data: vector<u8>, value_bytes: vector<u8>, tx_type: u64)Implementación
Copiar
public entry fun estimate_tx_gas(
    evm_from: vector<u8>,
    evm_to: vector<u8>,
    data: vector<u8>,
    value_bytes: vector<u8>,
    tx_type: u64,
) acquires Account, ContractEvent {
    let value = to_u256(value_bytes);
    if(tx_type == TX_TYPE_LEGACY) {
        let address_from = create_resource_address(&@aptos_framework, to_32bit(evm_from));
        assert!(exists<Account>(address_from), ACCOUNT_NOT_EXIST);
        let nonce = borrow_global<Account>(create_resource_address(&@aptos_framework, to_32bit(evm_from))).nonce;
        execute(to_32bit(evm_from), to_32bit(evm_to), nonce, data, value);
    } else {
        assert!(false, TX_NOT_SUPPORT);
    }
}Funcióndeposit
depositCopiar
public entry fun deposit(sender: &signer, evm_addr: vector<u8>, amount_bytes: vector<u8>)Implementación
Copiar
public entry fun deposit(sender: &signer, evm_addr: vector<u8>, amount_bytes: vector<u8>) acquires Account {
    let amount = to_u256(amount_bytes);
    assert!(vector::length(&evm_addr) == 20, ADDR_LENGTH);
    transfer_from_move_addr(sender, to_32bit(evm_addr), amount);
}Funciónget_move_address
get_move_addressCopiar
#[view]
public fun get_move_address(evm_addr: vector<u8>): addressImplementación
Copiar
public fun get_move_address(evm_addr: vector<u8>): address {
    create_resource_address(&@aptos_framework, to_32bit(evm_addr))
}Funciónquery
queryCopiar
#[view]
public fun query(sender: vector<u8>, contract_addr: vector<u8>, data: vector<u8>): vector<u8>Implementación
Copiar
public fun query(sender:vector<u8>, contract_addr: vector<u8>, data: vector<u8>): vector<u8> acquires Account, ContractEvent {
    contract_addr = to_32bit(contract_addr);
    let contract_store = borrow_global_mut<Account>(create_resource_address(&@aptos_framework, contract_addr));
    run(sender, sender, contract_addr, contract_store.code, data, true, 0)
}Funciónget_storage_at
get_storage_atCopiar
#[view]
public fun get_storage_at(addr: vector<u8>, slot: vector<u8>): vector<u8>Implementación
Copiar
public fun get_storage_at(addr: vector<u8>, slot: vector<u8>): vector<u8> acquires Account {
    let move_address = create_resource_address(&@aptos_framework, addr);
    if(exists<Account>(move_address)) {
        let account_store = borrow_global<Account>(move_address);
        let slot_u256 = data_to_u256(slot, 0, (vector::length(&slot) as u256));
        if(table::contains(&account_store.storage, slot_u256)) {
            *table::borrow(&account_store.storage, slot_u256)
        } else {
            vector::empty<u8>()
        }
    } else {
        vector::empty<u8>()
    }
}Funciónexecute
executeCopiar
fun execute(evm_from: vector<u8>, evm_to: vector<u8>, nonce: u64, data: vector<u8>, value: u256): vector<u8>Implementación
Copiar
fun execute(evm_from: vector<u8>, evm_to: vector<u8>, nonce: u64, data: vector<u8>, value: u256): vector<u8> acquires Account, ContractEvent {
    let address_from = create_resource_address(&@aptos_framework, evm_from);
    let address_to = create_resource_address(&@aptos_framework, evm_to);
    create_account_if_not_exist(address_from);
    create_account_if_not_exist(address_to);
    verify_nonce(address_from, nonce);
    let account_store_to = borrow_global_mut<Account>(address_to);
    if(evm_to == ZERO_ADDR) {
        let evm_contract = get_contract_address(evm_from, nonce);
        let address_contract = create_resource_address(&@aptos_framework, evm_contract);
        create_account_if_not_exist(address_contract);
        create_event_if_not_exist(address_contract);
        borrow_global_mut<Account>(address_contract).is_contract = true;
        borrow_global_mut<Account>(address_contract).code = run(evm_from, evm_from, evm_contract, data, x"", false, value);
        evm_contract
    } else if(evm_to == ONE_ADDR) {
        let amount = data_to_u256(data, 36, 32);
        let to = to_address(slice(data, 100, 32));
        transfer_to_move_addr(evm_from, to, amount);
        x""
    } else {
        if(account_store_to.is_contract) {
            run(evm_from, evm_from, evm_to, account_store_to.code, data, false, value)
        } else {
            transfer_to_evm_addr(evm_from, evm_to, value);
            x""
        }
    }
}Funciónrun
runCopiar
fun run(sender: vector<u8>, origin: vector<u8>, evm_contract_address: vector<u8>, code: vector<u8>, data: vector<u8>, readOnly: bool, value: u256): vector<u8>Implementación
Copiar
fun run(sender: vector<u8>, origin: vector<u8>, evm_contract_address: vector<u8>, code: vector<u8>, data: vector<u8>, readOnly: bool, value: u256): vector<u8> acquires Account, ContractEvent {
    let move_contract_address = create_resource_address(&@aptos_framework, evm_contract_address);
    transfer_to_evm_addr(sender, evm_contract_address, value);
    let stack = &mut vector::empty<u256>();
    let memory = &mut vector::empty<u8>();
    // let contract_store = borrow_global_mut<Account>(move_contract_address);
    // let event_store = borrow_global_mut<ContractEvent>(move_contract_address);
    // let storage = simple_map::borrow_mut<vector<u8>, T>(&mut global.contracts, &contract_addr).storage;
    let len = vector::length(&code);
    let runtime_code = vector::empty<u8>();
    let i = 0;
    let ret_size = 0;
    let ret_bytes = vector::empty<u8>();
    while (i < len) {
        let opcode = *vector::borrow(&code, i);
        // debug::print(&i);
        // debug::print(&opcode);
        // stop
        if(opcode == 0x00) {
            ret_bytes = runtime_code;
            break
        }
        else if(opcode == 0xf3) {
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            ret_bytes = slice(*memory, pos, len);
            break
        }
            //add
        else if(opcode == 0x01) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            if(a > 0 && b >= (U256_MAX - a + 1)) {
                vector::push_back(stack, b - (U256_MAX - a + 1));
            } else {
                vector::push_back(stack, a + b);
            };
            i = i + 1;
        }
            //mul
        else if(opcode == 0x02) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            vector::push_back(stack, a * b);
            i = i + 1;
        }
            //sub
        else if(opcode == 0x03) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            if(a >= b) {
                vector::push_back(stack, a - b);
            } else {
                vector::push_back(stack, U256_MAX - b + a + 1);
            };
            i = i + 1;
        }
            //div && sdiv
        else if(opcode == 0x04 || opcode == 0x05) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            vector::push_back(stack, a / b);
            i = i + 1;
        }
            //mod && smod
        else if(opcode == 0x06 || opcode == 0x07) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            vector::push_back(stack, a % b);
            i = i + 1;
        }
            //addmod
        else if(opcode == 0x08) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            let n = vector::pop_back(stack);
            vector::push_back(stack, (a + b) % n);
            i = i + 1;
        }
            //mulmod
        else if(opcode == 0x09) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            let n = vector::pop_back(stack);
            vector::push_back(stack, (a * b) % n);
            i = i + 1;
        }
            //exp
        else if(opcode == 0x0a) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            vector::push_back(stack, power(a, b));
            i = i + 1;
        }
            //lt
        else if(opcode == 0x10) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            if(a < b) {
                vector::push_back(stack, 1)
            } else {
                vector::push_back(stack, 0)
            };
            i = i + 1;
        }
            //gt
        else if(opcode == 0x11) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            if(a > b) {
                vector::push_back(stack, 1)
            } else {
                vector::push_back(stack, 0)
            };
            i = i + 1;
        }
            //slt
        else if(opcode == 0x12) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            let(sg_a, num_a) = to_int256(a);
            let(sg_b, num_b) = to_int256(b);
            let value = 0;
            if((sg_a && !sg_b) || (sg_a && sg_b && num_a > num_b) || (!sg_a && !sg_b && num_a < num_b)) {
                value = 1
            };
            vector::push_back(stack, value);
            i = i + 1;
        }
            //sgt
        else if(opcode == 0x13) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            let(sg_a, num_a) = to_int256(a);
            let(sg_b, num_b) = to_int256(b);
            let value = 0;
            if((sg_a && !sg_b) || (sg_a && sg_b && num_a < num_b) || (!sg_a && !sg_b && num_a > num_b)) {
                value = 1
            };
            vector::push_back(stack, value);
            i = i + 1;
        }
            //eq
        else if(opcode == 0x14) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            if(a == b) {
                vector::push_back(stack, 1);
            } else {
                vector::push_back(stack, 0);
            };
            i = i + 1;
        }
            //and
        else if(opcode == 0x16) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            vector::push_back(stack, a & b);
            i = i + 1;
        }
            //or
        else if(opcode == 0x17) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            vector::push_back(stack, a | b);
            i = i + 1;
        }
            //xor
        else if(opcode == 0x18) {
            let a = vector::pop_back(stack);
            let b = vector::pop_back(stack);
            vector::push_back(stack, a ^ b);
            i = i + 1;
        }
            //not
        else if(opcode == 0x19) {
            // 10 1010
            // 6 0101
            let n = vector::pop_back(stack);
            vector::push_back(stack, U256_MAX - n);
            i = i + 1;
        }
            //shl
        else if(opcode == 0x1b) {
            let b = vector::pop_back(stack);
            let a = vector::pop_back(stack);
            if(b >= 256) {
                vector::push_back(stack, 0);
            } else {
                vector::push_back(stack, a << (b as u8));
            };
            i = i + 1;
        }
            //shr
        else if(opcode == 0x1c) {
            let b = vector::pop_back(stack);
            let a = vector::pop_back(stack);
            if(b >= 256) {
                vector::push_back(stack, 0);
            } else {
                vector::push_back(stack, a >> (b as u8));
            };
            i = i + 1;
        }
            //push0
        else if(opcode == 0x5f) {
            vector::push_back(stack, 0);
            i = i + 1;
        }
            // push1 -> push32
        else if(opcode >= 0x60 && opcode <= 0x7f)  {
            let n = ((opcode - 0x60) as u64);
            let number = data_to_u256(code, ((i + 1) as u256), ((n + 1) as u256));
            vector::push_back(stack, (number as u256));
            i = i + n + 2;
        }
            // pop
        else if(opcode == 0x50) {
            vector::pop_back(stack);
            i = i + 1
        }
            //address
        else if(opcode == 0x30) {
            vector::push_back(stack, data_to_u256(evm_contract_address, 0, 32));
            i = i + 1;
        }
            //balance
        else if(opcode == 0x31) {
            let addr = u256_to_data(vector::pop_back(stack));
            let account_store = borrow_global<Account>(create_resource_address(&@aptos_framework, addr));
            vector::push_back(stack, account_store.balance);
            i = i + 1;
        }
            //origin
        else if(opcode == 0x32) {
            let value = data_to_u256(origin, 0, 32);
            vector::push_back(stack, value);
            i = i + 1;
        }
            //caller
        else if(opcode == 0x33) {
            let value = data_to_u256(sender, 0, 32);
            vector::push_back(stack, value);
            i = i + 1;
        }
            // callvalue
        else if(opcode == 0x34) {
            vector::push_back(stack, value);
            i = i + 1;
        }
            //calldataload
        else if(opcode == 0x35) {
            let pos = vector::pop_back(stack);
            vector::push_back(stack, data_to_u256(data, pos, 32));
            i = i + 1;
            // block.
        }
            //calldatasize
        else if(opcode == 0x36) {
            vector::push_back(stack, (vector::length(&data) as u256));
            i = i + 1;
        }
            //calldatacopy
        else if(opcode == 0x37) {
            let m_pos = vector::pop_back(stack);
            let d_pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let end = d_pos + len;
            // debug::print(&utf8(b"calldatacopy"));
            // debug::print(&data);
            while (d_pos < end) {
                // debug::print(&d_pos);
                // debug::print(&end);
                let bytes = if(end - d_pos >= 32) {
                    slice(data, d_pos, 32)
                } else {
                    slice(data, d_pos, end - d_pos)
                };
                // debug::print(&bytes);
                mstore(memory, m_pos, bytes);
                d_pos = d_pos + 32;
                m_pos = m_pos + 32;
            };
            i = i + 1
        }
            //codesize
        else if(opcode == 0x38) {
            vector::push_back(stack, (vector::length(&code) as u256));
            i = i + 1
        }
            //codecopy
        else if(opcode == 0x39) {
            let m_pos = vector::pop_back(stack);
            let d_pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let end = d_pos + len;
            runtime_code = slice(code, d_pos, len);
            while (d_pos < end) {
                let bytes = if(end - d_pos >= 32) {
                    slice(code, d_pos, 32)
                } else {
                    slice(code, d_pos, end - d_pos)
                };
                mstore(memory, m_pos, bytes);
                d_pos = d_pos + 32;
                m_pos = m_pos + 32;
            };
            i = i + 1
        }
            //extcodesize
        else if(opcode == 0x3b) {
            let bytes = u256_to_data(vector::pop_back(stack));
            let target_evm = to_32bit(slice(bytes, 12, 20));
            let target_address = create_resource_address(&@aptos_framework, target_evm);
            if(exists<Account>(target_address)) {
                let code = borrow_global<Account>(target_address).code;
                vector::push_back(stack, (vector::length(&code) as u256));
            } else {
                vector::push_back(stack, 0);
            };
            i = i + 1;
        }
            //returndatacopy
        else if(opcode == 0x3e) {
            // mstore()
            let m_pos = vector::pop_back(stack);
            let d_pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let bytes = slice(ret_bytes, d_pos, len);
            mstore(memory, m_pos, bytes);
            i = i + 1;
        }
            //returndatasize
        else if(opcode == 0x3d) {
            vector::push_back(stack, ret_size);
            i = i + 1;
        }
            //blockhash
        else if(opcode == 0x40) {
            vector::push_back(stack, 0);
            i = i + 1;
        }
            //coinbase
        else if(opcode == 0x41) {
            vector::push_back(stack, 0);
            i = i + 1;
        }
            //timestamp
        else if(opcode == 0x42) {
            vector::push_back(stack, (now_microseconds() as u256) / 1000000);
            i = i + 1;
        }
            //number
        else if(opcode == 0x43) {
            vector::push_back(stack, (block::get_current_block_height() as u256));
            i = i + 1;
        }
            //difficulty
        else if(opcode == 0x44) {
            vector::push_back(stack, 0);
            i = i + 1;
        }
            //gaslimit
        else if(opcode == 0x45) {
            vector::push_back(stack, 30000000);
            i = i + 1;
        }
            //chainid
        else if(opcode == 0x46) {
            vector::push_back(stack, 1);
            i = i + 1
        }
            //self balance
        else if(opcode == 0x47) {
            let contract_store = borrow_global_mut<Account>(move_contract_address);
            vector::push_back(stack, contract_store.balance);
            i = i + 1;
        }
            // mload
        else if(opcode == 0x51) {
            let pos = vector::pop_back(stack);
            vector::push_back(stack, data_to_u256(slice(*memory, pos, 32), 0, 32));
            i = i + 1;
        }
            // mstore
        else if(opcode == 0x52) {
            let pos = vector::pop_back(stack);
            let value = vector::pop_back(stack);
            mstore(memory, pos, u256_to_data(value));
            // debug::print(memory);
            i = i + 1;
        }
            //mstore8
        else if(opcode == 0x53) {
            let pos = vector::pop_back(stack);
            let value = vector::pop_back(stack);
            *vector::borrow_mut(memory, (pos as u64)) = ((value & 0xff) as u8);
            // mstore(memory, pos, u256_to_data(value & 0xff));
            // debug::print(memory);
            i = i + 1;
        }
            // sload
        else if(opcode == 0x54) {
            let pos = vector::pop_back(stack);
            let contract_store = borrow_global_mut<Account>(move_contract_address);
            if(table::contains(&contract_store.storage, pos)) {
                let value = *table::borrow(&mut contract_store.storage, pos);
                vector::push_back(stack, data_to_u256(value, 0, 32));
            } else {
                vector::push_back(stack, 0);
            };
            i = i + 1;
        }
            // sstore
        else if(opcode == 0x55) {
            if(readOnly) {
                assert!(false, CONTRACT_READ_ONLY);
            };
            let contract_store = borrow_global_mut<Account>(move_contract_address);
            let pos = vector::pop_back(stack);
            let value = vector::pop_back(stack);
            table::upsert(&mut contract_store.storage, pos, u256_to_data(value));
            // debug::print(&utf8(b"sstore"));
            // debug::print(&evm_contract_address);
            // debug::print(&pos);
            // debug::print(&value);
            i = i + 1;
        }
            //dup1 -> dup16
        else if(opcode >= 0x80 && opcode <= 0x8f) {
            let size = vector::length(stack);
            let value = *vector::borrow(stack, size - ((opcode - 0x80 + 1) as u64));
            vector::push_back(stack, value);
            i = i + 1;
        }
            //swap1 -> swap16
        else if(opcode >= 0x90 && opcode <= 0x9f) {
            let size = vector::length(stack);
            vector::swap(stack, size - 1, size - ((opcode - 0x90 + 2) as u64));
            i = i + 1;
        }
            //iszero
        else if(opcode == 0x15) {
            let value = vector::pop_back(stack);
            if(value == 0) {
                vector::push_back(stack, 1)
            } else {
                vector::push_back(stack, 0)
            };
            i = i + 1;
        }
            //jump
        else if(opcode == 0x56) {
            let dest = vector::pop_back(stack);
            i = (dest as u64) + 1
        }
            //jumpi
        else if(opcode == 0x57) {
            let dest = vector::pop_back(stack);
            let condition = vector::pop_back(stack);
            if(condition > 0) {
                i = (dest as u64) + 1
            } else {
                i = i + 1
            }
        }
            //gas
        else if(opcode == 0x5a) {
            vector::push_back(stack, 0);
            i = i + 1
        }
            //jump dest (no action, continue execution)
        else if(opcode == 0x5b) {
            i = i + 1
        }
            //sha3
        else if(opcode == 0x20) {
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let bytes = slice(*memory, pos, len);
            // debug::print(&utf8(b"sha3"));
            // debug::print(&bytes);
            let value = data_to_u256(keccak256(bytes), 0, 32);
            // debug::print(&value);
            vector::push_back(stack, value);
            i = i + 1
        }
            //call 0xf1 static call 0xfa delegate call 0xf4
        else if(opcode == 0xf1 || opcode == 0xfa || opcode == 0xf4) {
            let readOnly = if (opcode == 0xfa) true else false;
            let _gas = vector::pop_back(stack);
            let evm_dest_addr = to_32bit(u256_to_data(vector::pop_back(stack)));
            let move_dest_addr = create_resource_address(&@aptos_framework, evm_dest_addr);
            let msg_value = if (opcode == 0xf1) vector::pop_back(stack) else 0;
            let m_pos = vector::pop_back(stack);
            let m_len = vector::pop_back(stack);
            let ret_pos = vector::pop_back(stack);
            let ret_len = vector::pop_back(stack);
            // debug::print(&utf8(b"call 222"));
            // debug::print(&opcode);
            // debug::print(&dest_addr);
            if (exists<Account>(move_dest_addr)) {
                let ret_end = ret_len + ret_pos;
                let params = slice(*memory, m_pos, m_len);
                let account_store_dest = borrow_global_mut<Account>(move_dest_addr);
                let target = if (opcode == 0xf4) evm_contract_address else evm_dest_addr;
                let from = if (opcode == 0xf4) sender else evm_contract_address;
                // debug::print(&utf8(b"call"));
                // debug::print(¶ms);
                // if(opcode == 0xf4) {
                //     debug::print(&utf8(b"delegate call"));
                //     debug::print(&sender);
                //     debug::print(&target);
                // };
                ret_bytes = run(from, sender, target, account_store_dest.code, params, readOnly, msg_value);
                ret_size = (vector::length(&ret_bytes) as u256);
                let index = 0;
                // if(opcode == 0xf4) {
                //     storage = simple_map::borrow_mut<vector<u8>, T>(&mut global.contracts, &contract_addr).storage;
                // };
                while (ret_pos < ret_end) {
                    let bytes = if (ret_end - ret_pos >= 32) {
                        slice(ret_bytes, index, 32)
                    } else {
                        slice(ret_bytes, index, ret_end - ret_pos)
                    };
                    mstore(memory, ret_pos, bytes);
                    ret_pos = ret_pos + 32;
                    index = index + 32;
                };
                vector::push_back(stack, 1);
            } else {
                if (opcode == 0xfa) {
                    vector::push_back(stack, 0);
                } else {
                    transfer_to_evm_addr(evm_contract_address, evm_dest_addr, msg_value);
                }
            };
            // debug::print(&opcode);
            i = i + 1
        }
            //create
        else if(opcode == 0xf0) {
            if(readOnly) {
                assert!(false, CONTRACT_READ_ONLY);
            };
            let msg_value = vector::pop_back(stack);
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let new_codes = slice(*memory, pos, len);
            let contract_store = borrow_global_mut<Account>(move_contract_address);
            let nonce = contract_store.nonce;
            // must be 20 bytes
            let new_evm_contract_addr = get_contract_address(evm_contract_address, nonce);
            debug::print(&utf8(b"create start"));
            debug::print(&new_evm_contract_addr);
            let new_move_contract_addr = create_resource_address(&@aptos_framework, new_evm_contract_addr);
            contract_store.nonce = contract_store.nonce + 1;
            debug::print(&exists<Account>(new_move_contract_addr));
            assert!(!exist_contract(new_move_contract_addr), CONTRACT_DEPLOYED);
            create_account_if_not_exist(new_move_contract_addr);
            create_event_if_not_exist(new_move_contract_addr);
            // let new_contract_store = borrow_global_mut<Account>(new_move_contract_addr);
            borrow_global_mut<Account>(move_contract_address).nonce = 1;
            borrow_global_mut<Account>(move_contract_address).is_contract = true;
            borrow_global_mut<Account>(move_contract_address).code = run(evm_contract_address, sender, new_evm_contract_addr, new_codes, x"", false, msg_value);
            debug::print(&utf8(b"create end"));
            ret_size = 32;
            ret_bytes = new_evm_contract_addr;
            vector::push_back(stack, data_to_u256(new_evm_contract_addr, 0, 32));
            i = i + 1
        }
            //create2
        else if(opcode == 0xf5) {
            if(readOnly) {
                assert!(false, CONTRACT_READ_ONLY);
            };
            let msg_value = vector::pop_back(stack);
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let salt = u256_to_data(vector::pop_back(stack));
            let new_codes = slice(*memory, pos, len);
            let p = vector::empty<u8>();
            // let contract_store = ;
            vector::append(&mut p, x"ff");
            // must be 20 bytes
            vector::append(&mut p, slice(evm_contract_address, 12, 20));
            vector::append(&mut p, salt);
            vector::append(&mut p, keccak256(new_codes));
            let new_evm_contract_addr = to_32bit(slice(keccak256(p), 12, 20));
            let new_move_contract_addr = create_resource_address(&@aptos_framework, new_evm_contract_addr);
            debug::print(&utf8(b"create2 start"));
            debug::print(&new_evm_contract_addr);
            debug::print(&exists<Account>(new_move_contract_addr));
            assert!(!exist_contract(new_move_contract_addr), CONTRACT_DEPLOYED);
            create_account_if_not_exist(new_move_contract_addr);
            create_event_if_not_exist(new_move_contract_addr);
            // debug::print(&p);
            // debug::print(&new_codes);
            // debug::print(&new_contract_addr);
            borrow_global_mut<Account>(move_contract_address).nonce = borrow_global_mut<Account>(move_contract_address).nonce + 1;
            // let new_contract_store = borrow_global_mut<Account>(new_move_contract_addr);
            borrow_global_mut<Account>(new_move_contract_addr).nonce = 1;
            borrow_global_mut<Account>(new_move_contract_addr).is_contract = true;
            borrow_global_mut<Account>(new_move_contract_addr).code = run(evm_contract_address, sender, new_evm_contract_addr, new_codes, x"", false, msg_value);
            // new_contract_store.code = code;
            ret_size = 32;
            ret_bytes = new_evm_contract_addr;
            vector::push_back(stack, data_to_u256(new_evm_contract_addr,0, 32));
            i = i + 1
        }
            //revert
        else if(opcode == 0xfd) {
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let bytes = slice(*memory, pos, len);
            debug::print(&bytes);
            // debug::print(&pos);
            // debug::print(&len);
            // debug::print(memory);
            i = i + 1;
            assert!(false, (opcode as u64));
        }
            //log0
        else if(opcode == 0xa0) {
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let data = slice(*memory, pos, len);
            let event_store = borrow_global_mut<ContractEvent>(move_contract_address);
            event::emit_event<Log0Event>(
                &mut event_store.log0Event,
                Log0Event{
                    contract: evm_contract_address,
                    data,
                },
            );
            i = i + 1
        }
            //log1
        else if(opcode == 0xa1) {
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let data = slice(*memory, pos, len);
            let topic0 = u256_to_data(vector::pop_back(stack));
            let event_store = borrow_global_mut<ContractEvent>(move_contract_address);
            event::emit_event<Log1Event>(
                &mut event_store.log1Event,
                Log1Event{
                    contract: evm_contract_address,
                    data,
                    topic0,
                },
            );
            i = i + 1
        }
            //log2
        else if(opcode == 0xa2) {
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let data = slice(*memory, pos, len);
            let topic0 = u256_to_data(vector::pop_back(stack));
            let topic1 = u256_to_data(vector::pop_back(stack));
            let event_store = borrow_global_mut<ContractEvent>(move_contract_address);
            event::emit_event<Log2Event>(
                &mut event_store.log2Event,
                Log2Event{
                    contract: evm_contract_address,
                    data,
                    topic0,
                    topic1
                },
            );
            i = i + 1
        }
            //log3
        else if(opcode == 0xa3) {
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let data = slice(*memory, pos, len);
            let topic0 = u256_to_data(vector::pop_back(stack));
            let topic1 = u256_to_data(vector::pop_back(stack));
            let topic2 = u256_to_data(vector::pop_back(stack));
            let event_store = borrow_global_mut<ContractEvent>(move_contract_address);
            event::emit_event<Log3Event>(
                &mut event_store.log3Event,
                Log3Event{
                    contract: evm_contract_address,
                    data,
                    topic0,
                    topic1,
                    topic2
                },
            );
            i = i + 1
        }
            //log4
        else if(opcode == 0xa4) {
            let pos = vector::pop_back(stack);
            let len = vector::pop_back(stack);
            let data = slice(*memory, pos, len);
            let topic0 = u256_to_data(vector::pop_back(stack));
            let topic1 = u256_to_data(vector::pop_back(stack));
            let topic2 = u256_to_data(vector::pop_back(stack));
            let topic3 = u256_to_data(vector::pop_back(stack));
            let event_store = borrow_global_mut<ContractEvent>(move_contract_address);
            event::emit_event<Log4Event>(
                &mut event_store.log4Event,
                Log4Event{
                    contract: evm_contract_address,
                    data,
                    topic0,
                    topic1,
                    topic2,
                    topic3
                },
            );
            i = i + 1
        }
        else {
            assert!(false, (opcode as u64));
        };
        // debug::print(stack);
        // debug::print(&vector::length(stack));
    };
    // simple_map::borrow_mut<vector<u8>, T>(&mut global.contracts, &contract_addr).storage = storage;
    ret_bytes
}Funciónexist_contract
exist_contractCopiar
fun exist_contract(addr: address): boolImplementación
Copiar
fun exist_contract(addr: address): bool acquires Account {
    exists<Account>(addr) && (vector::length(&borrow_global<Account>(addr).code) > 0)
}Funciónadd_balance
add_balanceCopiar
fun add_balance(addr: address, amount: u256)Implementación
Copiar
fun add_balance(addr: address, amount: u256) acquires Account {
    create_account_if_not_exist(addr);
    if(amount > 0) {
        let account_store = borrow_global_mut<Account>(addr);
        account_store.balance = account_store.balance + amount;
    }
}Funcióntransfer_from_move_addr
transfer_from_move_addrCopiar
fun transfer_from_move_addr(signer: &signer, evm_to: vector<u8>, amount: u256)Implementación
Copiar
fun transfer_from_move_addr(signer: &signer, evm_to: vector<u8>, amount: u256) acquires Account {
    if(amount > 0) {
        let move_to = create_resource_address(&@aptos_framework, evm_to);
        create_account_if_not_exist(move_to);
        coin::transfer<AptosCoin>(signer, move_to, ((amount / CONVERT_BASE)  as u64));
        let account_store_to = borrow_global_mut<Account>(move_to);
        account_store_to.balance = account_store_to.balance + amount;
    }
}Funcióntransfer_to_evm_addr
transfer_to_evm_addrCopiar
fun transfer_to_evm_addr(evm_from: vector<u8>, evm_to: vector<u8>, amount: u256)Implementación
Copiar
fun transfer_to_evm_addr(evm_from: vector<u8>, evm_to: vector<u8>, amount: u256) acquires Account {
    if(amount > 0) {
        let move_from = create_resource_address(&@aptos_framework, evm_from);
        let move_to = create_resource_address(&@aptos_framework, evm_to);
        let account_store_from = borrow_global_mut<Account>(move_from);
        assert!(account_store_from.balance >= amount, INSUFFIENT_BALANCE);
        account_store_from.balance = account_store_from.balance - amount;
        let account_store_to = borrow_global_mut<Account>(move_to);
        account_store_to.balance = account_store_to.balance + amount;
        let signer = create_signer(move_from);
        coin::transfer<AptosCoin>(&signer, move_to, ((amount / CONVERT_BASE)  as u64));
    }
}Funcióntransfer_to_move_addr
transfer_to_move_addrCopiar
fun transfer_to_move_addr(evm_from: vector<u8>, move_to: address, amount: u256)Implementación
Copiar
fun transfer_to_move_addr(evm_from: vector<u8>, move_to: address, amount: u256) acquires Account {
    if(amount > 0) {
        let move_from = create_resource_address(&@aptos_framework, evm_from);
        let account_store_from = borrow_global_mut<Account>(move_from);
        assert!(account_store_from.balance >= amount, INSUFFIENT_BALANCE);
        account_store_from.balance = account_store_from.balance - amount;
        let signer = create_signer(move_from);
        coin::transfer<AptosCoin>(&signer, move_to, ((amount / CONVERT_BASE)  as u64));
    }
}Funcióncreate_event_if_not_exist
create_event_if_not_existCopiar
fun create_event_if_not_exist(addr: address)Implementación
Copiar
fun create_event_if_not_exist(addr: address) {
    if(!exists<ContractEvent>(addr)) {
        let signer = create_signer(addr);
        move_to(&signer, ContractEvent {
            log0Event: new_event_handle<Log0Event>(&signer),
            log1Event: new_event_handle<Log1Event>(&signer),
            log2Event: new_event_handle<Log2Event>(&signer),
            log3Event: new_event_handle<Log3Event>(&signer),
            log4Event: new_event_handle<Log4Event>(&signer),
        })
    }
}Funcióncreate_account_if_not_exist
create_account_if_not_existCopiar
fun create_account_if_not_exist(addr: address)Implementación
Copiar
fun create_account_if_not_exist(addr: address) {
    if(!exists<Account>(addr)) {
        if(!exists_at(addr)) {
            create_account(addr);
        };
        let signer = create_signer(addr);
        coin::register<AptosCoin>(&signer);
        move_to(&signer, Account {
            code: vector::empty(),
            storage: table::new<u256, vector<u8>>(),
            balance: 0,
            is_contract: false,
            nonce: 0
        })
    };
}Funciónverify_nonce
verify_nonceCopiar
fun verify_nonce(addr: address, nonce: u64)Implementación
Copiar
fun verify_nonce(addr: address, nonce: u64) acquires Account {
    let coin_store_from = borrow_global_mut<Account>(addr);
    assert!(coin_store_from.nonce == nonce, NONCE);
    coin_store_from.nonce = coin_store_from.nonce + 1;
}Funciónverify_signature
verify_signatureCopiar
fun verify_signature(from: vector<u8>, message_hash: vector<u8>, r: vector<u8>, s: vector<u8>, v: u64)Implementación
Copiar
fun verify_signature(from: vector<u8>, message_hash: vector<u8>, r: vector<u8>, s: vector<u8>, v: u64) {
    let input_bytes = r;
    vector::append(&mut input_bytes, s);
    let signature = ecdsa_signature_from_bytes(input_bytes);
    let recovery_id = ((v - (CHAIN_ID * 2) - 35) as u8);
    let pk_recover = ecdsa_recover(message_hash, recovery_id, &signature);
    let pk = keccak256(ecdsa_raw_public_key_to_bytes(borrow(&pk_recover)));
    debug::print(&slice(pk, 12, 20));
    assert!(slice(pk, 12, 20) == from, SIGNATURE);
}Last updated
