Brief Intro to the Cross-Chain Communication
Last updated
Last updated
The Exsat-EVM allow communication between the EVM layer and the native Vaulta layer. This doc will cover this topic.
Each Vaulta account has a mapped reserved EVM address. The rule is using the uint64 value of the Vaulta name as the last 8 bytes of the EVM address, and then pad the rest with 0xbb. E.g. the name “eosio.evm” is mapped to “0xbbbbbbbbbbbbbbbbbbbbbbbb5530ea015b900000”
We will use addr_evm(vaulta_acct) to represent the reserved address of the vaulta_acct.
The Vaulta-EVM system is run in a way that each EVM transaction is actually part of Vaulta transactions. The EVM runtime contract will process Vaulta transactions invoking EVM transactions.
We will use evm_runtime to represent the Vaulta account of the evm runtime contract. Thus the reserved address of the evm runtime contract will be addr_evm(evm_runtime)
Each Vaulta account can call “open” action of EVM runtime to open a bridge balance. This balance can be used to hold “dusts” beyond Vaulta token precision and to hold the gas for call EVM contracts. User can deposit to this balance by sending some tokens to evm_runtime with the vaulta name of the target balance (in string) as memo.
We will call this balance the bridge balance.
Sending messages from EVM to Vaulta is done by the Bridge Massage mechanism.
The receiver Vaulta account receiver registered a message channel.
A handler can be assigned to process this message. It can be the same account as the receiver.
The min_fee sets a minimum bridge fee for bridge messages in this channel. Details will be covered below.
The EVM contracts should call bridgeMsgV0(string,bool,bytes) function at addr_evm(evm_runtime)
The three parameter for this call should be:
string receiver: the receiver vaulta name in string representation.
bool force_atomic: whether the call is atomic or not. Currently only atomic mode is supported. So this parameter should always be true.
bytes data: The message data sent to the Vaulta side.
The method is payable. Users can set a value to pay with the call.
After detected such calls, the EVM runtime contract will generate inline actons calling onbridgemsg(const bridge_message_t &message) action of the registered handler for the receiver
The message received by the handler is defined as:
Where
As mentioned above, the bridgeMsgV0 method is payable. Users can set a value to pay with the call. The value paid will go into the receiver’s balance in evm runtime contract. If a min_fee is set, the evm runtime will fail the call if the requirement is not met.
bridgeMsgV0 will ALWAYS succeed viewed from the EVM side. No logic should rely on the result of the call.
If anything is wrong during the message processing, the handler should consider failing the whole transaction if it does not want the EVM state to change.
Vaulta to EVM communication can be done by letting the Vaulta account generate EVM transactions by code.
The sender should call “open” at evm_runtime to open the bridge balance to pay for the EVM calls.
The sender should deposit some gas token to its bridge balance.
Someone could call this action of the evm_runtime to generate an EVM transaction.
One could also call the exec action to call the view functions of EVM contracts. Currently the caller can only get the result via call_backs. Support for synchronously calls will be available after the next major Vaulta upgrade.
Payment value and gas fee will be deducted from the bridge balance of the vaulta_caller