Breaking Changes v0.9
This guide is designed to highlight the key distinctions between v0.8 and v0.9, offering assistance to those transitioning an existing application or individuals already acquainted with v0.8 who require a concise overview.
Front-end
Inputs
v0.9 makes use of a single InputBox contract to receive inputs from users or other contracts (instead of each dApp having its independent entrypoint to receive inputs). The InputBox is a trustless and permissionless smart contract that keeps append-only lists for the inputs for each dApp, ensuring data availability by emitting InputAdded events for every successful input addition, allowing for encoding-agnostic and decentralized access to input data.
Deposits
ERC20
v0.9 makes use of the new depositERC20Tokens function on the ERC20Portal contract, which replaces calling erc20Deposit
on the dApp contract. The depositERC20Tokens
function:
- Transfers the specified
_amount
of_token
(ERC-20) from the message sender's account to the_dapp
address. - Encodes the transaction information (success status, token, sender, amount, and execution layer data) into an input.
- Adds the encoded input to the dApp's InputBox, enabling the off-chain execution layer to access and process the transaction information.
ERC721
v0.9 makes use of the new depositERC721Token function on the ERC721Portal contract, which replaces calling safeTransfer
on the appropriate ERC-721 contract. The depositERC721Token
function:
- Transfers the specified ERC-721
_token
with_tokenId
from the message sender's account to the_dapp
address, providing_baseLayerData
for the transfer. - Encodes the transaction information (token, sender, tokenId, base layer data, and execution layer data) into an input.
- Adds the encoded input to the dApp's InputBox.
Ether
v0.9 makes use of the new depositEther function on the EtherPortal, which replaces calling etherDeposit
on the dApp contract. The new function:
- Transfers the Ether sent along with the function call (
msg.value
) from the message sender's account to the_dapp
address. - Encodes the transaction information (sender, Ether value, and execution layer data) into an input.
- Adds the encoded input to the dApp's InputBox, enabling the off-chain execution layer to access and process the transaction information.
ERC1155
v0.9 introduces support for ERC-1155 assets, with two new methods:
depositSingleERC1155Token function on the ERC1155SinglePortal, which transfers a specified amount of an ERC-1155 token with a given ID to a dApp, while also adding an input to the dApp's InputBox to signal the operation.
depositBatchERC1155Token function on the ERC1155BatchPortal, which transfers a batch of ERC-1155 tokens with specified IDs and amounts to a dApp, while also adding an input to the dApp's InputBox to signal the operation.
GraphQL API
Epochs
All Epoch objects have been removed. This includes:
EpochConnection
EpochEdge
Epoch
All Epoch queries have been removed. This includes:
epochI
epoch
epochs
Identifiers
Removal of Epochs from the API makes all input indices global. This means that you can directly retrieve a specific input as a top-level query, just by specifying its index.
ID fields have also been removed from all objects, and now only numeric indices are used in queries for retrieving inputs and outputs.
InputFilter
It is now possible to filter inputs in the top-level inputs query by specifying the indexLowerThan
or indexGreaterThan
fields of the InputFilter object.
Proof
The internal structure of the Proof object has changed.
These changes should not affect clients using Proof objects to call executeVoucher and validateNotice functions, as long as the code does not inspect or manipulate the Proof object's internal fields.
Back-end
Handling deposits
In v0.8 TRANSFER_HEADERs
were used to identify transfers that were coming from the Portal. When the dApp received a transaction, it would check if the header of the transaction matched the TRANSFER_HEADER
. If the headers matched, the dApp would know that the transaction is a valid transfer from the Portal. If they didn't match, the transaction would be rejected.
In v0.9 Portals are identified by checking if the msg_sender
metadata field of the input matches the appropriate Portal address. Naturally, the addresses of the relevant Portals in the base layer must be known a priori by the back-end code.
Emitting withdrawal vouchers
Vouchers allow dApps in the execution layer to interact with base layer contracts through message calls, and they can be used for various applications such as withdrawing funds. In v0.9 the emission of withdrawal vouchers changed for Ether, and support for ERC-1155 assets was added.
Ether
The new function withdrawEther replaces etherWithdrawal
, and is still called on the dApp contract to transfer a specified amount of Ether, in Wei, to a designated recipient. The new withdrawEther
function now directly receives the receiver address and the amount to transfer, instead of an ABI-encoded payload containing that information.
The withdrawEther
function can only be invoked by the dApp itself through vouchers, ensuring that the transfer is limited to internal use. It checks whether the Ether was successfully sent, and raises an error if the transfer fails.
ERC-1155
To emit withdrawal vouchers for ERC-1155 tokens, you need to encode a call to either safeTransferFrom
(for single tokens) or safeBatchTransferFrom
(for multiple tokens) on the appropriate ERC-1155 contract on the base layer.
Please refer to the Assets handling section for general information about emitting withdrawal vouchers.
No more Setup Input
In v0.8 most dApps needed to know their own address on the base layer, and a mandatory "Setup Input" was always added as the very first input for every dApp. As such, the back-end code had to always be prepared to handle this very first input, from which it could safely capture its msg_sender
metadata as the dApp's contract address.
In v0.9, the dApp's address is needed only for more specific cases, and there is no longer this mandatory "Setup Input" as the very first input a dApp always receives. Instead, a special contract - DAppAddressRelay
- is introduced that allows anyone, at any time, to call it to safely relay the dApp's address as an input to be received and handled by the back-end code.
If a dApp needs to know its own address (which is required for withdrawing Ether and ERC-721 tokens), its back-end will need to handle the input sent by DAppAddressRelay
with the dApp address as payload. In this case, the back-end should know a priori the address of the DAppAddressRelay
contract on the base layer, and then check the msg_sender
metadata of the input to safely accept its payload as the trusted dApp's address.
The significant advantage of dAppAddressRelay
is its optional engagement; you only need to call it if you actually need it. For instance, a straightforward dApp like Echo Python doesn't need to concern itself with this. Another advantage is that anyone can resend that input at any time, refreshing the back-end's memory. Even if there's an update that changes the dApp's address, we can still notify the back-end about the change.