aurora-is-near / evm2near

evm2near compiles Solidity contracts into NEAR WebAssembly contracts.
Creative Commons Zero v1.0 Universal
24 stars 4 forks source link

"ExecutionError":"WebAssembly trap: An `unreachable` opcode was executed." #4

Open Scofield-04-21-076 opened 1 year ago

Scofield-04-21-076 commented 1 year ago
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.16;

contract Calc {

    address public owner;
    uint256 public num;

    function multiply(address addr) public returns (address) {

        return addr;
    }
}

The contract can be deployed, but when I call the multiply method: near call name_contract.testnet multiply '{"addr": "account1.testnet"}' --accountId name_contract.testnet

I get an error: Error: {"index":0,"kind":{"ExecutionError":"WebAssembly trap: An unreachable opcode was executed."}}

After the call: near call name_contract.testnet multiply '{"addr": "account1.testnet"}' --accountId name_contract.testnet I expect to be returned the account passed in the function parameter: account1.testnet

birchmd commented 1 year ago

This is an interesting example @Scofield-04-21-076 . Conceptually it might make sense that Solidity's address type should map onto NEAR's AccountId type. However this minimum viable version of the compiler does make any kind of conceptual mapping; it verbatim executes the code as it would on Ethereum. Therefore, the reason for the failure is because the input account1.testnet is not a valid address (20 bytes). If you make the call with a valid input then it does work as expected, for example

$ near --networkId testnet --accountId birchmd.testnet call dev-1663014663747-27418521013742 multiply '{"addr": "0x0000000000000deadbeef0000000000000000000"}'
Scheduling a call: dev-1663014663747-27418521013742.multiply({"addr": "0x0000000000000deadbeef0000000000000000000"})

Doing account.functionCall()
Transaction Id Hh6bgj4kkWEQNKrtDDKR2Ux5eoHe6fFcpKvQUNKoTCVu
To see the transaction in the transaction explorer, please open this url in your browser
https://explorer.testnet.near.org/transactions/Hh6bgj4kkWEQNKrtDDKR2Ux5eoHe6fFcpKvQUNKoTCVu
{
  output: '0x0000000000000deadbeef0000000000000000000',
  status: 'SUCCESS'
}

We could certainly improve the error message here to give something more helpful than "unreachable", but I don't really think the quality of the error message is what you are worried about here.

Scofield-04-21-076 commented 1 year ago

But addresses in the NEAR Protocol usually look like: alice.testnet, bob.testnet, carl.testnet, alice.near or dev-1663014663747-27418521013742.

  1. Can they be converted as in the case of TRON?

  2. Should the user create an account with similar names as "0x0000000000000deadbeef0000000000000000000"? But in the case of the testnet it will look like this: "0x0000000000000deadbeef0000000000000000000.testnet". How to provide testing of contracts in such a case?

birchmd commented 1 year ago

Yes, as I said, it would make sense conceptually to map Solidity's address type to NEAR's AccountId type. However, the implementation for this is non-obvious. As you pointed out, there could be multiple ways of doing this, depending on how faithfully you want to represent NEAR's accounts.

Solving this kind of design problem is unfortunately out of scope for the project currently because we have limited resources for maintaining it. However, if you are interested in seeing this feature pushed forward then you are absolutely welcome to submit a proposal for the design, and work on the implementation if the design looks good.